Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/doctest/test.py
8817 views
1
"""
2
Test the doctesting framework
3
4
Many tests (with expected failures or crashes) are run in a
5
subprocess, those tests can be found in the ``tests/`` subdirectory.
6
7
EXAMPLES::
8
9
sage: import signal
10
sage: import subprocess
11
sage: import time
12
sage: from sage.env import SAGE_SRC
13
sage: tests_dir = os.path.join(SAGE_SRC, 'sage', 'doctest', 'tests')
14
sage: tests_env = dict(os.environ)
15
16
Unset :envvar:`TERM` when running doctests, see :trac:`14370`::
17
18
sage: try:
19
....: del tests_env['TERM']
20
....: except KeyError:
21
....: pass
22
sage: kwds = {'cwd': tests_dir, 'env':tests_env}
23
24
Check that :trac:`2235` has been fixed::
25
26
sage: subprocess.call(["sage", "-t", "longtime.rst"], **kwds) # long time
27
Running doctests...
28
Doctesting 1 file.
29
sage -t longtime.rst
30
[0 tests, ...s]
31
----------------------------------------------------------------------
32
All tests passed!
33
----------------------------------------------------------------------
34
...
35
0
36
sage: subprocess.call(["sage", "-t", "-l", "longtime.rst"], **kwds) # long time
37
Running doctests...
38
Doctesting 1 file.
39
sage -t --long longtime.rst
40
[1 test, ...s]
41
----------------------------------------------------------------------
42
All tests passed!
43
----------------------------------------------------------------------
44
...
45
0
46
47
Test the ``--initial`` option::
48
49
sage: subprocess.call(["sage", "-t", "-i", "initial.rst"], **kwds) # long time
50
Running doctests...
51
Doctesting 1 file.
52
sage -t initial.rst
53
**********************************************************************
54
File "initial.rst", line 4, in sage.doctest.tests.initial
55
Failed example:
56
a = binomiak(10,5) # random to test that we still get the exception
57
Exception raised:
58
Traceback (most recent call last):
59
...
60
NameError: name 'binomiak' is not defined
61
**********************************************************************
62
File "initial.rst", line 14, in sage.doctest.tests.initial
63
Failed example:
64
binomial(10,5)
65
Expected:
66
255
67
Got:
68
252
69
**********************************************************************
70
...
71
----------------------------------------------------------------------
72
sage -t initial.rst # 5 doctests failed
73
----------------------------------------------------------------------
74
...
75
1
76
77
Test a timeout using the ``SAGE_TIMEOUT`` environment variable::
78
79
sage: from copy import deepcopy
80
sage: kwds2 = deepcopy(kwds)
81
sage: kwds2['env']['SAGE_TIMEOUT'] = "3"
82
sage: subprocess.call(["sage", "-t", "99seconds.rst"], **kwds2) # long time
83
Running doctests...
84
Doctesting 1 file.
85
sage -t 99seconds.rst
86
Timed out
87
**********************************************************************
88
Tests run before process (pid=...) timed out:
89
...
90
----------------------------------------------------------------------
91
sage -t 99seconds.rst # Timed out
92
----------------------------------------------------------------------
93
...
94
4
95
96
Test handling of ``KeyboardInterrupt`` in doctests::
97
98
sage: subprocess.call(["sage", "-t", "keyboardinterrupt.rst"], **kwds) # long time
99
Running doctests...
100
Doctesting 1 file.
101
sage -t keyboardinterrupt.rst
102
**********************************************************************
103
File "keyboardinterrupt.rst", line 11, in sage.doctest.tests.keyboardinterrupt
104
Failed example:
105
raise KeyboardInterrupt
106
Exception raised:
107
Traceback (most recent call last):
108
...
109
KeyboardInterrupt
110
**********************************************************************
111
...
112
----------------------------------------------------------------------
113
sage -t keyboardinterrupt.rst # 1 doctest failed
114
----------------------------------------------------------------------
115
...
116
1
117
118
Interrupt the doctester::
119
120
sage: subprocess.call(["sage", "-t", "interrupt.rst"], **kwds) # long time
121
Running doctests...
122
Doctesting 1 file.
123
sage -t interrupt.rst
124
Killing test interrupt.rst
125
----------------------------------------------------------------------
126
Doctests interrupted: 0/1 files tested
127
----------------------------------------------------------------------
128
...
129
128
130
131
Interrupt the doctester (while parallel testing) when a doctest cannot
132
be interrupted. We also test that passing a ridiculous number of threads
133
doesn't hurt::
134
135
sage: F = tmp_filename()
136
sage: from copy import deepcopy
137
sage: kwds2 = deepcopy(kwds)
138
sage: kwds2['env']['DOCTEST_TEST_PID_FILE'] = F # Doctester will write its PID in this file
139
sage: subprocess.call(["sage", "-tp", "1000000", "--timeout=120", # long time
140
....: "99seconds.rst", "interrupt_diehard.rst"], **kwds2)
141
Running doctests...
142
Doctesting 2 files using 1000000 threads.
143
Killing test 99seconds.rst
144
Killing test interrupt_diehard.rst
145
----------------------------------------------------------------------
146
Doctests interrupted: 0/2 files tested
147
----------------------------------------------------------------------
148
...
149
128
150
151
Even though the doctester master process has exited, the child process
152
is still alive, but it should be killed automatically
153
in max(20, 120 * 0.05) = 20 seconds::
154
155
sage: pid = int(open(F).read()) # long time
156
sage: time.sleep(2) # long time
157
sage: os.kill(pid, signal.SIGHUP) # long time; 2 seconds passed => still alive
158
sage: time.sleep(23) # long time
159
sage: os.kill(pid, signal.SIGHUP) # long time; 25 seconds passed => dead
160
Traceback (most recent call last):
161
...
162
OSError: ...
163
164
Test a doctest failing with ``abort()``::
165
166
sage: subprocess.call(["sage", "-t", "abort.rst"], **kwds) # long time
167
Running doctests...
168
Doctesting 1 file.
169
sage -t abort.rst
170
Killed due to abort
171
**********************************************************************
172
Tests run before process (pid=...) failed:
173
...
174
------------------------------------------------------------------------
175
Unhandled SIGABRT: An abort() occurred in Sage.
176
This probably occurred because a *compiled* component of Sage has a bug
177
in it and is not properly wrapped with sig_on(), sig_off().
178
Sage will now terminate.
179
------------------------------------------------------------------------
180
...
181
----------------------------------------------------------------------
182
sage -t abort.rst # Killed due to abort
183
----------------------------------------------------------------------
184
...
185
16
186
187
A different kind of crash::
188
189
sage: subprocess.call(["sage", "-t", "fail_and_die.rst"], **kwds) # long time
190
Running doctests...
191
Doctesting 1 file.
192
sage -t fail_and_die.rst
193
**********************************************************************
194
File "fail_and_die.rst", line 5, in sage.doctest.tests.fail_and_die
195
Failed example:
196
this_gives_a_NameError
197
Exception raised:
198
Traceback (most recent call last):
199
...
200
NameError: name 'this_gives_a_NameError' is not defined
201
Killed due to kill signal
202
**********************************************************************
203
Tests run before process (pid=...) failed:
204
...
205
----------------------------------------------------------------------
206
sage -t fail_and_die.rst # Killed due to kill signal
207
----------------------------------------------------------------------
208
...
209
16
210
211
Test that ``sig_on_count`` is checked correctly::
212
213
sage: subprocess.call(["sage", "-t", "sig_on.rst"], **kwds) # long time
214
Running doctests...
215
Doctesting 1 file.
216
sage -t sig_on.rst
217
**********************************************************************
218
File "sig_on.rst", line 5, in sage.doctest.tests.sig_on
219
Failed example:
220
sig_on_count()
221
Expected:
222
0
223
Got:
224
1
225
**********************************************************************
226
1 item had failures:
227
1 of 4 in sage.doctest.tests.sig_on
228
[2 tests, 1 failure, ...]
229
----------------------------------------------------------------------
230
sage -t sig_on.rst # 1 doctest failed
231
----------------------------------------------------------------------
232
...
233
1
234
235
Test the ``--debug`` option::
236
237
sage: subprocess.call(["sage", "-t", "--debug", "simple_failure.rst"], stdin=open(os.devnull), **kwds) # long time
238
Running doctests...
239
Doctesting 1 file.
240
sage -t simple_failure.rst
241
**********************************************************************
242
File "simple_failure.rst", line 7, in sage.doctest.tests.simple_failure
243
Failed example:
244
a * b
245
Expected:
246
20
247
Got:
248
15
249
**********************************************************************
250
Previously executed commands:
251
s...: a = 3
252
s...: b = 5
253
s...: a + b
254
8
255
debug:
256
<BLANKLINE>
257
Returning to doctests...
258
**********************************************************************
259
1 item had failures:
260
1 of 5 in sage.doctest.tests.simple_failure
261
[4 tests, 1 failure, ...]
262
----------------------------------------------------------------------
263
sage -t simple_failure.rst # 1 doctest failed
264
----------------------------------------------------------------------
265
...
266
1
267
268
Test running under gdb, without and with a timeout::
269
270
sage: subprocess.call(["sage", "-t", "--gdb", "1second.rst"], stdin=open(os.devnull), **kwds) # long time, optional: gdb
271
exec gdb ...
272
Running doctests...
273
Doctesting 1 file.
274
sage -t 1second.rst
275
[2 tests, ... s]
276
----------------------------------------------------------------------
277
All tests passed!
278
----------------------------------------------------------------------
279
...
280
0
281
sage: subprocess.call(["sage", "-t", "--gdb", "-T" "5", "99seconds.rst"], stdin=open(os.devnull), **kwds) # long time, optional: gdb
282
exec gdb ...
283
Running doctests...
284
Timed out
285
4
286
287
Test the ``--show-skipped`` option::
288
289
sage: subprocess.call(["sage", "-t", "--show-skipped", "show_skipped.rst"], **kwds) # long time
290
Running doctests ...
291
Doctesting 1 file.
292
sage -t show_skipped.rst
293
1 unlabeled test not run
294
2 tests not run due to known bugs
295
1 gap test not run
296
1 long test not run
297
1 other test skipped
298
[1 test, ... s]
299
----------------------------------------------------------------------
300
All tests passed!
301
----------------------------------------------------------------------
302
...
303
0
304
305
Optional tests are run correctly::
306
307
sage: subprocess.call(["sage", "-t", "--long", "--show-skipped", "--optional=sage,gap", "show_skipped.rst"], **kwds) # long time
308
Running doctests ...
309
Doctesting 1 file.
310
sage -t --long show_skipped.rst
311
1 unlabeled test not run
312
2 tests not run due to known bugs
313
1 other test skipped
314
[3 tests, ... s]
315
----------------------------------------------------------------------
316
All tests passed!
317
----------------------------------------------------------------------
318
...
319
0
320
321
sage: subprocess.call(["sage", "-t", "--long", "--show-skipped", "--optional=gAp", "show_skipped.rst"], **kwds) # long time
322
Running doctests ...
323
Doctesting 1 file.
324
sage -t --long show_skipped.rst
325
1 unlabeled test not run
326
2 tests not run due to known bugs
327
1 sage test not run
328
1 other test skipped
329
[2 tests, ... s]
330
----------------------------------------------------------------------
331
All tests passed!
332
----------------------------------------------------------------------
333
...
334
0
335
336
Test an invalid value for ``--optional``::
337
338
sage: subprocess.call(["sage", "-t", "--optional=bad-option", "show_skipped.rst"], **kwds)
339
Traceback (most recent call last):
340
...
341
ValueError: invalid optional tag 'bad-option'
342
1
343
344
Test ``atexit`` support in the doctesting framework::
345
346
sage: F = tmp_filename()
347
sage: os.path.isfile(F)
348
True
349
sage: from copy import deepcopy
350
sage: kwds2 = deepcopy(kwds)
351
sage: kwds2['env']['DOCTEST_DELETE_FILE'] = F
352
sage: subprocess.call(["sage", "-t", "atexit.rst"], **kwds2) # long time
353
Running doctests...
354
Doctesting 1 file.
355
sage -t atexit.rst
356
[3 tests, ... s]
357
----------------------------------------------------------------------
358
All tests passed!
359
----------------------------------------------------------------------
360
...
361
0
362
sage: os.path.isfile(F) # long time
363
False
364
sage: try:
365
....: os.unlink(F)
366
....: except OSError:
367
....: pass
368
"""
369
370