Ticket #12415: 12415_test.patch

File 12415_test.patch, 12.8 KB (added by jdemeyer, 7 years ago)
  • sage/doctest/control.py

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1362174931 -3600
    # Node ID 2deca38587e4bdbbbf411ff2c552dbf252e12cef
    # Parent  eee466f22f8ab4a9d43243c91ad22c6abb57e187
    Add tests for doctesting
    
    diff --git a/sage/doctest/control.py b/sage/doctest/control.py
    a b  
    364364            sage: DC = DocTestController(DD, [dirname])
    365365            sage: DC.expand_files_into_sources()
    366366            sage: len(DC.sources)
    367             8
     367            9
    368368            sage: DC.sources[0].optional
    369369            True
    370370
     
    453453            Sorting sources by runtime so that slower doctests are run first....
    454454            sage: print "\n".join([source.basename for source in DC.sources])
    455455            sage.doctest.util
     456            sage.doctest.test
    456457            sage.doctest.sources
    457458            sage.doctest.reporting
    458459            sage.doctest.parsing
  • new file sage/doctest/test.py

    diff --git a/sage/doctest/test.py b/sage/doctest/test.py
    new file mode 100644
    - +  
     1"""
     2Various tests for the doctesting framework.
     3
     4Many tests (with expected failures or crashes) are run in a
     5subprocess, those tests can be found in the ``tests/`` subdirectory.
     6
     7EXAMPLES::
     8
     9    sage: import signal
     10    sage: import subprocess
     11    sage: import time
     12    sage: tests_dir = os.path.join(SAGE_ROOT, 'devel', 'sage', 'sage', 'doctest', 'tests')
     13
     14Test the ``--initial`` option::
     15
     16    sage: subprocess.call(["sage", "-t", "-i", "initial.rst"], cwd=tests_dir)  # long time
     17    Running doctests...
     18    Doctesting 1 file.
     19    sage -t initial.rst
     20    **********************************************************************
     21    File "initial.rst", line 3, in sage.doctest.tests.initial
     22    Failed example:
     23        a = binomiak(10,5)
     24    Exception raised:
     25        Traceback (most recent call last):
     26        ...
     27        NameError: name 'binomiak' is not defined
     28    **********************************************************************
     29    File "initial.rst", line 13, in sage.doctest.tests.initial
     30    Failed example:
     31        binomial(10,5)
     32    Expected:
     33        255
     34    Got:
     35        252
     36    **********************************************************************
     37    ...
     38    ------------------------------------------------------------------------
     39    sage -t initial.rst  # 5 doctests failed
     40    ------------------------------------------------------------------------
     41    ...
     42    1
     43
     44Test a timeout::
     45
     46    sage: subprocess.call(["sage", "-t", "-T", "3", "99seconds.rst"], cwd=tests_dir)  # long time
     47    Running doctests...
     48    Doctesting 1 file.
     49    sage -t 99seconds.rst
     50        Time out
     51    ********************************************************************************
     52    Tests run before process timed out:
     53    ...
     54    ------------------------------------------------------------------------
     55    sage -t 99seconds.rst  # Time out
     56    ------------------------------------------------------------------------
     57    ...
     58    4
     59
     60Test handling of ``KeyboardInterrupt``s in doctests::
     61
     62    sage: subprocess.call(["sage", "-t", "keyboardinterrupt.rst"], cwd=tests_dir)  # long time
     63    Running doctests...
     64    Doctesting 1 file.
     65    sage -t keyboardinterrupt.rst
     66    **********************************************************************
     67    File "keyboardinterrupt.rst", line 11, in sage.doctest.tests.keyboardinterrupt
     68    Failed example:
     69        raise KeyboardInterrupt
     70    Exception raised:
     71        Traceback (most recent call last):
     72        ...
     73        KeyboardInterrupt
     74    **********************************************************************
     75    ...
     76    ------------------------------------------------------------------------
     77    sage -t keyboardinterrupt.rst  # 1 doctest failed
     78    ------------------------------------------------------------------------
     79    ...
     80    1
     81
     82Interrupt the doctester::
     83
     84    sage: subprocess.call(["sage", "-t", "interrupt.rst"], cwd=tests_dir)  # long time
     85    Running doctests...
     86    Doctesting 1 file.
     87    sage -t interrupt.rst
     88    Killing test interrupt.rst
     89    ------------------------------------------------------------------------
     90    Doctests interrupted: 0/1 files tested
     91    ------------------------------------------------------------------------
     92    ...
     93    128
     94
     95Interrupt the doctester when a doctest cannot be interrupted::
     96
     97    sage: F = tmp_filename()
     98    sage: env = dict(os.environ)
     99    sage: env['DOCTEST_TEST_PID_FILE'] = F  # Doctester will write its PID in this file
     100    sage: subprocess.call(["sage", "-t", "-T", "120", "interrupt_diehard.rst"], cwd=tests_dir, env=env)  # long time
     101    Running doctests...
     102    Doctesting 1 file.
     103    sage -t interrupt_diehard.rst
     104    Killing test interrupt_diehard.rst
     105    ------------------------------------------------------------------------
     106    Doctests interrupted: 0/1 files tested
     107    ------------------------------------------------------------------------
     108    ...
     109    128
     110
     111Even though the doctester master process has exited, the child process
     112is still alive, but it should be killed automatically
     113in 120 * 0.05 = 6 seconds::
     114
     115    sage: pid = int(open(F).read())    # long time
     116    sage: time.sleep(2)                # long time
     117    sage: os.kill(pid, signal.SIGHUP)  # long time; 2 seconds passed => still alive
     118    sage: time.sleep(6)                # long time
     119    sage: os.kill(pid, signal.SIGHUP)  # long time; 8 seconds passed => dead
     120    Traceback (most recent call last):
     121    ...
     122    OSError: ...
     123
     124Test a doctest failing with ``abort()``::
     125
     126    sage: subprocess.call(["sage", "-t", "abort.rst"], cwd=tests_dir)  # long time
     127    Running doctests...
     128    Doctesting 1 file.
     129    sage -t abort.rst
     130        Killed due to abort
     131    ********************************************************************************
     132    Tests run before process failed:
     133    ...
     134    ------------------------------------------------------------------------
     135    Unhandled SIGABRT: An abort() occurred in Sage.
     136    This probably occurred because a *compiled* component of Sage has a bug
     137    in it and is not properly wrapped with sig_on(), sig_off(). You might
     138    want to run Sage under gdb with 'sage -gdb' to debug this.
     139    Sage will now terminate.
     140    ------------------------------------------------------------------------
     141    ...
     142    ------------------------------------------------------------------------
     143    sage -t abort.rst  # Killed due to abort
     144    ------------------------------------------------------------------------
     145    ...
     146    16
     147
     148A different kind of crash::
     149
     150    sage: subprocess.call(["sage", "-t", "fail_and_die.rst"], cwd=tests_dir)  # long time
     151    Running doctests...
     152    Doctesting 1 file.
     153    sage -t fail_and_die.rst
     154    **********************************************************************
     155    File "fail_and_die.rst", line 6, in sage.doctest.tests.fail_and_die
     156    Failed example:
     157        this_gives_a_NameError
     158    Exception raised:
     159        Traceback (most recent call last):
     160        ...
     161        NameError: name 'this_gives_a_NameError' is not defined
     162        Killed due to kill signal
     163    ********************************************************************************
     164    Tests run before process failed:
     165    ...
     166    ------------------------------------------------------------------------
     167    sage -t fail_and_die.rst  # Killed due to kill signal
     168    ------------------------------------------------------------------------
     169    ...
     170    16
     171
     172Test running under gdb, without and with a timeout::
     173
     174    sage: subprocess.call(["sage", "-t", "--gdb", "1second.rst"], cwd=tests_dir, stdin=open(os.devnull))  # long time, optional: gdb
     175    exec gdb ...
     176    Running doctests...
     177    Doctesting 1 file.
     178    sage -t 1second.rst
     179        [2 tests, 1.0 s]
     180    ------------------------------------------------------------------------
     181    All tests passed!
     182    ------------------------------------------------------------------------
     183    ...
     184    0
     185    sage: subprocess.call(["sage", "-t", "--gdb", "-T" "5", "99seconds.rst"], cwd=tests_dir, stdin=open(os.devnull))  # long time, optional: gdb
     186    exec gdb ...
     187    Running doctests...
     188    Doctesting 1 file.
     189        Time out
     190    4
     191"""
  • new file sage/doctest/tests/1second.rst

    diff --git a/sage/doctest/tests/1second.rst b/sage/doctest/tests/1second.rst
    new file mode 100644
    - +  
     1A test taking one second::
     2
     3    sage: import time
     4    sage: time.sleep(1)
  • new file sage/doctest/tests/99seconds.rst

    diff --git a/sage/doctest/tests/99seconds.rst b/sage/doctest/tests/99seconds.rst
    new file mode 100644
    - +  
     1A test taking 99 seconds::
     2
     3    sage: import time
     4    sage: time.sleep(99)
  • new file sage/doctest/tests/abort.rst

    diff --git a/sage/doctest/tests/abort.rst b/sage/doctest/tests/abort.rst
    new file mode 100644
    - +  
     1This causes an "Unhandled SIGABRT..." which should be handled by
     2the doctester::
     3
     4    sage: from sage.tests.interrupt import *
     5    sage: unguarded_abort()
  • new file sage/doctest/tests/fail_and_die.rst

    diff --git a/sage/doctest/tests/fail_and_die.rst b/sage/doctest/tests/fail_and_die.rst
    new file mode 100644
    - +  
     1The ``NameError`` raised on the second line should be displayed, even
     2if we crash immediately afterwards::
     3
     4    sage: import time
     5    sage: import signal
     6    sage: this_gives_a_NameError
     7    sage: os.kill(os.getpid(), signal.SIGKILL)
  • new file sage/doctest/tests/initial.rst

    diff --git a/sage/doctest/tests/initial.rst b/sage/doctest/tests/initial.rst
    new file mode 100644
    - +  
     1One initial typo causes many failures::
     2
     3    sage: a = binomiak(10,5)
     4    sage: a
     5    252
     6    sage: a == factorial(10)/factorial(5)^2
     7    True
     8    sage: a//12
     9    21
     10
     11But this is a new failure::
     12
     13    sage: binomial(10,5)
     14    255
  • new file sage/doctest/tests/interrupt.rst

    diff --git a/sage/doctest/tests/interrupt.rst b/sage/doctest/tests/interrupt.rst
    new file mode 100644
    - +  
     1Interrupt the doctester (the parent process)::
     2
     3    sage: import signal
     4    sage: import time
     5    sage: os.kill(os.getppid(), signal.SIGINT)
     6    sage: time.sleep(10)
     7    sage: os._exit(0)
  • new file sage/doctest/tests/interrupt_diehard.rst

    diff --git a/sage/doctest/tests/interrupt_diehard.rst b/sage/doctest/tests/interrupt_diehard.rst
    new file mode 100644
    - +  
     1Save the current PID to the file given by :envvar:DOCTEST_TEST_PID_FILE::
     2
     3    sage: open(os.environ['DOCTEST_TEST_PID_FILE'], "w").write(str(os.getpid()))
     4
     5Interrupt the doctester (the parent process) while blocking the hangup
     6signal (used to kill this process)::
     7
     8    sage: import signal
     9    sage: import time
     10    sage: from sage.ext.pselect import PSelecter
     11    sage: with PSelecter([signal.SIGHUP]):
     12    ....:     os.kill(os.getppid(), signal.SIGINT)
     13    ....:     time.sleep(30)
  • new file sage/doctest/tests/keyboardinterrupt.rst

    diff --git a/sage/doctest/tests/keyboardinterrupt.rst b/sage/doctest/tests/keyboardinterrupt.rst
    new file mode 100644
    - +  
     1We explicitly raise an interrupt and expect it::
     2
     3    sage: raise KeyboardInterrupt
     4    Traceback (most recent call last):
     5    ...
     6    KeyboardInterrupt
     7
     8We now raise an interrupt without expecting it, which should lead to
     9an ordinary doctest failure::
     10
     11    sage: raise KeyboardInterrupt
  • new file sage/doctest/tests/nodoctest.py

    diff --git a/sage/doctest/tests/nodoctest.py b/sage/doctest/tests/nodoctest.py
    new file mode 100644
    - +  
     1"""
     2This directories contains various files with doctests to test the
     3doctesting framework. Many of these are supposed to fail in various
     4ways. They are run by ``../test.py``.
     5"""
  • new file sage/doctest/tests/sleep_and_raise.rst

    diff --git a/sage/doctest/tests/sleep_and_raise.rst b/sage/doctest/tests/sleep_and_raise.rst
    new file mode 100644
    - +  
     1This is a file used to manually test terminal and interrupt handling::
     2
     3    sage: for i in range(100): print i
     4    0
     5    1
     6    2
     7    3
     8    4
     9    5
     10    6
     11    7
     12    8
     13    9
     14    10
     15    11
     16    12
     17    13
     18    14
     19    15
     20    16
     21    17
     22    18
     23    19
     24    20
     25    21
     26    22
     27    23
     28    24
     29    25
     30    26
     31    27
     32    28
     33    29
     34    30
     35    31
     36    32
     37    33
     38    34
     39    35
     40    36
     41    37
     42    38
     43    39
     44    40
     45    41
     46    42
     47    43
     48    44
     49    45
     50    46
     51    47
     52    48
     53    49
     54    50
     55    51
     56    52
     57    53
     58    54
     59    55
     60    56
     61    57
     62    58
     63    59
     64    60
     65    61
     66    62
     67    63
     68    64
     69    65
     70    66
     71    67
     72    68
     73    69
     74    70
     75    71
     76    72
     77    73
     78    74
     79    75
     80    76
     81    77
     82    78
     83    79
     84    80
     85    81
     86    82
     87    83
     88    84
     89    85
     90    86
     91    87
     92    88
     93    89
     94    90
     95    91
     96    92
     97    93
     98    94
     99    95
     100    96
     101    97
     102    98
     103    99
     104    sage: import time
     105    sage: time.sleep(10)
     106    sage: raise RuntimeError