// Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 #ifdef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/_metrics/ungrouped_processor.h" # include # include "opentelemetry/nostd/shared_ptr.h" # include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h" namespace metric_sdk = opentelemetry::sdk::metrics; namespace metrics_api = opentelemetry::metrics; namespace nostd = opentelemetry::nostd; /* Test that CheckpointSelf() will return the amount of unique records in it, then call FinishedCollection and see the map reset */ TEST(UngroupedMetricsProcessor, UngroupedProcessorFinishedCollectionStateless) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(false)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator2 = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5.5); aggregator->checkpoint(); aggregator2->update(500.4); aggregator2->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); // Must have different (name, description, label, instrument) to map to metric_sdk::Record r2("name2", "description2", "labels2", aggregator2); processor->process(r); processor->process(r2); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint.size(), 2); processor->FinishedCollection(); checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint.size(), 0); } /* Test that CheckpointSelf() will return the amount of unique records in it, then call FinishedCollection and see the map stay the same */ TEST(UngroupedMetricsProcessor, UngroupedProcessorFinishedCollectionStateful) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator2 = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5.5); aggregator->checkpoint(); aggregator2->update(500.4); aggregator2->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); // Must have different (name, description, label, instrument) to map to metric_sdk::Record r2("name2", "description2", "labels2", aggregator2); processor->process(r); processor->process(r2); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint.size(), 2); processor->FinishedCollection(); ASSERT_EQ(checkpoint.size(), 2); } // Test to make sure we keep information from record(short) that goes through process() TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatelessShort) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(false)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(4); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()), aggregator); } // Test to make sure we keep information from record(int) that goes through process() TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatelessInt) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(false)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()), aggregator); } // Test to make sure we keep information from record(float) that goes through process() TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatelessFloat) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(false)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(8.5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()), aggregator); } // Test to make sure we keep information from record(double) that goes through process() TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatelessDouble) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(false)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5.5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()), aggregator); } /** * The following tests are for the Stateful version of the processor. These tests will make sure * that when we send the same aggreagtor twice through process(), that the values will be merged. * We can easily recreate this expected value by making a test aggregator that is updated through * both process functions but only checkpointed at the end. */ TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulShort) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator_test = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5); aggregator_test->update(5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(4); aggregator_test->update(4); aggregator->checkpoint(); aggregator_test->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint()[0], aggregator_test->get_checkpoint()[0]); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulInt) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator_test = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5); aggregator_test->update(5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(4); aggregator_test->update(4); aggregator->checkpoint(); aggregator_test->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint()[0], aggregator_test->get_checkpoint()[0]); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulFloat) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator_test = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5); aggregator_test->update(5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(4); aggregator_test->update(4); aggregator->checkpoint(); aggregator_test->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint()[0], aggregator_test->get_checkpoint()[0]); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulDouble) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator_test = std::shared_ptr>( new metric_sdk::CounterAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(5.5); aggregator_test->update(5.5); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(4.4); aggregator_test->update(4.4); aggregator->checkpoint(); aggregator_test->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint()[0], aggregator_test->get_checkpoint()[0]); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulMinMaxSumCount) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::MinMaxSumCountAggregator(metrics_api::InstrumentKind::Counter)); auto aggregator2 = std::shared_ptr>( new metric_sdk::MinMaxSumCountAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(1.1); aggregator->update(2.2); aggregator2->update(1.1); aggregator2->update(2.2); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(5.5); aggregator2->update(5.5); aggregator->checkpoint(); aggregator2->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ( nostd::get>>(checkpoint2[0].GetAggregator()) ->get_checkpoint(), aggregator2->get_checkpoint()); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulGauge) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::GaugeAggregator(metrics_api::InstrumentKind::Counter)); aggregator->update(1.1); aggregator->update(2.2); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(5.4); aggregator->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ( nostd::get>>(checkpoint2[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulExact) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::ExactAggregator(metrics_api::InstrumentKind::Counter, false)); auto aggregator2 = std::shared_ptr>( new metric_sdk::ExactAggregator(metrics_api::InstrumentKind::Counter, false)); aggregator->update(1.1); aggregator->update(2.2); aggregator2->update(1.1); aggregator2->update(2.2); aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ( nostd::get>>(checkpoint[0].GetAggregator()) ->get_checkpoint(), aggregator->get_checkpoint()); aggregator->update(5.4); aggregator2->update(5.4); aggregator->checkpoint(); aggregator2->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ( nostd::get>>(checkpoint2[0].GetAggregator()) ->get_checkpoint(), aggregator2->get_checkpoint()); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulHistogram) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); std::vector boundaries{10, 20, 30, 40, 50}; auto aggregator = std::shared_ptr>( new metric_sdk::HistogramAggregator(metrics_api::InstrumentKind::Counter, boundaries)); auto aggregator2 = std::shared_ptr>( new metric_sdk::HistogramAggregator(metrics_api::InstrumentKind::Counter, boundaries)); for (int i = 0; i < 60; i++) { aggregator->update(i); aggregator2->update(i); } aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()) ->get_boundaries(), aggregator->get_boundaries()); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()) ->get_counts(), aggregator->get_counts()); for (int i = 0; i < 60; i++) { aggregator->update(i); aggregator2->update(i); } aggregator->checkpoint(); aggregator2->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2.size(), 1); ASSERT_EQ(checkpoint2[0].GetName(), "name"); ASSERT_EQ(checkpoint2[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint2[0].GetDescription(), "description"); ASSERT_EQ(nostd::get>>(checkpoint2[0].GetAggregator()) ->get_boundaries(), aggregator->get_boundaries()); ASSERT_EQ(nostd::get>>(checkpoint2[0].GetAggregator()) ->get_counts(), aggregator2->get_counts()); ASSERT_EQ(nostd::get>>(checkpoint2[0].GetAggregator()) ->get_checkpoint(), aggregator2->get_checkpoint()); } TEST(UngroupedMetricsProcessor, UngroupedProcessorKeepsRecordInformationStatefulSketch) { auto processor = std::unique_ptr( new metric_sdk::UngroupedMetricsProcessor(true)); auto aggregator = std::shared_ptr>( new metric_sdk::SketchAggregator(metrics_api::InstrumentKind::Counter, .00005)); auto test_aggregator = std::shared_ptr>( new metric_sdk::SketchAggregator(metrics_api::InstrumentKind::Counter, .00005)); for (int i = 0; i < 60; i++) { aggregator->update(i); test_aggregator->update(i); } aggregator->checkpoint(); metric_sdk::Record r("name", "description", "labels", aggregator); processor->process(r); std::vector checkpoint = processor->CheckpointSelf(); ASSERT_EQ(checkpoint[0].GetName(), "name"); ASSERT_EQ(checkpoint[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint[0].GetDescription(), "description"); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()) ->get_boundaries(), aggregator->get_boundaries()); ASSERT_EQ(nostd::get>>(checkpoint[0].GetAggregator()) ->get_counts(), aggregator->get_counts()); for (int i = 0; i < 60; i++) { aggregator->update(i); test_aggregator->update(i); } aggregator->checkpoint(); test_aggregator->checkpoint(); processor->process(r); std::vector checkpoint2 = processor->CheckpointSelf(); ASSERT_EQ(checkpoint2[0].GetName(), "name"); ASSERT_EQ(checkpoint2[0].GetLabels(), "labels"); ASSERT_EQ(checkpoint2[0].GetDescription(), "description"); ASSERT_EQ(nostd::get>>(checkpoint2[0].GetAggregator()) ->get_boundaries(), test_aggregator->get_boundaries()); ASSERT_EQ(nostd::get>>(checkpoint2[0].GetAggregator()) ->get_counts(), test_aggregator->get_counts()); ASSERT_EQ(nostd::get>>(checkpoint2[0].GetAggregator()) ->get_checkpoint(), test_aggregator->get_checkpoint()); } #endif