1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/metrics/parsing_utils/config_update_utils.h"
16
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <private/android_filesystem_config.h>
20 #include <stdio.h>
21
22 #include <set>
23 #include <unordered_map>
24 #include <vector>
25
26 #include "src/condition/CombinationConditionTracker.h"
27 #include "src/condition/SimpleConditionTracker.h"
28 #include "src/matchers/CombinationAtomMatchingTracker.h"
29 #include "src/metrics/CountMetricProducer.h"
30 #include "src/metrics/DurationMetricProducer.h"
31 #include "src/metrics/GaugeMetricProducer.h"
32 #include "src/metrics/KllMetricProducer.h"
33 #include "src/metrics/NumericValueMetricProducer.h"
34 #include "src/metrics/parsing_utils/metrics_manager_util.h"
35 #include "src/statsd_config.pb.h"
36 #include "tests/statsd_test_util.h"
37
38 using namespace testing;
39 using android::sp;
40 using android::os::statsd::Predicate;
41 using std::map;
42 using std::nullopt;
43 using std::optional;
44 using std::set;
45 using std::unordered_map;
46 using std::vector;
47
48 #ifdef __ANDROID__
49
50 namespace android {
51 namespace os {
52 namespace statsd {
53
54 namespace {
55
56 const int configId = 456;
57 const ConfigKey key(123, configId);
58 const int64_t timeBaseNs = 1000 * NS_PER_SEC;
59
60 sp<UidMap> uidMap = new UidMap();
61 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
62 sp<AlarmMonitor> anomalyAlarmMonitor;
63 sp<AlarmMonitor> periodicAlarmMonitor = new AlarmMonitor(
64 /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
__anonad64a68c0202(const shared_ptr<IStatsCompanionService>&, int64_t) 65 [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
__anonad64a68c0302(const shared_ptr<IStatsCompanionService>&) 66 [](const shared_ptr<IStatsCompanionService>&) {});
67 sp<ConfigMetadataProvider> configMetadataProvider;
68 unordered_map<int, vector<int>> allTagIdsToMatchersMap;
69 vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
70 unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
71 vector<sp<ConditionTracker>> oldConditionTrackers;
72 unordered_map<int64_t, int> oldConditionTrackerMap;
73 vector<sp<MetricProducer>> oldMetricProducers;
74 unordered_map<int64_t, int> oldMetricProducerMap;
75 vector<sp<AnomalyTracker>> oldAnomalyTrackers;
76 unordered_map<int64_t, int> oldAlertTrackerMap;
77 vector<sp<AlarmTracker>> oldAlarmTrackers;
78 unordered_map<int, vector<int>> tmpConditionToMetricMap;
79 unordered_map<int, vector<int>> tmpTrackerToMetricMap;
80 unordered_map<int, vector<int>> tmpTrackerToConditionMap;
81 unordered_map<int, vector<int>> tmpActivationAtomTrackerToMetricMap;
82 unordered_map<int, vector<int>> tmpDeactivationAtomTrackerToMetricMap;
83 vector<int> metricsWithActivation;
84 map<int64_t, uint64_t> oldStateHashes;
85 set<int64_t> noReportMetricIds;
86
initConfig(const StatsdConfig & config)87 bool initConfig(const StatsdConfig& config) {
88 // initStatsdConfig returns nullopt if config is valid
89 return !initStatsdConfig(
90 key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
91 timeBaseNs, timeBaseNs, configMetadataProvider, allTagIdsToMatchersMap,
92 oldAtomMatchingTrackers, oldAtomMatchingTrackerMap, oldConditionTrackers,
93 oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
94 oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap,
95 tmpTrackerToMetricMap, tmpTrackerToConditionMap,
96 tmpActivationAtomTrackerToMetricMap, tmpDeactivationAtomTrackerToMetricMap,
97 oldAlertTrackerMap, metricsWithActivation, oldStateHashes, noReportMetricIds)
98 .has_value();
99 }
100
filterMatcherIndexesById(const vector<sp<AtomMatchingTracker>> & atomMatchingTrackers,const vector<int64_t> & ids)101 vector<int> filterMatcherIndexesById(const vector<sp<AtomMatchingTracker>>& atomMatchingTrackers,
102 const vector<int64_t>& ids) {
103 vector<int> result;
104
105 for (auto& id : ids) {
106 for (int i = 0; i < atomMatchingTrackers.size(); i++) {
107 if (atomMatchingTrackers[i]->getId() == id) {
108 result.push_back(i);
109 }
110 }
111 }
112
113 return result;
114 }
115
116 class ConfigUpdateTest : public ::testing::Test {
117 public:
SetUp()118 void SetUp() override {
119 allTagIdsToMatchersMap.clear();
120 oldAtomMatchingTrackers.clear();
121 oldAtomMatchingTrackerMap.clear();
122 oldConditionTrackers.clear();
123 oldConditionTrackerMap.clear();
124 oldMetricProducers.clear();
125 oldMetricProducerMap.clear();
126 oldAnomalyTrackers.clear();
127 oldAlarmTrackers.clear();
128 tmpConditionToMetricMap.clear();
129 tmpTrackerToMetricMap.clear();
130 tmpTrackerToConditionMap.clear();
131 tmpActivationAtomTrackerToMetricMap.clear();
132 tmpDeactivationAtomTrackerToMetricMap.clear();
133 oldAlertTrackerMap.clear();
134 metricsWithActivation.clear();
135 oldStateHashes.clear();
136 noReportMetricIds.clear();
137 StateManager::getInstance().clear();
138 }
139 };
140
141 struct DimLimitTestCase {
142 int oldLimit;
143 int newLimit;
144 int actualLimit;
145
PrintTo(const DimLimitTestCase & testCase,ostream * os)146 friend void PrintTo(const DimLimitTestCase& testCase, ostream* os) {
147 *os << testCase.oldLimit << "To" << testCase.newLimit;
148 }
149 };
150
151 class ConfigUpdateDimLimitTest : public ConfigUpdateTest,
152 public WithParamInterface<DimLimitTestCase> {};
153
154 const vector<DimLimitTestCase> dimLimitTestCases = {
155 {900, 900, 900}, {1000, 850, 850}, {1100, 1500, 1500},
156 {800, 799, 800}, {3000, 3001, 3000}, {800, 0, 800},
157 };
158
159 INSTANTIATE_TEST_SUITE_P(DimLimit, ConfigUpdateDimLimitTest, ValuesIn(dimLimitTestCases),
160 PrintToStringParamName());
161
162 } // anonymous namespace
163
TEST_F(ConfigUpdateTest,TestSimpleMatcherPreserve)164 TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) {
165 StatsdConfig config;
166 AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
167 int64_t matcherId = matcher.id();
168 *config.add_atom_matcher() = matcher;
169
170 // Create an initial config.
171 EXPECT_TRUE(initConfig(config));
172
173 vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
174 vector<uint8_t> cycleTracker(1, false);
175 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
176 newAtomMatchingTrackerMap[matcherId] = 0;
177 EXPECT_EQ(determineMatcherUpdateStatus(config, 0, oldAtomMatchingTrackerMap,
178 oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
179 matchersToUpdate, cycleTracker),
180 nullopt);
181 EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
182 }
183
TEST_F(ConfigUpdateTest,TestSimpleMatcherReplace)184 TEST_F(ConfigUpdateTest, TestSimpleMatcherReplace) {
185 StatsdConfig config;
186 AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
187 *config.add_atom_matcher() = matcher;
188
189 EXPECT_TRUE(initConfig(config));
190
191 StatsdConfig newConfig;
192 // Same id, different atom, so should be replaced.
193 AtomMatcher newMatcher = CreateSimpleAtomMatcher("TEST", /*atom=*/11);
194 int64_t matcherId = newMatcher.id();
195 EXPECT_EQ(matcherId, matcher.id());
196 *newConfig.add_atom_matcher() = newMatcher;
197
198 vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
199 vector<uint8_t> cycleTracker(1, false);
200 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
201 newAtomMatchingTrackerMap[matcherId] = 0;
202 EXPECT_EQ(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
203 oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
204 matchersToUpdate, cycleTracker),
205 nullopt);
206 EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
207 }
208
TEST_F(ConfigUpdateTest,TestSimpleMatcherNew)209 TEST_F(ConfigUpdateTest, TestSimpleMatcherNew) {
210 StatsdConfig config;
211 AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
212 *config.add_atom_matcher() = matcher;
213
214 EXPECT_TRUE(initConfig(config));
215
216 StatsdConfig newConfig;
217 // Different id, so should be a new matcher.
218 AtomMatcher newMatcher = CreateSimpleAtomMatcher("DIFFERENT_NAME", /*atom=*/10);
219 int64_t matcherId = newMatcher.id();
220 EXPECT_NE(matcherId, matcher.id());
221 *newConfig.add_atom_matcher() = newMatcher;
222
223 vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
224 vector<uint8_t> cycleTracker(1, false);
225 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
226 newAtomMatchingTrackerMap[matcherId] = 0;
227 EXPECT_EQ(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
228 oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
229 matchersToUpdate, cycleTracker),
230 nullopt);
231 EXPECT_EQ(matchersToUpdate[0], UPDATE_NEW);
232 }
233
TEST_F(ConfigUpdateTest,TestCombinationMatcherPreserve)234 TEST_F(ConfigUpdateTest, TestCombinationMatcherPreserve) {
235 StatsdConfig config;
236 AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
237 int64_t matcher1Id = matcher1.id();
238 *config.add_atom_matcher() = matcher1;
239
240 AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
241 *config.add_atom_matcher() = matcher2;
242 int64_t matcher2Id = matcher2.id();
243
244 AtomMatcher matcher3;
245 matcher3.set_id(StringToId("TEST3"));
246 AtomMatcher_Combination* combination = matcher3.mutable_combination();
247 combination->set_operation(LogicalOperation::OR);
248 combination->add_matcher(matcher1Id);
249 combination->add_matcher(matcher2Id);
250 int64_t matcher3Id = matcher3.id();
251 *config.add_atom_matcher() = matcher3;
252
253 EXPECT_TRUE(initConfig(config));
254
255 StatsdConfig newConfig;
256 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
257 // Same matchers, different order, all should be preserved.
258 *newConfig.add_atom_matcher() = matcher2;
259 newAtomMatchingTrackerMap[matcher2Id] = 0;
260 *newConfig.add_atom_matcher() = matcher3;
261 newAtomMatchingTrackerMap[matcher3Id] = 1;
262 *newConfig.add_atom_matcher() = matcher1;
263 newAtomMatchingTrackerMap[matcher1Id] = 2;
264
265 vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
266 vector<uint8_t> cycleTracker(3, false);
267 // Only update the combination. It should recurse the two child matchers and preserve all 3.
268 EXPECT_EQ(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
269 oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
270 matchersToUpdate, cycleTracker),
271 nullopt);
272 EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
273 EXPECT_EQ(matchersToUpdate[1], UPDATE_PRESERVE);
274 EXPECT_EQ(matchersToUpdate[2], UPDATE_PRESERVE);
275 }
276
TEST_F(ConfigUpdateTest,TestCombinationMatcherReplace)277 TEST_F(ConfigUpdateTest, TestCombinationMatcherReplace) {
278 StatsdConfig config;
279 AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
280 int64_t matcher1Id = matcher1.id();
281 *config.add_atom_matcher() = matcher1;
282
283 AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
284 *config.add_atom_matcher() = matcher2;
285 int64_t matcher2Id = matcher2.id();
286
287 AtomMatcher matcher3;
288 matcher3.set_id(StringToId("TEST3"));
289 AtomMatcher_Combination* combination = matcher3.mutable_combination();
290 combination->set_operation(LogicalOperation::OR);
291 combination->add_matcher(matcher1Id);
292 combination->add_matcher(matcher2Id);
293 int64_t matcher3Id = matcher3.id();
294 *config.add_atom_matcher() = matcher3;
295
296 EXPECT_TRUE(initConfig(config));
297
298 // Change the logical operation of the combination matcher, causing a replacement.
299 matcher3.mutable_combination()->set_operation(LogicalOperation::AND);
300
301 StatsdConfig newConfig;
302 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
303 *newConfig.add_atom_matcher() = matcher2;
304 newAtomMatchingTrackerMap[matcher2Id] = 0;
305 *newConfig.add_atom_matcher() = matcher3;
306 newAtomMatchingTrackerMap[matcher3Id] = 1;
307 *newConfig.add_atom_matcher() = matcher1;
308 newAtomMatchingTrackerMap[matcher1Id] = 2;
309
310 vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
311 vector<uint8_t> cycleTracker(3, false);
312 // Only update the combination. The simple matchers should not be evaluated.
313 EXPECT_EQ(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
314 oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
315 matchersToUpdate, cycleTracker),
316 nullopt);
317 EXPECT_EQ(matchersToUpdate[0], UPDATE_UNKNOWN);
318 EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
319 EXPECT_EQ(matchersToUpdate[2], UPDATE_UNKNOWN);
320 }
321
TEST_F(ConfigUpdateTest,TestCombinationMatcherDepsChange)322 TEST_F(ConfigUpdateTest, TestCombinationMatcherDepsChange) {
323 StatsdConfig config;
324 AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
325 int64_t matcher1Id = matcher1.id();
326 *config.add_atom_matcher() = matcher1;
327
328 AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
329 *config.add_atom_matcher() = matcher2;
330 int64_t matcher2Id = matcher2.id();
331
332 AtomMatcher matcher3;
333 matcher3.set_id(StringToId("TEST3"));
334 AtomMatcher_Combination* combination = matcher3.mutable_combination();
335 combination->set_operation(LogicalOperation::OR);
336 combination->add_matcher(matcher1Id);
337 combination->add_matcher(matcher2Id);
338 int64_t matcher3Id = matcher3.id();
339 *config.add_atom_matcher() = matcher3;
340
341 EXPECT_TRUE(initConfig(config));
342
343 // Change a dependency of matcher 3.
344 matcher2.mutable_simple_atom_matcher()->set_atom_id(12);
345
346 StatsdConfig newConfig;
347 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
348 *newConfig.add_atom_matcher() = matcher2;
349 newAtomMatchingTrackerMap[matcher2Id] = 0;
350 *newConfig.add_atom_matcher() = matcher3;
351 newAtomMatchingTrackerMap[matcher3Id] = 1;
352 *newConfig.add_atom_matcher() = matcher1;
353 newAtomMatchingTrackerMap[matcher1Id] = 2;
354
355 vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
356 vector<uint8_t> cycleTracker(3, false);
357 // Only update the combination.
358 EXPECT_EQ(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
359 oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
360 matchersToUpdate, cycleTracker),
361 nullopt);
362 // Matcher 2 and matcher3 must be reevaluated. Matcher 1 might, but does not need to be.
363 EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
364 EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
365 }
366
TEST_F(ConfigUpdateTest,TestUpdateMatchers)367 TEST_F(ConfigUpdateTest, TestUpdateMatchers) {
368 StatsdConfig config;
369 // Will be preserved.
370 AtomMatcher simple1 = CreateSimpleAtomMatcher("SIMPLE1", /*atom=*/10);
371 int64_t simple1Id = simple1.id();
372 *config.add_atom_matcher() = simple1;
373
374 // Will be replaced.
375 AtomMatcher simple2 = CreateSimpleAtomMatcher("SIMPLE2", /*atom=*/11);
376 *config.add_atom_matcher() = simple2;
377 int64_t simple2Id = simple2.id();
378
379 // Will be removed.
380 AtomMatcher simple3 = CreateSimpleAtomMatcher("SIMPLE3", /*atom=*/12);
381 *config.add_atom_matcher() = simple3;
382 int64_t simple3Id = simple3.id();
383
384 // Will be preserved.
385 AtomMatcher combination1;
386 combination1.set_id(StringToId("combination1"));
387 AtomMatcher_Combination* combination = combination1.mutable_combination();
388 combination->set_operation(LogicalOperation::NOT);
389 combination->add_matcher(simple1Id);
390 int64_t combination1Id = combination1.id();
391 *config.add_atom_matcher() = combination1;
392
393 // Will be replaced since it depends on simple2.
394 AtomMatcher combination2;
395 combination2.set_id(StringToId("combination2"));
396 combination = combination2.mutable_combination();
397 combination->set_operation(LogicalOperation::AND);
398 combination->add_matcher(simple1Id);
399 combination->add_matcher(simple2Id);
400 int64_t combination2Id = combination2.id();
401 *config.add_atom_matcher() = combination2;
402
403 EXPECT_TRUE(initConfig(config));
404
405 // Change simple2, causing simple2 and combination2 to be replaced.
406 simple2.mutable_simple_atom_matcher()->set_atom_id(111);
407
408 // 2 new matchers: simple4 and combination3:
409 AtomMatcher simple4 = CreateSimpleAtomMatcher("SIMPLE4", /*atom=*/13);
410 int64_t simple4Id = simple4.id();
411
412 AtomMatcher combination3;
413 combination3.set_id(StringToId("combination3"));
414 combination = combination3.mutable_combination();
415 combination->set_operation(LogicalOperation::AND);
416 combination->add_matcher(simple4Id);
417 combination->add_matcher(simple2Id);
418 int64_t combination3Id = combination3.id();
419
420 StatsdConfig newConfig;
421 *newConfig.add_atom_matcher() = combination3;
422 *newConfig.add_atom_matcher() = simple2;
423 *newConfig.add_atom_matcher() = combination2;
424 *newConfig.add_atom_matcher() = simple1;
425 *newConfig.add_atom_matcher() = simple4;
426 *newConfig.add_atom_matcher() = combination1;
427
428 unordered_map<int, vector<int>> newTagIds;
429 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
430 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
431 set<int64_t> replacedMatchers;
432 EXPECT_EQ(updateAtomMatchingTrackers(newConfig, uidMap, oldAtomMatchingTrackerMap,
433 oldAtomMatchingTrackers, newTagIds,
434 newAtomMatchingTrackerMap, newAtomMatchingTrackers,
435 replacedMatchers),
436 nullopt);
437
438 ASSERT_EQ(newTagIds.size(), 3);
439 EXPECT_EQ(newTagIds.count(10), 1);
440 EXPECT_EQ(newTagIds.count(111), 1);
441 EXPECT_EQ(newTagIds.count(13), 1);
442
443 EXPECT_EQ(newTagIds[10].size(), 3); // simple1, combination1, combination2
444 EXPECT_THAT(newTagIds[10], UnorderedElementsAreArray(filterMatcherIndexesById(
445 newAtomMatchingTrackers,
446 {simple1.id(), combination1.id(), combination2.id()})));
447 EXPECT_EQ(newTagIds[111].size(), 3); // simple2, combination2, combination3
448 EXPECT_THAT(newTagIds[111], UnorderedElementsAreArray(filterMatcherIndexesById(
449 newAtomMatchingTrackers,
450 {simple2.id(), combination2.id(), combination3.id()})));
451 EXPECT_EQ(newTagIds[13].size(), 2); // simple4, combination3
452 EXPECT_THAT(newTagIds[13],
453 UnorderedElementsAreArray(filterMatcherIndexesById(
454 newAtomMatchingTrackers, {simple4.id(), combination3.id()})));
455
456 ASSERT_EQ(newAtomMatchingTrackerMap.size(), 6);
457 EXPECT_EQ(newAtomMatchingTrackerMap.at(combination3Id), 0);
458 EXPECT_EQ(newAtomMatchingTrackerMap.at(simple2Id), 1);
459 EXPECT_EQ(newAtomMatchingTrackerMap.at(combination2Id), 2);
460 EXPECT_EQ(newAtomMatchingTrackerMap.at(simple1Id), 3);
461 EXPECT_EQ(newAtomMatchingTrackerMap.at(simple4Id), 4);
462 EXPECT_EQ(newAtomMatchingTrackerMap.at(combination1Id), 5);
463
464 ASSERT_EQ(newAtomMatchingTrackers.size(), 6);
465 // Make sure all atom matchers are initialized:
466 for (const sp<AtomMatchingTracker>& tracker : newAtomMatchingTrackers) {
467 EXPECT_TRUE(tracker->mInitialized);
468 }
469 // Make sure preserved atom matchers are the same.
470 EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple1Id)],
471 newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple1Id)]);
472 EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination1Id)],
473 newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination1Id)]);
474 // Make sure replaced matchers are different.
475 EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple2Id)],
476 newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple2Id)]);
477 EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination2Id)],
478 newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination2Id)]);
479
480 // Validation, make sure the matchers have the proper ids. Could do more checks here.
481 EXPECT_EQ(newAtomMatchingTrackers[0]->getId(), combination3Id);
482 EXPECT_EQ(newAtomMatchingTrackers[1]->getId(), simple2Id);
483 EXPECT_EQ(newAtomMatchingTrackers[2]->getId(), combination2Id);
484 EXPECT_EQ(newAtomMatchingTrackers[3]->getId(), simple1Id);
485 EXPECT_EQ(newAtomMatchingTrackers[4]->getId(), simple4Id);
486 EXPECT_EQ(newAtomMatchingTrackers[5]->getId(), combination1Id);
487
488 // Verify child indices of Combination Matchers are correct.
489 CombinationAtomMatchingTracker* combinationTracker1 =
490 static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[5].get());
491 vector<int>* childMatchers = &combinationTracker1->mChildren;
492 EXPECT_EQ(childMatchers->size(), 1);
493 EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());
494
495 CombinationAtomMatchingTracker* combinationTracker2 =
496 static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[2].get());
497 childMatchers = &combinationTracker2->mChildren;
498 EXPECT_EQ(childMatchers->size(), 2);
499 EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
500 EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());
501
502 CombinationAtomMatchingTracker* combinationTracker3 =
503 static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[0].get());
504 childMatchers = &combinationTracker3->mChildren;
505 EXPECT_EQ(childMatchers->size(), 2);
506 EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
507 EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 4), childMatchers->end());
508
509 // Expect replacedMatchers to have simple2 and combination2
510 ASSERT_EQ(replacedMatchers.size(), 2);
511 EXPECT_NE(replacedMatchers.find(simple2Id), replacedMatchers.end());
512 EXPECT_NE(replacedMatchers.find(combination2Id), replacedMatchers.end());
513 }
514
TEST_F(ConfigUpdateTest,TestSimpleConditionPreserve)515 TEST_F(ConfigUpdateTest, TestSimpleConditionPreserve) {
516 StatsdConfig config;
517 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
518 *config.add_atom_matcher() = startMatcher;
519 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
520 *config.add_atom_matcher() = stopMatcher;
521
522 Predicate predicate = CreateScreenIsOnPredicate();
523 *config.add_predicate() = predicate;
524
525 // Create an initial config.
526 EXPECT_TRUE(initConfig(config));
527
528 set<int64_t> replacedMatchers;
529 vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
530 vector<uint8_t> cycleTracker(1, false);
531 unordered_map<int64_t, int> newConditionTrackerMap;
532 newConditionTrackerMap[predicate.id()] = 0;
533 EXPECT_EQ(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
534 oldConditionTrackers, newConditionTrackerMap,
535 replacedMatchers, conditionsToUpdate, cycleTracker),
536 nullopt);
537 EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
538 }
539
TEST_F(ConfigUpdateTest,TestSimpleConditionReplace)540 TEST_F(ConfigUpdateTest, TestSimpleConditionReplace) {
541 StatsdConfig config;
542 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
543 *config.add_atom_matcher() = startMatcher;
544 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
545 *config.add_atom_matcher() = stopMatcher;
546
547 Predicate predicate = CreateScreenIsOnPredicate();
548 *config.add_predicate() = predicate;
549
550 EXPECT_TRUE(initConfig(config));
551
552 // Modify the predicate.
553 config.mutable_predicate(0)->mutable_simple_predicate()->set_count_nesting(true);
554
555 set<int64_t> replacedMatchers;
556 vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
557 vector<uint8_t> cycleTracker(1, false);
558 unordered_map<int64_t, int> newConditionTrackerMap;
559 newConditionTrackerMap[predicate.id()] = 0;
560 EXPECT_EQ(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
561 oldConditionTrackers, newConditionTrackerMap,
562 replacedMatchers, conditionsToUpdate, cycleTracker),
563 nullopt);
564 EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
565 }
566
TEST_F(ConfigUpdateTest,TestSimpleConditionDepsChange)567 TEST_F(ConfigUpdateTest, TestSimpleConditionDepsChange) {
568 StatsdConfig config;
569 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
570 int64_t startMatcherId = startMatcher.id();
571 *config.add_atom_matcher() = startMatcher;
572 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
573 *config.add_atom_matcher() = stopMatcher;
574
575 Predicate predicate = CreateScreenIsOnPredicate();
576 *config.add_predicate() = predicate;
577
578 EXPECT_TRUE(initConfig(config));
579
580 // Start matcher was replaced.
581 set<int64_t> replacedMatchers;
582 replacedMatchers.insert(startMatcherId);
583
584 vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
585 vector<uint8_t> cycleTracker(1, false);
586 unordered_map<int64_t, int> newConditionTrackerMap;
587 newConditionTrackerMap[predicate.id()] = 0;
588 EXPECT_EQ(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
589 oldConditionTrackers, newConditionTrackerMap,
590 replacedMatchers, conditionsToUpdate, cycleTracker),
591 nullopt);
592 EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
593 }
594
TEST_F(ConfigUpdateTest,TestCombinationConditionPreserve)595 TEST_F(ConfigUpdateTest, TestCombinationConditionPreserve) {
596 StatsdConfig config;
597 AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
598 *config.add_atom_matcher() = screenOnMatcher;
599 AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
600 *config.add_atom_matcher() = screenOffMatcher;
601
602 Predicate simple1 = CreateScreenIsOnPredicate();
603 *config.add_predicate() = simple1;
604 Predicate simple2 = CreateScreenIsOffPredicate();
605 *config.add_predicate() = simple2;
606
607 Predicate combination1;
608 combination1.set_id(StringToId("COMBINATION1"));
609 Predicate_Combination* combinationInternal = combination1.mutable_combination();
610 combinationInternal->set_operation(LogicalOperation::NAND);
611 combinationInternal->add_predicate(simple1.id());
612 combinationInternal->add_predicate(simple2.id());
613 *config.add_predicate() = combination1;
614
615 EXPECT_TRUE(initConfig(config));
616
617 // Same predicates, different order
618 StatsdConfig newConfig;
619 unordered_map<int64_t, int> newConditionTrackerMap;
620 *newConfig.add_predicate() = combination1;
621 newConditionTrackerMap[combination1.id()] = 0;
622 *newConfig.add_predicate() = simple2;
623 newConditionTrackerMap[simple2.id()] = 1;
624 *newConfig.add_predicate() = simple1;
625 newConditionTrackerMap[simple1.id()] = 2;
626
627 set<int64_t> replacedMatchers;
628 vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
629 vector<uint8_t> cycleTracker(3, false);
630 // Only update the combination. It should recurse the two child predicates and preserve all 3.
631 EXPECT_EQ(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
632 oldConditionTrackers, newConditionTrackerMap,
633 replacedMatchers, conditionsToUpdate, cycleTracker),
634 nullopt);
635 EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
636 EXPECT_EQ(conditionsToUpdate[1], UPDATE_PRESERVE);
637 EXPECT_EQ(conditionsToUpdate[2], UPDATE_PRESERVE);
638 }
639
TEST_F(ConfigUpdateTest,TestCombinationConditionReplace)640 TEST_F(ConfigUpdateTest, TestCombinationConditionReplace) {
641 StatsdConfig config;
642 AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
643 *config.add_atom_matcher() = screenOnMatcher;
644 AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
645 *config.add_atom_matcher() = screenOffMatcher;
646
647 Predicate simple1 = CreateScreenIsOnPredicate();
648 *config.add_predicate() = simple1;
649 Predicate simple2 = CreateScreenIsOffPredicate();
650 *config.add_predicate() = simple2;
651
652 Predicate combination1;
653 combination1.set_id(StringToId("COMBINATION1"));
654 Predicate_Combination* combinationInternal = combination1.mutable_combination();
655 combinationInternal->set_operation(LogicalOperation::NAND);
656 combinationInternal->add_predicate(simple1.id());
657 combinationInternal->add_predicate(simple2.id());
658 *config.add_predicate() = combination1;
659
660 EXPECT_TRUE(initConfig(config));
661
662 // Changing the logical operation changes the predicate definition, so it should be replaced.
663 combination1.mutable_combination()->set_operation(LogicalOperation::OR);
664
665 StatsdConfig newConfig;
666 unordered_map<int64_t, int> newConditionTrackerMap;
667 *newConfig.add_predicate() = combination1;
668 newConditionTrackerMap[combination1.id()] = 0;
669 *newConfig.add_predicate() = simple2;
670 newConditionTrackerMap[simple2.id()] = 1;
671 *newConfig.add_predicate() = simple1;
672 newConditionTrackerMap[simple1.id()] = 2;
673
674 set<int64_t> replacedMatchers;
675 vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
676 vector<uint8_t> cycleTracker(3, false);
677 // Only update the combination. The simple conditions should not be evaluated.
678 EXPECT_EQ(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
679 oldConditionTrackers, newConditionTrackerMap,
680 replacedMatchers, conditionsToUpdate, cycleTracker),
681 nullopt);
682 EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
683 EXPECT_EQ(conditionsToUpdate[1], UPDATE_UNKNOWN);
684 EXPECT_EQ(conditionsToUpdate[2], UPDATE_UNKNOWN);
685 }
686
TEST_F(ConfigUpdateTest,TestCombinationConditionDepsChange)687 TEST_F(ConfigUpdateTest, TestCombinationConditionDepsChange) {
688 StatsdConfig config;
689 AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
690 *config.add_atom_matcher() = screenOnMatcher;
691 AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
692 *config.add_atom_matcher() = screenOffMatcher;
693
694 Predicate simple1 = CreateScreenIsOnPredicate();
695 *config.add_predicate() = simple1;
696 Predicate simple2 = CreateScreenIsOffPredicate();
697 *config.add_predicate() = simple2;
698
699 Predicate combination1;
700 combination1.set_id(StringToId("COMBINATION1"));
701 Predicate_Combination* combinationInternal = combination1.mutable_combination();
702 combinationInternal->set_operation(LogicalOperation::NAND);
703 combinationInternal->add_predicate(simple1.id());
704 combinationInternal->add_predicate(simple2.id());
705 *config.add_predicate() = combination1;
706
707 EXPECT_TRUE(initConfig(config));
708
709 simple2.mutable_simple_predicate()->set_count_nesting(false);
710
711 StatsdConfig newConfig;
712 unordered_map<int64_t, int> newConditionTrackerMap;
713 *newConfig.add_predicate() = combination1;
714 newConditionTrackerMap[combination1.id()] = 0;
715 *newConfig.add_predicate() = simple2;
716 newConditionTrackerMap[simple2.id()] = 1;
717 *newConfig.add_predicate() = simple1;
718 newConditionTrackerMap[simple1.id()] = 2;
719
720 set<int64_t> replacedMatchers;
721 vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
722 vector<uint8_t> cycleTracker(3, false);
723 // Only update the combination. Simple2 and combination1 must be evaluated.
724 EXPECT_EQ(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
725 oldConditionTrackers, newConditionTrackerMap,
726 replacedMatchers, conditionsToUpdate, cycleTracker),
727 nullopt);
728 EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
729 EXPECT_EQ(conditionsToUpdate[1], UPDATE_REPLACE);
730 }
731
TEST_F(ConfigUpdateTest,TestUpdateConditions)732 TEST_F(ConfigUpdateTest, TestUpdateConditions) {
733 StatsdConfig config;
734 // Add atom matchers. These are mostly needed for initStatsdConfig
735 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
736 int64_t matcher1Id = matcher1.id();
737 *config.add_atom_matcher() = matcher1;
738
739 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
740 int64_t matcher2Id = matcher2.id();
741 *config.add_atom_matcher() = matcher2;
742
743 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
744 int64_t matcher3Id = matcher3.id();
745 *config.add_atom_matcher() = matcher3;
746
747 AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
748 int64_t matcher4Id = matcher4.id();
749 *config.add_atom_matcher() = matcher4;
750
751 AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
752 int64_t matcher5Id = matcher5.id();
753 *config.add_atom_matcher() = matcher5;
754
755 AtomMatcher matcher6 = CreateBatterySaverModeStopAtomMatcher();
756 int64_t matcher6Id = matcher6.id();
757 *config.add_atom_matcher() = matcher6;
758
759 // Add the predicates.
760 // Will be preserved.
761 Predicate simple1 = CreateScreenIsOnPredicate();
762 int64_t simple1Id = simple1.id();
763 *config.add_predicate() = simple1;
764
765 // Will be preserved.
766 Predicate simple2 = CreateScheduledJobPredicate();
767 int64_t simple2Id = simple2.id();
768 *config.add_predicate() = simple2;
769
770 // Will be replaced.
771 Predicate simple3 = CreateBatterySaverModePredicate();
772 int64_t simple3Id = simple3.id();
773 *config.add_predicate() = simple3;
774
775 // Will be preserved
776 Predicate combination1;
777 combination1.set_id(StringToId("COMBINATION1"));
778 combination1.mutable_combination()->set_operation(LogicalOperation::AND);
779 combination1.mutable_combination()->add_predicate(simple1Id);
780 combination1.mutable_combination()->add_predicate(simple2Id);
781 int64_t combination1Id = combination1.id();
782 *config.add_predicate() = combination1;
783
784 // Will be replaced since simple3 will be replaced.
785 Predicate combination2;
786 combination2.set_id(StringToId("COMBINATION2"));
787 combination2.mutable_combination()->set_operation(LogicalOperation::OR);
788 combination2.mutable_combination()->add_predicate(simple1Id);
789 combination2.mutable_combination()->add_predicate(simple3Id);
790 int64_t combination2Id = combination2.id();
791 *config.add_predicate() = combination2;
792
793 // Will be removed.
794 Predicate combination3;
795 combination3.set_id(StringToId("COMBINATION3"));
796 combination3.mutable_combination()->set_operation(LogicalOperation::NOT);
797 combination3.mutable_combination()->add_predicate(simple2Id);
798 int64_t combination3Id = combination3.id();
799 *config.add_predicate() = combination3;
800
801 EXPECT_TRUE(initConfig(config));
802
803 // Mark marcher 5 as replaced. Causes simple3, and therefore combination2 to be replaced.
804 set<int64_t> replacedMatchers;
805 replacedMatchers.insert(matcher6Id);
806
807 // Change the condition of simple1 to false.
808 ASSERT_EQ(oldConditionTrackers[0]->getConditionId(), simple1Id);
809 LogEvent event(/*uid=*/0, /*pid=*/0); // Empty event is fine since there are no dimensions.
810 // Mark the stop matcher as matched, condition should be false.
811 vector<MatchingState> eventMatcherValues(6, MatchingState::kNotMatched);
812 eventMatcherValues[1] = MatchingState::kMatched;
813 vector<ConditionState> tmpConditionCache(6, ConditionState::kNotEvaluated);
814 vector<uint8_t> conditionChangeCache(6, false);
815 oldConditionTrackers[0]->evaluateCondition(event, eventMatcherValues, oldConditionTrackers,
816 tmpConditionCache, conditionChangeCache);
817 EXPECT_EQ(tmpConditionCache[0], ConditionState::kFalse);
818 EXPECT_EQ(conditionChangeCache[0], true);
819
820 // New combination predicate. Should have an initial condition of true since it is NOT(simple1).
821 Predicate combination4;
822 combination4.set_id(StringToId("COMBINATION4"));
823 combination4.mutable_combination()->set_operation(LogicalOperation::NOT);
824 combination4.mutable_combination()->add_predicate(simple1Id);
825 int64_t combination4Id = combination4.id();
826 *config.add_predicate() = combination4;
827
828 // Map the matchers in reverse order to force the indices to change.
829 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
830 const int matcher6Index = 0;
831 newAtomMatchingTrackerMap[matcher6Id] = 0;
832 const int matcher5Index = 1;
833 newAtomMatchingTrackerMap[matcher5Id] = 1;
834 const int matcher4Index = 2;
835 newAtomMatchingTrackerMap[matcher4Id] = 2;
836 const int matcher3Index = 3;
837 newAtomMatchingTrackerMap[matcher3Id] = 3;
838 const int matcher2Index = 4;
839 newAtomMatchingTrackerMap[matcher2Id] = 4;
840 const int matcher1Index = 5;
841 newAtomMatchingTrackerMap[matcher1Id] = 5;
842
843 StatsdConfig newConfig;
844 *newConfig.add_predicate() = simple3;
845 const int simple3Index = 0;
846 *newConfig.add_predicate() = combination2;
847 const int combination2Index = 1;
848 *newConfig.add_predicate() = combination4;
849 const int combination4Index = 2;
850 *newConfig.add_predicate() = simple2;
851 const int simple2Index = 3;
852 *newConfig.add_predicate() = combination1;
853 const int combination1Index = 4;
854 *newConfig.add_predicate() = simple1;
855 const int simple1Index = 5;
856
857 unordered_map<int64_t, int> newConditionTrackerMap;
858 vector<sp<ConditionTracker>> newConditionTrackers;
859 unordered_map<int, vector<int>> trackerToConditionMap;
860 vector<ConditionState> conditionCache;
861 set<int64_t> replacedConditions;
862 EXPECT_EQ(updateConditions(key, newConfig, newAtomMatchingTrackerMap, replacedMatchers,
863 oldConditionTrackerMap, oldConditionTrackers, newConditionTrackerMap,
864 newConditionTrackers, trackerToConditionMap, conditionCache,
865 replacedConditions),
866 nullopt);
867
868 unordered_map<int64_t, int> expectedConditionTrackerMap = {
869 {simple1Id, simple1Index}, {simple2Id, simple2Index},
870 {simple3Id, simple3Index}, {combination1Id, combination1Index},
871 {combination2Id, combination2Index}, {combination4Id, combination4Index},
872 };
873 EXPECT_THAT(newConditionTrackerMap, ContainerEq(expectedConditionTrackerMap));
874
875 ASSERT_EQ(newConditionTrackers.size(), 6);
876 // Make sure all conditions are initialized:
877 for (const sp<ConditionTracker>& tracker : newConditionTrackers) {
878 EXPECT_TRUE(tracker->mInitialized);
879 }
880
881 // Make sure preserved conditions are the same.
882 EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple1Id)],
883 newConditionTrackers[newConditionTrackerMap.at(simple1Id)]);
884 EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple2Id)],
885 newConditionTrackers[newConditionTrackerMap.at(simple2Id)]);
886 EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(combination1Id)],
887 newConditionTrackers[newConditionTrackerMap.at(combination1Id)]);
888
889 // Make sure replaced conditions are different and included in replacedConditions.
890 EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(simple3Id)],
891 newConditionTrackers[newConditionTrackerMap.at(simple3Id)]);
892 EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(combination2Id)],
893 newConditionTrackers[newConditionTrackerMap.at(combination2Id)]);
894 EXPECT_THAT(replacedConditions, ContainerEq(set({simple3Id, combination2Id})));
895
896 // Verify the trackerToConditionMap
897 ASSERT_EQ(trackerToConditionMap.size(), 6);
898 const vector<int>& matcher1Conditions = trackerToConditionMap[matcher1Index];
899 EXPECT_THAT(matcher1Conditions, UnorderedElementsAre(simple1Index, combination1Index,
900 combination2Index, combination4Index));
901 const vector<int>& matcher2Conditions = trackerToConditionMap[matcher2Index];
902 EXPECT_THAT(matcher2Conditions, UnorderedElementsAre(simple1Index, combination1Index,
903 combination2Index, combination4Index));
904 const vector<int>& matcher3Conditions = trackerToConditionMap[matcher3Index];
905 EXPECT_THAT(matcher3Conditions, UnorderedElementsAre(simple2Index, combination1Index));
906 const vector<int>& matcher4Conditions = trackerToConditionMap[matcher4Index];
907 EXPECT_THAT(matcher4Conditions, UnorderedElementsAre(simple2Index, combination1Index));
908 const vector<int>& matcher5Conditions = trackerToConditionMap[matcher5Index];
909 EXPECT_THAT(matcher5Conditions, UnorderedElementsAre(simple3Index, combination2Index));
910 const vector<int>& matcher6Conditions = trackerToConditionMap[matcher6Index];
911 EXPECT_THAT(matcher6Conditions, UnorderedElementsAre(simple3Index, combination2Index));
912
913 // Verify the conditionCache. Specifically, simple1 is false and combination4 is true.
914 ASSERT_EQ(conditionCache.size(), 6);
915 EXPECT_EQ(conditionCache[simple1Index], ConditionState::kFalse);
916 EXPECT_EQ(conditionCache[simple2Index], ConditionState::kUnknown);
917 EXPECT_EQ(conditionCache[simple3Index], ConditionState::kUnknown);
918 EXPECT_EQ(conditionCache[combination1Index], ConditionState::kUnknown);
919 EXPECT_EQ(conditionCache[combination2Index], ConditionState::kUnknown);
920 EXPECT_EQ(conditionCache[combination4Index], ConditionState::kTrue);
921
922 // Verify tracker indices/ids are correct.
923 EXPECT_EQ(newConditionTrackers[simple1Index]->getConditionId(), simple1Id);
924 EXPECT_EQ(newConditionTrackers[simple1Index]->mIndex, simple1Index);
925 EXPECT_TRUE(newConditionTrackers[simple1Index]->IsSimpleCondition());
926 EXPECT_EQ(newConditionTrackers[simple2Index]->getConditionId(), simple2Id);
927 EXPECT_EQ(newConditionTrackers[simple2Index]->mIndex, simple2Index);
928 EXPECT_TRUE(newConditionTrackers[simple2Index]->IsSimpleCondition());
929 EXPECT_EQ(newConditionTrackers[simple3Index]->getConditionId(), simple3Id);
930 EXPECT_EQ(newConditionTrackers[simple3Index]->mIndex, simple3Index);
931 EXPECT_TRUE(newConditionTrackers[simple3Index]->IsSimpleCondition());
932 EXPECT_EQ(newConditionTrackers[combination1Index]->getConditionId(), combination1Id);
933 EXPECT_EQ(newConditionTrackers[combination1Index]->mIndex, combination1Index);
934 EXPECT_FALSE(newConditionTrackers[combination1Index]->IsSimpleCondition());
935 EXPECT_EQ(newConditionTrackers[combination2Index]->getConditionId(), combination2Id);
936 EXPECT_EQ(newConditionTrackers[combination2Index]->mIndex, combination2Index);
937 EXPECT_FALSE(newConditionTrackers[combination2Index]->IsSimpleCondition());
938 EXPECT_EQ(newConditionTrackers[combination4Index]->getConditionId(), combination4Id);
939 EXPECT_EQ(newConditionTrackers[combination4Index]->mIndex, combination4Index);
940 EXPECT_FALSE(newConditionTrackers[combination4Index]->IsSimpleCondition());
941
942 // Verify preserved trackers have indices updated.
943 SimpleConditionTracker* simpleTracker1 =
944 static_cast<SimpleConditionTracker*>(newConditionTrackers[simple1Index].get());
945 EXPECT_EQ(simpleTracker1->mStartLogMatcherIndex, matcher1Index);
946 EXPECT_EQ(simpleTracker1->mStopLogMatcherIndex, matcher2Index);
947 EXPECT_EQ(simpleTracker1->mStopAllLogMatcherIndex, -1);
948
949 SimpleConditionTracker* simpleTracker2 =
950 static_cast<SimpleConditionTracker*>(newConditionTrackers[simple2Index].get());
951 EXPECT_EQ(simpleTracker2->mStartLogMatcherIndex, matcher3Index);
952 EXPECT_EQ(simpleTracker2->mStopLogMatcherIndex, matcher4Index);
953 EXPECT_EQ(simpleTracker2->mStopAllLogMatcherIndex, -1);
954
955 CombinationConditionTracker* combinationTracker1 = static_cast<CombinationConditionTracker*>(
956 newConditionTrackers[combination1Index].get());
957 EXPECT_THAT(combinationTracker1->mChildren, UnorderedElementsAre(simple1Index, simple2Index));
958 EXPECT_THAT(combinationTracker1->mUnSlicedChildren,
959 UnorderedElementsAre(simple1Index, simple2Index));
960 EXPECT_THAT(combinationTracker1->mSlicedChildren, IsEmpty());
961 }
962
TEST_F(ConfigUpdateTest,TestUpdateStates)963 TEST_F(ConfigUpdateTest, TestUpdateStates) {
964 StatsdConfig config;
965 // Add states.
966 // Will be replaced because we add a state map.
967 State state1 = CreateScreenState();
968 int64_t state1Id = state1.id();
969 *config.add_state() = state1;
970
971 // Will be preserved.
972 State state2 = CreateUidProcessState();
973 int64_t state2Id = state2.id();
974 *config.add_state() = state2;
975
976 // Will be replaced since the atom changes from overlay to screen.
977 State state3 = CreateOverlayState();
978 int64_t state3Id = state3.id();
979 *config.add_state() = state3;
980
981 EXPECT_TRUE(initConfig(config));
982
983 // Change definitions of state1 and state3.
984 int64_t screenOnId = 0x4321, screenOffId = 0x1234;
985 *state1.mutable_map() = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
986 state3.set_atom_id(util::SCREEN_STATE_CHANGED);
987
988 StatsdConfig newConfig;
989 *newConfig.add_state() = state3;
990 *newConfig.add_state() = state1;
991 *newConfig.add_state() = state2;
992
993 unordered_map<int64_t, int> stateAtomIdMap;
994 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
995 map<int64_t, uint64_t> newStateProtoHashes;
996 set<int64_t> replacedStates;
997 EXPECT_EQ(updateStates(newConfig, oldStateHashes, stateAtomIdMap, allStateGroupMaps,
998 newStateProtoHashes, replacedStates),
999 nullopt);
1000 EXPECT_THAT(replacedStates, ContainerEq(set({state1Id, state3Id})));
1001
1002 unordered_map<int64_t, int> expectedStateAtomIdMap = {
1003 {state1Id, util::SCREEN_STATE_CHANGED},
1004 {state2Id, util::UID_PROCESS_STATE_CHANGED},
1005 {state3Id, util::SCREEN_STATE_CHANGED}};
1006 EXPECT_THAT(stateAtomIdMap, ContainerEq(expectedStateAtomIdMap));
1007
1008 unordered_map<int64_t, unordered_map<int, int64_t>> expectedStateGroupMaps = {
1009 {state1Id,
1010 {{android::view::DisplayStateEnum::DISPLAY_STATE_OFF, screenOffId},
1011 {android::view::DisplayStateEnum::DISPLAY_STATE_ON, screenOnId}}}};
1012 EXPECT_THAT(allStateGroupMaps, ContainerEq(expectedStateGroupMaps));
1013 }
1014
TEST_F(ConfigUpdateTest,TestEventMetricPreserve)1015 TEST_F(ConfigUpdateTest, TestEventMetricPreserve) {
1016 StatsdConfig config;
1017 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1018 *config.add_atom_matcher() = startMatcher;
1019 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1020 *config.add_atom_matcher() = stopMatcher;
1021 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1022 *config.add_atom_matcher() = whatMatcher;
1023
1024 Predicate predicate = CreateScreenIsOnPredicate();
1025 *config.add_predicate() = predicate;
1026
1027 EventMetric* metric = config.add_event_metric();
1028 metric->set_id(12345);
1029 metric->set_what(whatMatcher.id());
1030 metric->set_condition(predicate.id());
1031
1032 // Create an initial config.
1033 EXPECT_TRUE(initConfig(config));
1034
1035 unordered_map<int64_t, int> metricToActivationMap;
1036 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1037 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1038 metricToActivationMap,
1039 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1040 /*replacedStates=*/{}, metricsToUpdate),
1041 nullopt);
1042 EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1043 }
1044
TEST_F(ConfigUpdateTest,TestEventMetricActivationAdded)1045 TEST_F(ConfigUpdateTest, TestEventMetricActivationAdded) {
1046 StatsdConfig config;
1047 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1048 *config.add_atom_matcher() = startMatcher;
1049 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1050 *config.add_atom_matcher() = stopMatcher;
1051 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1052 *config.add_atom_matcher() = whatMatcher;
1053
1054 Predicate predicate = CreateScreenIsOnPredicate();
1055 *config.add_predicate() = predicate;
1056
1057 EventMetric* metric = config.add_event_metric();
1058 metric->set_id(12345);
1059 metric->set_what(whatMatcher.id());
1060 metric->set_condition(predicate.id());
1061
1062 // Create an initial config.
1063 EXPECT_TRUE(initConfig(config));
1064
1065 // Add a metric activation, which should change the proto, causing replacement.
1066 MetricActivation* activation = config.add_metric_activation();
1067 activation->set_metric_id(12345);
1068 EventActivation* eventActivation = activation->add_event_activation();
1069 eventActivation->set_atom_matcher_id(startMatcher.id());
1070 eventActivation->set_ttl_seconds(5);
1071
1072 unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
1073 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1074 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1075 metricToActivationMap,
1076 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1077 /*replacedStates=*/{}, metricsToUpdate),
1078 nullopt);
1079 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1080 }
1081
TEST_F(ConfigUpdateTest,TestEventMetricWhatChanged)1082 TEST_F(ConfigUpdateTest, TestEventMetricWhatChanged) {
1083 StatsdConfig config;
1084 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1085 *config.add_atom_matcher() = startMatcher;
1086 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1087 *config.add_atom_matcher() = stopMatcher;
1088 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1089 *config.add_atom_matcher() = whatMatcher;
1090
1091 Predicate predicate = CreateScreenIsOnPredicate();
1092 *config.add_predicate() = predicate;
1093
1094 EventMetric* metric = config.add_event_metric();
1095 metric->set_id(12345);
1096 metric->set_what(whatMatcher.id());
1097 metric->set_condition(predicate.id());
1098
1099 // Create an initial config.
1100 EXPECT_TRUE(initConfig(config));
1101
1102 unordered_map<int64_t, int> metricToActivationMap;
1103 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1104 EXPECT_EQ(determineAllMetricUpdateStatuses(
1105 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1106 /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1107 /*replacedStates=*/{}, metricsToUpdate),
1108 nullopt);
1109 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1110 }
1111
TEST_F(ConfigUpdateTest,TestEventMetricConditionChanged)1112 TEST_F(ConfigUpdateTest, TestEventMetricConditionChanged) {
1113 StatsdConfig config;
1114 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1115 *config.add_atom_matcher() = startMatcher;
1116 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1117 *config.add_atom_matcher() = stopMatcher;
1118 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1119 *config.add_atom_matcher() = whatMatcher;
1120
1121 Predicate predicate = CreateScreenIsOnPredicate();
1122 *config.add_predicate() = predicate;
1123
1124 EventMetric* metric = config.add_event_metric();
1125 metric->set_id(12345);
1126 metric->set_what(whatMatcher.id());
1127 metric->set_condition(predicate.id());
1128
1129 // Create an initial config.
1130 EXPECT_TRUE(initConfig(config));
1131
1132 unordered_map<int64_t, int> metricToActivationMap;
1133 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1134 EXPECT_EQ(determineAllMetricUpdateStatuses(
1135 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1136 /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1137 /*replacedStates=*/{}, metricsToUpdate),
1138 nullopt);
1139 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1140 }
1141
TEST_F(ConfigUpdateTest,TestMetricConditionLinkDepsChanged)1142 TEST_F(ConfigUpdateTest, TestMetricConditionLinkDepsChanged) {
1143 StatsdConfig config;
1144 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1145 *config.add_atom_matcher() = startMatcher;
1146 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1147 *config.add_atom_matcher() = stopMatcher;
1148 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1149 *config.add_atom_matcher() = whatMatcher;
1150
1151 Predicate predicate = CreateScreenIsOnPredicate();
1152 *config.add_predicate() = predicate;
1153
1154 Predicate linkPredicate = CreateScreenIsOffPredicate();
1155 *config.add_predicate() = linkPredicate;
1156
1157 EventMetric* metric = config.add_event_metric();
1158 metric->set_id(12345);
1159 metric->set_what(whatMatcher.id());
1160 metric->set_condition(predicate.id());
1161 // Doesn't make sense as a real metric definition, but suffices as a separate predicate
1162 // From the one in the condition.
1163 MetricConditionLink* link = metric->add_links();
1164 link->set_condition(linkPredicate.id());
1165
1166 // Create an initial config.
1167 EXPECT_TRUE(initConfig(config));
1168
1169 unordered_map<int64_t, int> metricToActivationMap;
1170 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1171 EXPECT_EQ(determineAllMetricUpdateStatuses(
1172 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1173 /*replacedMatchers*/ {}, /*replacedConditions=*/{linkPredicate.id()},
1174 /*replacedStates=*/{}, metricsToUpdate),
1175 nullopt);
1176 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1177 }
1178
TEST_F(ConfigUpdateTest,TestEventMetricActivationDepsChange)1179 TEST_F(ConfigUpdateTest, TestEventMetricActivationDepsChange) {
1180 StatsdConfig config;
1181 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1182 *config.add_atom_matcher() = startMatcher;
1183 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1184 *config.add_atom_matcher() = stopMatcher;
1185 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1186 *config.add_atom_matcher() = whatMatcher;
1187
1188 Predicate predicate = CreateScreenIsOnPredicate();
1189 *config.add_predicate() = predicate;
1190
1191 EventMetric* metric = config.add_event_metric();
1192 metric->set_id(12345);
1193 metric->set_what(whatMatcher.id());
1194 metric->set_condition(predicate.id());
1195
1196 MetricActivation* activation = config.add_metric_activation();
1197 activation->set_metric_id(12345);
1198 EventActivation* eventActivation = activation->add_event_activation();
1199 eventActivation->set_atom_matcher_id(startMatcher.id());
1200 eventActivation->set_ttl_seconds(5);
1201
1202 // Create an initial config.
1203 EXPECT_TRUE(initConfig(config));
1204
1205 unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
1206 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1207 EXPECT_EQ(determineAllMetricUpdateStatuses(
1208 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1209 /*replacedMatchers*/ {startMatcher.id()}, /*replacedConditions=*/{},
1210 /*replacedStates=*/{}, metricsToUpdate),
1211 nullopt);
1212 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1213 }
1214
TEST_F(ConfigUpdateTest,TestCountMetricPreserve)1215 TEST_F(ConfigUpdateTest, TestCountMetricPreserve) {
1216 StatsdConfig config;
1217 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1218 *config.add_atom_matcher() = startMatcher;
1219 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1220 *config.add_atom_matcher() = stopMatcher;
1221 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1222 *config.add_atom_matcher() = whatMatcher;
1223
1224 Predicate predicate = CreateScreenIsOnPredicate();
1225 *config.add_predicate() = predicate;
1226 State sliceState = CreateScreenState();
1227 *config.add_state() = sliceState;
1228
1229 CountMetric* metric = config.add_count_metric();
1230 metric->set_id(12345);
1231 metric->set_what(whatMatcher.id());
1232 metric->set_condition(predicate.id());
1233 metric->add_slice_by_state(sliceState.id());
1234 metric->set_bucket(ONE_HOUR);
1235
1236 // Create an initial config.
1237 EXPECT_TRUE(initConfig(config));
1238
1239 unordered_map<int64_t, int> metricToActivationMap;
1240 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1241 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1242 metricToActivationMap,
1243 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1244 /*replacedStates=*/{}, metricsToUpdate),
1245 nullopt);
1246 EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1247 }
1248
TEST_F(ConfigUpdateTest,TestCountMetricDefinitionChange)1249 TEST_F(ConfigUpdateTest, TestCountMetricDefinitionChange) {
1250 StatsdConfig config;
1251 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1252 *config.add_atom_matcher() = startMatcher;
1253 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1254 *config.add_atom_matcher() = stopMatcher;
1255 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1256 *config.add_atom_matcher() = whatMatcher;
1257
1258 Predicate predicate = CreateScreenIsOnPredicate();
1259 *config.add_predicate() = predicate;
1260
1261 CountMetric* metric = config.add_count_metric();
1262 metric->set_id(12345);
1263 metric->set_what(whatMatcher.id());
1264 metric->set_condition(predicate.id());
1265 metric->set_bucket(ONE_HOUR);
1266
1267 // Create an initial config.
1268 EXPECT_TRUE(initConfig(config));
1269
1270 // Change bucket size, which should change the proto, causing replacement.
1271 metric->set_bucket(TEN_MINUTES);
1272
1273 unordered_map<int64_t, int> metricToActivationMap;
1274 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1275 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1276 metricToActivationMap,
1277 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1278 /*replacedStates=*/{}, metricsToUpdate),
1279 nullopt);
1280 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1281 }
1282
TEST_F(ConfigUpdateTest,TestCountMetricWhatChanged)1283 TEST_F(ConfigUpdateTest, TestCountMetricWhatChanged) {
1284 StatsdConfig config;
1285 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1286 *config.add_atom_matcher() = startMatcher;
1287 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1288 *config.add_atom_matcher() = stopMatcher;
1289 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1290 *config.add_atom_matcher() = whatMatcher;
1291
1292 Predicate predicate = CreateScreenIsOnPredicate();
1293 *config.add_predicate() = predicate;
1294
1295 CountMetric* metric = config.add_count_metric();
1296 metric->set_id(12345);
1297 metric->set_what(whatMatcher.id());
1298 metric->set_condition(predicate.id());
1299 metric->set_bucket(ONE_HOUR);
1300
1301 // Create an initial config.
1302 EXPECT_TRUE(initConfig(config));
1303
1304 unordered_map<int64_t, int> metricToActivationMap;
1305 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1306 EXPECT_EQ(determineAllMetricUpdateStatuses(
1307 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1308 /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1309 /*replacedStates=*/{}, metricsToUpdate),
1310 nullopt);
1311 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1312 }
1313
TEST_F(ConfigUpdateTest,TestCountMetricConditionChanged)1314 TEST_F(ConfigUpdateTest, TestCountMetricConditionChanged) {
1315 StatsdConfig config;
1316 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1317 *config.add_atom_matcher() = startMatcher;
1318 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1319 *config.add_atom_matcher() = stopMatcher;
1320 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1321 *config.add_atom_matcher() = whatMatcher;
1322
1323 Predicate predicate = CreateScreenIsOnPredicate();
1324 *config.add_predicate() = predicate;
1325
1326 CountMetric* metric = config.add_count_metric();
1327 metric->set_id(12345);
1328 metric->set_what(whatMatcher.id());
1329 metric->set_condition(predicate.id());
1330 metric->set_bucket(ONE_HOUR);
1331
1332 // Create an initial config.
1333 EXPECT_TRUE(initConfig(config));
1334
1335 unordered_map<int64_t, int> metricToActivationMap;
1336 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1337 EXPECT_EQ(determineAllMetricUpdateStatuses(
1338 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1339 /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1340 /*replacedStates=*/{}, metricsToUpdate),
1341 nullopt);
1342 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1343 }
1344
TEST_F(ConfigUpdateTest,TestCountMetricStateChanged)1345 TEST_F(ConfigUpdateTest, TestCountMetricStateChanged) {
1346 StatsdConfig config;
1347 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1348 *config.add_atom_matcher() = startMatcher;
1349 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1350 *config.add_atom_matcher() = stopMatcher;
1351 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1352 *config.add_atom_matcher() = whatMatcher;
1353
1354 State sliceState = CreateScreenState();
1355 *config.add_state() = sliceState;
1356
1357 CountMetric* metric = config.add_count_metric();
1358 metric->set_id(12345);
1359 metric->set_what(whatMatcher.id());
1360 metric->add_slice_by_state(sliceState.id());
1361 metric->set_bucket(ONE_HOUR);
1362
1363 // Create an initial config.
1364 EXPECT_TRUE(initConfig(config));
1365
1366 unordered_map<int64_t, int> metricToActivationMap;
1367 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1368 EXPECT_EQ(determineAllMetricUpdateStatuses(
1369 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1370 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1371 /*replacedStates=*/{sliceState.id()}, metricsToUpdate),
1372 nullopt);
1373 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1374 }
1375
TEST_F(ConfigUpdateTest,TestGaugeMetricPreserve)1376 TEST_F(ConfigUpdateTest, TestGaugeMetricPreserve) {
1377 StatsdConfig config;
1378 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1379 *config.add_atom_matcher() = startMatcher;
1380 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1381 *config.add_atom_matcher() = stopMatcher;
1382 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1383 *config.add_atom_matcher() = whatMatcher;
1384
1385 Predicate predicate = CreateScreenIsOnPredicate();
1386 *config.add_predicate() = predicate;
1387
1388 *config.add_gauge_metric() = createGaugeMetric(
1389 "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);
1390
1391 EXPECT_TRUE(initConfig(config));
1392
1393 unordered_map<int64_t, int> metricToActivationMap;
1394 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1395 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1396 metricToActivationMap,
1397 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1398 /*replacedStates=*/{}, metricsToUpdate),
1399 nullopt);
1400 EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1401 }
1402
TEST_F(ConfigUpdateTest,TestGaugeMetricDefinitionChange)1403 TEST_F(ConfigUpdateTest, TestGaugeMetricDefinitionChange) {
1404 StatsdConfig config;
1405 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1406 *config.add_atom_matcher() = whatMatcher;
1407
1408 *config.add_gauge_metric() = createGaugeMetric(
1409 "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
1410
1411 EXPECT_TRUE(initConfig(config));
1412
1413 // Change split bucket on app upgrade, which should change the proto, causing replacement.
1414 config.mutable_gauge_metric(0)->set_split_bucket_for_app_upgrade(false);
1415
1416 unordered_map<int64_t, int> metricToActivationMap;
1417 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1418 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1419 metricToActivationMap,
1420 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1421 /*replacedStates=*/{}, metricsToUpdate),
1422 nullopt);
1423 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1424 }
1425
TEST_F(ConfigUpdateTest,TestGaugeMetricWhatChanged)1426 TEST_F(ConfigUpdateTest, TestGaugeMetricWhatChanged) {
1427 StatsdConfig config;
1428 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1429 *config.add_atom_matcher() = whatMatcher;
1430
1431 *config.add_gauge_metric() = createGaugeMetric(
1432 "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
1433
1434 EXPECT_TRUE(initConfig(config));
1435
1436 unordered_map<int64_t, int> metricToActivationMap;
1437 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1438 EXPECT_EQ(determineAllMetricUpdateStatuses(
1439 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1440 /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1441 /*replacedStates=*/{}, metricsToUpdate),
1442 nullopt);
1443 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1444 }
1445
TEST_F(ConfigUpdateTest,TestGaugeMetricConditionChanged)1446 TEST_F(ConfigUpdateTest, TestGaugeMetricConditionChanged) {
1447 StatsdConfig config;
1448 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1449 *config.add_atom_matcher() = startMatcher;
1450 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1451 *config.add_atom_matcher() = stopMatcher;
1452 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1453 *config.add_atom_matcher() = whatMatcher;
1454
1455 Predicate predicate = CreateScreenIsOnPredicate();
1456 *config.add_predicate() = predicate;
1457
1458 *config.add_gauge_metric() = createGaugeMetric(
1459 "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);
1460
1461 EXPECT_TRUE(initConfig(config));
1462
1463 unordered_map<int64_t, int> metricToActivationMap;
1464 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1465 EXPECT_EQ(determineAllMetricUpdateStatuses(
1466 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1467 /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1468 /*replacedStates=*/{}, metricsToUpdate),
1469 nullopt);
1470 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1471 }
1472
TEST_F(ConfigUpdateTest,TestGaugeMetricTriggerEventChanged)1473 TEST_F(ConfigUpdateTest, TestGaugeMetricTriggerEventChanged) {
1474 StatsdConfig config;
1475 AtomMatcher triggerEvent = CreateScreenTurnedOnAtomMatcher();
1476 *config.add_atom_matcher() = triggerEvent;
1477 AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1478 *config.add_atom_matcher() = whatMatcher;
1479
1480 *config.add_gauge_metric() = createGaugeMetric(
1481 "GAUGE1", whatMatcher.id(), GaugeMetric::FIRST_N_SAMPLES, nullopt, triggerEvent.id());
1482
1483 EXPECT_TRUE(initConfig(config));
1484
1485 unordered_map<int64_t, int> metricToActivationMap;
1486 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1487 EXPECT_EQ(determineAllMetricUpdateStatuses(
1488 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1489 /*replacedMatchers*/ {triggerEvent.id()}, /*replacedConditions=*/{},
1490 /*replacedStates=*/{}, metricsToUpdate),
1491 nullopt);
1492 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1493 }
1494
TEST_F(ConfigUpdateTest,TestDurationMetricPreserve)1495 TEST_F(ConfigUpdateTest, TestDurationMetricPreserve) {
1496 StatsdConfig config;
1497 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1498 *config.add_atom_matcher() = startMatcher;
1499 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1500 *config.add_atom_matcher() = stopMatcher;
1501
1502 Predicate what = CreateScreenIsOnPredicate();
1503 *config.add_predicate() = what;
1504 Predicate condition = CreateScreenIsOffPredicate();
1505 *config.add_predicate() = condition;
1506
1507 State sliceState = CreateScreenState();
1508 *config.add_state() = sliceState;
1509
1510 *config.add_duration_metric() =
1511 createDurationMetric("DURATION1", what.id(), condition.id(), {sliceState.id()});
1512 EXPECT_TRUE(initConfig(config));
1513
1514 unordered_map<int64_t, int> metricToActivationMap;
1515 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1516 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1517 metricToActivationMap,
1518 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1519 /*replacedStates=*/{}, metricsToUpdate),
1520 nullopt);
1521 EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1522 }
1523
TEST_F(ConfigUpdateTest,TestDurationMetricDefinitionChange)1524 TEST_F(ConfigUpdateTest, TestDurationMetricDefinitionChange) {
1525 StatsdConfig config;
1526 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1527 *config.add_atom_matcher() = startMatcher;
1528 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1529 *config.add_atom_matcher() = stopMatcher;
1530
1531 Predicate what = CreateScreenIsOnPredicate();
1532 *config.add_predicate() = what;
1533
1534 *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
1535 EXPECT_TRUE(initConfig(config));
1536
1537 config.mutable_duration_metric(0)->set_aggregation_type(DurationMetric::MAX_SPARSE);
1538
1539 unordered_map<int64_t, int> metricToActivationMap;
1540 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1541 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1542 metricToActivationMap, /*replacedMatchers*/ {},
1543 /*replacedConditions=*/{}, /*replacedStates=*/{},
1544 metricsToUpdate),
1545 nullopt);
1546 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1547 }
1548
TEST_F(ConfigUpdateTest,TestDurationMetricWhatChanged)1549 TEST_F(ConfigUpdateTest, TestDurationMetricWhatChanged) {
1550 StatsdConfig config;
1551 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1552 *config.add_atom_matcher() = startMatcher;
1553 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1554 *config.add_atom_matcher() = stopMatcher;
1555
1556 Predicate what = CreateScreenIsOnPredicate();
1557 *config.add_predicate() = what;
1558
1559 *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
1560 EXPECT_TRUE(initConfig(config));
1561
1562 unordered_map<int64_t, int> metricToActivationMap;
1563 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1564 EXPECT_EQ(determineAllMetricUpdateStatuses(
1565 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1566 /*replacedMatchers*/ {}, /*replacedConditions=*/{what.id()},
1567 /*replacedStates=*/{}, metricsToUpdate),
1568 nullopt);
1569 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1570 }
1571
TEST_F(ConfigUpdateTest,TestDurationMetricConditionChanged)1572 TEST_F(ConfigUpdateTest, TestDurationMetricConditionChanged) {
1573 StatsdConfig config;
1574 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1575 *config.add_atom_matcher() = startMatcher;
1576 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1577 *config.add_atom_matcher() = stopMatcher;
1578
1579 Predicate what = CreateScreenIsOnPredicate();
1580 *config.add_predicate() = what;
1581 Predicate condition = CreateScreenIsOffPredicate();
1582 *config.add_predicate() = condition;
1583
1584 *config.add_duration_metric() = createDurationMetric("DURATION", what.id(), condition.id(), {});
1585 EXPECT_TRUE(initConfig(config));
1586
1587 unordered_map<int64_t, int> metricToActivationMap;
1588 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1589 EXPECT_EQ(determineAllMetricUpdateStatuses(
1590 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1591 /*replacedMatchers*/ {}, /*replacedConditions=*/{condition.id()},
1592 /*replacedStates=*/{}, metricsToUpdate),
1593 nullopt);
1594 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1595 }
1596
TEST_F(ConfigUpdateTest,TestDurationMetricStateChange)1597 TEST_F(ConfigUpdateTest, TestDurationMetricStateChange) {
1598 StatsdConfig config;
1599 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1600 *config.add_atom_matcher() = startMatcher;
1601 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1602 *config.add_atom_matcher() = stopMatcher;
1603
1604 Predicate what = CreateScreenIsOnPredicate();
1605 *config.add_predicate() = what;
1606
1607 State sliceState = CreateScreenState();
1608 *config.add_state() = sliceState;
1609
1610 *config.add_duration_metric() =
1611 createDurationMetric("DURATION1", what.id(), nullopt, {sliceState.id()});
1612 EXPECT_TRUE(initConfig(config));
1613
1614 unordered_map<int64_t, int> metricToActivationMap;
1615 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1616 EXPECT_EQ(determineAllMetricUpdateStatuses(
1617 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1618 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1619 /*replacedStates=*/{sliceState.id()}, metricsToUpdate),
1620 nullopt);
1621 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1622 }
1623
TEST_F(ConfigUpdateTest,TestValueMetricPreserve)1624 TEST_F(ConfigUpdateTest, TestValueMetricPreserve) {
1625 StatsdConfig config;
1626 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1627 *config.add_atom_matcher() = startMatcher;
1628 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1629 *config.add_atom_matcher() = stopMatcher;
1630 AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1631 *config.add_atom_matcher() = whatMatcher;
1632
1633 Predicate predicate = CreateScreenIsOnPredicate();
1634 *config.add_predicate() = predicate;
1635 State sliceState = CreateScreenState();
1636 *config.add_state() = sliceState;
1637
1638 *config.add_value_metric() =
1639 createValueMetric("VALUE1", whatMatcher, 2, predicate.id(), {sliceState.id()});
1640 EXPECT_TRUE(initConfig(config));
1641
1642 unordered_map<int64_t, int> metricToActivationMap;
1643 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1644 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1645 metricToActivationMap,
1646 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1647 /*replacedStates=*/{}, metricsToUpdate),
1648 nullopt);
1649 EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1650 }
1651
TEST_F(ConfigUpdateTest,TestValueMetricDefinitionChange)1652 TEST_F(ConfigUpdateTest, TestValueMetricDefinitionChange) {
1653 StatsdConfig config;
1654 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1655 *config.add_atom_matcher() = whatMatcher;
1656
1657 *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, 2, nullopt, {});
1658 EXPECT_TRUE(initConfig(config));
1659
1660 // Change skip zero diff output, which should change the proto, causing replacement.
1661 config.mutable_value_metric(0)->set_skip_zero_diff_output(true);
1662
1663 unordered_map<int64_t, int> metricToActivationMap;
1664 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1665 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1666 metricToActivationMap,
1667 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1668 /*replacedStates=*/{}, metricsToUpdate),
1669 nullopt);
1670 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1671 }
1672
TEST_F(ConfigUpdateTest,TestValueMetricWhatChanged)1673 TEST_F(ConfigUpdateTest, TestValueMetricWhatChanged) {
1674 StatsdConfig config;
1675 AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1676 *config.add_atom_matcher() = whatMatcher;
1677
1678 *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, 2, nullopt, {});
1679 EXPECT_TRUE(initConfig(config));
1680
1681 unordered_map<int64_t, int> metricToActivationMap;
1682 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1683 EXPECT_EQ(determineAllMetricUpdateStatuses(
1684 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1685 /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1686 /*replacedStates=*/{}, metricsToUpdate),
1687 nullopt);
1688 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1689 }
1690
TEST_F(ConfigUpdateTest,TestValueMetricConditionChanged)1691 TEST_F(ConfigUpdateTest, TestValueMetricConditionChanged) {
1692 StatsdConfig config;
1693 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1694 *config.add_atom_matcher() = startMatcher;
1695 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1696 *config.add_atom_matcher() = stopMatcher;
1697 AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1698 *config.add_atom_matcher() = whatMatcher;
1699
1700 Predicate predicate = CreateScreenIsOnPredicate();
1701 *config.add_predicate() = predicate;
1702
1703 *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, 2, predicate.id(), {});
1704 EXPECT_TRUE(initConfig(config));
1705
1706 unordered_map<int64_t, int> metricToActivationMap;
1707 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1708 EXPECT_EQ(determineAllMetricUpdateStatuses(
1709 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1710 /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1711 /*replacedStates=*/{}, metricsToUpdate),
1712 nullopt);
1713 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1714 }
1715
TEST_F(ConfigUpdateTest,TestValueMetricStateChanged)1716 TEST_F(ConfigUpdateTest, TestValueMetricStateChanged) {
1717 StatsdConfig config;
1718 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1719 *config.add_atom_matcher() = whatMatcher;
1720
1721 State sliceState = CreateScreenState();
1722 *config.add_state() = sliceState;
1723
1724 *config.add_value_metric() =
1725 createValueMetric("VALUE1", whatMatcher, 2, nullopt, {sliceState.id()});
1726 EXPECT_TRUE(initConfig(config));
1727
1728 unordered_map<int64_t, int> metricToActivationMap;
1729 vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1730 EXPECT_EQ(determineAllMetricUpdateStatuses(
1731 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1732 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1733 /*replacedStates=*/{sliceState.id()}, metricsToUpdate),
1734 nullopt);
1735 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1736 }
1737
TEST_F(ConfigUpdateTest,TestKllMetricPreserve)1738 TEST_F(ConfigUpdateTest, TestKllMetricPreserve) {
1739 StatsdConfig config;
1740 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1741 *config.add_atom_matcher() = startMatcher;
1742 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1743 *config.add_atom_matcher() = stopMatcher;
1744 AtomMatcher whatMatcher = CreateAppStartOccurredAtomMatcher();
1745 *config.add_atom_matcher() = whatMatcher;
1746
1747 Predicate predicate = CreateScreenIsOnPredicate();
1748 *config.add_predicate() = predicate;
1749
1750 *config.add_kll_metric() =
1751 createKllMetric("KLL1", whatMatcher, /*valueField=*/12, predicate.id());
1752 EXPECT_TRUE(initConfig(config));
1753
1754 unordered_map<int64_t, int> metricToActivationMap;
1755 vector<UpdateStatus> metricsToUpdate{UPDATE_UNKNOWN};
1756 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1757 metricToActivationMap,
1758 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1759 /*replacedStates=*/{}, metricsToUpdate),
1760 nullopt);
1761 EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1762 }
1763
TEST_F(ConfigUpdateTest,TestKllMetricDefinitionChange)1764 TEST_F(ConfigUpdateTest, TestKllMetricDefinitionChange) {
1765 StatsdConfig config;
1766 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1767 *config.add_atom_matcher() = whatMatcher;
1768
1769 *config.add_kll_metric() = createKllMetric("KLL1", whatMatcher, /*valueField=*/12, nullopt);
1770 EXPECT_TRUE(initConfig(config));
1771
1772 // Change split bucket setting for app upgrades, which should change the proto, causing
1773 // replacement.
1774 config.mutable_kll_metric(0)->set_split_bucket_for_app_upgrade(false);
1775
1776 unordered_map<int64_t, int> metricToActivationMap;
1777 vector<UpdateStatus> metricsToUpdate{UPDATE_UNKNOWN};
1778 EXPECT_EQ(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1779 metricToActivationMap,
1780 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1781 /*replacedStates=*/{}, metricsToUpdate),
1782 nullopt);
1783 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1784 }
1785
TEST_F(ConfigUpdateTest,TestKllMetricWhatChanged)1786 TEST_F(ConfigUpdateTest, TestKllMetricWhatChanged) {
1787 StatsdConfig config;
1788 AtomMatcher whatMatcher = CreateAppStartOccurredAtomMatcher();
1789 *config.add_atom_matcher() = whatMatcher;
1790
1791 *config.add_kll_metric() = createKllMetric("KLL1", whatMatcher, /*valueField=*/12, nullopt);
1792 EXPECT_TRUE(initConfig(config));
1793
1794 unordered_map<int64_t, int> metricToActivationMap;
1795 vector<UpdateStatus> metricsToUpdate{UPDATE_UNKNOWN};
1796 EXPECT_EQ(determineAllMetricUpdateStatuses(
1797 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1798 /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1799 /*replacedStates=*/{}, metricsToUpdate),
1800 nullopt);
1801 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1802 }
1803
TEST_F(ConfigUpdateTest,TestKllMetricConditionChanged)1804 TEST_F(ConfigUpdateTest, TestKllMetricConditionChanged) {
1805 StatsdConfig config;
1806 AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1807 *config.add_atom_matcher() = startMatcher;
1808 AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1809 *config.add_atom_matcher() = stopMatcher;
1810 AtomMatcher whatMatcher = CreateAppStartOccurredAtomMatcher();
1811 *config.add_atom_matcher() = whatMatcher;
1812
1813 Predicate predicate = CreateScreenIsOnPredicate();
1814 *config.add_predicate() = predicate;
1815
1816 *config.add_kll_metric() =
1817 createKllMetric("KLL1", whatMatcher, /*valueField=*/12, predicate.id());
1818 EXPECT_TRUE(initConfig(config));
1819
1820 unordered_map<int64_t, int> metricToActivationMap;
1821 vector<UpdateStatus> metricsToUpdate{UPDATE_UNKNOWN};
1822 EXPECT_EQ(determineAllMetricUpdateStatuses(
1823 config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1824 /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1825 /*replacedStates=*/{}, metricsToUpdate),
1826 nullopt);
1827 EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1828 }
1829
TEST_F(ConfigUpdateTest,TestUpdateEventMetrics)1830 TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) {
1831 StatsdConfig config;
1832
1833 // Add atom matchers/predicates. These are mostly needed for initStatsdConfig
1834 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
1835 int64_t matcher1Id = matcher1.id();
1836 *config.add_atom_matcher() = matcher1;
1837
1838 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
1839 int64_t matcher2Id = matcher2.id();
1840 *config.add_atom_matcher() = matcher2;
1841
1842 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
1843 int64_t matcher3Id = matcher3.id();
1844 *config.add_atom_matcher() = matcher3;
1845
1846 AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
1847 int64_t matcher4Id = matcher4.id();
1848 *config.add_atom_matcher() = matcher4;
1849
1850 AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
1851 int64_t matcher5Id = matcher5.id();
1852 *config.add_atom_matcher() = matcher5;
1853
1854 Predicate predicate1 = CreateScreenIsOnPredicate();
1855 int64_t predicate1Id = predicate1.id();
1856 *config.add_predicate() = predicate1;
1857
1858 Predicate predicate2 = CreateScheduledJobPredicate();
1859 int64_t predicate2Id = predicate2.id();
1860 *config.add_predicate() = predicate2;
1861
1862 // Add a few event metrics.
1863 // Will be preserved.
1864 EventMetric event1 = createEventMetric("EVENT1", matcher1Id, predicate2Id);
1865 int64_t event1Id = event1.id();
1866 *config.add_event_metric() = event1;
1867
1868 // Will be replaced.
1869 EventMetric event2 = createEventMetric("EVENT2", matcher2Id, nullopt);
1870 int64_t event2Id = event2.id();
1871 *config.add_event_metric() = event2;
1872
1873 // Will be replaced.
1874 EventMetric event3 = createEventMetric("EVENT3", matcher3Id, nullopt);
1875 int64_t event3Id = event3.id();
1876 *config.add_event_metric() = event3;
1877
1878 MetricActivation event3Activation;
1879 event3Activation.set_metric_id(event3Id);
1880 EventActivation* eventActivation = event3Activation.add_event_activation();
1881 eventActivation->set_atom_matcher_id(matcher5Id);
1882 eventActivation->set_ttl_seconds(5);
1883 *config.add_metric_activation() = event3Activation;
1884
1885 // Will be replaced.
1886 EventMetric event4 = createEventMetric("EVENT4", matcher4Id, predicate1Id);
1887 int64_t event4Id = event4.id();
1888 *config.add_event_metric() = event4;
1889
1890 // Will be deleted.
1891 EventMetric event5 = createEventMetric("EVENT5", matcher5Id, nullopt);
1892 int64_t event5Id = event5.id();
1893 *config.add_event_metric() = event5;
1894
1895 EXPECT_TRUE(initConfig(config));
1896
1897 // Used later to ensure the condition wizard is replaced. Get it before doing the update.
1898 sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
1899 EXPECT_EQ(oldConditionWizard->getStrongCount(), oldMetricProducers.size() + 1);
1900
1901 // Add a condition to event2, causing it to be replaced.
1902 event2.set_condition(predicate1Id);
1903
1904 // Mark matcher 5 as replaced. Causes event3 to be replaced.
1905 set<int64_t> replacedMatchers;
1906 replacedMatchers.insert(matcher5Id);
1907
1908 // Mark predicate 1 as replaced. Causes event4 to be replaced.
1909 set<int64_t> replacedConditions;
1910 replacedConditions.insert(predicate1Id);
1911
1912 // Fake that predicate 2 is true.
1913 ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
1914 oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
1915 EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);
1916
1917 // New event metric. Should have an initial condition of true since it depends on predicate2.
1918 EventMetric event6 = createEventMetric("EVENT6", matcher3Id, predicate2Id);
1919 int64_t event6Id = event6.id();
1920 MetricActivation event6Activation;
1921 event6Activation.set_metric_id(event6Id);
1922 eventActivation = event6Activation.add_event_activation();
1923 eventActivation->set_atom_matcher_id(matcher5Id);
1924 eventActivation->set_ttl_seconds(20);
1925
1926 // Map the matchers and predicates in reverse order to force the indices to change.
1927 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
1928 const int matcher5Index = 0;
1929 newAtomMatchingTrackerMap[matcher5Id] = 0;
1930 const int matcher4Index = 1;
1931 newAtomMatchingTrackerMap[matcher4Id] = 1;
1932 const int matcher3Index = 2;
1933 newAtomMatchingTrackerMap[matcher3Id] = 2;
1934 const int matcher2Index = 3;
1935 newAtomMatchingTrackerMap[matcher2Id] = 3;
1936 const int matcher1Index = 4;
1937 newAtomMatchingTrackerMap[matcher1Id] = 4;
1938 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
1939 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
1940 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
1941 newAtomMatchingTrackers.begin());
1942
1943 std::unordered_map<int64_t, int> newConditionTrackerMap;
1944 const int predicate2Index = 0;
1945 newConditionTrackerMap[predicate2Id] = 0;
1946 const int predicate1Index = 1;
1947 newConditionTrackerMap[predicate1Id] = 1;
1948 // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
1949 vector<sp<ConditionTracker>> newConditionTrackers(2);
1950 std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
1951 newConditionTrackers.begin());
1952 // Fake that predicate2 is true.
1953 vector<ConditionState> conditionCache = {ConditionState::kTrue, ConditionState::kUnknown};
1954
1955 StatsdConfig newConfig;
1956 *newConfig.add_event_metric() = event6;
1957 const int event6Index = 0;
1958 *newConfig.add_event_metric() = event3;
1959 const int event3Index = 1;
1960 *newConfig.add_event_metric() = event1;
1961 const int event1Index = 2;
1962 *newConfig.add_event_metric() = event4;
1963 const int event4Index = 3;
1964 *newConfig.add_event_metric() = event2;
1965 const int event2Index = 4;
1966 *newConfig.add_metric_activation() = event3Activation;
1967 *newConfig.add_metric_activation() = event6Activation;
1968
1969 // Output data structures to validate.
1970 unordered_map<int64_t, int> newMetricProducerMap;
1971 vector<sp<MetricProducer>> newMetricProducers;
1972 unordered_map<int, vector<int>> conditionToMetricMap;
1973 unordered_map<int, vector<int>> trackerToMetricMap;
1974 set<int64_t> noReportMetricIds;
1975 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
1976 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
1977 vector<int> metricsWithActivation;
1978 set<int64_t> replacedMetrics;
1979 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
1980 EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
1981 new StatsPullerManager(), oldAtomMatchingTrackerMap,
1982 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
1983 newConditionTrackerMap, replacedConditions, newConditionTrackers,
1984 conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
1985 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
1986 provider, newMetricProducerMap, newMetricProducers,
1987 conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
1988 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1989 metricsWithActivation, replacedMetrics),
1990 nullopt);
1991
1992 unordered_map<int64_t, int> expectedMetricProducerMap = {
1993 {event1Id, event1Index}, {event2Id, event2Index}, {event3Id, event3Index},
1994 {event4Id, event4Index}, {event6Id, event6Index},
1995 };
1996 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
1997 EXPECT_EQ(replacedMetrics, set<int64_t>({event2Id, event3Id, event4Id}));
1998
1999 // Make sure preserved metrics are the same.
2000 ASSERT_EQ(newMetricProducers.size(), 5);
2001 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(event1Id)],
2002 newMetricProducers[newMetricProducerMap.at(event1Id)]);
2003
2004 // Make sure replaced metrics are different.
2005 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event2Id)],
2006 newMetricProducers[newMetricProducerMap.at(event2Id)]);
2007 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event3Id)],
2008 newMetricProducers[newMetricProducerMap.at(event3Id)]);
2009 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event4Id)],
2010 newMetricProducers[newMetricProducerMap.at(event4Id)]);
2011
2012 // Verify the conditionToMetricMap.
2013 ASSERT_EQ(conditionToMetricMap.size(), 2);
2014 const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
2015 EXPECT_THAT(condition1Metrics, UnorderedElementsAre(event2Index, event4Index));
2016 const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
2017 EXPECT_THAT(condition2Metrics, UnorderedElementsAre(event1Index, event6Index));
2018
2019 // Verify the trackerToMetricMap.
2020 ASSERT_EQ(trackerToMetricMap.size(), 4);
2021 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2022 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(event1Index));
2023 const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
2024 EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(event2Index));
2025 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2026 EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(event3Index, event6Index));
2027 const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2028 EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(event4Index));
2029
2030 // Verify event activation/deactivation maps.
2031 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 1);
2032 EXPECT_THAT(activationAtomTrackerToMetricMap[matcher5Index],
2033 UnorderedElementsAre(event3Index, event6Index));
2034 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2035 ASSERT_EQ(metricsWithActivation.size(), 2);
2036 EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(event3Index, event6Index));
2037
2038 // Verify tracker indices/ids/conditions are correct.
2039 EXPECT_EQ(newMetricProducers[event1Index]->getMetricId(), event1Id);
2040 EXPECT_EQ(newMetricProducers[event1Index]->mConditionTrackerIndex, predicate2Index);
2041 EXPECT_EQ(newMetricProducers[event1Index]->mCondition, ConditionState::kTrue);
2042 EXPECT_EQ(newMetricProducers[event2Index]->getMetricId(), event2Id);
2043 EXPECT_EQ(newMetricProducers[event2Index]->mConditionTrackerIndex, predicate1Index);
2044 EXPECT_EQ(newMetricProducers[event2Index]->mCondition, ConditionState::kUnknown);
2045 EXPECT_EQ(newMetricProducers[event3Index]->getMetricId(), event3Id);
2046 EXPECT_EQ(newMetricProducers[event3Index]->mConditionTrackerIndex, -1);
2047 EXPECT_EQ(newMetricProducers[event3Index]->mCondition, ConditionState::kTrue);
2048 EXPECT_EQ(newMetricProducers[event4Index]->getMetricId(), event4Id);
2049 EXPECT_EQ(newMetricProducers[event4Index]->mConditionTrackerIndex, predicate1Index);
2050 EXPECT_EQ(newMetricProducers[event4Index]->mCondition, ConditionState::kUnknown);
2051 EXPECT_EQ(newMetricProducers[event6Index]->getMetricId(), event6Id);
2052 EXPECT_EQ(newMetricProducers[event6Index]->mConditionTrackerIndex, predicate2Index);
2053 EXPECT_EQ(newMetricProducers[event6Index]->mCondition, ConditionState::kTrue);
2054
2055 sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
2056 EXPECT_NE(newConditionWizard, oldConditionWizard);
2057 EXPECT_EQ(newConditionWizard->getStrongCount(), newMetricProducers.size() + 1);
2058 oldMetricProducers.clear();
2059 // Only reference to the old wizard should be the one in the test.
2060 EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
2061 }
2062
TEST_F(ConfigUpdateTest,TestUpdateCountMetrics)2063 TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) {
2064 StatsdConfig config;
2065
2066 // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2067 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2068 int64_t matcher1Id = matcher1.id();
2069 *config.add_atom_matcher() = matcher1;
2070
2071 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2072 int64_t matcher2Id = matcher2.id();
2073 *config.add_atom_matcher() = matcher2;
2074
2075 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
2076 int64_t matcher3Id = matcher3.id();
2077 *config.add_atom_matcher() = matcher3;
2078
2079 AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
2080 int64_t matcher4Id = matcher4.id();
2081 *config.add_atom_matcher() = matcher4;
2082
2083 AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
2084 int64_t matcher5Id = matcher5.id();
2085 *config.add_atom_matcher() = matcher5;
2086
2087 Predicate predicate1 = CreateScreenIsOnPredicate();
2088 int64_t predicate1Id = predicate1.id();
2089 *config.add_predicate() = predicate1;
2090
2091 State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
2092 int64_t state1Id = state1.id();
2093 *config.add_state() = state1;
2094
2095 State state2 = CreateScreenState();
2096 int64_t state2Id = state2.id();
2097 *config.add_state() = state2;
2098
2099 // Add a few count metrics.
2100 // Will be preserved.
2101 CountMetric count1 = createCountMetric("COUNT1", matcher1Id, predicate1Id, {state1Id});
2102 int64_t count1Id = count1.id();
2103 *config.add_count_metric() = count1;
2104
2105 // Will be replaced.
2106 CountMetric count2 = createCountMetric("COUNT2", matcher2Id, nullopt, {});
2107 int64_t count2Id = count2.id();
2108 *config.add_count_metric() = count2;
2109
2110 // Will be replaced.
2111 CountMetric count3 = createCountMetric("COUNT3", matcher3Id, nullopt, {});
2112 int64_t count3Id = count3.id();
2113 *config.add_count_metric() = count3;
2114
2115 // Will be replaced.
2116 CountMetric count4 = createCountMetric("COUNT4", matcher4Id, nullopt, {state2Id});
2117 int64_t count4Id = count4.id();
2118 *config.add_count_metric() = count4;
2119
2120 // Will be deleted.
2121 CountMetric count5 = createCountMetric("COUNT5", matcher5Id, nullopt, {});
2122 int64_t count5Id = count5.id();
2123 *config.add_count_metric() = count5;
2124
2125 EXPECT_TRUE(initConfig(config));
2126
2127 // Change bucket size of count2, causing it to be replaced.
2128 count2.set_bucket(ONE_HOUR);
2129
2130 // Mark matcher 3 as replaced. Causes count3 to be replaced.
2131 set<int64_t> replacedMatchers;
2132 replacedMatchers.insert(matcher3Id);
2133
2134 // Mark state 2 as replaced and change the state to be about a different atom.
2135 // Causes count4 to be replaced.
2136 set<int64_t> replacedStates;
2137 replacedStates.insert(state2Id);
2138 state2.set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
2139
2140 // Fake that predicate 1 is true for count metric 1.
2141 ASSERT_EQ(oldMetricProducers[0]->getMetricId(), count1Id);
2142 oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
2143 EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);
2144
2145 EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 1);
2146 // Tell the StateManager that the screen is on.
2147 unique_ptr<LogEvent> event =
2148 CreateScreenStateChangedEvent(0, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
2149 StateManager::getInstance().onLogEvent(*event);
2150
2151 // New count metric. Should have an initial condition of true since it depends on predicate1.
2152 CountMetric count6 = createCountMetric("EVENT6", matcher2Id, predicate1Id, {state1Id});
2153 int64_t count6Id = count6.id();
2154
2155 // Map the matchers and predicates in reverse order to force the indices to change.
2156 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
2157 const int matcher5Index = 0;
2158 newAtomMatchingTrackerMap[matcher5Id] = 0;
2159 const int matcher4Index = 1;
2160 newAtomMatchingTrackerMap[matcher4Id] = 1;
2161 const int matcher3Index = 2;
2162 newAtomMatchingTrackerMap[matcher3Id] = 2;
2163 const int matcher2Index = 3;
2164 newAtomMatchingTrackerMap[matcher2Id] = 3;
2165 const int matcher1Index = 4;
2166 newAtomMatchingTrackerMap[matcher1Id] = 4;
2167 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2168 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
2169 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2170 newAtomMatchingTrackers.begin());
2171
2172 std::unordered_map<int64_t, int> newConditionTrackerMap;
2173 const int predicate1Index = 0;
2174 newConditionTrackerMap[predicate1Id] = 0;
2175 // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
2176 vector<sp<ConditionTracker>> newConditionTrackers(1);
2177 std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2178 newConditionTrackers.begin());
2179 // Fake that predicate1 is true for all new metrics.
2180 vector<ConditionState> conditionCache = {ConditionState::kTrue};
2181
2182 StatsdConfig newConfig;
2183 *newConfig.add_count_metric() = count6;
2184 const int count6Index = 0;
2185 *newConfig.add_count_metric() = count3;
2186 const int count3Index = 1;
2187 *newConfig.add_count_metric() = count1;
2188 const int count1Index = 2;
2189 *newConfig.add_count_metric() = count4;
2190 const int count4Index = 3;
2191 *newConfig.add_count_metric() = count2;
2192 const int count2Index = 4;
2193
2194 *newConfig.add_state() = state1;
2195 *newConfig.add_state() = state2;
2196
2197 unordered_map<int64_t, int> stateAtomIdMap;
2198 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
2199 map<int64_t, uint64_t> stateProtoHashes;
2200 EXPECT_EQ(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes), nullopt);
2201 EXPECT_EQ(stateAtomIdMap[state2Id], util::BATTERY_SAVER_MODE_STATE_CHANGED);
2202
2203 // Output data structures to validate.
2204 unordered_map<int64_t, int> newMetricProducerMap;
2205 vector<sp<MetricProducer>> newMetricProducers;
2206 unordered_map<int, vector<int>> conditionToMetricMap;
2207 unordered_map<int, vector<int>> trackerToMetricMap;
2208 set<int64_t> noReportMetricIds;
2209 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2210 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2211 vector<int> metricsWithActivation;
2212 set<int64_t> replacedMetrics;
2213 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
2214 EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
2215 new StatsPullerManager(), oldAtomMatchingTrackerMap,
2216 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
2217 newConditionTrackerMap, /*replacedConditions=*/{}, newConditionTrackers,
2218 conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
2219 oldMetricProducerMap, oldMetricProducers, provider,
2220 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
2221 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
2222 deactivationAtomTrackerToMetricMap, metricsWithActivation,
2223 replacedMetrics),
2224 nullopt);
2225
2226 unordered_map<int64_t, int> expectedMetricProducerMap = {
2227 {count1Id, count1Index}, {count2Id, count2Index}, {count3Id, count3Index},
2228 {count4Id, count4Index}, {count6Id, count6Index},
2229 };
2230 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2231 EXPECT_EQ(replacedMetrics, set<int64_t>({count2Id, count3Id, count4Id}));
2232
2233 // Make sure preserved metrics are the same.
2234 ASSERT_EQ(newMetricProducers.size(), 5);
2235 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(count1Id)],
2236 newMetricProducers[newMetricProducerMap.at(count1Id)]);
2237
2238 // Make sure replaced metrics are different.
2239 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count2Id)],
2240 newMetricProducers[newMetricProducerMap.at(count2Id)]);
2241 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count3Id)],
2242 newMetricProducers[newMetricProducerMap.at(count3Id)]);
2243 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count4Id)],
2244 newMetricProducers[newMetricProducerMap.at(count4Id)]);
2245
2246 // Verify the conditionToMetricMap.
2247 ASSERT_EQ(conditionToMetricMap.size(), 1);
2248 const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
2249 EXPECT_THAT(condition1Metrics, UnorderedElementsAre(count1Index, count6Index));
2250
2251 // Verify the trackerToMetricMap.
2252 ASSERT_EQ(trackerToMetricMap.size(), 4);
2253 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2254 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(count1Index));
2255 const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
2256 EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(count2Index, count6Index));
2257 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2258 EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(count3Index));
2259 const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2260 EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(count4Index));
2261
2262 // Verify event activation/deactivation maps.
2263 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2264 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2265 ASSERT_EQ(metricsWithActivation.size(), 0);
2266
2267 // Verify tracker indices/ids/conditions/states are correct.
2268 EXPECT_EQ(newMetricProducers[count1Index]->getMetricId(), count1Id);
2269 EXPECT_EQ(newMetricProducers[count1Index]->mConditionTrackerIndex, predicate1Index);
2270 EXPECT_EQ(newMetricProducers[count1Index]->mCondition, ConditionState::kTrue);
2271 EXPECT_THAT(newMetricProducers[count1Index]->getSlicedStateAtoms(),
2272 UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
2273 EXPECT_EQ(newMetricProducers[count2Index]->getMetricId(), count2Id);
2274 EXPECT_EQ(newMetricProducers[count2Index]->mConditionTrackerIndex, -1);
2275 EXPECT_EQ(newMetricProducers[count2Index]->mCondition, ConditionState::kTrue);
2276 EXPECT_TRUE(newMetricProducers[count2Index]->getSlicedStateAtoms().empty());
2277 EXPECT_EQ(newMetricProducers[count3Index]->getMetricId(), count3Id);
2278 EXPECT_EQ(newMetricProducers[count3Index]->mConditionTrackerIndex, -1);
2279 EXPECT_EQ(newMetricProducers[count3Index]->mCondition, ConditionState::kTrue);
2280 EXPECT_TRUE(newMetricProducers[count3Index]->getSlicedStateAtoms().empty());
2281 EXPECT_EQ(newMetricProducers[count4Index]->getMetricId(), count4Id);
2282 EXPECT_EQ(newMetricProducers[count4Index]->mConditionTrackerIndex, -1);
2283 EXPECT_EQ(newMetricProducers[count4Index]->mCondition, ConditionState::kTrue);
2284 EXPECT_THAT(newMetricProducers[count4Index]->getSlicedStateAtoms(),
2285 UnorderedElementsAre(util::BATTERY_SAVER_MODE_STATE_CHANGED));
2286 EXPECT_EQ(newMetricProducers[count6Index]->getMetricId(), count6Id);
2287 EXPECT_EQ(newMetricProducers[count6Index]->mConditionTrackerIndex, predicate1Index);
2288 EXPECT_EQ(newMetricProducers[count6Index]->mCondition, ConditionState::kTrue);
2289 EXPECT_THAT(newMetricProducers[count6Index]->getSlicedStateAtoms(),
2290 UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
2291
2292 oldMetricProducers.clear();
2293 // Ensure that the screen state StateTracker did not get deleted and replaced.
2294 EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 2);
2295 FieldValue screenState;
2296 StateManager::getInstance().getStateValue(util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY,
2297 &screenState);
2298 EXPECT_EQ(screenState.mValue.int_value, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
2299 }
2300
TEST_F(ConfigUpdateTest,TestUpdateGaugeMetrics)2301 TEST_F(ConfigUpdateTest, TestUpdateGaugeMetrics) {
2302 StatsdConfig config;
2303
2304 // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2305 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2306 int64_t matcher1Id = matcher1.id();
2307 *config.add_atom_matcher() = matcher1;
2308
2309 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2310 int64_t matcher2Id = matcher2.id();
2311 *config.add_atom_matcher() = matcher2;
2312
2313 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
2314 int64_t matcher3Id = matcher3.id();
2315 *config.add_atom_matcher() = matcher3;
2316
2317 AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
2318 int64_t matcher4Id = matcher4.id();
2319 *config.add_atom_matcher() = matcher4;
2320
2321 AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
2322 int64_t matcher5Id = matcher5.id();
2323 *config.add_atom_matcher() = matcher5;
2324
2325 Predicate predicate1 = CreateScreenIsOnPredicate();
2326 int64_t predicate1Id = predicate1.id();
2327 *config.add_predicate() = predicate1;
2328
2329 // Add a few gauge metrics.
2330 // Will be preserved.
2331 GaugeMetric gauge1 = createGaugeMetric("GAUGE1", matcher4Id, GaugeMetric::FIRST_N_SAMPLES,
2332 predicate1Id, matcher1Id);
2333 int64_t gauge1Id = gauge1.id();
2334 *config.add_gauge_metric() = gauge1;
2335
2336 // Will be replaced.
2337 GaugeMetric gauge2 =
2338 createGaugeMetric("GAUGE2", matcher1Id, GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
2339 int64_t gauge2Id = gauge2.id();
2340 *config.add_gauge_metric() = gauge2;
2341
2342 // Will be replaced.
2343 GaugeMetric gauge3 = createGaugeMetric("GAUGE3", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
2344 nullopt, matcher3Id);
2345 int64_t gauge3Id = gauge3.id();
2346 *config.add_gauge_metric() = gauge3;
2347
2348 // Will be replaced.
2349 GaugeMetric gauge4 = createGaugeMetric("GAUGE4", matcher3Id, GaugeMetric::RANDOM_ONE_SAMPLE,
2350 predicate1Id, nullopt);
2351 int64_t gauge4Id = gauge4.id();
2352 *config.add_gauge_metric() = gauge4;
2353
2354 // Will be deleted.
2355 GaugeMetric gauge5 =
2356 createGaugeMetric("GAUGE5", matcher2Id, GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, {});
2357 int64_t gauge5Id = gauge5.id();
2358 *config.add_gauge_metric() = gauge5;
2359
2360 EXPECT_TRUE(initConfig(config));
2361
2362 // Used later to ensure the condition wizard is replaced. Get it before doing the update.
2363 sp<EventMatcherWizard> oldMatcherWizard =
2364 static_cast<GaugeMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
2365 EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);
2366
2367 // Change gauge2, causing it to be replaced.
2368 gauge2.set_max_num_gauge_atoms_per_bucket(50);
2369
2370 // Mark matcher 3 as replaced. Causes gauge3 and gauge4 to be replaced.
2371 set<int64_t> replacedMatchers = {matcher3Id};
2372
2373 // New gauge metric.
2374 GaugeMetric gauge6 = createGaugeMetric("GAUGE6", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
2375 predicate1Id, matcher3Id);
2376 int64_t gauge6Id = gauge6.id();
2377
2378 // Map the matchers and predicates in reverse order to force the indices to change.
2379 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
2380 const int matcher5Index = 0;
2381 newAtomMatchingTrackerMap[matcher5Id] = 0;
2382 const int matcher4Index = 1;
2383 newAtomMatchingTrackerMap[matcher4Id] = 1;
2384 const int matcher3Index = 2;
2385 newAtomMatchingTrackerMap[matcher3Id] = 2;
2386 const int matcher2Index = 3;
2387 newAtomMatchingTrackerMap[matcher2Id] = 3;
2388 const int matcher1Index = 4;
2389 newAtomMatchingTrackerMap[matcher1Id] = 4;
2390 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2391 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
2392 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2393 newAtomMatchingTrackers.begin());
2394
2395 std::unordered_map<int64_t, int> newConditionTrackerMap;
2396 const int predicate1Index = 0;
2397 newConditionTrackerMap[predicate1Id] = 0;
2398 // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
2399 vector<sp<ConditionTracker>> newConditionTrackers(1);
2400 std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2401 newConditionTrackers.begin());
2402 // Say that predicate1 is unknown since the initial condition never changed.
2403 vector<ConditionState> conditionCache = {ConditionState::kUnknown};
2404
2405 StatsdConfig newConfig;
2406 *newConfig.add_gauge_metric() = gauge6;
2407 const int gauge6Index = 0;
2408 *newConfig.add_gauge_metric() = gauge3;
2409 const int gauge3Index = 1;
2410 *newConfig.add_gauge_metric() = gauge1;
2411 const int gauge1Index = 2;
2412 *newConfig.add_gauge_metric() = gauge4;
2413 const int gauge4Index = 3;
2414 *newConfig.add_gauge_metric() = gauge2;
2415 const int gauge2Index = 4;
2416
2417 // Output data structures to validate.
2418 unordered_map<int64_t, int> newMetricProducerMap;
2419 vector<sp<MetricProducer>> newMetricProducers;
2420 unordered_map<int, vector<int>> conditionToMetricMap;
2421 unordered_map<int, vector<int>> trackerToMetricMap;
2422 set<int64_t> noReportMetricIds;
2423 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2424 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2425 vector<int> metricsWithActivation;
2426 set<int64_t> replacedMetrics;
2427 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
2428 EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
2429 new StatsPullerManager(), oldAtomMatchingTrackerMap,
2430 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
2431 newConditionTrackerMap, /*replacedConditions=*/{}, newConditionTrackers,
2432 conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
2433 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
2434 provider, newMetricProducerMap, newMetricProducers,
2435 conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
2436 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
2437 metricsWithActivation, replacedMetrics),
2438 nullopt);
2439
2440 unordered_map<int64_t, int> expectedMetricProducerMap = {
2441 {gauge1Id, gauge1Index}, {gauge2Id, gauge2Index}, {gauge3Id, gauge3Index},
2442 {gauge4Id, gauge4Index}, {gauge6Id, gauge6Index},
2443 };
2444 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2445 EXPECT_EQ(replacedMetrics, set<int64_t>({gauge2Id, gauge3Id, gauge4Id}));
2446
2447 // Make sure preserved metrics are the same.
2448 ASSERT_EQ(newMetricProducers.size(), 5);
2449 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(gauge1Id)],
2450 newMetricProducers[newMetricProducerMap.at(gauge1Id)]);
2451
2452 // Make sure replaced metrics are different.
2453 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge2Id)],
2454 newMetricProducers[newMetricProducerMap.at(gauge2Id)]);
2455 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge3Id)],
2456 newMetricProducers[newMetricProducerMap.at(gauge3Id)]);
2457 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge4Id)],
2458 newMetricProducers[newMetricProducerMap.at(gauge4Id)]);
2459
2460 // Verify the conditionToMetricMap.
2461 ASSERT_EQ(conditionToMetricMap.size(), 1);
2462 const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
2463 EXPECT_THAT(condition1Metrics, UnorderedElementsAre(gauge1Index, gauge4Index, gauge6Index));
2464
2465 // Verify the trackerToMetricMap.
2466 ASSERT_EQ(trackerToMetricMap.size(), 4);
2467 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2468 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(gauge1Index, gauge2Index));
2469 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2470 EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gauge3Index, gauge4Index, gauge6Index));
2471 const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2472 EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(gauge1Index));
2473 const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
2474 EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(gauge3Index, gauge6Index));
2475
2476 // Verify event activation/deactivation maps.
2477 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2478 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2479 ASSERT_EQ(metricsWithActivation.size(), 0);
2480
2481 // Verify tracker indices/ids/conditions/states are correct.
2482 GaugeMetricProducer* gaugeProducer1 =
2483 static_cast<GaugeMetricProducer*>(newMetricProducers[gauge1Index].get());
2484 EXPECT_EQ(gaugeProducer1->getMetricId(), gauge1Id);
2485 EXPECT_EQ(gaugeProducer1->mConditionTrackerIndex, predicate1Index);
2486 EXPECT_EQ(gaugeProducer1->mCondition, ConditionState::kUnknown);
2487 EXPECT_EQ(gaugeProducer1->mWhatMatcherIndex, matcher4Index);
2488 GaugeMetricProducer* gaugeProducer2 =
2489 static_cast<GaugeMetricProducer*>(newMetricProducers[gauge2Index].get());
2490 EXPECT_EQ(gaugeProducer2->getMetricId(), gauge2Id);
2491 EXPECT_EQ(gaugeProducer2->mConditionTrackerIndex, -1);
2492 EXPECT_EQ(gaugeProducer2->mCondition, ConditionState::kTrue);
2493 EXPECT_EQ(gaugeProducer2->mWhatMatcherIndex, matcher1Index);
2494 GaugeMetricProducer* gaugeProducer3 =
2495 static_cast<GaugeMetricProducer*>(newMetricProducers[gauge3Index].get());
2496 EXPECT_EQ(gaugeProducer3->getMetricId(), gauge3Id);
2497 EXPECT_EQ(gaugeProducer3->mConditionTrackerIndex, -1);
2498 EXPECT_EQ(gaugeProducer3->mCondition, ConditionState::kTrue);
2499 EXPECT_EQ(gaugeProducer3->mWhatMatcherIndex, matcher5Index);
2500 GaugeMetricProducer* gaugeProducer4 =
2501 static_cast<GaugeMetricProducer*>(newMetricProducers[gauge4Index].get());
2502 EXPECT_EQ(gaugeProducer4->getMetricId(), gauge4Id);
2503 EXPECT_EQ(gaugeProducer4->mConditionTrackerIndex, predicate1Index);
2504 EXPECT_EQ(gaugeProducer4->mCondition, ConditionState::kUnknown);
2505 EXPECT_EQ(gaugeProducer4->mWhatMatcherIndex, matcher3Index);
2506 GaugeMetricProducer* gaugeProducer6 =
2507 static_cast<GaugeMetricProducer*>(newMetricProducers[gauge6Index].get());
2508 EXPECT_EQ(gaugeProducer6->getMetricId(), gauge6Id);
2509 EXPECT_EQ(gaugeProducer6->mConditionTrackerIndex, predicate1Index);
2510 EXPECT_EQ(gaugeProducer6->mCondition, ConditionState::kUnknown);
2511 EXPECT_EQ(gaugeProducer6->mWhatMatcherIndex, matcher5Index);
2512
2513 sp<EventMatcherWizard> newMatcherWizard = gaugeProducer1->mEventMatcherWizard;
2514 EXPECT_NE(newMatcherWizard, oldMatcherWizard);
2515 EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
2516 oldMetricProducers.clear();
2517 // Only reference to the old wizard should be the one in the test.
2518 EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
2519 }
2520
TEST_F(ConfigUpdateTest,TestUpdateDurationMetrics)2521 TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) {
2522 StatsdConfig config;
2523 // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2524 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2525 int64_t matcher1Id = matcher1.id();
2526 *config.add_atom_matcher() = matcher1;
2527
2528 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2529 int64_t matcher2Id = matcher2.id();
2530 *config.add_atom_matcher() = matcher2;
2531
2532 AtomMatcher matcher3 = CreateAcquireWakelockAtomMatcher();
2533 int64_t matcher3Id = matcher3.id();
2534 *config.add_atom_matcher() = matcher3;
2535
2536 AtomMatcher matcher4 = CreateReleaseWakelockAtomMatcher();
2537 int64_t matcher4Id = matcher4.id();
2538 *config.add_atom_matcher() = matcher4;
2539
2540 AtomMatcher matcher5 = CreateMoveToForegroundAtomMatcher();
2541 int64_t matcher5Id = matcher5.id();
2542 *config.add_atom_matcher() = matcher5;
2543
2544 AtomMatcher matcher6 = CreateMoveToBackgroundAtomMatcher();
2545 int64_t matcher6Id = matcher6.id();
2546 *config.add_atom_matcher() = matcher6;
2547
2548 AtomMatcher matcher7 = CreateBatteryStateNoneMatcher();
2549 int64_t matcher7Id = matcher7.id();
2550 *config.add_atom_matcher() = matcher7;
2551
2552 AtomMatcher matcher8 = CreateBatteryStateUsbMatcher();
2553 int64_t matcher8Id = matcher8.id();
2554 *config.add_atom_matcher() = matcher8;
2555
2556 Predicate predicate1 = CreateScreenIsOnPredicate();
2557 int64_t predicate1Id = predicate1.id();
2558 *config.add_predicate() = predicate1;
2559
2560 Predicate predicate2 = CreateScreenIsOffPredicate();
2561 int64_t predicate2Id = predicate2.id();
2562 *config.add_predicate() = predicate2;
2563
2564 Predicate predicate3 = CreateDeviceUnpluggedPredicate();
2565 int64_t predicate3Id = predicate3.id();
2566 *config.add_predicate() = predicate3;
2567
2568 Predicate predicate4 = CreateIsInBackgroundPredicate();
2569 *predicate4.mutable_simple_predicate()->mutable_dimensions() =
2570 CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1});
2571 int64_t predicate4Id = predicate4.id();
2572 *config.add_predicate() = predicate4;
2573
2574 Predicate predicate5 = CreateHoldingWakelockPredicate();
2575 *predicate5.mutable_simple_predicate()->mutable_dimensions() =
2576 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2577 predicate5.mutable_simple_predicate()->set_stop_all(matcher7Id);
2578 int64_t predicate5Id = predicate5.id();
2579 *config.add_predicate() = predicate5;
2580
2581 State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
2582 int64_t state1Id = state1.id();
2583 *config.add_state() = state1;
2584
2585 State state2 = CreateScreenState();
2586 int64_t state2Id = state2.id();
2587 *config.add_state() = state2;
2588
2589 // Add a few duration metrics.
2590 // Will be preserved.
2591 DurationMetric duration1 =
2592 createDurationMetric("DURATION1", predicate5Id, predicate4Id, {state2Id});
2593 *duration1.mutable_dimensions_in_what() =
2594 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2595 MetricConditionLink* link = duration1.add_links();
2596 link->set_condition(predicate4Id);
2597 *link->mutable_fields_in_what() =
2598 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2599 *link->mutable_fields_in_condition() =
2600 CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
2601 int64_t duration1Id = duration1.id();
2602 *config.add_duration_metric() = duration1;
2603
2604 // Will be replaced.
2605 DurationMetric duration2 = createDurationMetric("DURATION2", predicate1Id, nullopt, {});
2606 int64_t duration2Id = duration2.id();
2607 *config.add_duration_metric() = duration2;
2608
2609 // Will be replaced.
2610 DurationMetric duration3 = createDurationMetric("DURATION3", predicate3Id, nullopt, {state1Id});
2611 int64_t duration3Id = duration3.id();
2612 *config.add_duration_metric() = duration3;
2613
2614 // Will be replaced.
2615 DurationMetric duration4 = createDurationMetric("DURATION4", predicate3Id, predicate2Id, {});
2616 int64_t duration4Id = duration4.id();
2617 *config.add_duration_metric() = duration4;
2618
2619 // Will be deleted.
2620 DurationMetric duration5 = createDurationMetric("DURATION5", predicate2Id, nullopt, {});
2621 int64_t duration5Id = duration5.id();
2622 *config.add_duration_metric() = duration5;
2623
2624 EXPECT_TRUE(initConfig(config));
2625
2626 // Make some sliced conditions true.
2627 int uid1 = 10;
2628 int uid2 = 11;
2629 vector<MatchingState> matchingStates(8, MatchingState::kNotMatched);
2630 matchingStates[2] = kMatched;
2631 vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
2632 vector<uint8_t> changedCache(5, false);
2633 unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid1}, {"tag"}, "wl1");
2634 oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
2635 conditionCache, changedCache);
2636 EXPECT_TRUE(oldConditionTrackers[4]->isSliced());
2637 EXPECT_TRUE(changedCache[4]);
2638 EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
2639 oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());
2640
2641 fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
2642 fill(changedCache.begin(), changedCache.end(), false);
2643 event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid2}, {"tag"}, "wl2");
2644 oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
2645 conditionCache, changedCache);
2646 EXPECT_TRUE(changedCache[4]);
2647 EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
2648 oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());
2649
2650 // Used later to ensure the condition wizard is replaced. Get it before doing the update.
2651 // The duration trackers have a pointer to the wizard, and 2 trackers were created above.
2652 sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
2653 EXPECT_EQ(oldConditionWizard->getStrongCount(), 8);
2654
2655 // Replace predicate1, predicate3, and state1. Causes duration2/3/4 to be replaced.
2656 set<int64_t> replacedConditions({predicate1Id, predicate2Id});
2657 set<int64_t> replacedStates({state1Id});
2658
2659 // New duration metric.
2660 DurationMetric duration6 = createDurationMetric("DURATION6", predicate4Id, predicate5Id, {});
2661 *duration6.mutable_dimensions_in_what() =
2662 CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
2663 link = duration6.add_links();
2664 link->set_condition(predicate5Id);
2665 *link->mutable_fields_in_what() =
2666 CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
2667 *link->mutable_fields_in_condition() =
2668 CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2669 int64_t duration6Id = duration6.id();
2670
2671 // Map the matchers and predicates in reverse order to force the indices to change.
2672 const int matcher8Index = 0, matcher7Index = 1, matcher6Index = 2, matcher5Index = 3,
2673 matcher4Index = 4, matcher3Index = 5, matcher2Index = 6, matcher1Index = 7;
2674 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap({{matcher8Id, matcher8Index},
2675 {matcher7Id, matcher7Index},
2676 {matcher6Id, matcher6Index},
2677 {matcher5Id, matcher5Index},
2678 {matcher4Id, matcher4Index},
2679 {matcher3Id, matcher3Index},
2680 {matcher2Id, matcher2Index},
2681 {matcher1Id, matcher1Index}});
2682 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2683 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(8);
2684 reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2685 newAtomMatchingTrackers.begin());
2686
2687 const int predicate5Index = 0, predicate4Index = 1, predicate3Index = 2, predicate2Index = 3,
2688 predicate1Index = 4;
2689 std::unordered_map<int64_t, int> newConditionTrackerMap({
2690 {predicate5Id, predicate5Index},
2691 {predicate4Id, predicate4Index},
2692 {predicate3Id, predicate3Index},
2693 {predicate2Id, predicate2Index},
2694 {predicate1Id, predicate1Index},
2695 });
2696 // Use the existing conditionTrackers and reinitialize them to get the initial condition cache.
2697 vector<sp<ConditionTracker>> newConditionTrackers(5);
2698 reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2699 newConditionTrackers.begin());
2700 vector<Predicate> conditionProtos(5);
2701 reverse_copy(config.predicate().begin(), config.predicate().end(), conditionProtos.begin());
2702 for (int i = 0; i < newConditionTrackers.size(); i++) {
2703 EXPECT_EQ(newConditionTrackers[i]->onConfigUpdated(conditionProtos, i, newConditionTrackers,
2704 newAtomMatchingTrackerMap,
2705 newConditionTrackerMap),
2706 nullopt);
2707 }
2708 vector<uint8_t> cycleTracker(5, false);
2709 fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
2710 for (int i = 0; i < newConditionTrackers.size(); i++) {
2711 EXPECT_EQ(
2712 newConditionTrackers[i]->init(conditionProtos, newConditionTrackers,
2713 newConditionTrackerMap, cycleTracker, conditionCache),
2714 nullopt);
2715 }
2716 // Predicate5 should be true since 2 uids have wakelocks
2717 EXPECT_EQ(conditionCache, vector({kTrue, kFalse, kUnknown, kUnknown, kUnknown}));
2718
2719 StatsdConfig newConfig;
2720 *newConfig.add_duration_metric() = duration6;
2721 const int duration6Index = 0;
2722 *newConfig.add_duration_metric() = duration3;
2723 const int duration3Index = 1;
2724 *newConfig.add_duration_metric() = duration1;
2725 const int duration1Index = 2;
2726 *newConfig.add_duration_metric() = duration4;
2727 const int duration4Index = 3;
2728 *newConfig.add_duration_metric() = duration2;
2729 const int duration2Index = 4;
2730
2731 for (const Predicate& predicate : conditionProtos) {
2732 *newConfig.add_predicate() = predicate;
2733 }
2734 *newConfig.add_state() = state1;
2735 *newConfig.add_state() = state2;
2736 unordered_map<int64_t, int> stateAtomIdMap;
2737 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
2738 map<int64_t, uint64_t> stateProtoHashes;
2739 EXPECT_EQ(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes), nullopt);
2740
2741 // Output data structures to validate.
2742 unordered_map<int64_t, int> newMetricProducerMap;
2743 vector<sp<MetricProducer>> newMetricProducers;
2744 unordered_map<int, vector<int>> conditionToMetricMap;
2745 unordered_map<int, vector<int>> trackerToMetricMap;
2746 set<int64_t> noReportMetricIds;
2747 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2748 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2749 vector<int> metricsWithActivation;
2750 set<int64_t> replacedMetrics;
2751 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
2752 EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
2753 new StatsPullerManager(), oldAtomMatchingTrackerMap,
2754 newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
2755 newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
2756 newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps,
2757 replacedStates, oldMetricProducerMap, oldMetricProducers, provider,
2758 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
2759 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
2760 deactivationAtomTrackerToMetricMap, metricsWithActivation,
2761 replacedMetrics),
2762 nullopt);
2763
2764 unordered_map<int64_t, int> expectedMetricProducerMap = {
2765 {duration1Id, duration1Index}, {duration2Id, duration2Index},
2766 {duration3Id, duration3Index}, {duration4Id, duration4Index},
2767 {duration6Id, duration6Index},
2768 };
2769 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2770 EXPECT_EQ(replacedMetrics, set<int64_t>({duration2Id, duration3Id, duration4Id}));
2771 // Make sure preserved metrics are the same.
2772 ASSERT_EQ(newMetricProducers.size(), 5);
2773 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(duration1Id)],
2774 newMetricProducers[newMetricProducerMap.at(duration1Id)]);
2775
2776 // Make sure replaced metrics are different.
2777 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration2Id)],
2778 newMetricProducers[newMetricProducerMap.at(duration2Id)]);
2779 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration3Id)],
2780 newMetricProducers[newMetricProducerMap.at(duration3Id)]);
2781 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration4Id)],
2782 newMetricProducers[newMetricProducerMap.at(duration4Id)]);
2783
2784 // Verify the conditionToMetricMap. Note that the "what" is not in this map.
2785 ASSERT_EQ(conditionToMetricMap.size(), 3);
2786 const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
2787 EXPECT_THAT(condition2Metrics, UnorderedElementsAre(duration4Index));
2788 const vector<int>& condition4Metrics = conditionToMetricMap[predicate4Index];
2789 EXPECT_THAT(condition4Metrics, UnorderedElementsAre(duration1Index));
2790 const vector<int>& condition5Metrics = conditionToMetricMap[predicate5Index];
2791 EXPECT_THAT(condition5Metrics, UnorderedElementsAre(duration6Index));
2792
2793 // Verify the trackerToMetricMap. The start/stop/stopall indices from the "what" should be here.
2794 ASSERT_EQ(trackerToMetricMap.size(), 8);
2795 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2796 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(duration2Index));
2797 const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
2798 EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(duration2Index));
2799 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2800 EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(duration1Index));
2801 const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2802 EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(duration1Index));
2803 const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
2804 EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(duration6Index));
2805 const vector<int>& matcher6Metrics = trackerToMetricMap[matcher6Index];
2806 EXPECT_THAT(matcher6Metrics, UnorderedElementsAre(duration6Index));
2807 const vector<int>& matcher7Metrics = trackerToMetricMap[matcher7Index];
2808 EXPECT_THAT(matcher7Metrics,
2809 UnorderedElementsAre(duration1Index, duration3Index, duration4Index));
2810 const vector<int>& matcher8Metrics = trackerToMetricMap[matcher8Index];
2811 EXPECT_THAT(matcher8Metrics, UnorderedElementsAre(duration3Index, duration4Index));
2812
2813 // Verify event activation/deactivation maps.
2814 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2815 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2816 ASSERT_EQ(metricsWithActivation.size(), 0);
2817
2818 // Verify tracker indices/ids/conditions are correct.
2819 DurationMetricProducer* durationProducer1 =
2820 static_cast<DurationMetricProducer*>(newMetricProducers[duration1Index].get());
2821 EXPECT_EQ(durationProducer1->getMetricId(), duration1Id);
2822 EXPECT_EQ(durationProducer1->mConditionTrackerIndex, predicate4Index);
2823 EXPECT_EQ(durationProducer1->mCondition, ConditionState::kFalse);
2824 EXPECT_EQ(durationProducer1->mStartIndex, matcher3Index);
2825 EXPECT_EQ(durationProducer1->mStopIndex, matcher4Index);
2826 EXPECT_EQ(durationProducer1->mStopAllIndex, matcher7Index);
2827 EXPECT_EQ(durationProducer1->mCurrentSlicedDurationTrackerMap.size(), 2);
2828 for (const auto& durationTrackerIt : durationProducer1->mCurrentSlicedDurationTrackerMap) {
2829 EXPECT_EQ(durationTrackerIt.second->mConditionTrackerIndex, predicate4Index);
2830 }
2831 DurationMetricProducer* durationProducer2 =
2832 static_cast<DurationMetricProducer*>(newMetricProducers[duration2Index].get());
2833 EXPECT_EQ(durationProducer2->getMetricId(), duration2Id);
2834 EXPECT_EQ(durationProducer2->mConditionTrackerIndex, -1);
2835 EXPECT_EQ(durationProducer2->mCondition, ConditionState::kTrue);
2836 EXPECT_EQ(durationProducer2->mStartIndex, matcher1Index);
2837 EXPECT_EQ(durationProducer2->mStopIndex, matcher2Index);
2838 EXPECT_EQ(durationProducer2->mStopAllIndex, -1);
2839 DurationMetricProducer* durationProducer3 =
2840 static_cast<DurationMetricProducer*>(newMetricProducers[duration3Index].get());
2841 EXPECT_EQ(durationProducer3->getMetricId(), duration3Id);
2842 EXPECT_EQ(durationProducer3->mConditionTrackerIndex, -1);
2843 EXPECT_EQ(durationProducer3->mCondition, ConditionState::kTrue);
2844 EXPECT_EQ(durationProducer3->mStartIndex, matcher7Index);
2845 EXPECT_EQ(durationProducer3->mStopIndex, matcher8Index);
2846 EXPECT_EQ(durationProducer3->mStopAllIndex, -1);
2847 DurationMetricProducer* durationProducer4 =
2848 static_cast<DurationMetricProducer*>(newMetricProducers[duration4Index].get());
2849 EXPECT_EQ(durationProducer4->getMetricId(), duration4Id);
2850 EXPECT_EQ(durationProducer4->mConditionTrackerIndex, predicate2Index);
2851 EXPECT_EQ(durationProducer4->mCondition, ConditionState::kUnknown);
2852 EXPECT_EQ(durationProducer4->mStartIndex, matcher7Index);
2853 EXPECT_EQ(durationProducer4->mStopIndex, matcher8Index);
2854 EXPECT_EQ(durationProducer4->mStopAllIndex, -1);
2855 DurationMetricProducer* durationProducer6 =
2856 static_cast<DurationMetricProducer*>(newMetricProducers[duration6Index].get());
2857 EXPECT_EQ(durationProducer6->getMetricId(), duration6Id);
2858 EXPECT_EQ(durationProducer6->mConditionTrackerIndex, predicate5Index);
2859 // TODO(b/167491517): should this be unknown since the condition is sliced?
2860 EXPECT_EQ(durationProducer6->mCondition, ConditionState::kTrue);
2861 EXPECT_EQ(durationProducer6->mStartIndex, matcher6Index);
2862 EXPECT_EQ(durationProducer6->mStopIndex, matcher5Index);
2863 EXPECT_EQ(durationProducer6->mStopAllIndex, -1);
2864
2865 sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
2866 EXPECT_NE(newConditionWizard, oldConditionWizard);
2867 EXPECT_EQ(newConditionWizard->getStrongCount(), 8);
2868 oldMetricProducers.clear();
2869 // Only reference to the old wizard should be the one in the test.
2870 EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
2871 }
2872
TEST_F(ConfigUpdateTest,TestUpdateValueMetrics)2873 TEST_F(ConfigUpdateTest, TestUpdateValueMetrics) {
2874 StatsdConfig config;
2875
2876 // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2877 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2878 int64_t matcher1Id = matcher1.id();
2879 *config.add_atom_matcher() = matcher1;
2880
2881 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2882 int64_t matcher2Id = matcher2.id();
2883 *config.add_atom_matcher() = matcher2;
2884
2885 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
2886 int64_t matcher3Id = matcher3.id();
2887 *config.add_atom_matcher() = matcher3;
2888
2889 AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
2890 int64_t matcher4Id = matcher4.id();
2891 *config.add_atom_matcher() = matcher4;
2892
2893 AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
2894 int64_t matcher5Id = matcher5.id();
2895 *config.add_atom_matcher() = matcher5;
2896
2897 Predicate predicate1 = CreateScreenIsOnPredicate();
2898 int64_t predicate1Id = predicate1.id();
2899 *config.add_predicate() = predicate1;
2900
2901 Predicate predicate2 = CreateScreenIsOffPredicate();
2902 int64_t predicate2Id = predicate2.id();
2903 *config.add_predicate() = predicate2;
2904
2905 State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
2906 int64_t state1Id = state1.id();
2907 *config.add_state() = state1;
2908
2909 State state2 = CreateScreenState();
2910 int64_t state2Id = state2.id();
2911 *config.add_state() = state2;
2912
2913 // Add a few value metrics.
2914 // Note that these will not work as "real" metrics since the value field is always 2.
2915 // Will be preserved.
2916 ValueMetric value1 = createValueMetric("VALUE1", matcher4, 2, predicate1Id, {state1Id});
2917 int64_t value1Id = value1.id();
2918 *config.add_value_metric() = value1;
2919
2920 // Will be replaced - definition change.
2921 ValueMetric value2 = createValueMetric("VALUE2", matcher1, 2, nullopt, {});
2922 int64_t value2Id = value2.id();
2923 *config.add_value_metric() = value2;
2924
2925 // Will be replaced - condition change.
2926 ValueMetric value3 = createValueMetric("VALUE3", matcher5, 2, predicate2Id, {});
2927 int64_t value3Id = value3.id();
2928 *config.add_value_metric() = value3;
2929
2930 // Will be replaced - state change.
2931 ValueMetric value4 = createValueMetric("VALUE4", matcher3, 2, nullopt, {state2Id});
2932 int64_t value4Id = value4.id();
2933 *config.add_value_metric() = value4;
2934
2935 // Will be deleted.
2936 ValueMetric value5 = createValueMetric("VALUE5", matcher2, 2, nullopt, {});
2937 int64_t value5Id = value5.id();
2938 *config.add_value_metric() = value5;
2939
2940 EXPECT_TRUE(initConfig(config));
2941
2942 // Used later to ensure the condition wizard is replaced. Get it before doing the update.
2943 sp<EventMatcherWizard> oldMatcherWizard =
2944 static_cast<NumericValueMetricProducer*>(oldMetricProducers[0].get())
2945 ->mEventMatcherWizard;
2946 EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);
2947
2948 // Change value2, causing it to be replaced.
2949 value2.set_aggregation_type(ValueMetric::AVG);
2950
2951 // Mark predicate 2 as replaced. Causes value3 to be replaced.
2952 set<int64_t> replacedConditions = {predicate2Id};
2953
2954 // Mark state 2 as replaced. Causes value4 to be replaced.
2955 set<int64_t> replacedStates = {state2Id};
2956
2957 // New value metric.
2958 ValueMetric value6 = createValueMetric("VALUE6", matcher5, 2, predicate1Id, {state1Id});
2959 int64_t value6Id = value6.id();
2960
2961 // Map the matchers and predicates in reverse order to force the indices to change.
2962 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
2963 const int matcher5Index = 0;
2964 newAtomMatchingTrackerMap[matcher5Id] = 0;
2965 const int matcher4Index = 1;
2966 newAtomMatchingTrackerMap[matcher4Id] = 1;
2967 const int matcher3Index = 2;
2968 newAtomMatchingTrackerMap[matcher3Id] = 2;
2969 const int matcher2Index = 3;
2970 newAtomMatchingTrackerMap[matcher2Id] = 3;
2971 const int matcher1Index = 4;
2972 newAtomMatchingTrackerMap[matcher1Id] = 4;
2973 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2974 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
2975 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2976 newAtomMatchingTrackers.begin());
2977
2978 std::unordered_map<int64_t, int> newConditionTrackerMap;
2979 const int predicate2Index = 0;
2980 newConditionTrackerMap[predicate2Id] = 0;
2981 const int predicate1Index = 1;
2982 newConditionTrackerMap[predicate1Id] = 1;
2983 // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
2984 vector<sp<ConditionTracker>> newConditionTrackers(2);
2985 std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2986 newConditionTrackers.begin());
2987 // Say that predicate1 & predicate2 is unknown since the initial condition never changed.
2988 vector<ConditionState> conditionCache = {ConditionState::kUnknown, ConditionState::kUnknown};
2989
2990 StatsdConfig newConfig;
2991 *newConfig.add_value_metric() = value6;
2992 const int value6Index = 0;
2993 *newConfig.add_value_metric() = value3;
2994 const int value3Index = 1;
2995 *newConfig.add_value_metric() = value1;
2996 const int value1Index = 2;
2997 *newConfig.add_value_metric() = value4;
2998 const int value4Index = 3;
2999 *newConfig.add_value_metric() = value2;
3000 const int value2Index = 4;
3001
3002 *newConfig.add_state() = state1;
3003 *newConfig.add_state() = state2;
3004
3005 unordered_map<int64_t, int> stateAtomIdMap;
3006 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
3007 map<int64_t, uint64_t> stateProtoHashes;
3008 EXPECT_EQ(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes), nullopt);
3009
3010 // Output data structures to validate.
3011 unordered_map<int64_t, int> newMetricProducerMap;
3012 vector<sp<MetricProducer>> newMetricProducers;
3013 unordered_map<int, vector<int>> conditionToMetricMap;
3014 unordered_map<int, vector<int>> trackerToMetricMap;
3015 set<int64_t> noReportMetricIds;
3016 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3017 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3018 vector<int> metricsWithActivation;
3019 set<int64_t> replacedMetrics;
3020 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
3021 EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
3022 new StatsPullerManager(), oldAtomMatchingTrackerMap,
3023 newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
3024 newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
3025 newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps,
3026 replacedStates, oldMetricProducerMap, oldMetricProducers, provider,
3027 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
3028 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
3029 deactivationAtomTrackerToMetricMap, metricsWithActivation,
3030 replacedMetrics),
3031 nullopt);
3032
3033 unordered_map<int64_t, int> expectedMetricProducerMap = {
3034 {value1Id, value1Index}, {value2Id, value2Index}, {value3Id, value3Index},
3035 {value4Id, value4Index}, {value6Id, value6Index},
3036 };
3037 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
3038 EXPECT_EQ(replacedMetrics, set<int64_t>({value2Id, value3Id, value4Id}));
3039
3040 // Make sure preserved metrics are the same.
3041 ASSERT_EQ(newMetricProducers.size(), 5);
3042 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(value1Id)],
3043 newMetricProducers[newMetricProducerMap.at(value1Id)]);
3044
3045 // Make sure replaced metrics are different.
3046 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value2Id)],
3047 newMetricProducers[newMetricProducerMap.at(value2Id)]);
3048 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value3Id)],
3049 newMetricProducers[newMetricProducerMap.at(value3Id)]);
3050 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value4Id)],
3051 newMetricProducers[newMetricProducerMap.at(value4Id)]);
3052
3053 // Verify the conditionToMetricMap.
3054 ASSERT_EQ(conditionToMetricMap.size(), 2);
3055 const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
3056 EXPECT_THAT(condition1Metrics, UnorderedElementsAre(value1Index, value6Index));
3057 const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
3058 EXPECT_THAT(condition2Metrics, UnorderedElementsAre(value3Index));
3059
3060 // Verify the trackerToMetricMap.
3061 ASSERT_EQ(trackerToMetricMap.size(), 4);
3062 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
3063 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(value2Index));
3064 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
3065 EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(value4Index));
3066 const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
3067 EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(value1Index));
3068 const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
3069 EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(value3Index, value6Index));
3070
3071 // Verify event activation/deactivation maps.
3072 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
3073 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
3074 ASSERT_EQ(metricsWithActivation.size(), 0);
3075
3076 // Verify tracker indices/ids/conditions/states are correct.
3077 NumericValueMetricProducer* valueProducer1 =
3078 static_cast<NumericValueMetricProducer*>(newMetricProducers[value1Index].get());
3079 EXPECT_EQ(valueProducer1->getMetricId(), value1Id);
3080 EXPECT_EQ(valueProducer1->mConditionTrackerIndex, predicate1Index);
3081 EXPECT_EQ(valueProducer1->mCondition, ConditionState::kUnknown);
3082 EXPECT_EQ(valueProducer1->mWhatMatcherIndex, matcher4Index);
3083 NumericValueMetricProducer* valueProducer2 =
3084 static_cast<NumericValueMetricProducer*>(newMetricProducers[value2Index].get());
3085 EXPECT_EQ(valueProducer2->getMetricId(), value2Id);
3086 EXPECT_EQ(valueProducer2->mConditionTrackerIndex, -1);
3087 EXPECT_EQ(valueProducer2->mCondition, ConditionState::kTrue);
3088 EXPECT_EQ(valueProducer2->mWhatMatcherIndex, matcher1Index);
3089 NumericValueMetricProducer* valueProducer3 =
3090 static_cast<NumericValueMetricProducer*>(newMetricProducers[value3Index].get());
3091 EXPECT_EQ(valueProducer3->getMetricId(), value3Id);
3092 EXPECT_EQ(valueProducer3->mConditionTrackerIndex, predicate2Index);
3093 EXPECT_EQ(valueProducer3->mCondition, ConditionState::kUnknown);
3094 EXPECT_EQ(valueProducer3->mWhatMatcherIndex, matcher5Index);
3095 NumericValueMetricProducer* valueProducer4 =
3096 static_cast<NumericValueMetricProducer*>(newMetricProducers[value4Index].get());
3097 EXPECT_EQ(valueProducer4->getMetricId(), value4Id);
3098 EXPECT_EQ(valueProducer4->mConditionTrackerIndex, -1);
3099 EXPECT_EQ(valueProducer4->mCondition, ConditionState::kTrue);
3100 EXPECT_EQ(valueProducer4->mWhatMatcherIndex, matcher3Index);
3101 NumericValueMetricProducer* valueProducer6 =
3102 static_cast<NumericValueMetricProducer*>(newMetricProducers[value6Index].get());
3103 EXPECT_EQ(valueProducer6->getMetricId(), value6Id);
3104 EXPECT_EQ(valueProducer6->mConditionTrackerIndex, predicate1Index);
3105 EXPECT_EQ(valueProducer6->mCondition, ConditionState::kUnknown);
3106 EXPECT_EQ(valueProducer6->mWhatMatcherIndex, matcher5Index);
3107
3108 sp<EventMatcherWizard> newMatcherWizard = valueProducer1->mEventMatcherWizard;
3109 EXPECT_NE(newMatcherWizard, oldMatcherWizard);
3110 EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
3111 oldMetricProducers.clear();
3112 // Only reference to the old wizard should be the one in the test.
3113 EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
3114 }
3115
TEST_F(ConfigUpdateTest,TestUpdateKllMetrics)3116 TEST_F(ConfigUpdateTest, TestUpdateKllMetrics) {
3117 StatsdConfig config;
3118
3119 // Add atom matchers/predicates. These are mostly needed for initStatsdConfig.
3120 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
3121 int64_t matcher1Id = matcher1.id();
3122 *config.add_atom_matcher() = matcher1;
3123
3124 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
3125 int64_t matcher2Id = matcher2.id();
3126 *config.add_atom_matcher() = matcher2;
3127
3128 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
3129 int64_t matcher3Id = matcher3.id();
3130 *config.add_atom_matcher() = matcher3;
3131
3132 AtomMatcher matcher4 = CreateAppStartOccurredAtomMatcher();
3133 int64_t matcher4Id = matcher4.id();
3134 *config.add_atom_matcher() = matcher4;
3135
3136 AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
3137 int64_t matcher5Id = matcher5.id();
3138 *config.add_atom_matcher() = matcher5;
3139
3140 Predicate predicate1 = CreateScreenIsOnPredicate();
3141 int64_t predicate1Id = predicate1.id();
3142 *config.add_predicate() = predicate1;
3143
3144 Predicate predicate2 = CreateScreenIsOffPredicate();
3145 int64_t predicate2Id = predicate2.id();
3146 *config.add_predicate() = predicate2;
3147
3148 // Add a few kll metrics.
3149 // Note that these will not work as "real" metrics since the value field is always 2.
3150 // Will be preserved.
3151 KllMetric kll1 = createKllMetric("KLL1", matcher4, /*valueField=*/2, predicate1Id);
3152 int64_t kll1Id = kll1.id();
3153 *config.add_kll_metric() = kll1;
3154
3155 // Will be replaced - definition change.
3156 KllMetric kll2 = createKllMetric("KLL2", matcher1, /*valueField=*/2, nullopt);
3157 int64_t kll2Id = kll2.id();
3158 *config.add_kll_metric() = kll2;
3159
3160 // Will be replaced - condition change.
3161 KllMetric kll3 = createKllMetric("KLL3", matcher5, /*valueField=*/2, predicate2Id);
3162 int64_t kll3Id = kll3.id();
3163 *config.add_kll_metric() = kll3;
3164
3165 // Will be preserved.
3166 KllMetric kll4 = createKllMetric("KLL", matcher3, /*valueField=*/2, nullopt);
3167 int64_t kll4Id = kll4.id();
3168 *config.add_kll_metric() = kll4;
3169
3170 // Will be deleted.
3171 KllMetric kll5 = createKllMetric("KLL5", matcher2, /*valueField=*/2, nullopt);
3172 int64_t kll5Id = kll5.id();
3173 *config.add_kll_metric() = kll5;
3174
3175 ASSERT_TRUE(initConfig(config));
3176
3177 // Change kll2, causing it to be replaced.
3178 kll2.set_split_bucket_for_app_upgrade(false);
3179
3180 // Mark predicate 2 as replaced. Causes kll3 to be replaced.
3181 set<int64_t> replacedConditions = {predicate2Id};
3182
3183 // New kll metric.
3184 KllMetric kll6 = createKllMetric("KLL6", matcher5, /*valueField=*/2, predicate1Id);
3185 int64_t kll6Id = kll6.id();
3186
3187 // Map the matchers and predicates in reverse order to force the indices to change.
3188 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
3189 const int matcher5Index = 0;
3190 newAtomMatchingTrackerMap[matcher5Id] = 0;
3191 const int matcher4Index = 1;
3192 newAtomMatchingTrackerMap[matcher4Id] = 1;
3193 const int matcher3Index = 2;
3194 newAtomMatchingTrackerMap[matcher3Id] = 2;
3195 const int matcher2Index = 3;
3196 newAtomMatchingTrackerMap[matcher2Id] = 3;
3197 const int matcher1Index = 4;
3198 newAtomMatchingTrackerMap[matcher1Id] = 4;
3199 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
3200 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
3201 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
3202 newAtomMatchingTrackers.begin());
3203
3204 std::unordered_map<int64_t, int> newConditionTrackerMap;
3205 const int predicate2Index = 0;
3206 newConditionTrackerMap[predicate2Id] = 0;
3207 const int predicate1Index = 1;
3208 newConditionTrackerMap[predicate1Id] = 1;
3209 // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
3210 vector<sp<ConditionTracker>> newConditionTrackers(2);
3211 std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
3212 newConditionTrackers.begin());
3213 // Say that predicate1 & predicate2 is unknown since the initial condition never changed.
3214 vector<ConditionState> conditionCache = {ConditionState::kUnknown, ConditionState::kUnknown};
3215
3216 StatsdConfig newConfig;
3217 *newConfig.add_kll_metric() = kll6;
3218 const int kll6Index = 0;
3219 *newConfig.add_kll_metric() = kll3;
3220 const int kll3Index = 1;
3221 *newConfig.add_kll_metric() = kll1;
3222 const int kll1Index = 2;
3223 *newConfig.add_kll_metric() = kll4;
3224 const int kll4Index = 3;
3225 *newConfig.add_kll_metric() = kll2;
3226 const int kll2Index = 4;
3227
3228 // Output data structures to validate.
3229 unordered_map<int64_t, int> newMetricProducerMap;
3230 vector<sp<MetricProducer>> newMetricProducers;
3231 unordered_map<int, vector<int>> conditionToMetricMap;
3232 unordered_map<int, vector<int>> trackerToMetricMap;
3233 set<int64_t> noReportMetricIds;
3234 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3235 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3236 vector<int> metricsWithActivation;
3237 set<int64_t> replacedMetrics;
3238 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
3239 EXPECT_EQ(updateMetrics(
3240 key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
3241 new StatsPullerManager(), oldAtomMatchingTrackerMap,
3242 newAtomMatchingTrackerMap, /*replacedMatchers=*/{}, newAtomMatchingTrackers,
3243 newConditionTrackerMap, replacedConditions, newConditionTrackers,
3244 conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
3245 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, provider,
3246 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
3247 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
3248 deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
3249 nullopt);
3250
3251 unordered_map<int64_t, int> expectedMetricProducerMap = {
3252 {kll1Id, kll1Index}, {kll2Id, kll2Index}, {kll3Id, kll3Index},
3253 {kll4Id, kll4Index}, {kll6Id, kll6Index},
3254 };
3255 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
3256 EXPECT_EQ(replacedMetrics, set<int64_t>({kll2Id, kll3Id}));
3257
3258 // Make sure preserved metrics are the same.
3259 ASSERT_EQ(newMetricProducers.size(), 5);
3260 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(kll1Id)],
3261 newMetricProducers[newMetricProducerMap.at(kll1Id)]);
3262 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(kll4Id)],
3263 newMetricProducers[newMetricProducerMap.at(kll4Id)]);
3264
3265 // Make sure replaced metrics are different.
3266 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(kll2Id)],
3267 newMetricProducers[newMetricProducerMap.at(kll2Id)]);
3268 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(kll3Id)],
3269 newMetricProducers[newMetricProducerMap.at(kll3Id)]);
3270
3271 // Verify the conditionToMetricMap.
3272 ASSERT_EQ(conditionToMetricMap.size(), 2);
3273 const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
3274 EXPECT_THAT(condition1Metrics, UnorderedElementsAre(kll1Index, kll6Index));
3275 const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
3276 EXPECT_THAT(condition2Metrics, UnorderedElementsAre(kll3Index));
3277
3278 // Verify the trackerToMetricMap.
3279 ASSERT_EQ(trackerToMetricMap.size(), 4);
3280 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
3281 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(kll2Index));
3282 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
3283 EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(kll4Index));
3284 const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
3285 EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(kll1Index));
3286 const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
3287 EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(kll3Index, kll6Index));
3288
3289 // Verify event activation/deactivation maps.
3290 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
3291 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
3292 ASSERT_EQ(metricsWithActivation.size(), 0);
3293
3294 // Verify tracker indices/ids/conditions are correct.
3295 KllMetricProducer* kllProducer1 =
3296 static_cast<KllMetricProducer*>(newMetricProducers[kll1Index].get());
3297 EXPECT_EQ(kllProducer1->getMetricId(), kll1Id);
3298 EXPECT_EQ(kllProducer1->mConditionTrackerIndex, predicate1Index);
3299 EXPECT_EQ(kllProducer1->mCondition, ConditionState::kUnknown);
3300 EXPECT_EQ(kllProducer1->mWhatMatcherIndex, matcher4Index);
3301 KllMetricProducer* kllProducer2 =
3302 static_cast<KllMetricProducer*>(newMetricProducers[kll2Index].get());
3303 EXPECT_EQ(kllProducer2->getMetricId(), kll2Id);
3304 EXPECT_EQ(kllProducer2->mConditionTrackerIndex, -1);
3305 EXPECT_EQ(kllProducer2->mCondition, ConditionState::kTrue);
3306 EXPECT_EQ(kllProducer2->mWhatMatcherIndex, matcher1Index);
3307 KllMetricProducer* kllProducer3 =
3308 static_cast<KllMetricProducer*>(newMetricProducers[kll3Index].get());
3309 EXPECT_EQ(kllProducer3->getMetricId(), kll3Id);
3310 EXPECT_EQ(kllProducer3->mConditionTrackerIndex, predicate2Index);
3311 EXPECT_EQ(kllProducer3->mCondition, ConditionState::kUnknown);
3312 EXPECT_EQ(kllProducer3->mWhatMatcherIndex, matcher5Index);
3313 KllMetricProducer* kllProducer4 =
3314 static_cast<KllMetricProducer*>(newMetricProducers[kll4Index].get());
3315 EXPECT_EQ(kllProducer4->getMetricId(), kll4Id);
3316 EXPECT_EQ(kllProducer4->mConditionTrackerIndex, -1);
3317 EXPECT_EQ(kllProducer4->mCondition, ConditionState::kTrue);
3318 EXPECT_EQ(kllProducer4->mWhatMatcherIndex, matcher3Index);
3319 KllMetricProducer* kllProducer6 =
3320 static_cast<KllMetricProducer*>(newMetricProducers[kll6Index].get());
3321 EXPECT_EQ(kllProducer6->getMetricId(), kll6Id);
3322 EXPECT_EQ(kllProducer6->mConditionTrackerIndex, predicate1Index);
3323 EXPECT_EQ(kllProducer6->mCondition, ConditionState::kUnknown);
3324 EXPECT_EQ(kllProducer6->mWhatMatcherIndex, matcher5Index);
3325
3326 oldMetricProducers.clear();
3327 }
3328
TEST_F(ConfigUpdateTest,TestUpdateMetricActivations)3329 TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) {
3330 StatsdConfig config;
3331 // Add atom matchers
3332 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
3333 int64_t matcher1Id = matcher1.id();
3334 *config.add_atom_matcher() = matcher1;
3335
3336 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
3337 int64_t matcher2Id = matcher2.id();
3338 *config.add_atom_matcher() = matcher2;
3339
3340 AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
3341 int64_t matcher3Id = matcher3.id();
3342 *config.add_atom_matcher() = matcher3;
3343
3344 AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
3345 int64_t matcher4Id = matcher4.id();
3346 *config.add_atom_matcher() = matcher4;
3347
3348 // Add an event metric with multiple activations.
3349 EventMetric event1 = createEventMetric("EVENT1", matcher1Id, nullopt);
3350 int64_t event1Id = event1.id();
3351 *config.add_event_metric() = event1;
3352
3353 int64_t matcher2TtlSec = 2, matcher3TtlSec = 3, matcher4TtlSec = 4;
3354 MetricActivation metricActivation;
3355 metricActivation.set_metric_id(event1Id);
3356 EventActivation* activation = metricActivation.add_event_activation();
3357 activation->set_atom_matcher_id(matcher2Id);
3358 activation->set_ttl_seconds(matcher2TtlSec);
3359 activation->set_activation_type(ACTIVATE_IMMEDIATELY);
3360 activation->set_deactivation_atom_matcher_id(matcher1Id);
3361 activation = metricActivation.add_event_activation();
3362 activation->set_atom_matcher_id(matcher3Id);
3363 activation->set_ttl_seconds(matcher3TtlSec);
3364 activation->set_activation_type(ACTIVATE_ON_BOOT);
3365 activation->set_deactivation_atom_matcher_id(matcher1Id);
3366 activation = metricActivation.add_event_activation();
3367 activation->set_atom_matcher_id(matcher4Id);
3368 activation->set_ttl_seconds(matcher4TtlSec);
3369 activation->set_activation_type(ACTIVATE_IMMEDIATELY);
3370 activation->set_deactivation_atom_matcher_id(matcher2Id);
3371 *config.add_metric_activation() = metricActivation;
3372
3373 EXPECT_TRUE(initConfig(config));
3374
3375 // Activate some of the event activations.
3376 ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
3377 int64_t matcher2StartNs = 12345;
3378 oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher2Id], matcher2StartNs);
3379 int64_t matcher3StartNs = 23456;
3380 oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher3Id], matcher3StartNs);
3381 EXPECT_TRUE(oldMetricProducers[0]->isActive());
3382
3383 // Map the matchers and predicates in reverse order to force the indices to change.
3384 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
3385 const int matcher4Index = 0;
3386 newAtomMatchingTrackerMap[matcher4Id] = 0;
3387 const int matcher3Index = 1;
3388 newAtomMatchingTrackerMap[matcher3Id] = 1;
3389 const int matcher2Index = 2;
3390 newAtomMatchingTrackerMap[matcher2Id] = 2;
3391 const int matcher1Index = 3;
3392 newAtomMatchingTrackerMap[matcher1Id] = 3;
3393 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
3394 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(4);
3395 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
3396 newAtomMatchingTrackers.begin());
3397 set<int64_t> replacedMatchers;
3398
3399 unordered_map<int64_t, int> newConditionTrackerMap;
3400 vector<sp<ConditionTracker>> newConditionTrackers;
3401 set<int64_t> replacedConditions;
3402 vector<ConditionState> conditionCache;
3403 unordered_map<int64_t, int> newMetricProducerMap;
3404 vector<sp<MetricProducer>> newMetricProducers;
3405 unordered_map<int, vector<int>> conditionToMetricMap;
3406 unordered_map<int, vector<int>> trackerToMetricMap;
3407 set<int64_t> noReportMetricIds;
3408 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3409 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3410 vector<int> metricsWithActivation;
3411 set<int64_t> replacedMetrics;
3412 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
3413 EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
3414 new StatsPullerManager(), oldAtomMatchingTrackerMap,
3415 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
3416 newConditionTrackerMap, replacedConditions, newConditionTrackers,
3417 conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
3418 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
3419 provider, newMetricProducerMap, newMetricProducers,
3420 conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
3421 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
3422 metricsWithActivation, replacedMetrics),
3423 nullopt);
3424
3425 // Verify event activation/deactivation maps.
3426 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 3);
3427 EXPECT_THAT(activationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
3428 EXPECT_THAT(activationAtomTrackerToMetricMap[matcher3Index], UnorderedElementsAre(0));
3429 EXPECT_THAT(activationAtomTrackerToMetricMap[matcher4Index], UnorderedElementsAre(0));
3430 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 2);
3431 EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher1Index], UnorderedElementsAre(0, 0));
3432 EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
3433 ASSERT_EQ(metricsWithActivation.size(), 1);
3434 EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(0));
3435
3436 // Verify mEventActivation and mEventDeactivation map of the producer.
3437 sp<MetricProducer> producer = newMetricProducers[0];
3438 EXPECT_TRUE(producer->isActive());
3439 ASSERT_EQ(producer->mEventActivationMap.size(), 3);
3440 shared_ptr<Activation> matcher2Activation = producer->mEventActivationMap[matcher2Index];
3441 EXPECT_EQ(matcher2Activation->ttl_ns, matcher2TtlSec * NS_PER_SEC);
3442 EXPECT_EQ(matcher2Activation->activationType, ACTIVATE_IMMEDIATELY);
3443 EXPECT_EQ(matcher2Activation->state, kActive);
3444 EXPECT_EQ(matcher2Activation->start_ns, matcher2StartNs);
3445 shared_ptr<Activation> matcher3Activation = producer->mEventActivationMap[matcher3Index];
3446 EXPECT_EQ(matcher3Activation->ttl_ns, matcher3TtlSec * NS_PER_SEC);
3447 EXPECT_EQ(matcher3Activation->activationType, ACTIVATE_ON_BOOT);
3448 EXPECT_EQ(matcher3Activation->state, kActiveOnBoot);
3449 shared_ptr<Activation> matcher4Activation = producer->mEventActivationMap[matcher4Index];
3450 EXPECT_EQ(matcher4Activation->ttl_ns, matcher4TtlSec * NS_PER_SEC);
3451 EXPECT_EQ(matcher4Activation->activationType, ACTIVATE_IMMEDIATELY);
3452 EXPECT_EQ(matcher4Activation->state, kNotActive);
3453
3454 ASSERT_EQ(producer->mEventDeactivationMap.size(), 2);
3455 EXPECT_THAT(producer->mEventDeactivationMap[matcher1Index],
3456 UnorderedElementsAre(matcher2Activation, matcher3Activation));
3457 EXPECT_THAT(producer->mEventDeactivationMap[matcher2Index],
3458 UnorderedElementsAre(matcher4Activation));
3459 }
3460
TEST_F(ConfigUpdateTest,TestUpdateMetricsMultipleTypes)3461 TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) {
3462 StatsdConfig config;
3463 // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig
3464 AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
3465 int64_t matcher1Id = matcher1.id();
3466 *config.add_atom_matcher() = matcher1;
3467
3468 AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
3469 int64_t matcher2Id = matcher2.id();
3470 *config.add_atom_matcher() = matcher2;
3471
3472 AtomMatcher matcher3 = CreateTemperatureAtomMatcher();
3473 int64_t matcher3Id = matcher3.id();
3474 *config.add_atom_matcher() = matcher3;
3475
3476 Predicate predicate1 = CreateScreenIsOnPredicate();
3477 int64_t predicate1Id = predicate1.id();
3478 *config.add_predicate() = predicate1;
3479
3480 // Add a few count metrics.
3481 // Will be preserved.
3482 CountMetric countMetric = createCountMetric("COUNT1", matcher1Id, predicate1Id, {});
3483 int64_t countMetricId = countMetric.id();
3484 *config.add_count_metric() = countMetric;
3485
3486 // Will be replaced since matcher2 is replaced.
3487 EventMetric eventMetric = createEventMetric("EVENT1", matcher2Id, nullopt);
3488 int64_t eventMetricId = eventMetric.id();
3489 *config.add_event_metric() = eventMetric;
3490
3491 // Will be replaced because the definition changes - a predicate is added.
3492 GaugeMetric gaugeMetric = createGaugeMetric("GAUGE1", matcher3Id,
3493 GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
3494 int64_t gaugeMetricId = gaugeMetric.id();
3495 *config.add_gauge_metric() = gaugeMetric;
3496
3497 // Preserved.
3498 ValueMetric valueMetric = createValueMetric("VALUE1", matcher3, 2, predicate1Id, {});
3499 int64_t valueMetricId = valueMetric.id();
3500 *config.add_value_metric() = valueMetric;
3501
3502 // Preserved.
3503 DurationMetric durationMetric = createDurationMetric("DURATION1", predicate1Id, nullopt, {});
3504 int64_t durationMetricId = durationMetric.id();
3505 *config.add_duration_metric() = durationMetric;
3506
3507 // Preserved.
3508 KllMetric kllMetric = createKllMetric("KLL1", matcher3, /*valueField=*/2, predicate1Id);
3509 int64_t kllMetricId = kllMetric.id();
3510 *config.add_kll_metric() = kllMetric;
3511
3512 EXPECT_TRUE(initConfig(config));
3513
3514 // Used later to ensure the condition wizard is replaced. Get it before doing the update.
3515 sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
3516 EXPECT_EQ(oldConditionWizard->getStrongCount(), 7);
3517
3518 // Mark matcher 2 as replaced. Causes eventMetric to be replaced.
3519 set<int64_t> replacedMatchers;
3520 replacedMatchers.insert(matcher2Id);
3521
3522 // Add predicate1 as a predicate on gaugeMetric, causing it to be replaced.
3523 gaugeMetric.set_condition(predicate1Id);
3524
3525 // Map the matchers and predicates in reverse order to force the indices to change.
3526 std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
3527 const int matcher3Index = 0;
3528 newAtomMatchingTrackerMap[matcher3Id] = 0;
3529 const int matcher2Index = 1;
3530 newAtomMatchingTrackerMap[matcher2Id] = 1;
3531 const int matcher1Index = 2;
3532 newAtomMatchingTrackerMap[matcher1Id] = 2;
3533 // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
3534 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(3);
3535 std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
3536 newAtomMatchingTrackers.begin());
3537
3538 std::unordered_map<int64_t, int> newConditionTrackerMap;
3539 const int predicate1Index = 0;
3540 newConditionTrackerMap[predicate1Id] = 0;
3541 // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
3542 vector<sp<ConditionTracker>> newConditionTrackers(1);
3543 std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
3544 newConditionTrackers.begin());
3545 vector<ConditionState> conditionCache = {ConditionState::kUnknown};
3546
3547 // The order matters. we parse in the order of: count, duration, event, value, gauge.
3548 StatsdConfig newConfig;
3549 *newConfig.add_count_metric() = countMetric;
3550 const int countMetricIndex = 0;
3551 *newConfig.add_duration_metric() = durationMetric;
3552 const int durationMetricIndex = 1;
3553 *newConfig.add_event_metric() = eventMetric;
3554 const int eventMetricIndex = 2;
3555 *newConfig.add_value_metric() = valueMetric;
3556 const int valueMetricIndex = 3;
3557 *newConfig.add_gauge_metric() = gaugeMetric;
3558 const int gaugeMetricIndex = 4;
3559 *newConfig.add_kll_metric() = kllMetric;
3560 const int kllMetricIndex = 5;
3561
3562 // Add the predicate since duration metric needs it.
3563 *newConfig.add_predicate() = predicate1;
3564
3565 // Output data structures to validate.
3566 unordered_map<int64_t, int> newMetricProducerMap;
3567 vector<sp<MetricProducer>> newMetricProducers;
3568 unordered_map<int, vector<int>> conditionToMetricMap;
3569 unordered_map<int, vector<int>> trackerToMetricMap;
3570 set<int64_t> noReportMetricIds;
3571 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3572 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3573 vector<int> metricsWithActivation;
3574 set<int64_t> replacedMetrics;
3575 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
3576 EXPECT_EQ(updateMetrics(key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
3577 new StatsPullerManager(), oldAtomMatchingTrackerMap,
3578 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
3579 newConditionTrackerMap, /*replacedConditions=*/{}, newConditionTrackers,
3580 conditionCache, /*stateAtomIdMap*/ {}, /*allStateGroupMaps=*/{},
3581 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers,
3582 provider, newMetricProducerMap, newMetricProducers,
3583 conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
3584 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
3585 metricsWithActivation, replacedMetrics),
3586 nullopt);
3587
3588 unordered_map<int64_t, int> expectedMetricProducerMap = {
3589 {countMetricId, countMetricIndex}, {durationMetricId, durationMetricIndex},
3590 {eventMetricId, eventMetricIndex}, {valueMetricId, valueMetricIndex},
3591 {gaugeMetricId, gaugeMetricIndex}, {kllMetricId, kllMetricIndex}};
3592 EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
3593
3594 EXPECT_EQ(replacedMetrics, set<int64_t>({eventMetricId, gaugeMetricId}));
3595
3596 // Make sure preserved metrics are the same.
3597 ASSERT_EQ(newMetricProducers.size(), 6);
3598 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(countMetricId)],
3599 newMetricProducers[newMetricProducerMap.at(countMetricId)]);
3600 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(durationMetricId)],
3601 newMetricProducers[newMetricProducerMap.at(durationMetricId)]);
3602 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(valueMetricId)],
3603 newMetricProducers[newMetricProducerMap.at(valueMetricId)]);
3604 EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(kllMetricId)],
3605 newMetricProducers[newMetricProducerMap.at(kllMetricId)]);
3606
3607 // Make sure replaced metrics are different.
3608 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(eventMetricId)],
3609 newMetricProducers[newMetricProducerMap.at(eventMetricId)]);
3610 EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gaugeMetricId)],
3611 newMetricProducers[newMetricProducerMap.at(gaugeMetricId)]);
3612
3613 // Verify the conditionToMetricMap.
3614 ASSERT_EQ(conditionToMetricMap.size(), 1);
3615 const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
3616 EXPECT_THAT(condition1Metrics, UnorderedElementsAre(countMetricIndex, gaugeMetricIndex,
3617 valueMetricIndex, kllMetricIndex));
3618
3619 // Verify the trackerToMetricMap.
3620 ASSERT_EQ(trackerToMetricMap.size(), 3);
3621 const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
3622 EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(countMetricIndex, durationMetricIndex));
3623 const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
3624 EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(eventMetricIndex, durationMetricIndex));
3625 const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
3626 EXPECT_THAT(matcher3Metrics,
3627 UnorderedElementsAre(gaugeMetricIndex, valueMetricIndex, kllMetricIndex));
3628
3629 // Verify event activation/deactivation maps.
3630 ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
3631 ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
3632 ASSERT_EQ(metricsWithActivation.size(), 0);
3633
3634 // Verify tracker indices/ids/conditions are correct.
3635 EXPECT_EQ(newMetricProducers[countMetricIndex]->getMetricId(), countMetricId);
3636 EXPECT_EQ(newMetricProducers[countMetricIndex]->mConditionTrackerIndex, predicate1Index);
3637 EXPECT_EQ(newMetricProducers[countMetricIndex]->mCondition, ConditionState::kUnknown);
3638 EXPECT_EQ(newMetricProducers[durationMetricIndex]->getMetricId(), durationMetricId);
3639 EXPECT_EQ(newMetricProducers[durationMetricIndex]->mConditionTrackerIndex, -1);
3640 EXPECT_EQ(newMetricProducers[durationMetricIndex]->mCondition, ConditionState::kTrue);
3641 EXPECT_EQ(newMetricProducers[eventMetricIndex]->getMetricId(), eventMetricId);
3642 EXPECT_EQ(newMetricProducers[eventMetricIndex]->mConditionTrackerIndex, -1);
3643 EXPECT_EQ(newMetricProducers[eventMetricIndex]->mCondition, ConditionState::kTrue);
3644 EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->getMetricId(), gaugeMetricId);
3645 EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mConditionTrackerIndex, predicate1Index);
3646 EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mCondition, ConditionState::kUnknown);
3647 EXPECT_EQ(newMetricProducers[kllMetricIndex]->getMetricId(), kllMetricId);
3648 EXPECT_EQ(newMetricProducers[kllMetricIndex]->mConditionTrackerIndex, predicate1Index);
3649 EXPECT_EQ(newMetricProducers[kllMetricIndex]->mCondition, ConditionState::kUnknown);
3650
3651 sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
3652 EXPECT_NE(newConditionWizard, oldConditionWizard);
3653 EXPECT_EQ(newConditionWizard->getStrongCount(), 7);
3654 oldMetricProducers.clear();
3655 // Only reference to the old wizard should be the one in the test.
3656 EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
3657 }
3658
TEST_F(ConfigUpdateTest,TestAlertPreserve)3659 TEST_F(ConfigUpdateTest, TestAlertPreserve) {
3660 StatsdConfig config;
3661 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
3662 *config.add_atom_matcher() = whatMatcher;
3663
3664 *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
3665
3666 Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
3667 *config.add_alert() = alert;
3668 EXPECT_TRUE(initConfig(config));
3669
3670 UpdateStatus updateStatus = UPDATE_UNKNOWN;
3671 EXPECT_EQ(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
3672 /*replacedMetrics*/ {}, updateStatus),
3673 nullopt);
3674 EXPECT_EQ(updateStatus, UPDATE_PRESERVE);
3675 }
3676
TEST_F(ConfigUpdateTest,TestAlertMetricChanged)3677 TEST_F(ConfigUpdateTest, TestAlertMetricChanged) {
3678 StatsdConfig config;
3679 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
3680 *config.add_atom_matcher() = whatMatcher;
3681
3682 CountMetric metric = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
3683 *config.add_count_metric() = metric;
3684
3685 Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
3686 *config.add_alert() = alert;
3687 EXPECT_TRUE(initConfig(config));
3688
3689 UpdateStatus updateStatus = UPDATE_UNKNOWN;
3690 EXPECT_EQ(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
3691 /*replacedMetrics*/ {metric.id()}, updateStatus),
3692 nullopt);
3693 EXPECT_EQ(updateStatus, UPDATE_REPLACE);
3694 }
3695
TEST_F(ConfigUpdateTest,TestAlertDefinitionChanged)3696 TEST_F(ConfigUpdateTest, TestAlertDefinitionChanged) {
3697 StatsdConfig config;
3698 AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
3699 *config.add_atom_matcher() = whatMatcher;
3700
3701 *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
3702
3703 Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
3704 *config.add_alert() = alert;
3705 EXPECT_TRUE(initConfig(config));
3706
3707 alert.set_num_buckets(2);
3708
3709 UpdateStatus updateStatus = UPDATE_UNKNOWN;
3710 EXPECT_EQ(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
3711 /*replacedMetrics*/ {}, updateStatus),
3712 nullopt);
3713 EXPECT_EQ(updateStatus, UPDATE_REPLACE);
3714 }
3715
TEST_F(ConfigUpdateTest,TestUpdateAlerts)3716 TEST_F(ConfigUpdateTest, TestUpdateAlerts) {
3717 StatsdConfig config;
3718 // Add atom matchers/predicates/metrics. These are mostly needed for initStatsdConfig
3719 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
3720 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
3721 *config.add_predicate() = CreateScreenIsOnPredicate();
3722
3723 CountMetric countMetric = createCountMetric("COUNT1", config.atom_matcher(0).id(), nullopt, {});
3724 int64_t countMetricId = countMetric.id();
3725 *config.add_count_metric() = countMetric;
3726
3727 DurationMetric durationMetric =
3728 createDurationMetric("DURATION1", config.predicate(0).id(), nullopt, {});
3729 int64_t durationMetricId = durationMetric.id();
3730 *config.add_duration_metric() = durationMetric;
3731
3732 // Add alerts.
3733 // Preserved.
3734 Alert alert1 = createAlert("Alert1", durationMetricId, /*buckets*/ 1, /*triggerSum*/ 5000);
3735 int64_t alert1Id = alert1.id();
3736 *config.add_alert() = alert1;
3737
3738 // Replaced.
3739 Alert alert2 = createAlert("Alert2", countMetricId, /*buckets*/ 1, /*triggerSum*/ 2);
3740 int64_t alert2Id = alert2.id();
3741 *config.add_alert() = alert2;
3742
3743 // Replaced.
3744 Alert alert3 = createAlert("Alert3", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 5000);
3745 int64_t alert3Id = alert3.id();
3746 *config.add_alert() = alert3;
3747
3748 // Add Subscriptions.
3749 Subscription subscription1 = createSubscription("S1", Subscription::ALERT, alert1Id);
3750 *config.add_subscription() = subscription1;
3751 Subscription subscription2 = createSubscription("S2", Subscription::ALERT, alert1Id);
3752 *config.add_subscription() = subscription2;
3753 Subscription subscription3 = createSubscription("S3", Subscription::ALERT, alert2Id);
3754 *config.add_subscription() = subscription3;
3755
3756 EXPECT_TRUE(initConfig(config));
3757
3758 // Add a duration tracker to the duration metric to ensure durationTrackers are updated
3759 // with the proper anomalyTrackers.
3760 unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
3761 timeBaseNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
3762 oldMetricProducers[1]->onMatchedLogEvent(0, *event.get());
3763
3764 // Change the count metric. Causes alert2 to be replaced.
3765 config.mutable_count_metric(0)->set_bucket(ONE_DAY);
3766 // Change num buckets on alert3, causing replacement.
3767 alert3.set_num_buckets(5);
3768
3769 // New alert.
3770 Alert alert4 = createAlert("Alert4", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 10000);
3771 int64_t alert4Id = alert4.id();
3772
3773 // Move subscription2 to be on alert2 and make a new subscription.
3774 subscription2.set_rule_id(alert2Id);
3775 Subscription subscription4 = createSubscription("S4", Subscription::ALERT, alert2Id);
3776
3777 // Create the new config. Modify the old one to avoid adding the matchers/predicates.
3778 // Add alerts in different order so the map is changed.
3779 config.clear_alert();
3780 *config.add_alert() = alert4;
3781 const int alert4Index = 0;
3782 *config.add_alert() = alert3;
3783 const int alert3Index = 1;
3784 *config.add_alert() = alert1;
3785 const int alert1Index = 2;
3786 *config.add_alert() = alert2;
3787 const int alert2Index = 3;
3788
3789 // Subscription3 is removed.
3790 config.clear_subscription();
3791 *config.add_subscription() = subscription4;
3792 *config.add_subscription() = subscription2;
3793 *config.add_subscription() = subscription1;
3794
3795 // Output data structures from update metrics. Don't care about the outputs besides
3796 // replacedMetrics, but need to do this so that the metrics clear their anomaly trackers.
3797 unordered_map<int64_t, int> newMetricProducerMap;
3798 vector<sp<MetricProducer>> newMetricProducers;
3799 unordered_map<int, vector<int>> conditionToMetricMap;
3800 unordered_map<int, vector<int>> trackerToMetricMap;
3801 set<int64_t> noReportMetricIds;
3802 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3803 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3804 vector<int> metricsWithActivation;
3805 set<int64_t> replacedMetrics;
3806 int64_t currentTimeNs = 12345;
3807 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
3808 EXPECT_EQ(updateMetrics(
3809 key, config, /*timeBaseNs=*/123, currentTimeNs, new StatsPullerManager(),
3810 oldAtomMatchingTrackerMap, oldAtomMatchingTrackerMap, /*replacedMatchers*/ {},
3811 oldAtomMatchingTrackers, oldConditionTrackerMap, /*replacedConditions=*/{},
3812 oldConditionTrackers, {ConditionState::kUnknown}, /*stateAtomIdMap*/ {},
3813 /*allStateGroupMaps=*/{},
3814 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, provider,
3815 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
3816 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
3817 deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
3818 nullopt);
3819
3820 EXPECT_EQ(replacedMetrics, set<int64_t>({countMetricId}));
3821
3822 unordered_map<int64_t, int> newAlertTrackerMap;
3823 vector<sp<AnomalyTracker>> newAnomalyTrackers;
3824 EXPECT_EQ(updateAlerts(config, currentTimeNs, newMetricProducerMap, replacedMetrics,
3825 oldAlertTrackerMap, oldAnomalyTrackers, anomalyAlarmMonitor,
3826 newMetricProducers, newAlertTrackerMap, newAnomalyTrackers),
3827 nullopt);
3828
3829 unordered_map<int64_t, int> expectedAlertMap = {
3830 {alert1Id, alert1Index},
3831 {alert2Id, alert2Index},
3832 {alert3Id, alert3Index},
3833 {alert4Id, alert4Index},
3834 };
3835 EXPECT_THAT(newAlertTrackerMap, ContainerEq(expectedAlertMap));
3836
3837 // Make sure preserved alerts are the same.
3838 ASSERT_EQ(newAnomalyTrackers.size(), 4);
3839 EXPECT_EQ(oldAnomalyTrackers[oldAlertTrackerMap.at(alert1Id)],
3840 newAnomalyTrackers[newAlertTrackerMap.at(alert1Id)]);
3841
3842 // Make sure replaced alerts are different.
3843 EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert2Id)],
3844 newAnomalyTrackers[newAlertTrackerMap.at(alert2Id)]);
3845 EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert3Id)],
3846 newAnomalyTrackers[newAlertTrackerMap.at(alert3Id)]);
3847
3848 // Verify the alerts have the correct anomaly trackers.
3849 ASSERT_EQ(newMetricProducers.size(), 2);
3850 EXPECT_THAT(newMetricProducers[0]->mAnomalyTrackers,
3851 UnorderedElementsAre(newAnomalyTrackers[alert2Index]));
3852 // For durationMetric, make sure the duration trackers get the updated anomalyTrackers.
3853 DurationMetricProducer* durationProducer =
3854 static_cast<DurationMetricProducer*>(newMetricProducers[1].get());
3855 EXPECT_THAT(
3856 durationProducer->mAnomalyTrackers,
3857 UnorderedElementsAre(newAnomalyTrackers[alert1Index], newAnomalyTrackers[alert3Index],
3858 newAnomalyTrackers[alert4Index]));
3859 ASSERT_EQ(durationProducer->mCurrentSlicedDurationTrackerMap.size(), 1);
3860 for (const auto& durationTrackerIt : durationProducer->mCurrentSlicedDurationTrackerMap) {
3861 EXPECT_EQ(durationTrackerIt.second->mAnomalyTrackers, durationProducer->mAnomalyTrackers);
3862 }
3863
3864 // Verify alerts have the correct subscriptions. Use subscription id as proxy for equivalency.
3865 vector<int64_t> alert1Subscriptions;
3866 for (const Subscription& subscription : newAnomalyTrackers[alert1Index]->mSubscriptions) {
3867 alert1Subscriptions.push_back(subscription.id());
3868 }
3869 EXPECT_THAT(alert1Subscriptions, UnorderedElementsAre(subscription1.id()));
3870 vector<int64_t> alert2Subscriptions;
3871 for (const Subscription& subscription : newAnomalyTrackers[alert2Index]->mSubscriptions) {
3872 alert2Subscriptions.push_back(subscription.id());
3873 }
3874 EXPECT_THAT(alert2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription4.id()));
3875 EXPECT_THAT(newAnomalyTrackers[alert3Index]->mSubscriptions, IsEmpty());
3876 EXPECT_THAT(newAnomalyTrackers[alert4Index]->mSubscriptions, IsEmpty());
3877 }
3878
TEST_F(ConfigUpdateTest,TestUpdateAlarms)3879 TEST_F(ConfigUpdateTest, TestUpdateAlarms) {
3880 StatsdConfig config;
3881 // Add alarms.
3882 Alarm alarm1 = createAlarm("Alarm1", /*offset*/ 1 * MS_PER_SEC, /*period*/ 50 * MS_PER_SEC);
3883 int64_t alarm1Id = alarm1.id();
3884 *config.add_alarm() = alarm1;
3885
3886 Alarm alarm2 = createAlarm("Alarm2", /*offset*/ 1 * MS_PER_SEC, /*period*/ 2000 * MS_PER_SEC);
3887 int64_t alarm2Id = alarm2.id();
3888 *config.add_alarm() = alarm2;
3889
3890 Alarm alarm3 = createAlarm("Alarm3", /*offset*/ 10 * MS_PER_SEC, /*period*/ 5000 * MS_PER_SEC);
3891 int64_t alarm3Id = alarm3.id();
3892 *config.add_alarm() = alarm3;
3893
3894 // Add Subscriptions.
3895 Subscription subscription1 = createSubscription("S1", Subscription::ALARM, alarm1Id);
3896 *config.add_subscription() = subscription1;
3897 Subscription subscription2 = createSubscription("S2", Subscription::ALARM, alarm1Id);
3898 *config.add_subscription() = subscription2;
3899 Subscription subscription3 = createSubscription("S3", Subscription::ALARM, alarm2Id);
3900 *config.add_subscription() = subscription3;
3901
3902 EXPECT_TRUE(initConfig(config));
3903
3904 ASSERT_EQ(oldAlarmTrackers.size(), 3);
3905 // Config is created at statsd start time, so just add the offsets.
3906 EXPECT_EQ(oldAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
3907 EXPECT_EQ(oldAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
3908 EXPECT_EQ(oldAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
3909
3910 // Change alarm2/alarm3.
3911 config.mutable_alarm(1)->set_offset_millis(5 * MS_PER_SEC);
3912 config.mutable_alarm(2)->set_period_millis(10000 * MS_PER_SEC);
3913
3914 // Move subscription2 to be on alarm2 and make a new subscription.
3915 config.mutable_subscription(1)->set_rule_id(alarm2Id);
3916 Subscription subscription4 = createSubscription("S4", Subscription::ALARM, alarm1Id);
3917 *config.add_subscription() = subscription4;
3918
3919 // Update time is 2 seconds after the base time.
3920 int64_t currentTimeNs = timeBaseNs + 2 * NS_PER_SEC;
3921 vector<sp<AlarmTracker>> newAlarmTrackers;
3922 EXPECT_EQ(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
3923 newAlarmTrackers),
3924 nullopt);
3925
3926 ASSERT_EQ(newAlarmTrackers.size(), 3);
3927 // Config is updated 2 seconds after statsd start
3928 // The offset has passed for alarm1, but not for alarms 2/3.
3929 EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 50);
3930 EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5);
3931 EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
3932
3933 // Verify alarms have the correct subscriptions. Use subscription id as proxy for equivalency.
3934 vector<int64_t> alarm1Subscriptions;
3935 for (const Subscription& subscription : newAlarmTrackers[0]->mSubscriptions) {
3936 alarm1Subscriptions.push_back(subscription.id());
3937 }
3938 EXPECT_THAT(alarm1Subscriptions, UnorderedElementsAre(subscription1.id(), subscription4.id()));
3939 vector<int64_t> alarm2Subscriptions;
3940 for (const Subscription& subscription : newAlarmTrackers[1]->mSubscriptions) {
3941 alarm2Subscriptions.push_back(subscription.id());
3942 }
3943 EXPECT_THAT(alarm2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription3.id()));
3944 EXPECT_THAT(newAlarmTrackers[2]->mSubscriptions, IsEmpty());
3945
3946 // Verify the alarm monitor is updated accordingly once the old alarms are removed.
3947 // Alarm2 fires the earliest.
3948 oldAlarmTrackers.clear();
3949 EXPECT_EQ(periodicAlarmMonitor->getRegisteredAlarmTimeSec(), timeBaseNs / NS_PER_SEC + 5);
3950
3951 // Do another update 60 seconds after config creation time, after the offsets of each alarm.
3952 currentTimeNs = timeBaseNs + 60 * NS_PER_SEC;
3953 newAlarmTrackers.clear();
3954 EXPECT_EQ(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
3955 newAlarmTrackers),
3956 nullopt);
3957
3958 ASSERT_EQ(newAlarmTrackers.size(), 3);
3959 // Config is updated one minute after statsd start.
3960 // Two periods have passed for alarm 1, one has passed for alarms2/3.
3961 EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 2 * 50);
3962 EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5 + 2000);
3963 EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10 + 10000);
3964 }
3965
TEST_F(ConfigUpdateTest,TestMetricHasMultipleActivations)3966 TEST_F(ConfigUpdateTest, TestMetricHasMultipleActivations) {
3967 StatsdConfig config;
3968 int64_t metricId = 1;
3969 auto metric_activation1 = config.add_metric_activation();
3970 metric_activation1->set_metric_id(metricId);
3971 metric_activation1->set_activation_type(ACTIVATE_IMMEDIATELY);
3972 EXPECT_TRUE(initConfig(config));
3973
3974 auto metric_activation2 = config.add_metric_activation();
3975 metric_activation2->set_metric_id(metricId);
3976 metric_activation2->set_activation_type(ACTIVATE_IMMEDIATELY);
3977
3978 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
3979 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
3980 unordered_map<int64_t, int> newConditionTrackerMap;
3981 unordered_map<int64_t, int> newMetricProducerMap;
3982 unordered_map<int64_t, int> stateAtomIdMap;
3983 unordered_map<int, vector<int>> conditionToMetricMap;
3984 unordered_map<int, vector<int>> trackerToMetricMap;
3985 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3986 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3987 set<int64_t> noReportMetricIds;
3988 vector<int> metricsWithActivation;
3989 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
3990 vector<sp<ConditionTracker>> newConditionTrackers;
3991 vector<sp<MetricProducer>> newMetricProducers;
3992 vector<ConditionState> conditionCache;
3993 set<int64_t> replacedMetrics;
3994 set<int64_t> replacedMatchers;
3995 set<int64_t> replacedConditions;
3996 set<int64_t> replacedStates;
3997 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
3998 EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
3999 new StatsPullerManager(), oldAtomMatchingTrackerMap,
4000 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
4001 newConditionTrackerMap, replacedConditions, newConditionTrackers,
4002 conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
4003 oldMetricProducerMap, oldMetricProducers, provider,
4004 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
4005 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
4006 deactivationAtomTrackerToMetricMap, metricsWithActivation,
4007 replacedMetrics),
4008 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS, metricId));
4009 }
4010
TEST_F(ConfigUpdateTest,TestNoReportMetricNotFound)4011 TEST_F(ConfigUpdateTest, TestNoReportMetricNotFound) {
4012 StatsdConfig config;
4013 int64_t metricId = 1;
4014 config.add_no_report_metric(metricId);
4015
4016 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
4017 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
4018 unordered_map<int64_t, int> newConditionTrackerMap;
4019 unordered_map<int64_t, int> newMetricProducerMap;
4020 unordered_map<int64_t, int> stateAtomIdMap;
4021 unordered_map<int, vector<int>> conditionToMetricMap;
4022 unordered_map<int, vector<int>> trackerToMetricMap;
4023 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
4024 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
4025 set<int64_t> noReportMetricIds;
4026 vector<int> metricsWithActivation;
4027 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
4028 vector<sp<ConditionTracker>> newConditionTrackers;
4029 vector<sp<MetricProducer>> newMetricProducers;
4030 vector<ConditionState> conditionCache;
4031 set<int64_t> replacedMetrics;
4032 set<int64_t> replacedMatchers;
4033 set<int64_t> replacedConditions;
4034 set<int64_t> replacedStates;
4035 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
4036 EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
4037 new StatsPullerManager(), oldAtomMatchingTrackerMap,
4038 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
4039 newConditionTrackerMap, replacedConditions, newConditionTrackers,
4040 conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
4041 oldMetricProducerMap, oldMetricProducers, provider,
4042 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
4043 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
4044 deactivationAtomTrackerToMetricMap, metricsWithActivation,
4045 replacedMetrics),
4046 InvalidConfigReason(INVALID_CONFIG_REASON_NO_REPORT_METRIC_NOT_FOUND, metricId));
4047 }
4048
TEST_F(ConfigUpdateTest,TestMetricSlicedStateAtomAllowedFromAnyUid)4049 TEST_F(ConfigUpdateTest, TestMetricSlicedStateAtomAllowedFromAnyUid) {
4050 StatsdConfig config;
4051 CountMetric* metric = config.add_count_metric();
4052 *metric = createCountMetric(/*name=*/"Count", /*what=*/StringToId("ScreenTurnedOn"),
4053 /*condition=*/nullopt, /*states=*/{});
4054 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
4055 *config.add_state() = CreateScreenState();
4056 metric->add_slice_by_state(StringToId("ScreenState"));
4057 EXPECT_TRUE(initConfig(config));
4058
4059 config.add_whitelisted_atom_ids(util::SCREEN_STATE_CHANGED);
4060
4061 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
4062 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
4063 unordered_map<int64_t, int> newConditionTrackerMap;
4064 unordered_map<int64_t, int> newMetricProducerMap;
4065 unordered_map<int64_t, int> stateAtomIdMap;
4066 unordered_map<int, vector<int>> conditionToMetricMap;
4067 unordered_map<int, vector<int>> trackerToMetricMap;
4068 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
4069 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
4070 set<int64_t> noReportMetricIds;
4071 vector<int> metricsWithActivation;
4072 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
4073 vector<sp<ConditionTracker>> newConditionTrackers;
4074 vector<sp<MetricProducer>> newMetricProducers;
4075 vector<ConditionState> conditionCache;
4076 set<int64_t> replacedMetrics;
4077 set<int64_t> replacedMatchers;
4078 set<int64_t> replacedConditions;
4079 set<int64_t> replacedStates;
4080 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
4081
4082 newAtomMatchingTrackerMap[StringToId("ScreenTurnedOn")] = 0;
4083 stateAtomIdMap[StringToId("ScreenState")] = util::SCREEN_STATE_CHANGED;
4084 EXPECT_EQ(
4085 updateMetrics(
4086 key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
4087 new StatsPullerManager(), oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap,
4088 replacedMatchers, newAtomMatchingTrackers, newConditionTrackerMap,
4089 replacedConditions, newConditionTrackers, conditionCache, stateAtomIdMap,
4090 allStateGroupMaps, replacedStates, oldMetricProducerMap, oldMetricProducers,
4091 provider, newMetricProducerMap, newMetricProducers, conditionToMetricMap,
4092 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
4093 deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
4094 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
4095 StringToId("Count")));
4096 }
4097
TEST_F(ConfigUpdateTest,TestMatcherDuplicate)4098 TEST_F(ConfigUpdateTest, TestMatcherDuplicate) {
4099 StatsdConfig config;
4100 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
4101 EXPECT_TRUE(initConfig(config));
4102
4103 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
4104
4105 unordered_map<int, vector<int>> newTagIds;
4106 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
4107 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
4108 set<int64_t> replacedMatchers;
4109 EXPECT_EQ(updateAtomMatchingTrackers(
4110 config, uidMap, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers, newTagIds,
4111 newAtomMatchingTrackerMap, newAtomMatchingTrackers, replacedMatchers),
4112 createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_DUPLICATE,
4113 StringToId("ScreenTurnedOn")));
4114 }
4115
TEST_F(ConfigUpdateTest,TestConditionDuplicate)4116 TEST_F(ConfigUpdateTest, TestConditionDuplicate) {
4117 StatsdConfig config;
4118 *config.add_predicate() = CreateScreenIsOnPredicate();
4119 EXPECT_TRUE(initConfig(config));
4120
4121 *config.add_predicate() = CreateScreenIsOnPredicate();
4122
4123 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
4124 unordered_map<int64_t, int> newConditionTrackerMap;
4125 vector<sp<ConditionTracker>> newConditionTrackers;
4126 unordered_map<int, vector<int>> trackerToConditionMap;
4127 vector<ConditionState> conditionCache;
4128 set<int64_t> replacedConditions;
4129 set<int64_t> replacedMatchers;
4130 EXPECT_EQ(updateConditions(key, config, newAtomMatchingTrackerMap, replacedMatchers,
4131 oldConditionTrackerMap, oldConditionTrackers, newConditionTrackerMap,
4132 newConditionTrackers, trackerToConditionMap, conditionCache,
4133 replacedConditions),
4134 createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_DUPLICATE,
4135 StringToId("ScreenIsOn")));
4136 }
4137
TEST_F(ConfigUpdateTest,TestUpdateConfigNonEventMetricHasRestrictedDelegate)4138 TEST_F(ConfigUpdateTest, TestUpdateConfigNonEventMetricHasRestrictedDelegate) {
4139 StatsdConfig config;
4140 CountMetric* metric = config.add_count_metric();
4141 config.set_restricted_metrics_delegate_package_name("com.android.app.test");
4142
4143 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
4144 unordered_map<int64_t, int> newAtomMatchingTrackerMap;
4145 unordered_map<int64_t, int> newConditionTrackerMap;
4146 unordered_map<int64_t, int> newMetricProducerMap;
4147 unordered_map<int64_t, int> stateAtomIdMap;
4148 unordered_map<int, vector<int>> conditionToMetricMap;
4149 unordered_map<int, vector<int>> trackerToMetricMap;
4150 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
4151 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
4152 set<int64_t> noReportMetricIds;
4153 vector<int> metricsWithActivation;
4154 vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
4155 vector<sp<ConditionTracker>> newConditionTrackers;
4156 vector<sp<MetricProducer>> newMetricProducers;
4157 vector<ConditionState> conditionCache;
4158 set<int64_t> replacedMetrics;
4159 set<int64_t> replacedMatchers;
4160 set<int64_t> replacedConditions;
4161 set<int64_t> replacedStates;
4162 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
4163
4164 EXPECT_EQ(updateMetrics(key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
4165 new StatsPullerManager(), oldAtomMatchingTrackerMap,
4166 newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
4167 newConditionTrackerMap, replacedConditions, newConditionTrackers,
4168 conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
4169 oldMetricProducerMap, oldMetricProducers, provider,
4170 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
4171 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
4172 deactivationAtomTrackerToMetricMap, metricsWithActivation,
4173 replacedMetrics),
4174 InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED));
4175 }
4176
TEST_P(ConfigUpdateDimLimitTest,TestDimLimit)4177 TEST_P(ConfigUpdateDimLimitTest, TestDimLimit) {
4178 StatsdConfig config = buildGoodConfig(configId);
4179 const auto& [oldLimit, newLimit, actualLimit] = GetParam();
4180 if (oldLimit > 0) {
4181 config.mutable_count_metric(0)->set_max_dimensions_per_bucket(oldLimit);
4182 config.mutable_duration_metric(0)->set_max_dimensions_per_bucket(oldLimit);
4183 config.mutable_gauge_metric(0)->set_max_dimensions_per_bucket(oldLimit);
4184 config.mutable_value_metric(0)->set_max_dimensions_per_bucket(oldLimit);
4185 config.mutable_kll_metric(0)->set_max_dimensions_per_bucket(oldLimit);
4186 }
4187
4188 EXPECT_TRUE(initConfig(config));
4189
4190 StatsdConfig newConfig = config;
4191 if (newLimit == 0) {
4192 newConfig.mutable_count_metric(0)->clear_max_dimensions_per_bucket();
4193 newConfig.mutable_duration_metric(0)->clear_max_dimensions_per_bucket();
4194 newConfig.mutable_gauge_metric(0)->clear_max_dimensions_per_bucket();
4195 newConfig.mutable_value_metric(0)->clear_max_dimensions_per_bucket();
4196 newConfig.mutable_kll_metric(0)->clear_max_dimensions_per_bucket();
4197 } else {
4198 newConfig.mutable_count_metric(0)->set_max_dimensions_per_bucket(newLimit);
4199 newConfig.mutable_duration_metric(0)->set_max_dimensions_per_bucket(newLimit);
4200 newConfig.mutable_gauge_metric(0)->set_max_dimensions_per_bucket(newLimit);
4201 newConfig.mutable_value_metric(0)->set_max_dimensions_per_bucket(newLimit);
4202 newConfig.mutable_kll_metric(0)->set_max_dimensions_per_bucket(newLimit);
4203 }
4204
4205 unordered_map<int64_t, int> newMetricProducerMap;
4206 unordered_map<int, vector<int>> conditionToMetricMap;
4207 unordered_map<int, vector<int>> trackerToMetricMap;
4208 unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
4209 unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
4210 set<int64_t> noReportMetricIds;
4211 vector<int> metricsWithActivation;
4212 vector<sp<MetricProducer>> newMetricProducers;
4213 set<int64_t> replacedMetrics;
4214 sp<MockConfigMetadataProvider> provider = makeMockConfigMetadataProvider(/*enabled=*/false);
4215 EXPECT_EQ(updateMetrics(
4216 key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345,
4217 new StatsPullerManager(), oldAtomMatchingTrackerMap,
4218 oldAtomMatchingTrackerMap, /*replacedMatchers=*/{}, oldAtomMatchingTrackers,
4219 oldConditionTrackerMap, /*replacedConditions=*/{}, oldConditionTrackers,
4220 /*conditionCache=*/{}, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
4221 /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, provider,
4222 newMetricProducerMap, newMetricProducers, conditionToMetricMap,
4223 trackerToMetricMap, noReportMetricIds, activationAtomTrackerToMetricMap,
4224 deactivationAtomTrackerToMetricMap, metricsWithActivation, replacedMetrics),
4225 nullopt);
4226
4227 ASSERT_EQ(5u, oldMetricProducers.size());
4228 ASSERT_EQ(5u, newMetricProducers.size());
4229
4230 // Check that old MetricProducers have the old dimension limit and the new producers have the
4231 // new dimension limit.
4232
4233 // Count
4234 sp<MetricProducer> producer =
4235 oldMetricProducers[oldMetricProducerMap.at(config.count_metric(0).id())];
4236 CountMetricProducer* countProducer = static_cast<CountMetricProducer*>(producer.get());
4237 EXPECT_EQ(countProducer->mDimensionHardLimit, oldLimit);
4238
4239 producer = newMetricProducers[newMetricProducerMap.at(newConfig.count_metric(0).id())];
4240 countProducer = static_cast<CountMetricProducer*>(producer.get());
4241 EXPECT_EQ(countProducer->mDimensionHardLimit, actualLimit);
4242
4243 // Duration
4244 producer = oldMetricProducers[oldMetricProducerMap.at(config.duration_metric(0).id())];
4245 DurationMetricProducer* durationProducer = static_cast<DurationMetricProducer*>(producer.get());
4246 EXPECT_EQ(durationProducer->mDimensionHardLimit, oldLimit);
4247
4248 producer = newMetricProducers[newMetricProducerMap.at(newConfig.duration_metric(0).id())];
4249 durationProducer = static_cast<DurationMetricProducer*>(producer.get());
4250 EXPECT_EQ(durationProducer->mDimensionHardLimit, actualLimit);
4251
4252 // Gauge
4253 producer = oldMetricProducers[oldMetricProducerMap.at(config.gauge_metric(0).id())];
4254 GaugeMetricProducer* gaugeProducer = static_cast<GaugeMetricProducer*>(producer.get());
4255 EXPECT_EQ(gaugeProducer->mDimensionHardLimit, oldLimit);
4256
4257 producer = newMetricProducers[newMetricProducerMap.at(newConfig.gauge_metric(0).id())];
4258 gaugeProducer = static_cast<GaugeMetricProducer*>(producer.get());
4259 EXPECT_EQ(gaugeProducer->mDimensionHardLimit, actualLimit);
4260
4261 // Value
4262 producer = oldMetricProducers[oldMetricProducerMap.at(config.value_metric(0).id())];
4263 NumericValueMetricProducer* numericValueProducer =
4264 static_cast<NumericValueMetricProducer*>(producer.get());
4265 EXPECT_EQ(numericValueProducer->mDimensionHardLimit, oldLimit);
4266
4267 producer = newMetricProducers[newMetricProducerMap.at(newConfig.value_metric(0).id())];
4268 numericValueProducer = static_cast<NumericValueMetricProducer*>(producer.get());
4269 EXPECT_EQ(numericValueProducer->mDimensionHardLimit, actualLimit);
4270
4271 // KLL
4272 producer = oldMetricProducers[oldMetricProducerMap.at(config.kll_metric(0).id())];
4273 KllMetricProducer* kllProducer = static_cast<KllMetricProducer*>(producer.get());
4274 EXPECT_EQ(kllProducer->mDimensionHardLimit, oldLimit);
4275
4276 producer = newMetricProducers[newMetricProducerMap.at(newConfig.kll_metric(0).id())];
4277 kllProducer = static_cast<KllMetricProducer*>(producer.get());
4278 EXPECT_EQ(kllProducer->mDimensionHardLimit, actualLimit);
4279 }
4280
4281 } // namespace statsd
4282 } // namespace os
4283 } // namespace android
4284
4285 #else
4286 GTEST_LOG_(INFO) << "This test does nothing.\n";
4287 #endif
4288