Viewing file: test_trace.py (5.88 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Testing the line trace facility.
import test_support import unittest import sys import difflib
if not __debug__: raise test_support.TestSkipped, "tracing not supported under -O"
# A very basic example. If this fails, we're in deep trouble. def basic(): return 1
basic.events = [(0, 'call'), (0, 'line'), (1, 'line'), (1, 'return')]
# Armin Rigo's failing example: def arigo_example(): x = 1 del x while 0: pass x = 1
arigo_example.events = [(0, 'call'), (0, 'line'), (1, 'line'), (2, 'line'), (3, 'line'), (3, 'line'), (5, 'line'), (5, 'return')]
# check that lines consisting of just one instruction get traced: def one_instr_line(): x = 1 del x x = 1
one_instr_line.events = [(0, 'call'), (0, 'line'), (1, 'line'), (2, 'line'), (3, 'line'), (3, 'return')]
def no_pop_tops(): # 0 x = 1 # 1 for a in range(2): # 2 if a: # 3 x = 1 # 4 else: # 5 x = 1 # 6
no_pop_tops.events = [(0, 'call'), (0, 'line'), (1, 'line'), (2, 'line'), (2, 'line'), (3, 'line'), (6, 'line'), (2, 'line'), (3, 'line'), (4, 'line'), (2, 'line'), (2, 'return')]
def no_pop_blocks(): while 0: bla x = 1
no_pop_blocks.events = [(0, 'call'), (0, 'line'), (1, 'line'), (1, 'line'), (3, 'line'), (3, 'return')]
def called(): # line -3 x = 1
def call(): # line 0 called()
call.events = [(0, 'call'), (0, 'line'), (1, 'line'), (-3, 'call'), (-3, 'line'), (-2, 'line'), (-2, 'return'), (1, 'return')]
def raises(): raise Exception
def test_raise(): try: raises() except Exception, exc: x = 1
test_raise.events = [(0, 'call'), (0, 'line'), (1, 'line'), (2, 'line'), (-3, 'call'), (-3, 'line'), (-2, 'line'), (-2, 'exception'), (2, 'exception'), (3, 'line'), (4, 'line'), (4, 'return')]
def _settrace_and_return(tracefunc): sys.settrace(tracefunc) sys._getframe().f_back.f_trace = tracefunc def settrace_and_return(tracefunc): _settrace_and_return(tracefunc)
settrace_and_return.events = [(1, 'return')]
def _settrace_and_raise(tracefunc): sys.settrace(tracefunc) sys._getframe().f_back.f_trace = tracefunc raise RuntimeError def settrace_and_raise(tracefunc): try: _settrace_and_raise(tracefunc) except RuntimeError, exc: pass
settrace_and_raise.events = [(2, 'exception'), (3, 'line'), (4, 'line'), (4, 'return')]
class Tracer: def __init__(self): self.events = [] def trace(self, frame, event, arg): self.events.append((frame.f_lineno, event)) return self.trace
class TraceTestCase(unittest.TestCase): def compare_events(self, line_offset, events, expected_events): events = [(l - line_offset, e) for (l, e) in events] if events != expected_events: self.fail( "events did not match expectation:\n" + "\n".join(difflib.ndiff(map(str, expected_events), map(str, events))))
def run_test(self, func): tracer = Tracer() sys.settrace(tracer.trace) func() sys.settrace(None) self.compare_events(func.func_code.co_firstlineno, tracer.events, func.events)
def run_test2(self, func): tracer = Tracer() func(tracer.trace) sys.settrace(None) self.compare_events(func.func_code.co_firstlineno, tracer.events, func.events)
def test_1_basic(self): self.run_test(basic) def test_2_arigo(self): self.run_test(arigo_example) def test_3_one_instr(self): self.run_test(one_instr_line) def test_4_no_pop_blocks(self): self.run_test(no_pop_blocks) def test_5_no_pop_tops(self): self.run_test(no_pop_tops) def test_6_call(self): self.run_test(call) def test_7_raise(self): self.run_test(test_raise)
def test_8_settrace_and_return(self): self.run_test2(settrace_and_return) def test_9_settrace_and_raise(self): self.run_test2(settrace_and_raise)
class RaisingTraceFuncTestCase(unittest.TestCase): def test_it(self): def tr(frame, event, arg): raise ValueError # just something that isn't RuntimeError def f(): return 1 try: for i in xrange(sys.getrecursionlimit() + 1): sys.settrace(tr) try: f() except ValueError: pass else: self.fail("exception not thrown!") except RuntimeError: self.fail("recursion counter not reset")
def test_main(): test_support.run_unittest(TraceTestCase) test_support.run_unittest(RaisingTraceFuncTestCase)
if __name__ == "__main__": test_main()
|