@@ -79,3 +79,107 @@ def fake_func(self):
79
79
self .global_context = span_context
80
80
self .global_trace_id = span_context .trace_id
81
81
self .global_span_id = span_context .span_id
82
+
83
+ def print_square (self , num ):
84
+ with self ._tracer .start_as_current_span ("square" ):
85
+ return num * num
86
+
87
+ def print_cube (self , num ):
88
+ with self ._tracer .start_as_current_span ("cube" ):
89
+ return num * num * num
90
+
91
+ def print_square_with_thread (self , num ):
92
+ with self ._tracer .start_as_current_span ("square" ):
93
+ cube_thread = threading .Thread (target = self .print_cube , args = (10 ,))
94
+
95
+ cube_thread .start ()
96
+ cube_thread .join ()
97
+ return num * num
98
+
99
+ def calculate (self , num ):
100
+ with self ._tracer .start_as_current_span ("calculate" ):
101
+ square_thread = threading .Thread (
102
+ target = self .print_square , args = (num ,)
103
+ )
104
+ cube_thread = threading .Thread (target = self .print_cube , args = (num ,))
105
+ square_thread .start ()
106
+ square_thread .join ()
107
+
108
+ cube_thread .start ()
109
+ cube_thread .join ()
110
+
111
+ def test_without_thread_nesting (self ):
112
+ square_thread = threading .Thread (target = self .print_square , args = (10 ,))
113
+
114
+ with self ._tracer .start_as_current_span ("root" ):
115
+ square_thread .start ()
116
+ square_thread .join ()
117
+
118
+ spans = self .memory_exporter .get_finished_spans ()
119
+ self .assertEqual (len (spans ), 2 )
120
+
121
+ # pylint: disable=unbalanced-tuple-unpacking
122
+ target , root = spans [:2 ]
123
+
124
+ self .assertIs (target .parent , root .get_span_context ())
125
+ self .assertIsNone (root .parent )
126
+
127
+ def test_with_thread_nesting (self ):
128
+ #
129
+ # Following scenario is tested.
130
+ # threadA -> methodA -> threadB -> methodB
131
+ #
132
+
133
+ square_thread = threading .Thread (
134
+ target = self .print_square_with_thread , args = (10 ,)
135
+ )
136
+
137
+ with self ._tracer .start_as_current_span ("root" ):
138
+ square_thread .start ()
139
+ square_thread .join ()
140
+
141
+ spans = self .memory_exporter .get_finished_spans ()
142
+
143
+ self .assertEqual (len (spans ), 3 )
144
+ # pylint: disable=unbalanced-tuple-unpacking
145
+ cube , square , root = spans [:3 ]
146
+
147
+ self .assertIs (cube .parent , square .get_span_context ())
148
+ self .assertIs (square .parent , root .get_span_context ())
149
+ self .assertIsNone (root .parent )
150
+
151
+ def test_with_thread_multi_nesting (self ):
152
+ #
153
+ # Following scenario is tested.
154
+ # / threadB -> methodB
155
+ # threadA -> methodA ->
156
+ # \ threadC -> methodC
157
+ #
158
+ calculate_thread = threading .Thread (target = self .calculate , args = (10 ,))
159
+
160
+ with self ._tracer .start_as_current_span ("root" ):
161
+ calculate_thread .start ()
162
+ calculate_thread .join ()
163
+
164
+ spans = self .memory_exporter .get_finished_spans ()
165
+
166
+ self .assertEqual (len (spans ), 4 )
167
+
168
+ # pylint: disable=unbalanced-tuple-unpacking
169
+ cube , square , calculate , root = spans [:4 ]
170
+
171
+ self .assertIs (cube .parent , calculate .get_span_context ())
172
+ self .assertIs (square .parent , calculate .get_span_context ())
173
+ self .assertIs (calculate .parent , root .get_span_context ())
174
+ self .assertIsNone (root .parent )
175
+
176
+ def test_uninstrumented (self ):
177
+ ThreadingInstrumentor ().uninstrument ()
178
+
179
+ square_thread = threading .Thread (target = self .print_square , args = (10 ,))
180
+ square_thread .start ()
181
+ square_thread .join ()
182
+ spans = self .memory_exporter .get_finished_spans ()
183
+ self .assertEqual (len (spans ), 1 )
184
+
185
+ ThreadingInstrumentor ().instrument ()
0 commit comments