Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_trace_exporters.cpp File Reference
#include <gtest/gtest.h>
#include <kcenon/monitoring/exporters/trace_exporters.h>
#include <kcenon/monitoring/exporters/opentelemetry_adapter.h>
#include <thread>
#include <chrono>
#include <kcenon/monitoring/exporters/otlp_grpc_exporter.h>
Include dependency graph for test_trace_exporters.cpp:

Go to the source code of this file.

Classes

class  TraceExportersTest
 
class  OtlpGrpcExporterTest
 

Functions

 TEST_F (TraceExportersTest, TraceExportConfigValidation)
 
 TEST_F (TraceExportersTest, JaegerSpanConversion)
 
 TEST_F (TraceExportersTest, JaegerExporterBasicFunctionality)
 
 TEST_F (TraceExportersTest, ZipkinSpanConversion)
 
 TEST_F (TraceExportersTest, ZipkinExporterBasicFunctionality)
 
 TEST_F (TraceExportersTest, OtlpExporterBasicFunctionality)
 
 TEST_F (TraceExportersTest, TraceExporterFactory)
 
 TEST_F (TraceExportersTest, SupportedFormatsQuery)
 
 TEST_F (TraceExportersTest, HelperFunctions)
 
 TEST_F (TraceExportersTest, InvalidFormatHandling)
 
 TEST_F (TraceExportersTest, EmptySpansHandling)
 
 TEST_F (TraceExportersTest, LargeSpanBatch)
 
 TEST_F (OtlpGrpcExporterTest, ConfigValidation)
 
 TEST_F (OtlpGrpcExporterTest, SpanConverterBasic)
 
 TEST_F (OtlpGrpcExporterTest, SpanConverterEmptySpans)
 
 TEST_F (OtlpGrpcExporterTest, ExporterWithStubTransport)
 
 TEST_F (OtlpGrpcExporterTest, ExporterFailedConnection)
 
 TEST_F (OtlpGrpcExporterTest, ExporterRetryBehavior)
 
 TEST_F (OtlpGrpcExporterTest, ExporterDetailedStats)
 
 TEST_F (OtlpGrpcExporterTest, FactoryFunctions)
 
 TEST_F (OtlpGrpcExporterTest, ExportEmptySpans)
 

Function Documentation

◆ TEST_F() [1/21]

TEST_F ( OtlpGrpcExporterTest ,
ConfigValidation  )

Definition at line 389 of file test_trace_exporters.cpp.

389 {
390 // Valid configuration
391 otlp_grpc_config valid_config;
392 valid_config.endpoint = "localhost:4317";
393 valid_config.timeout = std::chrono::milliseconds(5000);
394 valid_config.max_batch_size = 512;
395
396 auto validation = valid_config.validate();
397 EXPECT_TRUE(validation.is_ok());
398
399 // Invalid endpoint (empty)
400 otlp_grpc_config invalid_endpoint;
401 invalid_endpoint.endpoint = "";
402 auto endpoint_validation = invalid_endpoint.validate();
403 EXPECT_TRUE(endpoint_validation.is_err());
404
405 // Invalid timeout (zero)
406 otlp_grpc_config invalid_timeout;
407 invalid_timeout.endpoint = "localhost:4317";
408 invalid_timeout.timeout = std::chrono::milliseconds(0);
409 auto timeout_validation = invalid_timeout.validate();
410 EXPECT_TRUE(timeout_validation.is_err());
411
412 // Invalid batch size (zero)
413 otlp_grpc_config invalid_batch;
414 invalid_batch.endpoint = "localhost:4317";
415 invalid_batch.max_batch_size = 0;
416 auto batch_validation = invalid_batch.validate();
417 EXPECT_TRUE(batch_validation.is_err());
418}
Configuration for OTLP gRPC exporter.
std::string endpoint
OTLP receiver endpoint.
common::VoidResult validate() const
Validate configuration.
std::size_t max_batch_size
Maximum spans per batch.
std::chrono::milliseconds timeout
Request timeout.

References kcenon::monitoring::otlp_grpc_config::endpoint, kcenon::monitoring::otlp_grpc_config::max_batch_size, kcenon::monitoring::otlp_grpc_config::timeout, and kcenon::monitoring::otlp_grpc_config::validate().

Here is the call graph for this function:

◆ TEST_F() [2/21]

TEST_F ( OtlpGrpcExporterTest ,
ExportEmptySpans  )

Definition at line 599 of file test_trace_exporters.cpp.

599 {
600 otlp_grpc_config config;
601 config.endpoint = "localhost:4317";
602
603 auto stub_transport = create_stub_grpc_transport();
604 otlp_grpc_exporter exporter(config, std::move(stub_transport));
605
606 auto start_result = exporter.start();
607 EXPECT_TRUE(start_result.is_ok());
608
609 // Export empty vector should succeed without sending
610 std::vector<trace_span> empty_spans;
611 auto export_result = exporter.export_spans(empty_spans);
612 EXPECT_TRUE(export_result.is_ok());
613
614 auto stats = exporter.get_stats();
615 EXPECT_EQ(stats["exported_spans"], 0u);
616}
std::unique_ptr< stub_grpc_transport > create_stub_grpc_transport()
Create stub gRPC transport for testing.

References kcenon::monitoring::create_stub_grpc_transport(), kcenon::monitoring::otlp_grpc_config::endpoint, kcenon::monitoring::otlp_grpc_exporter::export_spans(), kcenon::monitoring::otlp_grpc_exporter::get_stats(), and kcenon::monitoring::otlp_grpc_exporter::start().

Here is the call graph for this function:

◆ TEST_F() [3/21]

TEST_F ( OtlpGrpcExporterTest ,
ExporterDetailedStats  )

Definition at line 543 of file test_trace_exporters.cpp.

543 {
544 otlp_grpc_config config;
545 config.endpoint = "localhost:4317";
546
547 auto stub_transport = create_stub_grpc_transport();
548 // Set response handler to simulate realistic export time
549 stub_transport->set_response_handler([](const grpc_request&) {
550 // Simulate a small delay to ensure measurable export time
551 std::this_thread::sleep_for(std::chrono::microseconds(100));
552 grpc_response response;
553 response.status_code = 0; // OK
554 response.status_message = "OK";
555 return response;
556 });
557 otlp_grpc_exporter exporter(config, std::move(stub_transport));
558
559 auto start_result = exporter.start();
560 EXPECT_TRUE(start_result.is_ok());
561
562 // Export multiple batches
563 for (int i = 0; i < 3; ++i) {
564 auto result = exporter.export_spans(test_spans_);
565 EXPECT_TRUE(result.is_ok());
566 }
567
568 auto detailed_stats = exporter.get_detailed_stats();
569 EXPECT_EQ(detailed_stats.spans_exported, test_spans_.size() * 3);
570 EXPECT_EQ(detailed_stats.spans_dropped, 0u);
571 EXPECT_EQ(detailed_stats.export_failures, 0u);
572 EXPECT_GT(detailed_stats.total_export_time.count(), 0);
573}
gRPC request configuration

References kcenon::monitoring::create_stub_grpc_transport(), kcenon::monitoring::otlp_grpc_config::endpoint, kcenon::monitoring::otlp_grpc_exporter::export_spans(), kcenon::monitoring::otlp_grpc_exporter::get_detailed_stats(), kcenon::monitoring::otlp_grpc_exporter::start(), kcenon::monitoring::grpc_response::status_code, and kcenon::monitoring::grpc_response::status_message.

Here is the call graph for this function:

◆ TEST_F() [4/21]

TEST_F ( OtlpGrpcExporterTest ,
ExporterFailedConnection  )

Definition at line 487 of file test_trace_exporters.cpp.

487 {
488 otlp_grpc_config config;
489 config.endpoint = "localhost:4317";
490
491 // Create stub transport that simulates failure
492 auto stub_transport = create_stub_grpc_transport();
493 stub_transport->set_simulate_success(false);
494
495 otlp_grpc_exporter exporter(config, std::move(stub_transport));
496
497 // Start should fail due to connection failure
498 auto start_result = exporter.start();
499 EXPECT_TRUE(start_result.is_err());
500}

References kcenon::monitoring::create_stub_grpc_transport(), kcenon::monitoring::otlp_grpc_config::endpoint, and kcenon::monitoring::otlp_grpc_exporter::start().

Here is the call graph for this function:

◆ TEST_F() [5/21]

TEST_F ( OtlpGrpcExporterTest ,
ExporterRetryBehavior  )

Definition at line 502 of file test_trace_exporters.cpp.

502 {
503 otlp_grpc_config config;
504 config.endpoint = "localhost:4317";
505 config.max_retry_attempts = 3;
506 config.initial_backoff = std::chrono::milliseconds(10);
507
508 // Track call count
509 int call_count = 0;
510
511 auto stub_transport = create_stub_grpc_transport();
512 stub_transport->set_response_handler([&call_count](const grpc_request&) {
513 call_count++;
514 grpc_response response;
515 if (call_count < 3) {
516 // Simulate UNAVAILABLE error (retryable)
517 response.status_code = 14;
518 response.status_message = "Service unavailable";
519 } else {
520 // Success on third attempt
521 response.status_code = 0;
522 response.status_message = "OK";
523 }
524 return response;
525 });
526
527 otlp_grpc_exporter exporter(config, std::move(stub_transport));
528
529 auto start_result = exporter.start();
530 EXPECT_TRUE(start_result.is_ok());
531
532 auto export_result = exporter.export_spans(test_spans_);
533 EXPECT_TRUE(export_result.is_ok());
534
535 // Should have retried twice before success
536 EXPECT_EQ(call_count, 3);
537
538 auto stats = exporter.get_stats();
539 EXPECT_EQ(stats["retries"], 2u);
540 EXPECT_EQ(stats["exported_spans"], test_spans_.size());
541}
std::size_t max_retry_attempts
Maximum retry attempts.
std::chrono::milliseconds initial_backoff
Initial retry backoff.

References kcenon::monitoring::create_stub_grpc_transport(), kcenon::monitoring::otlp_grpc_config::endpoint, kcenon::monitoring::otlp_grpc_exporter::export_spans(), kcenon::monitoring::otlp_grpc_exporter::get_stats(), kcenon::monitoring::otlp_grpc_config::initial_backoff, kcenon::monitoring::otlp_grpc_config::max_retry_attempts, kcenon::monitoring::otlp_grpc_exporter::start(), kcenon::monitoring::grpc_response::status_code, and kcenon::monitoring::grpc_response::status_message.

Here is the call graph for this function:

◆ TEST_F() [6/21]

TEST_F ( OtlpGrpcExporterTest ,
ExporterWithStubTransport  )

Definition at line 449 of file test_trace_exporters.cpp.

449 {
450 otlp_grpc_config config;
451 config.endpoint = "localhost:4317";
452 config.service_name = "test_service";
453 config.service_version = "1.0.0";
454
455 // Create exporter with stub transport for testing
456 auto stub_transport = create_stub_grpc_transport();
457 auto* stub_ptr = stub_transport.get();
458
459 otlp_grpc_exporter exporter(config, std::move(stub_transport));
460
461 // Start exporter (connects to stub)
462 auto start_result = exporter.start();
463 EXPECT_TRUE(start_result.is_ok());
464 EXPECT_TRUE(exporter.is_running());
465
466 // Export spans
467 auto export_result = exporter.export_spans(test_spans_);
468 EXPECT_TRUE(export_result.is_ok());
469
470 // Check stats
471 auto stats = exporter.get_stats();
472 EXPECT_EQ(stats["exported_spans"], test_spans_.size());
473 EXPECT_EQ(stats["dropped_spans"], 0u);
474 EXPECT_EQ(stats["failed_exports"], 0u);
475
476 // Check transport statistics
477 auto transport_stats = stub_ptr->get_statistics();
478 EXPECT_EQ(transport_stats.requests_sent, 1u);
479 EXPECT_GT(transport_stats.bytes_sent, 0u);
480
481 // Shutdown
482 auto shutdown_result = exporter.shutdown();
483 EXPECT_TRUE(shutdown_result.is_ok());
484 EXPECT_FALSE(exporter.is_running());
485}
std::string service_version
Service version.

References kcenon::monitoring::create_stub_grpc_transport(), kcenon::monitoring::otlp_grpc_config::endpoint, kcenon::monitoring::otlp_grpc_exporter::export_spans(), kcenon::monitoring::otlp_grpc_exporter::get_stats(), kcenon::monitoring::otlp_grpc_exporter::is_running(), kcenon::monitoring::otlp_grpc_config::service_name, kcenon::monitoring::otlp_grpc_config::service_version, kcenon::monitoring::otlp_grpc_exporter::shutdown(), and kcenon::monitoring::otlp_grpc_exporter::start().

Here is the call graph for this function:

◆ TEST_F() [7/21]

TEST_F ( OtlpGrpcExporterTest ,
FactoryFunctions  )

Definition at line 575 of file test_trace_exporters.cpp.

575 {
576 // Test default factory
577 auto exporter1 = create_otlp_grpc_exporter();
578 EXPECT_TRUE(exporter1 != nullptr);
579 EXPECT_EQ(exporter1->config().endpoint, "localhost:4317");
580
581 // Test factory with endpoint
582 auto exporter2 = create_otlp_grpc_exporter("collector:4317");
583 EXPECT_TRUE(exporter2 != nullptr);
584 EXPECT_EQ(exporter2->config().endpoint, "collector:4317");
585
586 // Test factory with config
587 otlp_grpc_config config;
588 config.endpoint = "otlp.example.com:443";
589 config.use_tls = true;
590 config.service_name = "my_service";
591
592 auto exporter3 = create_otlp_grpc_exporter(config);
593 EXPECT_TRUE(exporter3 != nullptr);
594 EXPECT_EQ(exporter3->config().endpoint, "otlp.example.com:443");
595 EXPECT_TRUE(exporter3->config().use_tls);
596 EXPECT_EQ(exporter3->config().service_name, "my_service");
597}
std::unique_ptr< otlp_grpc_exporter > create_otlp_grpc_exporter(const std::string &endpoint="localhost:4317")
Create OTLP gRPC exporter with default configuration.

References kcenon::monitoring::create_otlp_grpc_exporter(), kcenon::monitoring::otlp_grpc_config::endpoint, kcenon::monitoring::otlp_grpc_config::service_name, and kcenon::monitoring::otlp_grpc_config::use_tls.

Here is the call graph for this function:

◆ TEST_F() [8/21]

TEST_F ( OtlpGrpcExporterTest ,
SpanConverterBasic  )

Definition at line 420 of file test_trace_exporters.cpp.

420 {
421 // Test span conversion to OTLP format
423 test_spans_,
424 "test_service",
425 "1.0.0",
426 {{"environment", "test"}});
427
428 // Verify payload is non-empty
429 EXPECT_GT(payload.size(), 0u);
430
431 // Verify protobuf wire format structure
432 // First byte should be 0x0A (field 1, length-delimited)
433 EXPECT_EQ(payload[0], 0x0A);
434}
static std::vector< uint8_t > convert_to_otlp(const std::vector< trace_span > &spans, const std::string &service_name, const std::string &service_version, const std::unordered_map< std::string, std::string > &resource_attributes)
Convert spans to OTLP protobuf format.

References kcenon::monitoring::otlp_span_converter::convert_to_otlp().

Here is the call graph for this function:

◆ TEST_F() [9/21]

TEST_F ( OtlpGrpcExporterTest ,
SpanConverterEmptySpans  )

Definition at line 436 of file test_trace_exporters.cpp.

436 {
437 std::vector<trace_span> empty_spans;
438
440 empty_spans,
441 "test_service",
442 "1.0.0",
443 {});
444
445 // Even with no spans, should have resource data
446 EXPECT_GT(payload.size(), 0u);
447}

References kcenon::monitoring::otlp_span_converter::convert_to_otlp().

Here is the call graph for this function:

◆ TEST_F() [10/21]

TEST_F ( TraceExportersTest ,
EmptySpansHandling  )

Definition at line 334 of file test_trace_exporters.cpp.

334 {
335 std::vector<trace_span> empty_spans;
336
337 trace_export_config config;
338 config.endpoint = "http://test:1234";
339 config.format = trace_export_format::jaeger_grpc;
340
341 jaeger_exporter exporter(config);
342 auto result = exporter.export_spans(empty_spans);
343 // Empty spans may succeed (nothing to send) or fail (stub transport)
344 // Either way, no spans were exported
345 auto stats = exporter.get_stats();
346 EXPECT_EQ(stats["exported_spans"], 0);
347}
Jaeger trace exporter implementation.
Configuration for trace exporters.

References kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::jaeger_exporter::export_spans(), kcenon::monitoring::trace_export_config::format, and kcenon::monitoring::jaeger_exporter::get_stats().

Here is the call graph for this function:

◆ TEST_F() [11/21]

TEST_F ( TraceExportersTest ,
HelperFunctions  )

Definition at line 288 of file test_trace_exporters.cpp.

288 {
289 // Test Jaeger helper
290 auto jaeger_exporter = create_jaeger_exporter("http://jaeger:14268",
291 trace_export_format::jaeger_thrift);
292 EXPECT_TRUE(jaeger_exporter);
293
294 // Test Zipkin helper
295 auto zipkin_exporter = create_zipkin_exporter("http://zipkin:9411",
296 trace_export_format::zipkin_protobuf);
297 EXPECT_TRUE(zipkin_exporter);
298
299 // Test OTLP helper
300 auto otlp_exporter = create_otlp_exporter("http://otlp:4317", otel_resource_,
301 trace_export_format::otlp_http_json);
302 EXPECT_TRUE(otlp_exporter);
303}
OpenTelemetry Protocol (OTLP) trace exporter implementation.
Zipkin trace exporter implementation.
std::unique_ptr< zipkin_exporter > create_zipkin_exporter(const std::string &endpoint, trace_export_format format=trace_export_format::zipkin_json)
Helper function to create a Zipkin exporter.
std::unique_ptr< otlp_exporter > create_otlp_exporter(const std::string &endpoint, const otel_resource &resource, trace_export_format format=trace_export_format::otlp_grpc)
Helper function to create an OTLP exporter.
std::unique_ptr< jaeger_exporter > create_jaeger_exporter(const std::string &endpoint, trace_export_format format=trace_export_format::jaeger_grpc)
Helper function to create a Jaeger exporter.

References kcenon::monitoring::create_jaeger_exporter(), kcenon::monitoring::create_otlp_exporter(), and kcenon::monitoring::create_zipkin_exporter().

Here is the call graph for this function:

◆ TEST_F() [12/21]

TEST_F ( TraceExportersTest ,
InvalidFormatHandling  )

Definition at line 305 of file test_trace_exporters.cpp.

305 {
306 trace_export_config invalid_jaeger_config;
307 invalid_jaeger_config.endpoint = "http://jaeger:14268";
308 invalid_jaeger_config.format = trace_export_format::zipkin_json; // Wrong format
309
310 jaeger_exporter jaeger_exp(invalid_jaeger_config);
311 auto jaeger_result = jaeger_exp.export_spans(test_spans_);
312 EXPECT_TRUE(jaeger_result.is_err());
313 EXPECT_EQ(jaeger_result.error().code, static_cast<int>(monitoring_error_code::invalid_configuration));
314
315 trace_export_config invalid_zipkin_config;
316 invalid_zipkin_config.endpoint = "http://zipkin:9411";
317 invalid_zipkin_config.format = trace_export_format::jaeger_grpc; // Wrong format
318
319 zipkin_exporter zipkin_exp(invalid_zipkin_config);
320 auto zipkin_result = zipkin_exp.export_spans(test_spans_);
321 EXPECT_TRUE(zipkin_result.is_err());
322 EXPECT_EQ(zipkin_result.error().code, static_cast<int>(monitoring_error_code::invalid_configuration));
323
324 trace_export_config invalid_otlp_config;
325 invalid_otlp_config.endpoint = "http://otlp:4317";
326 invalid_otlp_config.format = trace_export_format::jaeger_thrift; // Wrong format
327
328 otlp_exporter otlp_exp(invalid_otlp_config, otel_resource_);
329 auto otlp_result = otlp_exp.export_spans(test_spans_);
330 EXPECT_TRUE(otlp_result.is_err());
331 EXPECT_EQ(otlp_result.error().code, static_cast<int>(monitoring_error_code::invalid_configuration));
332}

References kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::jaeger_exporter::export_spans(), kcenon::monitoring::otlp_exporter::export_spans(), kcenon::monitoring::zipkin_exporter::export_spans(), and kcenon::monitoring::trace_export_config::format.

Here is the call graph for this function:

◆ TEST_F() [13/21]

TEST_F ( TraceExportersTest ,
JaegerExporterBasicFunctionality  )

Definition at line 145 of file test_trace_exporters.cpp.

145 {
146 trace_export_config config;
147 config.endpoint = "http://jaeger:14268/api/traces";
148 config.format = trace_export_format::jaeger_thrift;
149
150 jaeger_exporter exporter(config);
151
152 // Export spans — stub transport returns error (no real HTTP client)
153 auto export_result = exporter.export_spans(test_spans_);
154 EXPECT_TRUE(export_result.is_err());
155
156 // Check statistics — export failed so failed_exports should increment
157 auto stats = exporter.get_stats();
158 EXPECT_EQ(stats["failed_exports"], 1);
159
160 // Test flush and shutdown (should still work)
161 auto flush_result = exporter.flush();
162 EXPECT_TRUE(flush_result.is_ok());
163
164 auto shutdown_result = exporter.shutdown();
165 EXPECT_TRUE(shutdown_result.is_ok());
166}

References kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::jaeger_exporter::export_spans(), kcenon::monitoring::jaeger_exporter::flush(), kcenon::monitoring::trace_export_config::format, kcenon::monitoring::jaeger_exporter::get_stats(), and kcenon::monitoring::jaeger_exporter::shutdown().

Here is the call graph for this function:

◆ TEST_F() [14/21]

TEST_F ( TraceExportersTest ,
JaegerSpanConversion  )

Definition at line 105 of file test_trace_exporters.cpp.

105 {
106 trace_export_config config;
107 config.endpoint = "http://jaeger:14268/api/traces";
108 config.format = trace_export_format::jaeger_thrift;
109 config.service_name = "test_service";
110
111 jaeger_exporter exporter(config);
112
113 const auto& span = test_spans_[0];
114 auto jaeger_span = exporter.convert_span(span);
115
116 EXPECT_EQ(jaeger_span.trace_id, span.trace_id);
117 EXPECT_EQ(jaeger_span.span_id, span.span_id);
118 EXPECT_EQ(jaeger_span.operation_name, span.operation_name);
119 EXPECT_EQ(jaeger_span.service_name, "test_service"); // Override from config
120
121 // Check tags conversion
122 bool found_http_method = false;
123 bool found_http_url = false;
124 for (const auto& [key, value] : jaeger_span.tags) {
125 if (key == "http.method" && value == "GET") {
126 found_http_method = true;
127 }
128 if (key == "http.url" && value == "/api/users") {
129 found_http_url = true;
130 }
131 }
132 EXPECT_TRUE(found_http_method);
133 EXPECT_TRUE(found_http_url);
134
135 // Check process tags
136 bool found_service_name = false;
137 for (const auto& [key, value] : jaeger_span.process_tags) {
138 if (key == "service.name" && value == "test_service") {
139 found_service_name = true;
140 }
141 }
142 EXPECT_TRUE(found_service_name);
143}
std::optional< std::string > service_name
Override service name.

References kcenon::monitoring::jaeger_exporter::convert_span(), kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::trace_export_config::format, and kcenon::monitoring::trace_export_config::service_name.

Here is the call graph for this function:

◆ TEST_F() [15/21]

TEST_F ( TraceExportersTest ,
LargeSpanBatch  )

Definition at line 349 of file test_trace_exporters.cpp.

349 {
350 // Create a large batch of spans
351 std::vector<trace_span> large_batch;
352 for (int i = 0; i < 1000; ++i) {
353 trace_span span;
354 span.trace_id = "trace" + std::to_string(i);
355 span.span_id = "span" + std::to_string(i);
356 span.operation_name = "operation_" + std::to_string(i);
357 span.service_name = "test_service";
358 span.start_time = std::chrono::system_clock::now();
359 span.end_time = span.start_time + std::chrono::milliseconds(1);
360 large_batch.push_back(span);
361 }
362
363 trace_export_config config;
364 config.endpoint = "http://test:1234";
365 config.format = trace_export_format::otlp_grpc;
366 config.max_batch_size = 500; // Smaller than batch size
367
368 otlp_exporter exporter(config, otel_resource_);
369 auto result = exporter.export_spans(large_batch);
370 EXPECT_TRUE(result.is_ok());
371
372 auto stats = exporter.get_stats();
373 EXPECT_EQ(stats["exported_spans"], static_cast<std::size_t>(1000));
374}
std::size_t max_batch_size
Maximum spans per batch.
Trace span representing a unit of work in distributed tracing.
std::chrono::system_clock::time_point end_time
std::chrono::system_clock::time_point start_time

References kcenon::monitoring::trace_span::end_time, kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::otlp_exporter::export_spans(), kcenon::monitoring::trace_export_config::format, kcenon::monitoring::otlp_exporter::get_stats(), kcenon::monitoring::trace_export_config::max_batch_size, kcenon::monitoring::trace_span::operation_name, kcenon::monitoring::trace_span::service_name, kcenon::monitoring::trace_span::span_id, kcenon::monitoring::trace_span::start_time, and kcenon::monitoring::trace_span::trace_id.

Here is the call graph for this function:

◆ TEST_F() [16/21]

TEST_F ( TraceExportersTest ,
OtlpExporterBasicFunctionality  )

Definition at line 214 of file test_trace_exporters.cpp.

214 {
215 trace_export_config config;
216 config.endpoint = "http://otlp-collector:4317";
217 config.format = trace_export_format::otlp_grpc;
218
219 otlp_exporter exporter(config, otel_resource_);
220
221 // Export spans
222 auto export_result = exporter.export_spans(test_spans_);
223 EXPECT_TRUE(export_result.is_ok());
224
225 // Check statistics
226 auto stats = exporter.get_stats();
227 EXPECT_EQ(stats["exported_spans"], test_spans_.size());
228 EXPECT_EQ(stats["failed_exports"], 0);
229
230 // Test flush and shutdown
231 auto flush_result = exporter.flush();
232 EXPECT_TRUE(flush_result.is_ok());
233
234 auto shutdown_result = exporter.shutdown();
235 EXPECT_TRUE(shutdown_result.is_ok());
236}

References kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::otlp_exporter::export_spans(), kcenon::monitoring::otlp_exporter::flush(), kcenon::monitoring::trace_export_config::format, kcenon::monitoring::otlp_exporter::get_stats(), and kcenon::monitoring::otlp_exporter::shutdown().

Here is the call graph for this function:

◆ TEST_F() [17/21]

TEST_F ( TraceExportersTest ,
SupportedFormatsQuery  )

Definition at line 264 of file test_trace_exporters.cpp.

264 {
265 auto jaeger_formats = trace_exporter_factory::get_supported_formats("jaeger");
266 EXPECT_EQ(jaeger_formats.size(), 2);
267 EXPECT_TRUE(std::find(jaeger_formats.begin(), jaeger_formats.end(),
268 trace_export_format::jaeger_thrift) != jaeger_formats.end());
269 EXPECT_TRUE(std::find(jaeger_formats.begin(), jaeger_formats.end(),
270 trace_export_format::jaeger_grpc) != jaeger_formats.end());
271
272 auto zipkin_formats = trace_exporter_factory::get_supported_formats("zipkin");
273 EXPECT_EQ(zipkin_formats.size(), 2);
274 EXPECT_TRUE(std::find(zipkin_formats.begin(), zipkin_formats.end(),
275 trace_export_format::zipkin_json) != zipkin_formats.end());
276 EXPECT_TRUE(std::find(zipkin_formats.begin(), zipkin_formats.end(),
277 trace_export_format::zipkin_protobuf) != zipkin_formats.end());
278
279 auto otlp_formats = trace_exporter_factory::get_supported_formats("otlp");
280 EXPECT_EQ(otlp_formats.size(), 3);
281 EXPECT_TRUE(std::find(otlp_formats.begin(), otlp_formats.end(),
282 trace_export_format::otlp_grpc) != otlp_formats.end());
283
284 auto unknown_formats = trace_exporter_factory::get_supported_formats("unknown");
285 EXPECT_EQ(unknown_formats.size(), 0);
286}
static std::vector< trace_export_format > get_supported_formats(const std::string &backend)
Get supported formats for a specific backend.

References kcenon::monitoring::trace_exporter_factory::get_supported_formats().

Here is the call graph for this function:

◆ TEST_F() [18/21]

TEST_F ( TraceExportersTest ,
TraceExportConfigValidation  )

Definition at line 63 of file test_trace_exporters.cpp.

63 {
64 // Valid configuration
65 trace_export_config valid_config;
66 valid_config.endpoint = "http://jaeger:14268/api/traces";
67 valid_config.format = trace_export_format::jaeger_thrift;
68 valid_config.timeout = std::chrono::milliseconds(5000);
69 valid_config.max_batch_size = 100;
70 valid_config.max_queue_size = 1000;
71
72 auto validation = valid_config.validate();
73 EXPECT_TRUE(validation.is_ok());
74
75 // Invalid endpoint
76 trace_export_config invalid_endpoint;
77 invalid_endpoint.endpoint = "";
78 auto endpoint_validation = invalid_endpoint.validate();
79 EXPECT_TRUE(endpoint_validation.is_err());
80 EXPECT_EQ(endpoint_validation.error().code, static_cast<int>(monitoring_error_code::invalid_configuration));
81
82 // Invalid timeout
83 trace_export_config invalid_timeout;
84 invalid_timeout.endpoint = "http://test";
85 invalid_timeout.timeout = std::chrono::milliseconds(0);
86 auto timeout_validation = invalid_timeout.validate();
87 EXPECT_TRUE(timeout_validation.is_err());
88
89 // Invalid batch size
90 trace_export_config invalid_batch;
91 invalid_batch.endpoint = "http://test";
92 invalid_batch.max_batch_size = 0;
93 auto batch_validation = invalid_batch.validate();
94 EXPECT_TRUE(batch_validation.is_err());
95
96 // Invalid queue size
97 trace_export_config invalid_queue;
98 invalid_queue.endpoint = "http://test";
99 invalid_queue.max_batch_size = 100;
100 invalid_queue.max_queue_size = 50;
101 auto queue_validation = invalid_queue.validate();
102 EXPECT_TRUE(queue_validation.is_err());
103}
std::chrono::milliseconds timeout
Request timeout.
std::size_t max_queue_size
Maximum queued spans.
common::VoidResult validate() const
Validate export configuration.

References kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::trace_export_config::format, kcenon::monitoring::trace_export_config::max_batch_size, kcenon::monitoring::trace_export_config::max_queue_size, kcenon::monitoring::trace_export_config::timeout, and kcenon::monitoring::trace_export_config::validate().

Here is the call graph for this function:

◆ TEST_F() [19/21]

TEST_F ( TraceExportersTest ,
TraceExporterFactory  )

Definition at line 238 of file test_trace_exporters.cpp.

238 {
239 // Test Jaeger factory
240 trace_export_config jaeger_config;
241 jaeger_config.endpoint = "http://jaeger:14268";
242 jaeger_config.format = trace_export_format::jaeger_grpc;
243
244 auto jaeger_exporter = trace_exporter_factory::create_exporter(jaeger_config, otel_resource_);
245 EXPECT_TRUE(jaeger_exporter);
246
247 // Test Zipkin factory
248 trace_export_config zipkin_config;
249 zipkin_config.endpoint = "http://zipkin:9411";
250 zipkin_config.format = trace_export_format::zipkin_json;
251
252 auto zipkin_exporter = trace_exporter_factory::create_exporter(zipkin_config, otel_resource_);
253 EXPECT_TRUE(zipkin_exporter);
254
255 // Test OTLP factory
256 trace_export_config otlp_config;
257 otlp_config.endpoint = "http://otlp-collector:4317";
258 otlp_config.format = trace_export_format::otlp_grpc;
259
260 auto otlp_exporter = trace_exporter_factory::create_exporter(otlp_config, otel_resource_);
261 EXPECT_TRUE(otlp_exporter);
262}
static std::unique_ptr< trace_exporter_interface > create_exporter(const trace_export_config &config, const otel_resource &resource=create_service_resource("monitoring_system", "2.0.0"))
Create a trace exporter based on format.

References kcenon::monitoring::trace_exporter_factory::create_exporter(), kcenon::monitoring::trace_export_config::endpoint, and kcenon::monitoring::trace_export_config::format.

Here is the call graph for this function:

◆ TEST_F() [20/21]

TEST_F ( TraceExportersTest ,
ZipkinExporterBasicFunctionality  )

Definition at line 191 of file test_trace_exporters.cpp.

191 {
192 trace_export_config config;
193 config.endpoint = "http://zipkin:9411/api/v2/spans";
194 config.format = trace_export_format::zipkin_json;
195
196 zipkin_exporter exporter(config);
197
198 // Export spans — stub transport returns error (no real HTTP client)
199 auto export_result = exporter.export_spans(test_spans_);
200 EXPECT_TRUE(export_result.is_err());
201
202 // Check statistics — export failed
203 auto stats = exporter.get_stats();
204 EXPECT_EQ(stats["failed_exports"], 1);
205
206 // Test flush and shutdown (should still work)
207 auto flush_result = exporter.flush();
208 EXPECT_TRUE(flush_result.is_ok());
209
210 auto shutdown_result = exporter.shutdown();
211 EXPECT_TRUE(shutdown_result.is_ok());
212}

References kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::zipkin_exporter::export_spans(), kcenon::monitoring::zipkin_exporter::flush(), kcenon::monitoring::trace_export_config::format, kcenon::monitoring::zipkin_exporter::get_stats(), and kcenon::monitoring::zipkin_exporter::shutdown().

Here is the call graph for this function:

◆ TEST_F() [21/21]

TEST_F ( TraceExportersTest ,
ZipkinSpanConversion  )

Definition at line 168 of file test_trace_exporters.cpp.

168 {
169 trace_export_config config;
170 config.endpoint = "http://zipkin:9411/api/v2/spans";
171 config.format = trace_export_format::zipkin_json;
172 config.service_name = "test_service";
173
174 zipkin_exporter exporter(config);
175
176 const auto& span = test_spans_[0];
177 auto zipkin_span = exporter.convert_span(span);
178
179 EXPECT_EQ(zipkin_span.trace_id, span.trace_id);
180 EXPECT_EQ(zipkin_span.span_id, span.span_id);
181 EXPECT_EQ(zipkin_span.name, span.operation_name);
182 EXPECT_EQ(zipkin_span.local_endpoint_service_name, "test_service");
183 EXPECT_EQ(zipkin_span.kind, "server"); // From span.kind tag
184
185 // Check tags conversion (span.kind should be excluded)
186 EXPECT_EQ(zipkin_span.tags.count("span.kind"), 0);
187 EXPECT_EQ(zipkin_span.tags.count("http.method"), 1);
188 EXPECT_EQ(zipkin_span.tags["http.method"], "GET");
189}

References kcenon::monitoring::zipkin_exporter::convert_span(), kcenon::monitoring::trace_export_config::endpoint, kcenon::monitoring::trace_export_config::format, and kcenon::monitoring::trace_export_config::service_name.

Here is the call graph for this function: