-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrace_path_test.py
193 lines (172 loc) · 7.52 KB
/
trace_path_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# {{{ Imports
import unittest
from trace_path import TracePath
import pygraphviz as pgv
import os
import tempfile
# }}}
# {{{ Test Constructor
class TestTracePathConstructor(unittest.TestCase):
def setUp(self):
self.TestTracePath = TracePath(name="TestTracePath")
self.TestTracePathInstrumentationDisabled = TracePath(
name="TestTracePathInstrumentationDisabled", instrument=False)
@self.TestTracePathInstrumentationDisabled.inspect_function_execution
def instrumentation_disabled_function(x):
return x
instrumentation_disabled_function(2)
def test_constructor(self):
self.assertEqual(len(self.TestTracePath.function_mapping_list), 0)
self.assertEqual(self.TestTracePath.graph.number_of_nodes(), 0)
self.assertTrue(isinstance(self.TestTracePath, TracePath))
self.assertTrue(self.TestTracePath.instrument, True)
self.assertEqual(
self.TestTracePathInstrumentationDisabled.instrument, False)
self.assertTrue(
isinstance(
self.TestTracePath.function_mapping_list,
list))
self.assertTrue(
isinstance(
self.TestTracePath.function_measuring_list,
list))
self.assertTrue(isinstance(self.TestTracePath.graph, pgv.AGraph))
self.assertEqual(len(self.TestTracePathInstrumentationDisabled.function_mapping_list), 0)
# }}}
# {{{ Test Instrumentation Decorator
class TestTracePathInspectDecorator(unittest.TestCase):
# {{{ TracePath Setup
def setUp(self):
self.EmptyTestTracePath = TracePath(
name="EmptyTestTracePath", instrument=True)
self.TestTracePath = TracePath(name="TestTracePath", instrument=True)
self.TestTracePath.construct_graph()
@self.TestTracePath.inspect_function_execution
def myfunc(x, y="the_moon"):
return x
# Check if function invocations captured properly
myfunc(2, y="the_sun")
@self.TestTracePath.inspect_function_execution
def newfunc(x):
return x
def not_on_stack(x):
return newfunc(x)
self.EmptyTestTracePath.construct_graph()
# Instrument another function and check if we don't change behavior
# and we capture arguments and execution time
newfunc(2)
not_on_stack(2)
self.empty_graph_file_name = tempfile.mktemp(suffix='.svg')
self.graph_file_name = tempfile.mktemp(suffix='.svg')
# }}}
# {{{ Test Empty Case
def test_inspect_function_empty_execution(self):
# Check if empty graph handled properly
self.assertEqual(self.EmptyTestTracePath.graph.number_of_nodes(), 0)
self.assertEqual(self.EmptyTestTracePath.graph.number_of_edges(), 0)
# Instrument a function
# }}}
# {{{ Test Non Empty Case
def test_inspect_function_non_empty_execution(self):
# self.assertEqual(self.myfunc(2, y="the_sun"), 2)
# Check if function invocations captured properly
self.assertEqual(len(self.TestTracePath.function_mapping_list), 3)
self.assertEqual(len(self.TestTracePath.function_measuring_list), 3)
self.assertEqual(
self.TestTracePath.function_mapping_list[0].called,
'myfunc')
self.assertEqual(
self.TestTracePath.function_mapping_list[0].caller,
'setUp')
self.assertEqual(
str(self.TestTracePath.function_mapping_list[0].args),
'(2,)')
self.assertEqual(
self.TestTracePath.function_mapping_list[0].kwargs, {
'y': 'the_sun'})
self.assertGreater(
self.TestTracePath.function_measuring_list[0].elapsed_time, 0)
self.assertEqual(
self.TestTracePath.function_mapping_list[1].called,
'newfunc')
self.assertEqual(
self.TestTracePath.function_mapping_list[1].caller,
'setUp')
self.assertEqual(
str(self.TestTracePath.function_mapping_list[0].args),
'(2,)')
self.assertGreater(
self.TestTracePath.function_measuring_list[1].elapsed_time, 0)
# Ensure graph is empty because we haven't explicitly added anything
self.assertEqual(self.TestTracePath.graph.number_of_nodes(), 0)
self.assertEqual(self.TestTracePath.graph.number_of_edges(), 0)
self.TestTracePath.construct_graph()
not_on_stack_node = self.TestTracePath.get_node('not_on_stack')
self.assertEqual(not_on_stack_node.attr["color"], "orange")
self.TestTracePath.display_performance()
self.assertEqual(len(self.TestTracePath.stat_df), 3)
# }}}
# }}}
# {{{ Test Graph Construction
class TestTracePathGraphConstruction(unittest.TestCase):
# {{{ Graph Setup
def setUp(self):
self.EmptyTestTracePath = TracePath(
name="EmptyTestTracePath", instrument=True)
self.TestTracePath = TracePath(name="TestTracePath", instrument=True)
self.TestTracePath.construct_graph()
@self.TestTracePath.inspect_function_execution
def myfunc(x, y="the_moon"):
return x
# Check if function invocations captured properly
myfunc(2, y="the_sun")
@self.TestTracePath.inspect_function_execution
def newfunc(x):
return x
self.EmptyTestTracePath.construct_graph()
# Instrument another function and check if we don't change behavior
# and we capture arguments and execution time
newfunc(2)
self.empty_graph_file_name = tempfile.mktemp(suffix='.svg')
self.graph_file_name = tempfile.mktemp(suffix='.svg')
# }}}
# {{{ Test Empty Graph Case
def test_construct_empty_graph(self):
# Create the empty graph itself, construct_graph creates nodes
# and edges
# We called no functions from this function, hence 0 nodes and 0 edges
self.assertEqual(self.EmptyTestTracePath.graph.number_of_nodes(), 0)
self.assertEqual(self.EmptyTestTracePath.graph.number_of_edges(), 0)
self.assertRaises(
KeyError,
self.EmptyTestTracePath.graph.get_node,
'does_not_exist')
self.assertFalse(os.path.isfile(self.empty_graph_file_name))
# Write the file
self.TestTracePath.draw_graph(filename=self.empty_graph_file_name)
self.assertTrue(os.path.isfile(self.empty_graph_file_name))
# }}}
# {{{ Test Non Empty Graph Case
def test_construct_non_empty_graph(self):
# Create the graph itself, construct_graph creates nodes and edges
self.TestTracePath.construct_graph()
# We called two functions from this function, hence 3 nodes and 2 edges
self.assertEqual(self.TestTracePath.graph.number_of_nodes(), 3)
self.assertEqual(self.TestTracePath.graph.number_of_edges(), 2)
self.assertEqual(self.TestTracePath.get_node(
'newfunc').get_name(), 'newfunc')
self.assertEqual(self.TestTracePath.get_node(
'newfunc').get_name(), 'newfunc')
self.assertFalse(os.path.isfile(self.graph_file_name))
# Draw the graph itself
self.TestTracePath.draw_graph(filename=self.graph_file_name)
self.assertTrue(os.path.isfile(self.graph_file_name))
# }}}
# {{{ Graph Tear Down
def tearDown(self):
if os.path.isfile(self.graph_file_name):
os.remove(self.graph_file_name)
if os.path.isfile(self.empty_graph_file_name):
os.remove(self.empty_graph_file_name)
# }}}
# }}}