Skip to content

Commit c534a2c

Browse files
authored
Zipkin: More deterministic unit test for comparing zipkin annotations (open-telemetry#1168)
Zipkin annotation values are strings containing JSON documents. We cannot have deterministic ordering of event attributes as they may come in any order and python versions older than 3.7 don't have ordered dicts. We extract the annotations from exported spans, parse the JSON documents into Python dicts and then compare them.
1 parent b255940 commit c534a2c

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

exporter/opentelemetry-exporter-zipkin/tests/test_zipkin_exporter.py

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,8 @@ def test_constructor_explicit(self):
9898
self.assertEqual(exporter.ipv6, ipv6)
9999
self.assertEqual(exporter.url, url)
100100

101-
# pylint: disable=too-many-locals
101+
# pylint: disable=too-many-locals,too-many-statements
102102
def test_export(self):
103-
104103
span_names = ("test1", "test2", "test3", "test4")
105104
trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
106105
span_id = 0x34BF92DEEFC58C92
@@ -204,7 +203,7 @@ def test_export(self):
204203
local_endpoint = {"serviceName": service_name, "port": 9411}
205204

206205
exporter = ZipkinSpanExporter(service_name)
207-
expected = [
206+
expected_spans = [
208207
{
209208
"traceId": format(trace_id, "x"),
210209
"id": format(span_id, "x"),
@@ -220,22 +219,20 @@ def test_export(self):
220219
"otel.status_code": "2",
221220
"otel.status_description": "Example description",
222221
},
222+
"debug": True,
223+
"parentId": format(parent_id, "x"),
223224
"annotations": [
224225
{
225226
"timestamp": event_timestamp // 10 ** 3,
226-
"value": json.dumps(
227-
{
228-
"event0": {
229-
"annotation_bool": True,
230-
"annotation_string": "annotation_test",
231-
"key_float": 0.3,
232-
}
227+
"value": {
228+
"event0": {
229+
"annotation_bool": True,
230+
"annotation_string": "annotation_test",
231+
"key_float": 0.3,
233232
}
234-
),
233+
},
235234
}
236235
],
237-
"debug": True,
238-
"parentId": format(parent_id, "x"),
239236
},
240237
{
241238
"traceId": format(trace_id, "x"),
@@ -289,11 +286,21 @@ def test_export(self):
289286
status = exporter.export(otel_spans)
290287
self.assertEqual(SpanExportResult.SUCCESS, status)
291288

292-
mock_post.assert_called_with(
293-
url="http://localhost:9411/api/v2/spans",
294-
data=json.dumps(expected),
295-
headers={"Content-Type": "application/json"},
289+
# pylint: disable=unsubscriptable-object
290+
kwargs = mock_post.call_args[1]
291+
292+
self.assertEqual(kwargs["url"], "http://localhost:9411/api/v2/spans")
293+
actual_spans = sorted(
294+
json.loads(kwargs["data"]), key=lambda span: span["timestamp"]
296295
)
296+
for expected, actual in zip(expected_spans, actual_spans):
297+
expected_annotations = expected.pop("annotations", None)
298+
actual_annotations = actual.pop("annotations", None)
299+
if actual_annotations:
300+
for annotation in actual_annotations:
301+
annotation["value"] = json.loads(annotation["value"])
302+
self.assertEqual(expected, actual)
303+
self.assertEqual(expected_annotations, actual_annotations)
297304

298305
# pylint: disable=too-many-locals
299306
def test_zero_padding(self):

0 commit comments

Comments
 (0)