Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_distributed_tracing.cpp File Reference

Unit tests for distributed tracing functionality. More...

#include <gtest/gtest.h>
#include <thread>
#include <chrono>
#include <unordered_map>
#include <kcenon/monitoring/tracing/distributed_tracer.h>
#include <kcenon/monitoring/exporters/trace_exporters.h>
Include dependency graph for test_distributed_tracing.cpp:

Go to the source code of this file.

Classes

class  DistributedTracingTest
 
class  MockTraceExporter
 
class  ExporterIntegrationTest
 

Functions

 TEST_F (DistributedTracingTest, CreateRootSpan)
 
 TEST_F (DistributedTracingTest, CreateChildSpan)
 
 TEST_F (DistributedTracingTest, FinishSpan)
 
 TEST_F (DistributedTracingTest, CannotFinishSpanTwice)
 
 TEST_F (DistributedTracingTest, TraceContextPropagation)
 
 TEST_F (DistributedTracingTest, W3CTraceContextFormat)
 
 TEST_F (DistributedTracingTest, InjectExtractContext)
 
 TEST_F (DistributedTracingTest, StartSpanFromContext)
 
 TEST_F (DistributedTracingTest, CurrentSpanManagement)
 
 TEST_F (DistributedTracingTest, ScopedSpan)
 
 TEST_F (DistributedTracingTest, GetTrace)
 
 TEST_F (DistributedTracingTest, SpanTags)
 
 TEST_F (DistributedTracingTest, SpanStatus)
 
 TEST_F (DistributedTracingTest, BaggagePropagation)
 
 TEST_F (DistributedTracingTest, ExportSpans)
 
 TEST_F (DistributedTracingTest, TraceMacros)
 
 TEST_F (ExporterIntegrationTest, SetAndGetExporter)
 
 TEST_F (ExporterIntegrationTest, ConfigureExportSettings)
 
 TEST_F (ExporterIntegrationTest, AutoExportWhenBatchSizeReached)
 
 TEST_F (ExporterIntegrationTest, ManualFlush)
 
 TEST_F (ExporterIntegrationTest, FlushWithNoExporter)
 
 TEST_F (ExporterIntegrationTest, ExportFailureRetainsSpans)
 
 TEST_F (ExporterIntegrationTest, ExportStats)
 
 TEST_F (ExporterIntegrationTest, QueueSizeLimitEnforced)
 
 TEST_F (ExporterIntegrationTest, ExportedSpansContainCorrectData)
 

Detailed Description

Unit tests for distributed tracing functionality.

Definition in file test_distributed_tracing.cpp.

Function Documentation

◆ TEST_F() [1/25]

TEST_F ( DistributedTracingTest ,
BaggagePropagation  )

Definition at line 285 of file test_distributed_tracing.cpp.

285 {
286 auto parent_result = tracer.start_span("parent");
287 ASSERT_TRUE(parent_result.is_ok());
288 auto parent = parent_result.value();
289
290 parent->baggage["session_id"] = "abc123";
291 parent->baggage["feature_flag"] = "enabled";
292
293 auto child_result = tracer.start_child_span(*parent, "child");
294 ASSERT_TRUE(child_result.is_ok());
295 auto child = child_result.value();
296
297 // Child should inherit baggage
298 EXPECT_EQ(child->baggage["session_id"], "abc123");
299 EXPECT_EQ(child->baggage["feature_flag"], "enabled");
300
301 // Child can add its own baggage
302 child->baggage["child_data"] = "xyz";
303
304 auto grandchild_result = tracer.start_child_span(*child, "grandchild");
305 ASSERT_TRUE(grandchild_result.is_ok());
306 auto grandchild = grandchild_result.value();
307
308 // Grandchild should have all baggage
309 EXPECT_EQ(grandchild->baggage["session_id"], "abc123");
310 EXPECT_EQ(grandchild->baggage["feature_flag"], "enabled");
311 EXPECT_EQ(grandchild->baggage["child_data"], "xyz");
312}

◆ TEST_F() [2/25]

TEST_F ( DistributedTracingTest ,
CannotFinishSpanTwice  )

Definition at line 76 of file test_distributed_tracing.cpp.

76 {
77 auto span_result = tracer.start_span("test_operation");
78 ASSERT_TRUE(span_result.is_ok());
79 auto span = span_result.value();
80
81 auto first_finish = tracer.finish_span(span);
82 ASSERT_TRUE(first_finish.is_ok());
83
84 auto second_finish = tracer.finish_span(span);
85 ASSERT_TRUE(second_finish.is_err());
86}

◆ TEST_F() [3/25]

TEST_F ( DistributedTracingTest ,
CreateChildSpan  )

Definition at line 45 of file test_distributed_tracing.cpp.

45 {
46 auto parent_result = tracer.start_span("parent_operation");
47 ASSERT_TRUE(parent_result.is_ok());
48 auto parent = parent_result.value();
49
50 auto child_result = tracer.start_child_span(*parent, "child_operation");
51 ASSERT_TRUE(child_result.is_ok());
52 auto child = child_result.value();
53
54 EXPECT_EQ(child->trace_id, parent->trace_id);
55 EXPECT_NE(child->span_id, parent->span_id);
56 EXPECT_EQ(child->parent_span_id, parent->span_id);
57 EXPECT_EQ(child->operation_name, "child_operation");
58}

◆ TEST_F() [4/25]

TEST_F ( DistributedTracingTest ,
CreateRootSpan  )

Definition at line 32 of file test_distributed_tracing.cpp.

32 {
33 auto span_result = tracer.start_span("test_operation", "test_service");
34 ASSERT_TRUE(span_result.is_ok());
35
36 auto span = span_result.value();
37 EXPECT_FALSE(span->trace_id.empty());
38 EXPECT_FALSE(span->span_id.empty());
39 EXPECT_TRUE(span->parent_span_id.empty());
40 EXPECT_EQ(span->operation_name, "test_operation");
41 EXPECT_EQ(span->service_name, "test_service");
42 EXPECT_FALSE(span->is_finished());
43}

◆ TEST_F() [5/25]

TEST_F ( DistributedTracingTest ,
CurrentSpanManagement  )

Definition at line 174 of file test_distributed_tracing.cpp.

174 {
175 EXPECT_EQ(tracer.get_current_span(), nullptr);
176
177 auto span_result = tracer.start_span("test_operation");
178 ASSERT_TRUE(span_result.is_ok());
179 auto span = span_result.value();
180
181 tracer.set_current_span(span);
182 EXPECT_EQ(tracer.get_current_span(), span);
183
184 // Different thread should have different current span
185 std::thread other_thread([&]() {
186 EXPECT_EQ(tracer.get_current_span(), nullptr);
187
188 auto other_span_result = tracer.start_span("other_operation");
189 ASSERT_TRUE(other_span_result.is_ok());
190 auto other_span = other_span_result.value();
191
192 tracer.set_current_span(other_span);
193 EXPECT_EQ(tracer.get_current_span(), other_span);
194 });
195 other_thread.join();
196
197 // Original thread should still have its span
198 EXPECT_EQ(tracer.get_current_span(), span);
199}

◆ TEST_F() [6/25]

TEST_F ( DistributedTracingTest ,
ExportSpans  )

Definition at line 314 of file test_distributed_tracing.cpp.

314 {
315 std::vector<trace_span> spans_to_export;
316
317 // Create and finish spans
318 for (int i = 0; i < 5; ++i) {
319 auto span_result = tracer.start_span("operation_" + std::to_string(i));
320 ASSERT_TRUE(span_result.is_ok());
321 auto span = span_result.value();
322
323 tracer.finish_span(span);
324 spans_to_export.push_back(*span);
325 }
326
327 auto export_result = tracer.export_spans(spans_to_export);
328 ASSERT_TRUE(export_result.is_ok());
329
330 // Verify spans were stored
331 auto trace_result = tracer.get_trace(spans_to_export[0].trace_id);
332 ASSERT_TRUE(trace_result.is_ok());
333 auto trace = trace_result.value();
334
335 // Note: In this test, all spans have different trace IDs
336 // In a real scenario, they might be part of the same trace
337}

◆ TEST_F() [7/25]

TEST_F ( DistributedTracingTest ,
FinishSpan  )

Definition at line 60 of file test_distributed_tracing.cpp.

60 {
61 auto span_result = tracer.start_span("test_operation");
62 ASSERT_TRUE(span_result.is_ok());
63 auto span = span_result.value();
64
65 // Add some delay to have measurable duration
66 std::this_thread::sleep_for(std::chrono::milliseconds(10));
67
68 auto finish_result = tracer.finish_span(span);
69 ASSERT_TRUE(finish_result.is_ok());
70
71 EXPECT_TRUE(span->is_finished());
72 EXPECT_GT(span->duration.count(), 0);
73 EXPECT_EQ(span->status, trace_span::status_code::ok);
74}

◆ TEST_F() [8/25]

TEST_F ( DistributedTracingTest ,
GetTrace  )

Definition at line 217 of file test_distributed_tracing.cpp.

217 {
218 auto span1_result = tracer.start_span("operation1");
219 ASSERT_TRUE(span1_result.is_ok());
220 auto span1 = span1_result.value();
221
222 auto span2_result = tracer.start_child_span(*span1, "operation2");
223 ASSERT_TRUE(span2_result.is_ok());
224 auto span2 = span2_result.value();
225
226 auto span3_result = tracer.start_child_span(*span2, "operation3");
227 ASSERT_TRUE(span3_result.is_ok());
228 auto span3 = span3_result.value();
229
230 // Finish all spans
231 tracer.finish_span(span1);
232 tracer.finish_span(span2);
233 tracer.finish_span(span3);
234
235 // Get all spans for the trace
236 auto trace_result = tracer.get_trace(span1->trace_id);
237 ASSERT_TRUE(trace_result.is_ok());
238 auto trace = trace_result.value();
239
240 EXPECT_EQ(trace.size(), 3);
241
242 // All spans should have the same trace ID
243 for (const auto& span : trace) {
244 EXPECT_EQ(span.trace_id, span1->trace_id);
245 EXPECT_TRUE(span.is_finished());
246 }
247}

◆ TEST_F() [9/25]

TEST_F ( DistributedTracingTest ,
InjectExtractContext  )

Definition at line 124 of file test_distributed_tracing.cpp.

124 {
125 auto span_result = tracer.start_span("test_operation");
126 ASSERT_TRUE(span_result.is_ok());
127 auto span = span_result.value();
128
129 span->baggage["test_key"] = "test_value";
130
131 // Inject into carrier (simulating HTTP headers)
132 std::unordered_map<std::string, std::string> headers;
133 auto context = tracer.extract_context(*span);
134 tracer.inject_context(context, headers);
135
136 EXPECT_TRUE(headers.contains("traceparent"));
137 EXPECT_TRUE(headers.contains("baggage-test_key"));
138
139 // Verify traceparent header format (00-traceid-spanid-flags)
140 auto traceparent = headers["traceparent"];
141 EXPECT_EQ(traceparent.substr(0, 3), "00-");
142 EXPECT_FALSE(traceparent.empty());
143
144 // Extract from carrier
145 auto extracted_result = tracer.extract_context_from_carrier(headers);
146 ASSERT_TRUE(extracted_result.is_ok());
147 auto extracted = extracted_result.value();
148
149 // Verify baggage is preserved through inject/extract cycle
150 EXPECT_EQ(extracted.baggage["test_key"], "test_value");
151
152 // Verify trace_id and span_id are extracted (may differ from original due to W3C format)
153 EXPECT_FALSE(extracted.trace_id.empty());
154 EXPECT_FALSE(extracted.span_id.empty());
155}

◆ TEST_F() [10/25]

TEST_F ( DistributedTracingTest ,
ScopedSpan  )

Definition at line 201 of file test_distributed_tracing.cpp.

201 {
202 {
203 auto span_result = tracer.start_span("scoped_operation");
204 ASSERT_TRUE(span_result.is_ok());
205 scoped_span scoped(span_result.value(), &tracer);
206
207 EXPECT_EQ(tracer.get_current_span(), span_result.value());
208 EXPECT_FALSE(scoped->is_finished());
209
210 // Span should be accessible via scoped object
211 scoped->tags["custom_tag"] = "custom_value";
212 }
213 // Span should be finished after leaving scope
214 // Note: We can't directly check as the span is finished and stored
215}
Scoped span for RAII-style span management.

References kcenon::monitoring::trace_span::is_finished(), and kcenon::monitoring::trace_span::tags.

Here is the call graph for this function:

◆ TEST_F() [11/25]

TEST_F ( DistributedTracingTest ,
SpanStatus  )

Definition at line 268 of file test_distributed_tracing.cpp.

268 {
269 auto span_result = tracer.start_span("status_operation");
270 ASSERT_TRUE(span_result.is_ok());
271 auto span = span_result.value();
272
273 EXPECT_EQ(span->status, trace_span::status_code::unset);
274
275 // Set error status
276 span->status = trace_span::status_code::error;
277 span->status_message = "Operation failed due to timeout";
278
279 tracer.finish_span(span);
280
281 EXPECT_EQ(span->status, trace_span::status_code::error);
282 EXPECT_EQ(span->status_message, "Operation failed due to timeout");
283}

◆ TEST_F() [12/25]

TEST_F ( DistributedTracingTest ,
SpanTags  )

Definition at line 249 of file test_distributed_tracing.cpp.

249 {
250 auto span_result = tracer.start_span("tagged_operation", "my_service");
251 ASSERT_TRUE(span_result.is_ok());
252 auto span = span_result.value();
253
254 // Check default tags
255 EXPECT_EQ(span->tags["span.kind"], "internal");
256 EXPECT_EQ(span->tags["service.name"], "my_service");
257
258 // Add custom tags
259 span->tags["http.method"] = "GET";
260 span->tags["http.status_code"] = "200";
261 span->tags["user.id"] = "user123";
262
263 EXPECT_EQ(span->tags["http.method"], "GET");
264 EXPECT_EQ(span->tags["http.status_code"], "200");
265 EXPECT_EQ(span->tags["user.id"], "user123");
266}

◆ TEST_F() [13/25]

TEST_F ( DistributedTracingTest ,
StartSpanFromContext  )

Definition at line 157 of file test_distributed_tracing.cpp.

157 {
158 // Simulate incoming request with trace context
159 trace_context incoming_ctx;
160 incoming_ctx.trace_id = "0af7651916cd43dd8448eb211c80319c";
161 incoming_ctx.span_id = "b7ad6b7169203331";
162 incoming_ctx.baggage["user_id"] = "67890";
163
164 auto span_result = tracer.start_span_from_context(incoming_ctx, "handle_request");
165 ASSERT_TRUE(span_result.is_ok());
166 auto span = span_result.value();
167
168 EXPECT_EQ(span->trace_id, incoming_ctx.trace_id);
169 EXPECT_NE(span->span_id, incoming_ctx.span_id); // New span ID
170 EXPECT_EQ(span->parent_span_id, incoming_ctx.span_id);
171 EXPECT_EQ(span->baggage["user_id"], "67890");
172}
Trace context for propagation across service boundaries.
std::unordered_map< std::string, std::string > baggage

References kcenon::monitoring::trace_context::baggage, kcenon::monitoring::trace_context::span_id, and kcenon::monitoring::trace_context::trace_id.

◆ TEST_F() [14/25]

TEST_F ( DistributedTracingTest ,
TraceContextPropagation  )

Definition at line 88 of file test_distributed_tracing.cpp.

88 {
89 auto span_result = tracer.start_span("test_operation");
90 ASSERT_TRUE(span_result.is_ok());
91 auto span = span_result.value();
92
93 // Add baggage
94 span->baggage["user_id"] = "12345";
95 span->baggage["request_type"] = "api";
96
97 // Extract context - explicitly use const trace_span&
98 const trace_span& span_ref = *span;
99 auto context = tracer.extract_context(span_ref);
100 EXPECT_EQ(context.trace_id, span->trace_id);
101 EXPECT_EQ(context.span_id, span->span_id);
102 EXPECT_EQ(context.baggage["user_id"], "12345");
103 EXPECT_EQ(context.baggage["request_type"], "api");
104}
Trace span representing a unit of work in distributed tracing.

◆ TEST_F() [15/25]

TEST_F ( DistributedTracingTest ,
TraceMacros  )

Definition at line 340 of file test_distributed_tracing.cpp.

340 {
341 {
342 TRACE_SPAN("macro_operation");
343
344 // The span should be active
345 auto current = global_tracer().get_current_span();
346 ASSERT_NE(current, nullptr);
347 EXPECT_EQ(current->operation_name, "macro_operation");
348
349 // Nested span
350 {
351 TRACE_CHILD_SPAN(*current, "nested_operation");
352 auto nested = global_tracer().get_current_span();
353 ASSERT_NE(nested, nullptr);
354 EXPECT_EQ(nested->operation_name, "nested_operation");
355 EXPECT_EQ(nested->parent_span_id, current->span_id);
356 }
357 }
358 // Spans should be finished after leaving scope
359}
std::shared_ptr< trace_span > get_current_span() const
Get current active span for this thread.
#define TRACE_CHILD_SPAN(parent, operation_name)
#define TRACE_SPAN(operation_name)
Helper macro for creating a scoped span.
distributed_tracer & global_tracer()
Global tracer instance.

References kcenon::monitoring::distributed_tracer::get_current_span(), kcenon::monitoring::global_tracer(), TRACE_CHILD_SPAN, and TRACE_SPAN.

Here is the call graph for this function:

◆ TEST_F() [16/25]

TEST_F ( DistributedTracingTest ,
W3CTraceContextFormat  )

Definition at line 106 of file test_distributed_tracing.cpp.

106 {
107 trace_context ctx;
108 ctx.trace_id = "0af7651916cd43dd8448eb211c80319c";
109 ctx.span_id = "b7ad6b7169203331";
110 ctx.trace_flags = "01";
111
112 auto header = ctx.to_w3c_traceparent();
113 EXPECT_EQ(header, "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01");
114
115 auto parsed_result = trace_context::from_w3c_traceparent(header);
116 ASSERT_TRUE(parsed_result.is_ok());
117 auto parsed = parsed_result.value();
118
119 EXPECT_EQ(parsed.trace_id, ctx.trace_id);
120 EXPECT_EQ(parsed.span_id, ctx.span_id);
121 EXPECT_EQ(parsed.trace_flags, ctx.trace_flags);
122}
std::string to_w3c_traceparent() const
Serialize to W3C Trace Context format.
static common::Result< trace_context > from_w3c_traceparent(const std::string &header)
Parse from W3C Trace Context format.

References kcenon::monitoring::trace_context::from_w3c_traceparent(), kcenon::monitoring::trace_context::span_id, kcenon::monitoring::trace_context::to_w3c_traceparent(), kcenon::monitoring::trace_context::trace_flags, and kcenon::monitoring::trace_context::trace_id.

Here is the call graph for this function:

◆ TEST_F() [17/25]

TEST_F ( ExporterIntegrationTest ,
AutoExportWhenBatchSizeReached  )

Definition at line 440 of file test_distributed_tracing.cpp.

440 {
441 tracer.set_exporter(mock_exporter);
442
443 trace_export_settings settings;
444 settings.batch_size = 5;
445 settings.export_on_finish = true;
446 tracer.configure_export(settings);
447
448 // Create and finish enough spans to trigger export
449 for (int i = 0; i < 5; ++i) {
450 auto span_result = tracer.start_span("operation_" + std::to_string(i));
451 ASSERT_TRUE(span_result.is_ok());
452 tracer.finish_span(span_result.value());
453 }
454
455 // Should have triggered one export
456 EXPECT_EQ(mock_exporter->export_count.load(), 1);
457 EXPECT_EQ(mock_exporter->exported_spans.size(), 5);
458}
Configuration settings for trace export behavior.
bool export_on_finish
Export when batch is full.
std::size_t batch_size
Number of spans to batch before export.

References kcenon::monitoring::trace_export_settings::batch_size, and kcenon::monitoring::trace_export_settings::export_on_finish.

◆ TEST_F() [18/25]

TEST_F ( ExporterIntegrationTest ,
ConfigureExportSettings  )

Definition at line 426 of file test_distributed_tracing.cpp.

426 {
427 trace_export_settings settings;
428 settings.batch_size = 50;
429 settings.max_queue_size = 1000;
430 settings.export_on_finish = true;
431
432 tracer.configure_export(settings);
433
434 auto retrieved = tracer.get_export_settings();
435 EXPECT_EQ(retrieved.batch_size, 50);
436 EXPECT_EQ(retrieved.max_queue_size, 1000);
437 EXPECT_TRUE(retrieved.export_on_finish);
438}
std::size_t max_queue_size
Maximum spans in queue before dropping.

References kcenon::monitoring::trace_export_settings::batch_size, kcenon::monitoring::trace_export_settings::export_on_finish, and kcenon::monitoring::trace_export_settings::max_queue_size.

◆ TEST_F() [19/25]

TEST_F ( ExporterIntegrationTest ,
ExportedSpansContainCorrectData  )

Definition at line 579 of file test_distributed_tracing.cpp.

579 {
580 tracer.set_exporter(mock_exporter);
581
582 trace_export_settings settings;
583 settings.batch_size = 1; // Export immediately
584 tracer.configure_export(settings);
585
586 auto span_result = tracer.start_span("test_operation", "test_service");
587 ASSERT_TRUE(span_result.is_ok());
588 auto span = span_result.value();
589 span->tags["custom_tag"] = "custom_value";
590
591 tracer.finish_span(span);
592
593 ASSERT_EQ(mock_exporter->exported_spans.size(), 1);
594 const auto& exported = mock_exporter->exported_spans[0];
595
596 EXPECT_EQ(exported.operation_name, "test_operation");
597 EXPECT_EQ(exported.service_name, "test_service");
598 EXPECT_EQ(exported.trace_id, span->trace_id);
599 EXPECT_EQ(exported.span_id, span->span_id);
600 auto tag_it = exported.tags.find("custom_tag");
601 ASSERT_NE(tag_it, exported.tags.end());
602 EXPECT_EQ(tag_it->second, "custom_value");
603 EXPECT_TRUE(exported.is_finished());
604}

References kcenon::monitoring::trace_export_settings::batch_size.

◆ TEST_F() [20/25]

TEST_F ( ExporterIntegrationTest ,
ExportFailureRetainsSpans  )

Definition at line 503 of file test_distributed_tracing.cpp.

503 {
504 mock_exporter->should_fail = true;
505 tracer.set_exporter(mock_exporter);
506
507 trace_export_settings settings;
508 settings.batch_size = 100;
509 settings.max_queue_size = 200;
510 tracer.configure_export(settings);
511
512 // Create some spans
513 for (int i = 0; i < 3; ++i) {
514 auto span_result = tracer.start_span("operation_" + std::to_string(i));
515 ASSERT_TRUE(span_result.is_ok());
516 tracer.finish_span(span_result.value());
517 }
518
519 // Flush should fail
520 auto flush_result = tracer.flush();
521 EXPECT_TRUE(flush_result.is_err());
522
523 // Spans should still be in queue (we can verify via stats)
524 auto stats = tracer.get_export_stats();
525 EXPECT_EQ(stats["pending_spans"], 3);
526
527 // Now fix the exporter and try again
528 mock_exporter->should_fail = false;
529 flush_result = tracer.flush();
530 EXPECT_TRUE(flush_result.is_ok());
531
532 // Now spans should be exported
533 EXPECT_EQ(mock_exporter->exported_spans.size(), 3);
534}

References kcenon::monitoring::trace_export_settings::batch_size, and kcenon::monitoring::trace_export_settings::max_queue_size.

◆ TEST_F() [21/25]

TEST_F ( ExporterIntegrationTest ,
ExportStats  )

Definition at line 536 of file test_distributed_tracing.cpp.

536 {
537 tracer.set_exporter(mock_exporter);
538
539 trace_export_settings settings;
540 settings.batch_size = 5;
541 tracer.configure_export(settings);
542
543 // Create and finish spans
544 for (int i = 0; i < 10; ++i) {
545 auto span_result = tracer.start_span("operation_" + std::to_string(i));
546 ASSERT_TRUE(span_result.is_ok());
547 tracer.finish_span(span_result.value());
548 }
549
550 auto stats = tracer.get_export_stats();
551 EXPECT_EQ(stats["exported_spans"], 10);
552 EXPECT_EQ(stats["failed_exports"], 0);
553 EXPECT_EQ(stats["dropped_spans"], 0);
554}

References kcenon::monitoring::trace_export_settings::batch_size.

◆ TEST_F() [22/25]

TEST_F ( ExporterIntegrationTest ,
FlushWithNoExporter  )

Definition at line 487 of file test_distributed_tracing.cpp.

487 {
488 // No exporter set
489 EXPECT_EQ(tracer.get_exporter(), nullptr);
490
491 // Create and finish some spans
492 for (int i = 0; i < 3; ++i) {
493 auto span_result = tracer.start_span("operation_" + std::to_string(i));
494 ASSERT_TRUE(span_result.is_ok());
495 tracer.finish_span(span_result.value());
496 }
497
498 // Flush should succeed (just clears the buffer)
499 auto flush_result = tracer.flush();
500 EXPECT_TRUE(flush_result.is_ok());
501}

◆ TEST_F() [23/25]

TEST_F ( ExporterIntegrationTest ,
ManualFlush  )

Definition at line 460 of file test_distributed_tracing.cpp.

460 {
461 tracer.set_exporter(mock_exporter);
462
463 trace_export_settings settings;
464 settings.batch_size = 100; // Large batch size to prevent auto-export
465 settings.export_on_finish = true;
466 tracer.configure_export(settings);
467
468 // Create a few spans (less than batch size)
469 for (int i = 0; i < 3; ++i) {
470 auto span_result = tracer.start_span("operation_" + std::to_string(i));
471 ASSERT_TRUE(span_result.is_ok());
472 tracer.finish_span(span_result.value());
473 }
474
475 // No auto-export should have happened
476 EXPECT_EQ(mock_exporter->export_count.load(), 0);
477
478 // Manual flush
479 auto flush_result = tracer.flush();
480 ASSERT_TRUE(flush_result.is_ok());
481
482 // Now spans should be exported
483 EXPECT_EQ(mock_exporter->export_count.load(), 1);
484 EXPECT_EQ(mock_exporter->exported_spans.size(), 3);
485}

References kcenon::monitoring::trace_export_settings::batch_size, and kcenon::monitoring::trace_export_settings::export_on_finish.

◆ TEST_F() [24/25]

TEST_F ( ExporterIntegrationTest ,
QueueSizeLimitEnforced  )

Definition at line 556 of file test_distributed_tracing.cpp.

556 {
557 tracer.set_exporter(mock_exporter);
558 mock_exporter->should_fail = true; // Make exports fail to fill queue
559
560 trace_export_settings settings;
561 settings.batch_size = 100; // Large batch size
562 settings.max_queue_size = 5; // Small queue
563 settings.export_on_finish = false; // Disable auto-export
564 tracer.configure_export(settings);
565
566 // Create more spans than queue can hold
567 for (int i = 0; i < 10; ++i) {
568 auto span_result = tracer.start_span("operation_" + std::to_string(i));
569 ASSERT_TRUE(span_result.is_ok());
570 tracer.finish_span(span_result.value());
571 }
572
573 // Stats should show dropped spans
574 auto stats = tracer.get_export_stats();
575 EXPECT_GT(stats["dropped_spans"], 0);
576 EXPECT_LE(stats["pending_spans"], 5);
577}

References kcenon::monitoring::trace_export_settings::batch_size, kcenon::monitoring::trace_export_settings::export_on_finish, and kcenon::monitoring::trace_export_settings::max_queue_size.

◆ TEST_F() [25/25]

TEST_F ( ExporterIntegrationTest ,
SetAndGetExporter  )

Definition at line 416 of file test_distributed_tracing.cpp.

416 {
417 EXPECT_EQ(tracer.get_exporter(), nullptr);
418
419 tracer.set_exporter(mock_exporter);
420 EXPECT_EQ(tracer.get_exporter(), mock_exporter);
421
422 tracer.set_exporter(nullptr);
423 EXPECT_EQ(tracer.get_exporter(), nullptr);
424}