@@ -15,6 +15,40 @@ def is_soft():
1515 return softswitch
1616
1717
18+ def get_current_watchdog_list ():
19+ import gc
20+ result = []
21+
22+ def _tasklet (tlet ):
23+ if tlet is not None :
24+ assert tlet .paused
25+ gc .collect ()
26+ referrers = gc .get_referrers (tlet )
27+ for obj in referrers :
28+ if isinstance (obj , list ):
29+ result .append (obj )
30+ assert len (result ) == 1 , "list references %d" % len (l )
31+ else :
32+ stackless .tasklet (_tasklet )(stackless .current )
33+ stackless .run ()
34+ scheduled = []
35+ t = stackless .current .next
36+ while t not in (None , stackless .current ):
37+ scheduled .append (t )
38+ t = t .next
39+ for t in scheduled :
40+ t .remove ()
41+ stackless .tasklet (_tasklet )(None )
42+ try :
43+ stackless .run ()
44+ finally :
45+ for t in scheduled :
46+ t .insert ()
47+ if scheduled :
48+ assert stackless .current .next == scheduled [0 ]
49+ return result [0 ]
50+
51+
1852class SimpleScheduler (object ):
1953 """ Not really scheduler as such but used here to implement
2054 autoscheduling hack and store a schedule count. """
@@ -394,6 +428,16 @@ def setUp(self):
394428 super (TestNewWatchdog , self ).setUp ()
395429 self .done = 0
396430 self .worker = stackless .tasklet (self .worker_func )()
431+ self .watchdog_list = get_current_watchdog_list ()
432+ self .assertListEqual (self .watchdog_list , [None ], "Watchdog list is not empty before test: %r" % (self .watchdog_list ,))
433+
434+ def tearDown (self ):
435+ try :
436+ self .assertListEqual (self .watchdog_list , [None ], "Watchdog list is not empty after test: %r" % (self .watchdog_list ,))
437+ except AssertionError :
438+ self .watchdog_list [0 ] = None
439+ self .watchdog_list [1 :] = []
440+ super (TestNewWatchdog , self ).tearDown ()
397441
398442 def test_run_from_worker (self ):
399443 """Test that run() works from a different tasklet"""
@@ -538,7 +582,7 @@ def runner_func(recursive, start):
538582 if recursive :
539583 stackless .tasklet (runner_func )(recursive - 1 , start )
540584 with stackless .atomic ():
541- stackless .run (2 , soft = soft , totaltimeout = True , ignore_nesting = True )
585+ stackless .run (10000 , soft = soft , totaltimeout = True , ignore_nesting = True )
542586 a = self .awoken
543587 self .awoken += 1
544588 if recursive == start :
@@ -568,16 +612,48 @@ def test_watchdog_priority_hard(self):
568612 """Verify that outermost "real" watchdog gets awoken (hard)"""
569613 self ._test_watchdog_priority (False )
570614
615+ def _test_schedule_deeper (self , soft ):
616+ # get rid of self.worker
617+ stackless .run ()
618+ self .assertFalse (self .worker .alive )
619+ self .assertEqual (self .done , 1 )
620+ self .assertListEqual ([None ], self .watchdog_list )
621+
622+ tasklets = [None , None , None ] # watchdog1, watchdog2, worker
623+
624+ def worker ():
625+ self .assertListEqual ([tasklets [0 ], stackless .main , tasklets [0 ], tasklets [1 ]], self .watchdog_list )
626+ self .assertFalse (tasklets [1 ].scheduled )
627+ tasklets [1 ].insert ()
628+ self .done += 1
629+ for i in range (100 ):
630+ for j in range (100 ):
631+ dummy = i * j
632+ if soft :
633+ stackless .schedule ()
634+ self .done += 1
635+
636+ def watchdog2 ():
637+ tasklets [2 ] = stackless .tasklet (worker )()
638+ stackless .run ()
639+
640+ def watchdog1 ():
641+ tasklets [1 ] = stackless .tasklet (watchdog2 )()
642+ victim = stackless .run (1000 , soft = soft , ignore_nesting = True , totaltimeout = True )
643+ self .assertEqual (self .done , 2 , "worker interrupted too early or to late, adapt timeout: %d" % self .done )
644+ if not soft :
645+ self .assertEqual (tasklets [2 ], victim )
646+
647+ tasklets [0 ] = stackless .tasklet (watchdog1 )()
648+ stackless .run ()
649+ self .assertLessEqual ([None ], self .watchdog_list )
650+ stackless .run ()
651+
652+ def test_schedule_deeper_soft (self ):
653+ self ._test_schedule_deeper (True )
571654
572- def load_tests (loader , tests , pattern ):
573- """custom loader to run just a subset"""
574- suite = unittest .TestSuite ()
575- test_cases = [TestNewWatchdog ] # , TestDeadlock]
576- for test_class in test_cases :
577- tests = loader .loadTestsFromTestCase (test_class )
578- suite .addTests (tests )
579- return suite
580- del load_tests # disabled
655+ def test_schedule_deeper_hard (self ):
656+ self ._test_schedule_deeper (False )
581657
582658
583659if __name__ == '__main__' :
0 commit comments