]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | #include <opentracing/mocktracer/in_memory_recorder.h> |
2 | #include <opentracing/mocktracer/json.h> | |
3 | #include <opentracing/mocktracer/json_recorder.h> | |
4 | #include <opentracing/mocktracer/tracer.h> | |
5 | #include <opentracing/noop.h> | |
6 | #include <sstream> | |
7 | ||
8 | #define CATCH_CONFIG_MAIN | |
9 | #include <opentracing/catch2/catch.hpp> | |
10 | using namespace opentracing; | |
11 | using namespace mocktracer; | |
12 | ||
13 | TEST_CASE("tracer") { | |
14 | auto recorder = new InMemoryRecorder{}; | |
15 | MockTracerOptions tracer_options; | |
16 | tracer_options.recorder.reset(recorder); | |
17 | auto tracer = std::shared_ptr<opentracing::Tracer>{ | |
18 | new MockTracer{std::move(tracer_options)}}; | |
19 | ||
20 | SECTION("MockTracer can be constructed without a recorder.") { | |
21 | auto norecorder_tracer = std::shared_ptr<opentracing::Tracer>{ | |
22 | new MockTracer{MockTracerOptions{}}}; | |
23 | auto span = norecorder_tracer->StartSpan("a"); | |
24 | } | |
25 | ||
26 | SECTION("StartSpan applies the provided tags.") { | |
27 | { | |
28 | auto span = | |
29 | tracer->StartSpan("a", {SetTag("abc", 123), SetTag("xyz", true)}); | |
30 | CHECK(span); | |
31 | span->Finish(); | |
32 | } | |
33 | auto span = recorder->top(); | |
34 | CHECK(span.operation_name == "a"); | |
35 | std::map<std::string, Value> expected_tags = {{"abc", 123}, {"xyz", true}}; | |
36 | CHECK(span.tags == expected_tags); | |
37 | } | |
38 | ||
39 | SECTION("You can set a single child-of reference when starting a span.") { | |
40 | auto span_a = tracer->StartSpan("a"); | |
41 | CHECK(span_a); | |
42 | span_a->Finish(); | |
43 | auto span_b = tracer->StartSpan("b", {ChildOf(&span_a->context())}); | |
44 | CHECK(span_b); | |
45 | span_b->Finish(); | |
46 | auto spans = recorder->spans(); | |
47 | CHECK(spans.at(0).span_context.trace_id == | |
48 | spans.at(1).span_context.trace_id); | |
49 | std::vector<SpanReferenceData> expected_references = { | |
50 | {SpanReferenceType::ChildOfRef, spans.at(0).span_context.trace_id, | |
51 | spans.at(0).span_context.span_id}}; | |
52 | CHECK(spans.at(1).references == expected_references); | |
53 | } | |
54 | ||
55 | SECTION("You can set a single follows-from reference when starting a span.") { | |
56 | auto span_a = tracer->StartSpan("a"); | |
57 | CHECK(span_a); | |
58 | span_a->Finish(); | |
59 | auto span_b = tracer->StartSpan("b", {FollowsFrom(&span_a->context())}); | |
60 | CHECK(span_b); | |
61 | span_b->Finish(); | |
62 | auto spans = recorder->spans(); | |
63 | CHECK(spans.at(0).span_context.trace_id == | |
64 | spans.at(1).span_context.trace_id); | |
65 | std::vector<SpanReferenceData> expected_references = { | |
66 | {SpanReferenceType::FollowsFromRef, spans.at(0).span_context.trace_id, | |
67 | spans.at(0).span_context.span_id}}; | |
68 | CHECK(spans.at(1).references == expected_references); | |
69 | } | |
70 | ||
71 | SECTION("Multiple references are supported when starting a span.") { | |
72 | auto span_a = tracer->StartSpan("a"); | |
73 | CHECK(span_a); | |
74 | auto span_b = tracer->StartSpan("b"); | |
75 | CHECK(span_b); | |
76 | auto span_c = tracer->StartSpan( | |
77 | "c", {ChildOf(&span_a->context()), FollowsFrom(&span_b->context())}); | |
78 | span_a->Finish(); | |
79 | span_b->Finish(); | |
80 | span_c->Finish(); | |
81 | auto spans = recorder->spans(); | |
82 | std::vector<SpanReferenceData> expected_references = { | |
83 | {SpanReferenceType::ChildOfRef, spans.at(0).span_context.trace_id, | |
84 | spans.at(0).span_context.span_id}, | |
85 | {SpanReferenceType::FollowsFromRef, spans.at(1).span_context.trace_id, | |
86 | spans.at(1).span_context.span_id}}; | |
87 | CHECK(spans.at(2).references == expected_references); | |
88 | } | |
89 | ||
90 | SECTION( | |
91 | "Baggage from the span references are copied over to a new span " | |
92 | "context") { | |
93 | auto span_a = tracer->StartSpan("a"); | |
94 | CHECK(span_a); | |
95 | span_a->SetBaggageItem("a", "1"); | |
96 | auto span_b = tracer->StartSpan("b"); | |
97 | CHECK(span_b); | |
98 | span_b->SetBaggageItem("b", "2"); | |
99 | auto span_c = tracer->StartSpan( | |
100 | "c", {ChildOf(&span_a->context()), ChildOf(&span_b->context())}); | |
101 | CHECK(span_c); | |
102 | CHECK(span_c->BaggageItem("a") == "1"); | |
103 | CHECK(span_c->BaggageItem("b") == "2"); | |
104 | } | |
105 | ||
106 | SECTION("References to non-MockTracer spans and null pointers are ignored.") { | |
107 | auto noop_tracer = MakeNoopTracer(); | |
108 | auto noop_span = noop_tracer->StartSpan("noop"); | |
109 | CHECK(noop_span); | |
110 | StartSpanOptions options; | |
111 | options.references.push_back( | |
112 | std::make_pair(SpanReferenceType::ChildOfRef, &noop_span->context())); | |
113 | options.references.push_back( | |
114 | std::make_pair(SpanReferenceType::ChildOfRef, nullptr)); | |
115 | auto span = tracer->StartSpanWithOptions("a", options); | |
116 | CHECK(span); | |
117 | span->Finish(); | |
118 | CHECK(recorder->top().references.size() == 0); | |
119 | } | |
120 | ||
121 | SECTION("Calling Finish a second time does nothing.") { | |
122 | auto span = tracer->StartSpan("a"); | |
123 | CHECK(span); | |
124 | span->Finish(); | |
125 | CHECK(recorder->size() == 1); | |
126 | span->Finish(); | |
127 | CHECK(recorder->size() == 1); | |
128 | } | |
129 | ||
130 | SECTION("FinishWithOptions applies provided log records.") { | |
131 | std::vector<LogRecord> logs; | |
132 | { | |
133 | auto span = tracer->StartSpan("a"); | |
134 | CHECK(span); | |
135 | FinishSpanOptions options; | |
136 | auto timestamp = SystemClock::now(); | |
137 | logs = {{timestamp, {{"abc", 123}}}}; | |
138 | options.log_records = logs; | |
139 | span->FinishWithOptions(options); | |
140 | } | |
141 | auto span = recorder->top(); | |
142 | CHECK(span.operation_name == "a"); | |
143 | CHECK(span.logs == logs); | |
144 | } | |
145 | ||
146 | SECTION("Logs can be added to an active span.") { | |
147 | { | |
148 | auto span = tracer->StartSpan("a"); | |
149 | CHECK(span); | |
150 | span->Log({{"abc", 123}}); | |
151 | } | |
152 | auto span = recorder->top(); | |
153 | std::vector<std::pair<std::string, Value>> fields = {{"abc", 123}}; | |
154 | CHECK(span.logs.at(0).fields == fields); | |
155 | } | |
156 | ||
157 | SECTION("The operation name can be changed after the span is started.") { | |
158 | auto span = tracer->StartSpan("a"); | |
159 | CHECK(span); | |
160 | span->SetOperationName("b"); | |
161 | span->Finish(); | |
162 | CHECK(recorder->top().operation_name == "b"); | |
163 | } | |
164 | ||
165 | SECTION("Tags can be specified after a span is started.") { | |
166 | auto span = tracer->StartSpan("a"); | |
167 | CHECK(span); | |
168 | span->SetTag("abc", 123); | |
169 | span->Finish(); | |
170 | std::map<std::string, Value> expected_tags = {{"abc", 123}}; | |
171 | CHECK(recorder->top().tags == expected_tags); | |
172 | } | |
173 | } | |
174 | ||
175 | TEST_CASE("json_recorder") { | |
176 | auto oss = new std::ostringstream{}; | |
177 | MockTracerOptions tracer_options; | |
178 | tracer_options.recorder = std::unique_ptr<Recorder>{ | |
179 | new JsonRecorder{std::unique_ptr<std::ostream>{oss}}}; | |
180 | auto tracer = | |
181 | std::shared_ptr<Tracer>{new MockTracer{std::move(tracer_options)}}; | |
182 | ||
183 | SECTION("Spans are serialized to the stream upon Close.") { | |
184 | auto span = tracer->StartSpan("a"); | |
185 | CHECK(span); | |
186 | span->Finish(); | |
187 | tracer->Close(); | |
188 | CHECK(!oss->str().empty()); | |
189 | } | |
190 | } |