diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp index 93795d4b25e63..d32f5a947d126 100644 --- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp +++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp @@ -516,6 +516,21 @@ bool determineAllMetricUpdateStatuses(const StatsdConfig& config, return false; } } + for (int i = 0; i < config.duration_metric_size(); i++, metricIndex++) { + const DurationMetric& metric = config.duration_metric(i); + set conditionDependencies({metric.what()}); + if (metric.has_condition()) { + conditionDependencies.insert(metric.condition()); + } + if (!determineMetricUpdateStatus( + config, metric, metric.id(), METRIC_TYPE_DURATION, /*matcherDependencies=*/{}, + conditionDependencies, metric.slice_by_state(), metric.links(), + oldMetricProducerMap, oldMetricProducers, metricToActivationMap, + replacedMatchers, replacedConditions, replacedStates, + metricsToUpdate[metricIndex])) { + return false; + } + } for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) { const EventMetric& metric = config.event_metric(i); set conditionDependencies; @@ -538,8 +553,7 @@ bool determineAllMetricUpdateStatuses(const StatsdConfig& config, if (metric.has_condition()) { conditionDependencies.insert(metric.condition()); } - set matcherDependencies; - matcherDependencies.insert(metric.what()); + set matcherDependencies({metric.what()}); if (metric.has_trigger_event()) { matcherDependencies.insert(metric.trigger_event()); } @@ -552,7 +566,7 @@ bool determineAllMetricUpdateStatuses(const StatsdConfig& config, return false; } } - // TODO: determine update status for value, duration metrics. + // TODO: determine update status for value metrics. return true; } diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp index 60705cf5ffe76..a20be15d95419 100644 --- a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp +++ b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp @@ -155,6 +155,20 @@ GaugeMetric createGaugeMetric(string name, int64_t what, GaugeMetric::SamplingTy return metric; } +DurationMetric createDurationMetric(string name, int64_t what, optional condition, + vector states) { + DurationMetric metric; + metric.set_id(StringToId(name)); + metric.set_what(what); + metric.set_bucket(TEN_MINUTES); + if (condition) { + metric.set_condition(condition.value()); + } + for (const int64_t state : states) { + metric.add_slice_by_state(state); + } + return metric; +} } // anonymous namespace TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) { @@ -1398,6 +1412,130 @@ TEST_F(ConfigUpdateTest, TestGaugeMetricTriggerEventChanged) { EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE); } +TEST_F(ConfigUpdateTest, TestDurationMetricPreserve) { + StatsdConfig config; + AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = startMatcher; + AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = stopMatcher; + + Predicate what = CreateScreenIsOnPredicate(); + *config.add_predicate() = what; + Predicate condition = CreateScreenIsOffPredicate(); + *config.add_predicate() = condition; + + State sliceState = CreateScreenState(); + *config.add_state() = sliceState; + + *config.add_duration_metric() = + createDurationMetric("DURATION1", what.id(), condition.id(), {sliceState.id()}); + EXPECT_TRUE(initConfig(config)); + + unordered_map metricToActivationMap; + vector metricsToUpdate(1, UPDATE_UNKNOWN); + EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers, + metricToActivationMap, + /*replacedMatchers*/ {}, /*replacedConditions=*/{}, + /*replacedStates=*/{}, metricsToUpdate)); + EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE); +} + +TEST_F(ConfigUpdateTest, TestDurationMetricDefinitionChange) { + StatsdConfig config; + AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = startMatcher; + AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = stopMatcher; + + Predicate what = CreateScreenIsOnPredicate(); + *config.add_predicate() = what; + + *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {}); + EXPECT_TRUE(initConfig(config)); + + config.mutable_duration_metric(0)->set_aggregation_type(DurationMetric::MAX_SPARSE); + + unordered_map metricToActivationMap; + vector metricsToUpdate(1, UPDATE_UNKNOWN); + EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers, + metricToActivationMap, /*replacedMatchers*/ {}, + /*replacedConditions=*/{}, /*replacedStates=*/{}, + metricsToUpdate)); + EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE); +} + +TEST_F(ConfigUpdateTest, TestDurationMetricWhatChanged) { + StatsdConfig config; + AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = startMatcher; + AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = stopMatcher; + + Predicate what = CreateScreenIsOnPredicate(); + *config.add_predicate() = what; + + *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {}); + EXPECT_TRUE(initConfig(config)); + + unordered_map metricToActivationMap; + vector metricsToUpdate(1, UPDATE_UNKNOWN); + EXPECT_TRUE(determineAllMetricUpdateStatuses( + config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap, + /*replacedMatchers*/ {}, /*replacedConditions=*/{what.id()}, + /*replacedStates=*/{}, metricsToUpdate)); + EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE); +} + +TEST_F(ConfigUpdateTest, TestDurationMetricConditionChanged) { + StatsdConfig config; + AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = startMatcher; + AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = stopMatcher; + + Predicate what = CreateScreenIsOnPredicate(); + *config.add_predicate() = what; + Predicate condition = CreateScreenIsOffPredicate(); + *config.add_predicate() = condition; + + *config.add_duration_metric() = createDurationMetric("DURATION", what.id(), condition.id(), {}); + EXPECT_TRUE(initConfig(config)); + + unordered_map metricToActivationMap; + vector metricsToUpdate(1, UPDATE_UNKNOWN); + EXPECT_TRUE(determineAllMetricUpdateStatuses( + config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap, + /*replacedMatchers*/ {}, /*replacedConditions=*/{condition.id()}, + /*replacedStates=*/{}, metricsToUpdate)); + EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE); +} + +TEST_F(ConfigUpdateTest, TestDurationMetricStateChange) { + StatsdConfig config; + AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher(); + *config.add_atom_matcher() = startMatcher; + AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher(); + *config.add_atom_matcher() = stopMatcher; + + Predicate what = CreateScreenIsOnPredicate(); + *config.add_predicate() = what; + + State sliceState = CreateScreenState(); + *config.add_state() = sliceState; + + *config.add_duration_metric() = + createDurationMetric("DURATION1", what.id(), nullopt, {sliceState.id()}); + EXPECT_TRUE(initConfig(config)); + + unordered_map metricToActivationMap; + vector metricsToUpdate(1, UPDATE_UNKNOWN); + EXPECT_TRUE(determineAllMetricUpdateStatuses( + config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap, + /*replacedMatchers*/ {}, /*replacedConditions=*/{}, + /*replacedStates=*/{sliceState.id()}, metricsToUpdate)); + EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE); +} + TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) { StatsdConfig config;