44import sys
55import signal
66import weakref
7-
87import unittest
98
9+ from test import support
10+
1011
1112@unittest .skipUnless (hasattr (os , 'kill' ), "Test requires os.kill" )
1213@unittest .skipIf (sys .platform == "win32" , "Test cannot run on Windows" )
1314class TestBreak (unittest .TestCase ):
1415 int_handler = None
16+ # This number was smart-guessed, previously tests were failing
17+ # after 7th run. So, we take `x * 2 + 1` to be sure.
18+ default_repeats = 15
1519
1620 def setUp (self ):
1721 self ._default_handler = signal .getsignal (signal .SIGINT )
@@ -24,6 +28,27 @@ def tearDown(self):
2428 unittest .signals ._interrupt_handler = None
2529
2630
31+ def withRepeats (self , test_function , repeats = None ):
32+ if not support .check_impl_detail (cpython = True ):
33+ # Override repeats count on non-cpython to execute only once.
34+ # Because this test only makes sense to be repeated on CPython.
35+ repeats = 1
36+ elif repeats is None :
37+ repeats = self .default_repeats
38+
39+ for repeat in range (repeats ):
40+ with self .subTest (repeat = repeat ):
41+ # We don't run `setUp` for the very first repeat
42+ # and we don't run `tearDown` for the very last one,
43+ # because they are handled by the test class itself.
44+ if repeat != 0 :
45+ self .setUp ()
46+ try :
47+ test_function ()
48+ finally :
49+ if repeat != repeats - 1 :
50+ self .tearDown ()
51+
2752 def testInstallHandler (self ):
2853 default_handler = signal .getsignal (signal .SIGINT )
2954 unittest .installHandler ()
@@ -48,35 +73,34 @@ def testRegisterResult(self):
4873 unittest .removeResult (result )
4974
5075 def testInterruptCaught (self ):
51- default_handler = signal .getsignal (signal .SIGINT )
52-
53- result = unittest .TestResult ()
54- unittest .installHandler ()
55- unittest .registerResult (result )
56-
57- self .assertNotEqual (signal .getsignal (signal .SIGINT ), default_handler )
58-
5976 def test (result ):
6077 pid = os .getpid ()
6178 os .kill (pid , signal .SIGINT )
6279 result .breakCaught = True
6380 self .assertTrue (result .shouldStop )
6481
65- try :
66- test (result )
67- except KeyboardInterrupt :
68- self .fail ("KeyboardInterrupt not handled" )
69- self .assertTrue (result .breakCaught )
82+ def test_function ():
83+ result = unittest .TestResult ()
84+ unittest .installHandler ()
85+ unittest .registerResult (result )
7086
87+ self .assertNotEqual (
88+ signal .getsignal (signal .SIGINT ),
89+ self ._default_handler ,
90+ )
91+
92+ try :
93+ test (result )
94+ except KeyboardInterrupt :
95+ self .fail ("KeyboardInterrupt not handled" )
96+ self .assertTrue (result .breakCaught )
97+ self .withRepeats (test_function )
7198
7299 def testSecondInterrupt (self ):
73100 # Can't use skipIf decorator because the signal handler may have
74101 # been changed after defining this method.
75102 if signal .getsignal (signal .SIGINT ) == signal .SIG_IGN :
76103 self .skipTest ("test requires SIGINT to not be ignored" )
77- result = unittest .TestResult ()
78- unittest .installHandler ()
79- unittest .registerResult (result )
80104
81105 def test (result ):
82106 pid = os .getpid ()
@@ -86,64 +110,66 @@ def test(result):
86110 os .kill (pid , signal .SIGINT )
87111 self .fail ("Second KeyboardInterrupt not raised" )
88112
89- try :
90- test (result )
91- except KeyboardInterrupt :
92- pass
93- else :
94- self .fail ("Second KeyboardInterrupt not raised" )
95- self .assertTrue (result .breakCaught )
113+ def test_function ():
114+ result = unittest .TestResult ()
115+ unittest .installHandler ()
116+ unittest .registerResult (result )
96117
118+ with self .assertRaises (KeyboardInterrupt ):
119+ test (result )
120+ self .assertTrue (result .breakCaught )
121+ self .withRepeats (test_function )
97122
98- def testTwoResults (self ):
99- unittest .installHandler ()
100123
101- result = unittest . TestResult ()
102- unittest . registerResult ( result )
103- new_handler = signal . getsignal ( signal . SIGINT )
124+ def testTwoResults ( self ):
125+ def test_function ():
126+ unittest . installHandler ( )
104127
105- result2 = unittest .TestResult ()
106- unittest .registerResult (result2 )
107- self . assertEqual ( signal .getsignal (signal .SIGINT ), new_handler )
128+ result = unittest .TestResult ()
129+ unittest .registerResult (result )
130+ new_handler = signal .getsignal (signal .SIGINT )
108131
109- result3 = unittest .TestResult ()
132+ result2 = unittest .TestResult ()
133+ unittest .registerResult (result2 )
134+ self .assertEqual (signal .getsignal (signal .SIGINT ), new_handler )
110135
111- def test (result ):
112- pid = os .getpid ()
113- os .kill (pid , signal .SIGINT )
136+ result3 = unittest .TestResult ()
114137
115- try :
116- test ( result )
117- except KeyboardInterrupt :
118- self .fail ("KeyboardInterrupt not handled" )
138+ try :
139+ os . kill ( os . getpid (), signal . SIGINT )
140+ except KeyboardInterrupt :
141+ self .fail ("KeyboardInterrupt not handled" )
119142
120- self .assertTrue (result .shouldStop )
121- self .assertTrue (result2 .shouldStop )
122- self .assertFalse (result3 .shouldStop )
143+ self .assertTrue (result .shouldStop )
144+ self .assertTrue (result2 .shouldStop )
145+ self .assertFalse (result3 .shouldStop )
146+ self .withRepeats (test_function )
123147
124148
125149 def testHandlerReplacedButCalled (self ):
126150 # Can't use skipIf decorator because the signal handler may have
127151 # been changed after defining this method.
128152 if signal .getsignal (signal .SIGINT ) == signal .SIG_IGN :
129153 self .skipTest ("test requires SIGINT to not be ignored" )
130- # If our handler has been replaced (is no longer installed) but is
131- # called by the *new* handler, then it isn't safe to delay the
132- # SIGINT and we should immediately delegate to the default handler
133- unittest .installHandler ()
134-
135- handler = signal .getsignal (signal .SIGINT )
136- def new_handler (frame , signum ):
137- handler (frame , signum )
138- signal .signal (signal .SIGINT , new_handler )
139154
140- try :
141- pid = os .getpid ()
142- os .kill (pid , signal .SIGINT )
143- except KeyboardInterrupt :
144- pass
145- else :
146- self .fail ("replaced but delegated handler doesn't raise interrupt" )
155+ def test_function ():
156+ # If our handler has been replaced (is no longer installed) but is
157+ # called by the *new* handler, then it isn't safe to delay the
158+ # SIGINT and we should immediately delegate to the default handler
159+ unittest .installHandler ()
160+
161+ handler = signal .getsignal (signal .SIGINT )
162+ def new_handler (frame , signum ):
163+ handler (frame , signum )
164+ signal .signal (signal .SIGINT , new_handler )
165+
166+ try :
167+ os .kill (os .getpid (), signal .SIGINT )
168+ except KeyboardInterrupt :
169+ pass
170+ else :
171+ self .fail ("replaced but delegated handler doesn't raise interrupt" )
172+ self .withRepeats (test_function )
147173
148174 def testRunner (self ):
149175 # Creating a TextTestRunner with the appropriate argument should
0 commit comments