• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include "src/StatsLogProcessor.h"
20 #include "src/state/StateManager.h"
21 #include "src/state/StateTracker.h"
22 #include "tests/statsd_test_util.h"
23 
24 namespace android {
25 namespace os {
26 namespace statsd {
27 
28 #ifdef __ANDROID__
29 
30 /**
31  * Tests the initial condition and condition after the first log events for
32  * count metrics with either a combination condition or simple condition.
33  *
34  * Metrics should be initialized with condition kUnknown (given that the
35  * predicate is using the default InitialValue of UNKNOWN). The condition should
36  * be updated to either kFalse or kTrue if a condition event is logged for all
37  * children conditions.
38  */
TEST(CountMetricE2eTest,TestInitialConditionChanges)39 TEST(CountMetricE2eTest, TestInitialConditionChanges) {
40     // Initialize config.
41     StatsdConfig config;
42     config.add_allowed_log_source("AID_ROOT");     // LogEvent defaults to UID of root.
43     config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
44 
45     auto syncStartMatcher = CreateSyncStartAtomMatcher();
46     *config.add_atom_matcher() = syncStartMatcher;
47     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
48     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
49     *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
50     *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
51 
52     auto screenOnPredicate = CreateScreenIsOnPredicate();
53     *config.add_predicate() = screenOnPredicate;
54 
55     auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
56     *config.add_predicate() = deviceUnpluggedPredicate;
57 
58     auto screenOnOnBatteryPredicate = config.add_predicate();
59     screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
60     screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
61     addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
62     addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
63 
64     // CountSyncStartWhileScreenOnOnBattery (CombinationCondition)
65     CountMetric* countMetric1 = config.add_count_metric();
66     countMetric1->set_id(StringToId("CountSyncStartWhileScreenOnOnBattery"));
67     countMetric1->set_what(syncStartMatcher.id());
68     countMetric1->set_condition(screenOnOnBatteryPredicate->id());
69     countMetric1->set_bucket(FIVE_MINUTES);
70 
71     // CountSyncStartWhileOnBattery (SimpleCondition)
72     CountMetric* countMetric2 = config.add_count_metric();
73     countMetric2->set_id(StringToId("CountSyncStartWhileOnBatterySliceScreen"));
74     countMetric2->set_what(syncStartMatcher.id());
75     countMetric2->set_condition(deviceUnpluggedPredicate.id());
76     countMetric2->set_bucket(FIVE_MINUTES);
77 
78     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
79     const uint64_t bucketSizeNs =
80             TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
81     int uid = 12345;
82     int64_t cfgId = 98765;
83     ConfigKey cfgKey(uid, cfgId);
84     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
85 
86     EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
87     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
88     EXPECT_TRUE(metricsManager->isConfigValid());
89     EXPECT_EQ(2, metricsManager->mAllMetricProducers.size());
90 
91     sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
92     sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[1];
93 
94     EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
95     EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
96 
97     auto screenOnEvent =
98             CreateScreenStateChangedEvent(bucketStartTimeNs + 30, android::view::DISPLAY_STATE_ON);
99     processor->OnLogEvent(screenOnEvent.get());
100     EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
101     EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
102 
103     auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
104             bucketStartTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
105     processor->OnLogEvent(pluggedUsbEvent.get());
106     EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
107     EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
108 
109     auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
110             bucketStartTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
111     processor->OnLogEvent(pluggedNoneEvent.get());
112     EXPECT_EQ(ConditionState::kTrue, metricProducer1->mCondition);
113     EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
114 }
115 
116 /**
117 * Test a count metric that has one slice_by_state with no primary fields.
118 *
119 * Once the CountMetricProducer is initialized, it has one atom id in
120 * mSlicedStateAtoms and no entries in mStateGroupMap.
121 
122 * One StateTracker tracks the state atom, and it has one listener which is the
123 * CountMetricProducer that was initialized.
124 */
TEST(CountMetricE2eTest,TestSlicedState)125 TEST(CountMetricE2eTest, TestSlicedState) {
126     // Initialize config.
127     StatsdConfig config;
128     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
129 
130     auto syncStartMatcher = CreateSyncStartAtomMatcher();
131     *config.add_atom_matcher() = syncStartMatcher;
132 
133     auto state = CreateScreenState();
134     *config.add_state() = state;
135 
136     // Create count metric that slices by screen state.
137     int64_t metricId = 123456;
138     auto countMetric = config.add_count_metric();
139     countMetric->set_id(metricId);
140     countMetric->set_what(syncStartMatcher.id());
141     countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
142     countMetric->add_slice_by_state(state.id());
143 
144     // Initialize StatsLogProcessor.
145     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
146     const uint64_t bucketSizeNs =
147             TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
148     int uid = 12345;
149     int64_t cfgId = 98765;
150     ConfigKey cfgKey(uid, cfgId);
151     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
152 
153     // Check that CountMetricProducer was initialized correctly.
154     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
155     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
156     EXPECT_TRUE(metricsManager->isConfigValid());
157     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
158     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
159     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
160     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
161     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
162 
163     // Check that StateTrackers were initialized correctly.
164     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
165     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
166 
167     /*
168                bucket #1                      bucket #2
169     |     1     2     3     4     5     6     7     8     9     10 (minutes)
170     |-----------------------------|-----------------------------|--
171             x                x         x    x        x      x       (syncStartEvents)
172           |                                       |                 (ScreenIsOnEvent)
173                    |     |                                          (ScreenIsOffEvent)
174                                                         |           (ScreenDozeEvent)
175     */
176     // Initialize log events - first bucket.
177     std::vector<int> attributionUids1 = {123};
178     std::vector<string> attributionTags1 = {"App1"};
179 
180     std::vector<std::unique_ptr<LogEvent>> events;
181     events.push_back(CreateScreenStateChangedEvent(
182             bucketStartTimeNs + 50 * NS_PER_SEC,
183             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 1:00
184     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 75 * NS_PER_SEC, attributionUids1,
185                                           attributionTags1, "sync_name"));  // 1:25
186     events.push_back(CreateScreenStateChangedEvent(
187             bucketStartTimeNs + 150 * NS_PER_SEC,
188             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 2:40
189     events.push_back(CreateScreenStateChangedEvent(
190             bucketStartTimeNs + 200 * NS_PER_SEC,
191             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 3:30
192     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
193                                           attributionTags1, "sync_name"));  // 4:20
194 
195     // Initialize log events - second bucket.
196     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 350 * NS_PER_SEC, attributionUids1,
197                                           attributionTags1, "sync_name"));  // 6:00
198     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400 * NS_PER_SEC, attributionUids1,
199                                           attributionTags1, "sync_name"));  // 6:50
200     events.push_back(CreateScreenStateChangedEvent(
201             bucketStartTimeNs + 450 * NS_PER_SEC,
202             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 7:40
203     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 475 * NS_PER_SEC, attributionUids1,
204                                           attributionTags1, "sync_name"));  // 8:05
205     events.push_back(CreateScreenStateChangedEvent(
206             bucketStartTimeNs + 500 * NS_PER_SEC,
207             android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN));  // 8:30
208     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 520 * NS_PER_SEC, attributionUids1,
209                                           attributionTags1, "sync_name"));  // 8:50
210 
211     // Send log events to StatsLogProcessor.
212     for (auto& event : events) {
213         processor->OnLogEvent(event.get());
214     }
215 
216     // Check dump report.
217     vector<uint8_t> buffer;
218     ConfigMetricsReportList reports;
219     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
220                             FAST, &buffer);
221     ASSERT_GT(buffer.size(), 0);
222     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
223     backfillDimensionPath(&reports);
224     backfillStringInReport(&reports);
225     backfillStartEndTimestamp(&reports);
226 
227     ASSERT_EQ(1, reports.reports_size());
228     ASSERT_EQ(1, reports.reports(0).metrics_size());
229     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
230     StatsLogReport::CountMetricDataWrapper countMetrics;
231     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
232     ASSERT_EQ(3, countMetrics.data_size());
233 
234     // For each CountMetricData, check StateValue info is correct and buckets
235     // have correct counts.
236     auto data = countMetrics.data(0);
237     ASSERT_EQ(1, data.slice_by_state_size());
238     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
239     EXPECT_TRUE(data.slice_by_state(0).has_value());
240     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
241               data.slice_by_state(0).value());
242     ASSERT_EQ(1, data.bucket_info_size());
243     EXPECT_EQ(1, data.bucket_info(0).count());
244 
245     data = countMetrics.data(1);
246     ASSERT_EQ(1, data.slice_by_state_size());
247     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
248     EXPECT_TRUE(data.slice_by_state(0).has_value());
249     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
250     ASSERT_EQ(2, data.bucket_info_size());
251     EXPECT_EQ(1, data.bucket_info(0).count());
252     EXPECT_EQ(2, data.bucket_info(1).count());
253 
254     data = countMetrics.data(2);
255     ASSERT_EQ(1, data.slice_by_state_size());
256     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
257     EXPECT_TRUE(data.slice_by_state(0).has_value());
258     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
259     ASSERT_EQ(2, data.bucket_info_size());
260     EXPECT_EQ(1, data.bucket_info(0).count());
261     EXPECT_EQ(1, data.bucket_info(1).count());
262 }
263 
264 /**
265  * Test a count metric that has one slice_by_state with a mapping and no
266  * primary fields.
267  *
268  * Once the CountMetricProducer is initialized, it has one atom id in
269  * mSlicedStateAtoms and has one entry per state value in mStateGroupMap.
270  *
271  * One StateTracker tracks the state atom, and it has one listener which is the
272  * CountMetricProducer that was initialized.
273  */
TEST(CountMetricE2eTest,TestSlicedStateWithMap)274 TEST(CountMetricE2eTest, TestSlicedStateWithMap) {
275     // Initialize config.
276     StatsdConfig config;
277     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
278 
279     auto syncStartMatcher = CreateSyncStartAtomMatcher();
280     *config.add_atom_matcher() = syncStartMatcher;
281 
282     int64_t screenOnId = 4444;
283     int64_t screenOffId = 9876;
284     auto state = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
285     *config.add_state() = state;
286 
287     // Create count metric that slices by screen state with on/off map.
288     int64_t metricId = 123456;
289     auto countMetric = config.add_count_metric();
290     countMetric->set_id(metricId);
291     countMetric->set_what(syncStartMatcher.id());
292     countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
293     countMetric->add_slice_by_state(state.id());
294 
295     // Initialize StatsLogProcessor.
296     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
297     const uint64_t bucketSizeNs =
298             TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
299     int uid = 12345;
300     int64_t cfgId = 98765;
301     ConfigKey cfgKey(uid, cfgId);
302     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
303 
304     // Check that StateTrackers were initialized correctly.
305     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
306     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
307 
308     // Check that CountMetricProducer was initialized correctly.
309     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
310     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
311     EXPECT_TRUE(metricsManager->isConfigValid());
312     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
313     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
314     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
315     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
316     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
317 
318     StateMap map = state.map();
319     for (auto group : map.group()) {
320         for (auto value : group.value()) {
321             EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
322                       group.group_id());
323         }
324     }
325 
326     /*
327                bucket #1                      bucket #2
328     |     1     2     3     4     5     6     7     8     9     10 (minutes)
329     |-----------------------------|-----------------------------|--
330       x   x     x       x    x   x      x         x         x       (syncStartEvents)
331      -----------------------------------------------------------SCREEN_OFF events
332              |                  |                                   (ScreenStateOffEvent = 1)
333        |                  |                                         (ScreenStateDozeEvent = 3)
334                                                 |                   (ScreenStateDozeSuspendEvent =
335     4)
336      -----------------------------------------------------------SCREEN_ON events
337                    |                                       |        (ScreenStateOnEvent = 2)
338                       |                                             (ScreenStateVrEvent = 5)
339                                             |                       (ScreenStateOnSuspendEvent = 6)
340     */
341     // Initialize log events - first bucket.
342     std::vector<int> attributionUids1 = {123};
343     std::vector<string> attributionTags1 = {"App1"};
344 
345     std::vector<std::unique_ptr<LogEvent>> events;
346     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 20 * NS_PER_SEC, attributionUids1,
347                                           attributionTags1, "sync_name"));  // 0:30
348     events.push_back(CreateScreenStateChangedEvent(
349             bucketStartTimeNs + 30 * NS_PER_SEC,
350             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 0:40
351     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
352                                           attributionTags1, "sync_name"));  // 1:10
353     events.push_back(CreateScreenStateChangedEvent(
354             bucketStartTimeNs + 90 * NS_PER_SEC,
355             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:40
356     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 120 * NS_PER_SEC, attributionUids1,
357                                           attributionTags1, "sync_name"));  // 2:10
358     events.push_back(CreateScreenStateChangedEvent(
359             bucketStartTimeNs + 150 * NS_PER_SEC,
360             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:40
361     events.push_back(CreateScreenStateChangedEvent(
362             bucketStartTimeNs + 180 * NS_PER_SEC,
363             android::view::DisplayStateEnum::DISPLAY_STATE_VR));  // 3:10
364     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200 * NS_PER_SEC, attributionUids1,
365                                           attributionTags1, "sync_name"));  // 3:30
366     events.push_back(CreateScreenStateChangedEvent(
367             bucketStartTimeNs + 210 * NS_PER_SEC,
368             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 3:40
369     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
370                                           attributionTags1, "sync_name"));  // 4:20
371     events.push_back(CreateScreenStateChangedEvent(
372             bucketStartTimeNs + 280 * NS_PER_SEC,
373             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 4:50
374     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 285 * NS_PER_SEC, attributionUids1,
375                                           attributionTags1, "sync_name"));  // 4:55
376 
377     // Initialize log events - second bucket.
378     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 360 * NS_PER_SEC, attributionUids1,
379                                           attributionTags1, "sync_name"));  // 6:10
380     events.push_back(CreateScreenStateChangedEvent(
381             bucketStartTimeNs + 390 * NS_PER_SEC,
382             android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND));  // 6:40
383     events.push_back(CreateScreenStateChangedEvent(
384             bucketStartTimeNs + 430 * NS_PER_SEC,
385             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND));  // 7:20
386     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 440 * NS_PER_SEC, attributionUids1,
387                                           attributionTags1, "sync_name"));  // 7:30
388     events.push_back(CreateScreenStateChangedEvent(
389             bucketStartTimeNs + 540 * NS_PER_SEC,
390             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 9:10
391     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 570 * NS_PER_SEC, attributionUids1,
392                                           attributionTags1, "sync_name"));  // 9:40
393 
394     // Send log events to StatsLogProcessor.
395     for (auto& event : events) {
396         processor->OnLogEvent(event.get());
397     }
398 
399     // Check dump report.
400     vector<uint8_t> buffer;
401     ConfigMetricsReportList reports;
402     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
403                             FAST, &buffer);
404     ASSERT_GT(buffer.size(), 0);
405     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
406     backfillDimensionPath(&reports);
407     backfillStringInReport(&reports);
408     backfillStartEndTimestamp(&reports);
409 
410     ASSERT_EQ(1, reports.reports_size());
411     ASSERT_EQ(1, reports.reports(0).metrics_size());
412     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
413     StatsLogReport::CountMetricDataWrapper countMetrics;
414     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
415     ASSERT_EQ(3, countMetrics.data_size());
416 
417     // For each CountMetricData, check StateValue info is correct and buckets
418     // have correct counts.
419     auto data = countMetrics.data(0);
420     ASSERT_EQ(1, data.slice_by_state_size());
421     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
422     EXPECT_TRUE(data.slice_by_state(0).has_value());
423     EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
424     ASSERT_EQ(1, data.bucket_info_size());
425     EXPECT_EQ(1, data.bucket_info(0).count());
426 
427     data = countMetrics.data(1);
428     ASSERT_EQ(1, data.slice_by_state_size());
429     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
430     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
431     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
432     ASSERT_EQ(2, data.bucket_info_size());
433     EXPECT_EQ(1, data.bucket_info(0).count());
434     EXPECT_EQ(1, data.bucket_info(1).count());
435 
436     data = countMetrics.data(2);
437     ASSERT_EQ(1, data.slice_by_state_size());
438     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
439     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
440     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
441     ASSERT_EQ(2, data.bucket_info_size());
442     EXPECT_EQ(4, data.bucket_info(0).count());
443     EXPECT_EQ(2, data.bucket_info(1).count());
444 }
445 
446 /**
447 * Test a count metric that has one slice_by_state with a primary field.
448 
449 * Once the CountMetricProducer is initialized, it should have one
450 * MetricStateLink stored. State querying using a non-empty primary key
451 * should also work as intended.
452 */
TEST(CountMetricE2eTest,TestSlicedStateWithPrimaryFields)453 TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields) {
454     // Initialize config.
455     StatsdConfig config;
456     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
457 
458     auto appCrashMatcher =
459             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
460     *config.add_atom_matcher() = appCrashMatcher;
461 
462     auto state = CreateUidProcessState();
463     *config.add_state() = state;
464 
465     // Create count metric that slices by uid process state.
466     int64_t metricId = 123456;
467     auto countMetric = config.add_count_metric();
468     countMetric->set_id(metricId);
469     countMetric->set_what(appCrashMatcher.id());
470     countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
471     countMetric->add_slice_by_state(state.id());
472     MetricStateLink* stateLink = countMetric->add_state_link();
473     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
474     auto fieldsInWhat = stateLink->mutable_fields_in_what();
475     *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
476     auto fieldsInState = stateLink->mutable_fields_in_state();
477     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
478 
479     // Initialize StatsLogProcessor.
480     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
481     const uint64_t bucketSizeNs =
482             TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
483     int uid = 12345;
484     int64_t cfgId = 98765;
485     ConfigKey cfgKey(uid, cfgId);
486     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
487 
488     // Check that StateTrackers were initialized correctly.
489     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
490     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
491 
492     // Check that CountMetricProducer was initialized correctly.
493     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
494     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
495     EXPECT_TRUE(metricsManager->isConfigValid());
496     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
497     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
498     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
499     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
500     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
501     ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
502 
503     /*
504     NOTE: "1" or "2" represents the uid associated with the state/app crash event
505                bucket #1               bucket #2
506     |    1    2    3    4    5    6    7    8    9    10
507     |------------------------|-------------------------|--
508       1  1    1      1   1  2     1        1        2    (AppCrashEvents)
509      -----------------------------------------------------PROCESS STATE events
510            1               2                             (TopEvent = 1002)
511                        1             1                   (ForegroundServiceEvent = 1003)
512                                          2               (ImportantBackgroundEvent = 1006)
513        1          1                               1      (ImportantForegroundEvent = 1005)
514 
515     Based on the diagram above, an AppCrashEvent querying for process state value would return:
516     - StateTracker::kStateUnknown
517     - Important foreground
518     - Top
519     - Important foreground
520     - Foreground service
521     - Top (both the app crash and state still have matching uid = 2)
522 
523     - Foreground service
524     - Foreground service
525     - Important background
526     */
527     // Initialize log events - first bucket.
528     std::vector<std::unique_ptr<LogEvent>> events;
529     events.push_back(
530             CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/));  // 0:30
531     events.push_back(CreateUidProcessStateChangedEvent(
532             bucketStartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/,
533             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 0:40
534     events.push_back(
535             CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/));  // 1:10
536     events.push_back(CreateUidProcessStateChangedEvent(
537             bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
538             android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 1:40
539     events.push_back(
540             CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/));  // 2:10
541     events.push_back(CreateUidProcessStateChangedEvent(
542             bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
543             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 2:40
544     events.push_back(
545             CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/));  // 3:30
546     events.push_back(CreateUidProcessStateChangedEvent(
547             bucketStartTimeNs + 210 * NS_PER_SEC, 1 /*uid*/,
548             android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 3:40
549     events.push_back(
550             CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/));  // 4:20
551     events.push_back(CreateUidProcessStateChangedEvent(
552             bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
553             android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 4:50
554     events.push_back(
555             CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/));  // 4:55
556 
557     // Initialize log events - second bucket.
558     events.push_back(
559             CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/));  // 6:10
560     events.push_back(CreateUidProcessStateChangedEvent(
561             bucketStartTimeNs + 390 * NS_PER_SEC, 1 /*uid*/,
562             android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 6:40
563     events.push_back(CreateUidProcessStateChangedEvent(
564             bucketStartTimeNs + 430 * NS_PER_SEC, 2 /*uid*/,
565             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 7:20
566     events.push_back(
567             CreateAppCrashOccurredEvent(bucketStartTimeNs + 440 * NS_PER_SEC, 1 /*uid*/));  // 7:30
568     events.push_back(CreateUidProcessStateChangedEvent(
569             bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
570             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 9:10
571     events.push_back(
572             CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/));  // 9:40
573 
574     // Send log events to StatsLogProcessor.
575     for (auto& event : events) {
576         processor->OnLogEvent(event.get());
577     }
578 
579     // Check dump report.
580     vector<uint8_t> buffer;
581     ConfigMetricsReportList reports;
582     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
583                             FAST, &buffer);
584     ASSERT_GT(buffer.size(), 0);
585     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
586     backfillDimensionPath(&reports);
587     backfillStringInReport(&reports);
588     backfillStartEndTimestamp(&reports);
589 
590     ASSERT_EQ(1, reports.reports_size());
591     ASSERT_EQ(1, reports.reports(0).metrics_size());
592     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
593     StatsLogReport::CountMetricDataWrapper countMetrics;
594     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
595     ASSERT_EQ(5, countMetrics.data_size());
596 
597     // For each CountMetricData, check StateValue info is correct and buckets
598     // have correct counts.
599     auto data = countMetrics.data(0);
600     ASSERT_EQ(1, data.slice_by_state_size());
601     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
602     EXPECT_TRUE(data.slice_by_state(0).has_value());
603     EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
604     ASSERT_EQ(1, data.bucket_info_size());
605     EXPECT_EQ(1, data.bucket_info(0).count());
606 
607     data = countMetrics.data(1);
608     ASSERT_EQ(1, data.slice_by_state_size());
609     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
610     EXPECT_TRUE(data.slice_by_state(0).has_value());
611     EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
612     ASSERT_EQ(1, data.bucket_info_size());
613     EXPECT_EQ(2, data.bucket_info(0).count());
614 
615     data = countMetrics.data(2);
616     ASSERT_EQ(1, data.slice_by_state_size());
617     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
618     EXPECT_TRUE(data.slice_by_state(0).has_value());
619     EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
620     ASSERT_EQ(2, data.bucket_info_size());
621     EXPECT_EQ(1, data.bucket_info(0).count());
622     EXPECT_EQ(2, data.bucket_info(1).count());
623 
624     data = countMetrics.data(3);
625     ASSERT_EQ(1, data.slice_by_state_size());
626     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
627     EXPECT_TRUE(data.slice_by_state(0).has_value());
628     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
629     ASSERT_EQ(1, data.bucket_info_size());
630     EXPECT_EQ(2, data.bucket_info(0).count());
631 
632     data = countMetrics.data(4);
633     ASSERT_EQ(1, data.slice_by_state_size());
634     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
635     EXPECT_TRUE(data.slice_by_state(0).has_value());
636     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
637     ASSERT_EQ(1, data.bucket_info_size());
638     EXPECT_EQ(1, data.bucket_info(0).count());
639 }
640 
TEST(CountMetricE2eTest,TestMultipleSlicedStates)641 TEST(CountMetricE2eTest, TestMultipleSlicedStates) {
642     // Initialize config.
643     StatsdConfig config;
644     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
645 
646     auto appCrashMatcher =
647             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
648     *config.add_atom_matcher() = appCrashMatcher;
649 
650     int64_t screenOnId = 4444;
651     int64_t screenOffId = 9876;
652     auto state1 = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
653     *config.add_state() = state1;
654     auto state2 = CreateUidProcessState();
655     *config.add_state() = state2;
656 
657     // Create count metric that slices by screen state with on/off map and
658     // slices by uid process state.
659     int64_t metricId = 123456;
660     auto countMetric = config.add_count_metric();
661     countMetric->set_id(metricId);
662     countMetric->set_what(appCrashMatcher.id());
663     countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
664     countMetric->add_slice_by_state(state1.id());
665     countMetric->add_slice_by_state(state2.id());
666     MetricStateLink* stateLink = countMetric->add_state_link();
667     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
668     auto fieldsInWhat = stateLink->mutable_fields_in_what();
669     *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
670     auto fieldsInState = stateLink->mutable_fields_in_state();
671     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
672 
673     // Initialize StatsLogProcessor.
674     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
675     const uint64_t bucketSizeNs =
676             TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
677     int uid = 12345;
678     int64_t cfgId = 98765;
679     ConfigKey cfgKey(uid, cfgId);
680     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
681 
682     // Check that StateTrackers were properly initialized.
683     EXPECT_EQ(2, StateManager::getInstance().getStateTrackersCount());
684     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
685     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
686 
687     // Check that CountMetricProducer was initialized correctly.
688     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
689     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
690     EXPECT_TRUE(metricsManager->isConfigValid());
691     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
692     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
693     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
694     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
695     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(1), UID_PROCESS_STATE_ATOM_ID);
696     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
697     ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
698 
699     StateMap map = state1.map();
700     for (auto group : map.group()) {
701         for (auto value : group.value()) {
702             EXPECT_EQ(metricProducer->mStateGroupMap.at(SCREEN_STATE_ATOM_ID).at(value),
703                       group.group_id());
704         }
705     }
706 
707     /*
708                  bucket #1                      bucket #2
709       |    1    2    3    4    5    6    7    8    9    10 (minutes)
710       |------------------------|------------------------|--
711         1  1    1     1    1  2     1        1         2   (AppCrashEvents)
712        ---------------------------------------------------SCREEN_OFF events
713              |                              |              (ScreenOffEvent = 1)
714          |              |                                  (ScreenDozeEvent = 3)
715        ---------------------------------------------------SCREEN_ON events
716                    |                              |        (ScreenOnEvent = 2)
717                                         |                  (ScreenOnSuspendEvent = 6)
718        ---------------------------------------------------PROCESS STATE events
719              1               2                             (TopEvent = 1002)
720                                       1                    (ForegroundServiceEvent = 1003)
721                                             2              (ImportantBackgroundEvent = 1006)
722        1          1                                   1    (ImportantForegroundEvent = 1005)
723 
724        Based on the diagram above, Screen State / Process State pairs for each
725        AppCrashEvent are:
726        - StateTracker::kStateUnknown / important foreground
727        - off / important foreground
728        - off / Top
729        - on / important foreground
730        - off / important foreground
731        - off / top
732 
733        - off / important foreground
734        - off / foreground service
735        - on / important background
736 
737       */
738     // Initialize log events - first bucket.
739     std::vector<std::unique_ptr<LogEvent>> events;
740     events.push_back(CreateUidProcessStateChangedEvent(
741             bucketStartTimeNs + 5 * NS_PER_SEC, 1 /*uid*/,
742             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 0:15
743     events.push_back(
744             CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/));  // 0:30
745     events.push_back(CreateScreenStateChangedEvent(
746             bucketStartTimeNs + 30 * NS_PER_SEC,
747             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 0:40
748     events.push_back(
749             CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/));  // 1:10
750     events.push_back(CreateUidProcessStateChangedEvent(
751             bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
752             android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 1:40
753     events.push_back(CreateScreenStateChangedEvent(
754             bucketStartTimeNs + 90 * NS_PER_SEC,
755             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:40
756     events.push_back(
757             CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/));  // 2:10
758     events.push_back(CreateUidProcessStateChangedEvent(
759             bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
760             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 2:40
761     events.push_back(CreateScreenStateChangedEvent(
762             bucketStartTimeNs + 160 * NS_PER_SEC,
763             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:50
764     events.push_back(
765             CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/));  // 3:30
766     events.push_back(CreateScreenStateChangedEvent(
767             bucketStartTimeNs + 210 * NS_PER_SEC,
768             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 3:40
769     events.push_back(
770             CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/));  // 4:20
771     events.push_back(CreateUidProcessStateChangedEvent(
772             bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
773             android::app::ProcessStateEnum::PROCESS_STATE_TOP));  // 4:50
774     events.push_back(
775             CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/));  // 4:55
776 
777     // Initialize log events - second bucket.
778     events.push_back(
779             CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/));  // 6:10
780     events.push_back(CreateUidProcessStateChangedEvent(
781             bucketStartTimeNs + 380 * NS_PER_SEC, 1 /*uid*/,
782             android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 6:30
783     events.push_back(CreateScreenStateChangedEvent(
784             bucketStartTimeNs + 390 * NS_PER_SEC,
785             android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND));  // 6:40
786     events.push_back(CreateUidProcessStateChangedEvent(
787             bucketStartTimeNs + 420 * NS_PER_SEC, 2 /*uid*/,
788             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 7:10
789     events.push_back(CreateScreenStateChangedEvent(
790             bucketStartTimeNs + 440 * NS_PER_SEC,
791             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 7:30
792     events.push_back(
793             CreateAppCrashOccurredEvent(bucketStartTimeNs + 450 * NS_PER_SEC, 1 /*uid*/));  // 7:40
794     events.push_back(CreateScreenStateChangedEvent(
795             bucketStartTimeNs + 520 * NS_PER_SEC,
796             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 8:50
797     events.push_back(CreateUidProcessStateChangedEvent(
798             bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
799             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 9:10
800     events.push_back(
801             CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/));  // 9:40
802 
803     // Send log events to StatsLogProcessor.
804     for (auto& event : events) {
805         processor->OnLogEvent(event.get());
806     }
807 
808     // Check dump report.
809     vector<uint8_t> buffer;
810     ConfigMetricsReportList reports;
811     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
812                             FAST, &buffer);
813     ASSERT_GT(buffer.size(), 0);
814     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
815     backfillDimensionPath(&reports);
816     backfillStringInReport(&reports);
817     backfillStartEndTimestamp(&reports);
818 
819     ASSERT_EQ(1, reports.reports_size());
820     ASSERT_EQ(1, reports.reports(0).metrics_size());
821     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
822     StatsLogReport::CountMetricDataWrapper countMetrics;
823     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
824     ASSERT_EQ(6, countMetrics.data_size());
825 
826     // For each CountMetricData, check StateValue info is correct and buckets
827     // have correct counts.
828     auto data = countMetrics.data(0);
829     ASSERT_EQ(2, data.slice_by_state_size());
830     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
831     EXPECT_TRUE(data.slice_by_state(0).has_value());
832     EXPECT_EQ(-1, data.slice_by_state(0).value());
833     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
834     EXPECT_TRUE(data.slice_by_state(1).has_value());
835     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
836     ASSERT_EQ(1, data.bucket_info_size());
837     EXPECT_EQ(1, data.bucket_info(0).count());
838 
839     data = countMetrics.data(1);
840     ASSERT_EQ(2, data.slice_by_state_size());
841     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
842     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
843     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
844     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
845     EXPECT_TRUE(data.slice_by_state(1).has_value());
846     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
847     ASSERT_EQ(1, data.bucket_info_size());
848     EXPECT_EQ(1, data.bucket_info(0).count());
849 
850     data = countMetrics.data(2);
851     ASSERT_EQ(2, data.slice_by_state_size());
852     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
853     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
854     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
855     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
856     EXPECT_TRUE(data.slice_by_state(1).has_value());
857     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(1).value());
858     ASSERT_EQ(1, data.bucket_info_size());
859     EXPECT_EQ(1, data.bucket_info(0).count());
860 
861     data = countMetrics.data(3);
862     ASSERT_EQ(2, data.slice_by_state_size());
863     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
864     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
865     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
866     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
867     EXPECT_TRUE(data.slice_by_state(1).has_value());
868     EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(1).value());
869     ASSERT_EQ(1, data.bucket_info_size());
870     EXPECT_EQ(2, data.bucket_info(0).count());
871 
872     data = countMetrics.data(4);
873     ASSERT_EQ(2, data.slice_by_state_size());
874     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
875     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
876     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
877     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
878     EXPECT_TRUE(data.slice_by_state(1).has_value());
879     EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
880     ASSERT_EQ(1, data.bucket_info_size());
881     EXPECT_EQ(1, data.bucket_info(0).count());
882 
883     data = countMetrics.data(5);
884     ASSERT_EQ(2, data.slice_by_state_size());
885     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
886     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
887     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
888     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
889     EXPECT_TRUE(data.slice_by_state(1).has_value());
890     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
891     ASSERT_EQ(2, data.bucket_info_size());
892     EXPECT_EQ(2, data.bucket_info(0).count());
893     EXPECT_EQ(1, data.bucket_info(1).count());
894 }
895 
TEST(CountMetricE2eTest,TestUploadThreshold)896 TEST(CountMetricE2eTest, TestUploadThreshold) {
897     // Initialize config.
898     StatsdConfig config;
899     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
900 
901     auto appCrashMatcher = CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
902     *config.add_atom_matcher() = appCrashMatcher;
903 
904     int64_t thresholdCount = 2;
905     UploadThreshold threshold;
906     threshold.set_gt_int(thresholdCount);
907 
908     int64_t metricId = 123456;
909     CountMetric countMetric = createCountMetric("COUNT", appCrashMatcher.id(), nullopt, {});
910     *countMetric.mutable_dimensions_in_what() =
911             CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
912     *countMetric.mutable_threshold() = threshold;
913     *config.add_count_metric() = countMetric;
914 
915     // Initialize StatsLogProcessor.
916     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
917     const uint64_t bucketSizeNs =
918             TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
919     int uid = 12345;
920     int64_t cfgId = 98765;
921     ConfigKey cfgKey(uid, cfgId);
922     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
923 
924     int appUid1 = 1;
925     int appUid2 = 2;
926     std::vector<std::unique_ptr<LogEvent>> events;
927     events.push_back(
928             CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, appUid1));  // 0:30
929     events.push_back(
930             CreateAppCrashOccurredEvent(bucketStartTimeNs + 40 * NS_PER_SEC, appUid2));  // 0:50
931     events.push_back(
932             CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, appUid1));  // 1:10
933     events.push_back(
934             CreateAppCrashOccurredEvent(bucketStartTimeNs + 65 * NS_PER_SEC, appUid1));  // 1:15
935 
936     // Send log events to StatsLogProcessor.
937     for (auto& event : events) {
938         processor->OnLogEvent(event.get());
939     }
940 
941     // Check dump report.
942     vector<uint8_t> buffer;
943     ConfigMetricsReportList reports;
944     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
945                             FAST, &buffer);
946     ASSERT_GT(buffer.size(), 0);
947     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
948     backfillDimensionPath(&reports);
949     backfillStringInReport(&reports);
950     backfillStartEndTimestamp(&reports);
951 
952     ASSERT_EQ(1, reports.reports_size());
953     ASSERT_EQ(1, reports.reports(0).metrics_size());
954     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
955     StatsLogReport::CountMetricDataWrapper countMetrics;
956     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
957     ASSERT_EQ(1, countMetrics.data_size());
958 
959     CountMetricData data = countMetrics.data(0);
960 
961     // Uid 1 reports a count greater than the threshold.
962     // Uid 2 is dropped because the count was less than the threshold.
963     ValidateUidDimension(data.dimensions_in_what(), util::APP_CRASH_OCCURRED, appUid1);
964     ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
965                         3);
966 }
967 
968 }  // namespace statsd
969 }  // namespace os
970 }  // namespace android
971 #else
972 GTEST_LOG_(INFO) << "This test does nothing.\n";
973 #endif
974