4
4
import sys
5
5
import signal
6
6
import weakref
7
-
8
7
import unittest
9
8
9
+ from test import support
10
+
10
11
11
12
@unittest .skipUnless (hasattr (os , 'kill' ), "Test requires os.kill" )
12
13
@unittest .skipIf (sys .platform == "win32" , "Test cannot run on Windows" )
13
14
class TestBreak (unittest .TestCase ):
14
15
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
15
19
16
20
def setUp (self ):
17
21
self ._default_handler = signal .getsignal (signal .SIGINT )
@@ -24,6 +28,27 @@ def tearDown(self):
24
28
unittest .signals ._interrupt_handler = None
25
29
26
30
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
+
27
52
def testInstallHandler (self ):
28
53
default_handler = signal .getsignal (signal .SIGINT )
29
54
unittest .installHandler ()
@@ -48,35 +73,34 @@ def testRegisterResult(self):
48
73
unittest .removeResult (result )
49
74
50
75
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
-
59
76
def test (result ):
60
77
pid = os .getpid ()
61
78
os .kill (pid , signal .SIGINT )
62
79
result .breakCaught = True
63
80
self .assertTrue (result .shouldStop )
64
81
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 )
70
86
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 )
71
98
72
99
def testSecondInterrupt (self ):
73
100
# Can't use skipIf decorator because the signal handler may have
74
101
# been changed after defining this method.
75
102
if signal .getsignal (signal .SIGINT ) == signal .SIG_IGN :
76
103
self .skipTest ("test requires SIGINT to not be ignored" )
77
- result = unittest .TestResult ()
78
- unittest .installHandler ()
79
- unittest .registerResult (result )
80
104
81
105
def test (result ):
82
106
pid = os .getpid ()
@@ -86,64 +110,66 @@ def test(result):
86
110
os .kill (pid , signal .SIGINT )
87
111
self .fail ("Second KeyboardInterrupt not raised" )
88
112
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 )
96
117
118
+ with self .assertRaises (KeyboardInterrupt ):
119
+ test (result )
120
+ self .assertTrue (result .breakCaught )
121
+ self .withRepeats (test_function )
97
122
98
- def testTwoResults (self ):
99
- unittest .installHandler ()
100
123
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 ( )
104
127
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 )
108
131
109
- result3 = unittest .TestResult ()
132
+ result2 = unittest .TestResult ()
133
+ unittest .registerResult (result2 )
134
+ self .assertEqual (signal .getsignal (signal .SIGINT ), new_handler )
110
135
111
- def test (result ):
112
- pid = os .getpid ()
113
- os .kill (pid , signal .SIGINT )
136
+ result3 = unittest .TestResult ()
114
137
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" )
119
142
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 )
123
147
124
148
125
149
def testHandlerReplacedButCalled (self ):
126
150
# Can't use skipIf decorator because the signal handler may have
127
151
# been changed after defining this method.
128
152
if signal .getsignal (signal .SIGINT ) == signal .SIG_IGN :
129
153
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 )
139
154
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 )
147
173
148
174
def testRunner (self ):
149
175
# Creating a TextTestRunner with the appropriate argument should
0 commit comments