1010
1111#include " datadog/runtime_id.h"
1212#include " datadog/telemetry/telemetry_impl.h"
13- #include " mocks/event_schedulers.h"
1413#include " mocks/http_clients.h"
1514#include " mocks/loggers.h"
1615#include " test.h"
1716
1817using namespace datadog ::tracing;
1918using namespace datadog ::telemetry;
19+ using namespace std ::chrono_literals;
2020
2121namespace {
2222bool is_valid_telemetry_payload (const nlohmann::json& json) {
@@ -31,6 +31,43 @@ bool is_valid_telemetry_payload(const nlohmann::json& json) {
3131 json.contains (" /host" _json_pointer);
3232}
3333
34+ struct FakeEventScheduler : public EventScheduler {
35+ size_t count_tasks = 0 ;
36+ std::function<void ()> heartbeat_callback = nullptr ;
37+ std::function<void ()> metrics_callback = nullptr ;
38+ Optional<std::chrono::steady_clock::duration> heartbeat_interval;
39+ Optional<std::chrono::steady_clock::duration> metrics_interval;
40+ bool cancelled = false ;
41+
42+ // NOTE: White box testing. This is a limitation of the event scheduler API.
43+ Cancel schedule_recurring_event (std::chrono::steady_clock::duration interval,
44+ std::function<void ()> callback) override {
45+ if (count_tasks == 0 ) {
46+ heartbeat_callback = callback;
47+ heartbeat_interval = interval;
48+ } else if (count_tasks == 1 ) {
49+ metrics_callback = callback;
50+ metrics_interval = interval;
51+ }
52+ count_tasks++;
53+ return [this ]() { cancelled = true ; };
54+ }
55+
56+ void trigger_heartbeat () {
57+ assert (heartbeat_callback != nullptr );
58+ heartbeat_callback ();
59+ }
60+
61+ void trigger_metrics_capture () {
62+ assert (metrics_callback != nullptr );
63+ metrics_callback ();
64+ }
65+
66+ std::string config () const override {
67+ return nlohmann::json::object ({{" type" , " FakeEventScheduler" }}).dump ();
68+ }
69+ };
70+
3471} // namespace
3572
3673TEST_CASE (" Tracer telemetry" , " [telemetry]" ) {
@@ -43,27 +80,13 @@ TEST_CASE("Tracer telemetry", "[telemetry]") {
4380
4481 auto logger = std::make_shared<MockLogger>();
4582 auto client = std::make_shared<MockHTTPClient>();
46- auto scheduler = std::make_shared<MockEventScheduler>();
47-
48- auto trigger_heartbeat = [&]() {
49- // White box testing. The current implementation send a heartbeat every 60s
50- // and the task is executed every 10s.
51- // TODO(@dmehala): should depends on the config
52- scheduler->event_callback ();
53- scheduler->event_callback ();
54- scheduler->event_callback ();
55- scheduler->event_callback ();
56- scheduler->event_callback ();
57- scheduler->event_callback ();
58- };
83+ auto scheduler = std::make_shared<FakeEventScheduler>();
5984
6085 const TracerSignature tracer_signature{
6186 /* runtime_id = */ RuntimeID::generate (),
6287 /* service = */ " testsvc" ,
6388 /* environment = */ " test" };
6489
65- const std::string ignore{" " };
66-
6790 auto url = HTTPClient::URL::parse (" http://localhost:8000" );
6891 Telemetry telemetry{*finalize_config (),
6992 logger,
@@ -227,7 +250,7 @@ TEST_CASE("Tracer telemetry", "[telemetry]") {
227250
228251 SECTION (" generates a heartbeat message" ) {
229252 client->clear ();
230- trigger_heartbeat ();
253+ scheduler-> trigger_heartbeat ();
231254
232255 auto heartbeat_message = client->request_body ;
233256 auto message_batch = nlohmann::json::parse (heartbeat_message);
@@ -240,7 +263,8 @@ TEST_CASE("Tracer telemetry", "[telemetry]") {
240263 SECTION (" captures metrics and sends generate-metrics payload" ) {
241264 telemetry.metrics ().tracer .trace_segments_created_new .inc ();
242265 REQUIRE (telemetry.metrics ().tracer .trace_segments_created_new .value () == 1 );
243- trigger_heartbeat ();
266+ scheduler->trigger_metrics_capture ();
267+ scheduler->trigger_heartbeat ();
244268
245269 REQUIRE (telemetry.metrics ().tracer .trace_segments_created_new .value () == 0 );
246270
@@ -322,7 +346,7 @@ TEST_CASE("Tracer telemetry", "[telemetry]") {
322346
323347 client->clear ();
324348 test_case.apply (telemetry, test_case.input , test_case.stacktrace );
325- trigger_heartbeat ();
349+ scheduler-> trigger_heartbeat ();
326350
327351 auto message_batch = nlohmann::json::parse (client->request_body );
328352 REQUIRE (is_valid_telemetry_payload (message_batch));
@@ -345,3 +369,72 @@ TEST_CASE("Tracer telemetry", "[telemetry]") {
345369 }
346370 }
347371}
372+
373+ TEST_CASE (" Tracer telemetry configuration" , " [telemetry]" ) {
374+ // Cases:
375+ // - when `report_metrics` is set to false. No metrics are reported.
376+ // - when `report_logs` is set to false. No logs are reported.
377+ // - respects interval defined.
378+ // - telemetry disabled doesn't send anything.
379+
380+ auto logger = std::make_shared<MockLogger>();
381+ auto client = std::make_shared<MockHTTPClient>();
382+ auto scheduler = std::make_shared<FakeEventScheduler>();
383+ std::vector<std::shared_ptr<Metric>> metrics;
384+
385+ const TracerSignature tracer_signature{
386+ /* runtime_id = */ RuntimeID::generate (),
387+ /* service = */ " testsvc" ,
388+ /* environment = */ " test" };
389+
390+ auto url = HTTPClient::URL::parse (" http://localhost:8000" );
391+
392+ SECTION (" disabling metrics reporting do not collect metrics" ) {
393+ Configuration cfg;
394+ cfg.report_metrics = false ;
395+
396+ auto final_cfg = finalize_config (cfg);
397+ REQUIRE (final_cfg);
398+
399+ Telemetry telemetry (*final_cfg, logger, client, metrics, scheduler, *url);
400+ CHECK (scheduler->metrics_callback == nullptr );
401+ CHECK (scheduler->metrics_interval == nullopt );
402+ }
403+
404+ SECTION (" intervals are respected" ) {
405+ Configuration cfg;
406+ cfg.metrics_interval_seconds = .5 ;
407+ cfg.heartbeat_interval_seconds = 30 ;
408+
409+ auto final_cfg = finalize_config (cfg);
410+ REQUIRE (final_cfg);
411+
412+ Telemetry telemetry (*final_cfg, logger, client, metrics, scheduler, *url);
413+ CHECK (scheduler->metrics_callback != nullptr );
414+ CHECK (scheduler->metrics_interval == 500ms);
415+
416+ CHECK (scheduler->heartbeat_callback != nullptr );
417+ CHECK (scheduler->metrics_interval != 30s);
418+ }
419+
420+ SECTION (" disabling logs reporting do not collect logs" ) {
421+ client->clear ();
422+
423+ Configuration cfg;
424+ cfg.report_logs = false ;
425+
426+ auto final_cfg = finalize_config (cfg);
427+ REQUIRE (final_cfg);
428+
429+ Telemetry telemetry (*final_cfg, logger, client, metrics, scheduler, *url);
430+ telemetry.log_error (" error" );
431+
432+ // NOTE(@dmehala): logs are sent with an heartbeat.
433+ scheduler->trigger_heartbeat ();
434+
435+ auto message_batch = nlohmann::json::parse (client->request_body );
436+ REQUIRE (is_valid_telemetry_payload (message_batch));
437+ REQUIRE (message_batch[" payload" ].size () == 1 );
438+ CHECK (message_batch[" payload" ][0 ][" request_type" ] == " app-heartbeat" );
439+ }
440+ }
0 commit comments