summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_profilehooks.py
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2001-09-22 04:28:19 (GMT)
committerFred Drake <fdrake@acm.org>2001-09-22 04:28:19 (GMT)
commit3208d4b387641edb99c16126b7062e701114d655 (patch)
tree00b5a7d7983fefacac3d7071fe11dcdb9f935ecc /Lib/test/test_profilehooks.py
parent19c1cd5b352e503c4585398d2533e5ae3bf4c189 (diff)
downloadcpython-3208d4b387641edb99c16126b7062e701114d655.zip
cpython-3208d4b387641edb99c16126b7062e701114d655.tar.gz
cpython-3208d4b387641edb99c16126b7062e701114d655.tar.bz2
Start of a test to make sure the profiler/tracer support in the core
interpreter is reporting what we expect to see.
Diffstat (limited to 'Lib/test/test_profilehooks.py')
-rw-r--r--Lib/test/test_profilehooks.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/Lib/test/test_profilehooks.py b/Lib/test/test_profilehooks.py
new file mode 100644
index 0000000..93ad552
--- /dev/null
+++ b/Lib/test/test_profilehooks.py
@@ -0,0 +1,110 @@
+import pprint
+import sys
+import unittest
+
+import test_support
+
+
+class HookWatcher:
+ def __init__(self):
+ self.frames = []
+ self.events = []
+
+ def callback(self, frame, event, arg):
+ self.add_event(event, frame)
+
+ def add_event(self, event, frame=None):
+ """Add an event to the log."""
+ if frame is None:
+ frame = sys._getframe(1)
+
+ try:
+ frameno = self.frames.index(frame)
+ except ValueError:
+ frameno = len(self.frames)
+ self.frames.append(frame)
+
+ self.events.append((frameno, event, ident(frame)))
+
+ def get_events(self):
+ """Remove calls to add_event()."""
+ add_event = self.add_event.im_func.func_code
+ disallowed = (add_event.co_firstlineno, add_event.co_name)
+
+ return [item for item in self.events if item[2] != disallowed]
+
+
+class ProfileHookTestCase(unittest.TestCase):
+
+ def check_events(self, callable, expected):
+ events = capture_events(callable)
+ if events != expected:
+ self.fail("Expected events:\n%s\nReceived events:\n%s"
+ % (pprint.pformat(expected), pprint.pformat(events)))
+
+ def test_simple(self):
+ def f(p):
+ pass
+ f_ident = ident(f)
+ self.check_events(f, [(0, 'call', f_ident),
+ (0, 'return', f_ident),
+ ])
+
+ def test_exception(self):
+ def f(p):
+ try:
+ 1/0
+ except:
+ pass
+ f_ident = ident(f)
+ self.check_events(f, [(0, 'call', f_ident),
+ (0, 'exception', f_ident),
+ (0, 'return', f_ident),
+ ])
+
+ def test_nested_exception(self):
+ def f(p):
+ 1/0
+ def g(p):
+ try:
+ f(p)
+ except:
+ pass
+ f_ident = ident(f)
+ g_ident = ident(g)
+ self.check_events(g, [(0, 'call', g_ident),
+ (1, 'call', f_ident),
+ (1, 'exception', f_ident),
+ # This isn't what I expected:
+ (0, 'exception', g_ident),
+ (0, 'return', g_ident),
+ ])
+
+
+def ident(function):
+ if hasattr(function, "f_code"):
+ code = function.f_code
+ else:
+ code = function.func_code
+ return code.co_firstlineno, code.co_name
+
+
+def capture_events(callable):
+ p = HookWatcher()
+ sys.setprofile(p.callback)
+ callable(p)
+ sys.setprofile(None)
+ return p.get_events()
+
+
+def show_events(callable):
+ import pprint
+ pprint.pprint(capture_events(callable))
+
+
+def test_main():
+ test_support.run_unittest(ProfileHookTestCase)
+
+
+if __name__ == "__main__":
+ test_main()