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