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