blob: a5da9c8a6f56a49b693332218562d9b302609ce1 [file] [log] [blame]
tsaichristined21aacf2019-10-07 14:47:38 -07001/*
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"
tsaichristine69000e62019-10-18 17:34:52 -070021#include "src/state/StateTracker.h"
tsaichristined21aacf2019-10-07 14:47:38 -070022#include "tests/statsd_test_util.h"
23
24namespace android {
25namespace os {
26namespace statsd {
27
28#ifdef __ANDROID__
29
tsaichristine7747d372020-02-28 17:36:59 -080030/**
31* Test a count metric that has one slice_by_state with no primary fields.
32*
33* Once the CountMetricProducer is initialized, it has one atom id in
34* mSlicedStateAtoms and no entries in mStateGroupMap.
35
36* One StateTracker tracks the state atom, and it has one listener which is the
37* CountMetricProducer that was initialized.
38*/
39TEST(CountMetricE2eTest, TestSlicedState) {
40 // Initialize config.
41 StatsdConfig config;
42 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
43
44 auto syncStartMatcher = CreateSyncStartAtomMatcher();
45 *config.add_atom_matcher() = syncStartMatcher;
46
47 auto state = CreateScreenState();
48 *config.add_state() = state;
49
50 // Create count metric that slices by screen state.
51 int64_t metricId = 123456;
52 auto countMetric = config.add_count_metric();
53 countMetric->set_id(metricId);
54 countMetric->set_what(syncStartMatcher.id());
55 countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
56 countMetric->add_slice_by_state(state.id());
57
58 // Initialize StatsLogProcessor.
59 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
60 const uint64_t bucketSizeNs =
61 TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
62 int uid = 12345;
63 int64_t cfgId = 98765;
64 ConfigKey cfgKey(uid, cfgId);
65 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
66
67 // Check that CountMetricProducer was initialized correctly.
68 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
69 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
70 EXPECT_TRUE(metricsManager->isConfigValid());
71 EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
72 sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
73 EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
74 EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
75 EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
76
77 // Check that StateTrackers were initialized correctly.
78 EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
79 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
80
81 /*
82 bucket #1 bucket #2
83 | 1 2 3 4 5 6 7 8 9 10 (minutes)
84 |-----------------------------|-----------------------------|--
85 x x x x x x (syncStartEvents)
86 | | (ScreenIsOnEvent)
87 | | (ScreenIsOffEvent)
88 | (ScreenUnknownEvent)
89 */
90 // Initialize log events - first bucket.
91 std::vector<int> attributionUids1 = {123};
92 std::vector<string> attributionTags1 = {"App1"};
93
94 std::vector<std::unique_ptr<LogEvent>> events;
95 events.push_back(CreateScreenStateChangedEvent(
96 bucketStartTimeNs + 50 * NS_PER_SEC,
97 android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 1:00
98 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 75 * NS_PER_SEC, attributionUids1,
99 attributionTags1, "sync_name")); // 1:25
100 events.push_back(CreateScreenStateChangedEvent(
101 bucketStartTimeNs + 150 * NS_PER_SEC,
102 android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 2:40
103 events.push_back(CreateScreenStateChangedEvent(
104 bucketStartTimeNs + 200 * NS_PER_SEC,
105 android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 3:30
106 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
107 attributionTags1, "sync_name")); // 4:20
108
109 // Initialize log events - second bucket.
110 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 350 * NS_PER_SEC, attributionUids1,
111 attributionTags1, "sync_name")); // 6:00
112 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 400 * NS_PER_SEC, attributionUids1,
113 attributionTags1, "sync_name")); // 6:50
114 events.push_back(CreateScreenStateChangedEvent(
115 bucketStartTimeNs + 450 * NS_PER_SEC,
116 android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 7:40
117 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 475 * NS_PER_SEC, attributionUids1,
118 attributionTags1, "sync_name")); // 8:05
119 events.push_back(CreateScreenStateChangedEvent(
120 bucketStartTimeNs + 500 * NS_PER_SEC,
121 android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 8:30
122 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 520 * NS_PER_SEC, attributionUids1,
123 attributionTags1, "sync_name")); // 8:50
124
125 // Send log events to StatsLogProcessor.
126 for (auto& event : events) {
127 processor->OnLogEvent(event.get());
128 }
129
130 // Check dump report.
131 vector<uint8_t> buffer;
132 ConfigMetricsReportList reports;
133 processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
134 FAST, &buffer);
135 EXPECT_GT(buffer.size(), 0);
136 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
137 backfillDimensionPath(&reports);
138 backfillStringInReport(&reports);
139 backfillStartEndTimestamp(&reports);
140
141 EXPECT_EQ(1, reports.reports_size());
142 EXPECT_EQ(1, reports.reports(0).metrics_size());
143 EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
Tej Singh5d823b32019-05-21 20:13:21 -0700144 StatsLogReport::CountMetricDataWrapper countMetrics;
145 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
146 EXPECT_EQ(3, countMetrics.data_size());
tsaichristine7747d372020-02-28 17:36:59 -0800147
148 // For each CountMetricData, check StateValue info is correct and buckets
149 // have correct counts.
Tej Singh5d823b32019-05-21 20:13:21 -0700150 auto data = countMetrics.data(0);
tsaichristine7747d372020-02-28 17:36:59 -0800151 EXPECT_EQ(1, data.slice_by_state_size());
152 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
153 EXPECT_TRUE(data.slice_by_state(0).has_value());
154 EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
155 data.slice_by_state(0).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700156 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800157 EXPECT_EQ(1, data.bucket_info(0).count());
158
Tej Singh5d823b32019-05-21 20:13:21 -0700159 data = countMetrics.data(1);
tsaichristine7747d372020-02-28 17:36:59 -0800160 EXPECT_EQ(1, data.slice_by_state_size());
161 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
162 EXPECT_TRUE(data.slice_by_state(0).has_value());
163 EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700164 ASSERT_EQ(2, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800165 EXPECT_EQ(1, data.bucket_info(0).count());
166 EXPECT_EQ(2, data.bucket_info(1).count());
Tej Singh5d823b32019-05-21 20:13:21 -0700167
168 data = countMetrics.data(2);
169 EXPECT_EQ(1, data.slice_by_state_size());
170 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
171 EXPECT_TRUE(data.slice_by_state(0).has_value());
172 EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
173 ASSERT_EQ(2, data.bucket_info_size());
174 EXPECT_EQ(1, data.bucket_info(0).count());
175 EXPECT_EQ(1, data.bucket_info(1).count());
tsaichristine7747d372020-02-28 17:36:59 -0800176}
177
178/**
179 * Test a count metric that has one slice_by_state with a mapping and no
180 * primary fields.
181 *
182 * Once the CountMetricProducer is initialized, it has one atom id in
183 * mSlicedStateAtoms and has one entry per state value in mStateGroupMap.
184 *
185 * One StateTracker tracks the state atom, and it has one listener which is the
186 * CountMetricProducer that was initialized.
187 */
188TEST(CountMetricE2eTest, TestSlicedStateWithMap) {
189 // Initialize config.
190 StatsdConfig config;
191 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
192
193 auto syncStartMatcher = CreateSyncStartAtomMatcher();
194 *config.add_atom_matcher() = syncStartMatcher;
195
Tej Singh5d823b32019-05-21 20:13:21 -0700196 int64_t screenOnId = 4444;
197 int64_t screenOffId = 9876;
198 auto state = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
tsaichristine7747d372020-02-28 17:36:59 -0800199 *config.add_state() = state;
200
201 // Create count metric that slices by screen state with on/off map.
202 int64_t metricId = 123456;
203 auto countMetric = config.add_count_metric();
204 countMetric->set_id(metricId);
205 countMetric->set_what(syncStartMatcher.id());
206 countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
207 countMetric->add_slice_by_state(state.id());
208
209 // Initialize StatsLogProcessor.
210 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
211 const uint64_t bucketSizeNs =
212 TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
213 int uid = 12345;
214 int64_t cfgId = 98765;
215 ConfigKey cfgKey(uid, cfgId);
216 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
217
218 // Check that StateTrackers were initialized correctly.
219 EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
220 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
221
222 // Check that CountMetricProducer was initialized correctly.
223 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
224 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
225 EXPECT_TRUE(metricsManager->isConfigValid());
226 EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
227 sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
228 EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
229 EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
230 EXPECT_EQ(metricProducer->mStateGroupMap.size(), 1);
231
232 StateMap map = state.map();
233 for (auto group : map.group()) {
234 for (auto value : group.value()) {
235 EXPECT_EQ(metricProducer->mStateGroupMap[SCREEN_STATE_ATOM_ID][value],
236 group.group_id());
237 }
238 }
239
240 /*
241 bucket #1 bucket #2
242 | 1 2 3 4 5 6 7 8 9 10 (minutes)
243 |-----------------------------|-----------------------------|--
244 x x x x x x x x x (syncStartEvents)
245 -----------------------------------------------------------SCREEN_OFF events
246 | (ScreenStateUnknownEvent = 0)
247 | | (ScreenStateOffEvent = 1)
248 | (ScreenStateDozeEvent = 3)
249 | (ScreenStateDozeSuspendEvent =
250 4)
251 -----------------------------------------------------------SCREEN_ON events
252 | | (ScreenStateOnEvent = 2)
253 | (ScreenStateVrEvent = 5)
254 | (ScreenStateOnSuspendEvent = 6)
255 */
256 // Initialize log events - first bucket.
257 std::vector<int> attributionUids1 = {123};
258 std::vector<string> attributionTags1 = {"App1"};
259
260 std::vector<std::unique_ptr<LogEvent>> events;
261 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 20 * NS_PER_SEC, attributionUids1,
262 attributionTags1, "sync_name")); // 0:30
263 events.push_back(CreateScreenStateChangedEvent(
264 bucketStartTimeNs + 30 * NS_PER_SEC,
265 android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 0:40
266 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
267 attributionTags1, "sync_name")); // 1:10
268 events.push_back(CreateScreenStateChangedEvent(
269 bucketStartTimeNs + 90 * NS_PER_SEC,
270 android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:40
271 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 120 * NS_PER_SEC, attributionUids1,
272 attributionTags1, "sync_name")); // 2:10
273 events.push_back(CreateScreenStateChangedEvent(
274 bucketStartTimeNs + 150 * NS_PER_SEC,
275 android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:40
276 events.push_back(CreateScreenStateChangedEvent(
277 bucketStartTimeNs + 180 * NS_PER_SEC,
278 android::view::DisplayStateEnum::DISPLAY_STATE_VR)); // 3:10
279 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 200 * NS_PER_SEC, attributionUids1,
280 attributionTags1, "sync_name")); // 3:30
281 events.push_back(CreateScreenStateChangedEvent(
282 bucketStartTimeNs + 210 * NS_PER_SEC,
283 android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:40
284 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 250 * NS_PER_SEC, attributionUids1,
285 attributionTags1, "sync_name")); // 4:20
286 events.push_back(CreateScreenStateChangedEvent(
287 bucketStartTimeNs + 280 * NS_PER_SEC,
288 android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 4:50
289 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 285 * NS_PER_SEC, attributionUids1,
290 attributionTags1, "sync_name")); // 4:55
291
292 // Initialize log events - second bucket.
293 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 360 * NS_PER_SEC, attributionUids1,
294 attributionTags1, "sync_name")); // 6:10
295 events.push_back(CreateScreenStateChangedEvent(
296 bucketStartTimeNs + 390 * NS_PER_SEC,
297 android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
298 events.push_back(CreateScreenStateChangedEvent(
299 bucketStartTimeNs + 430 * NS_PER_SEC,
300 android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND)); // 7:20
301 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 440 * NS_PER_SEC, attributionUids1,
302 attributionTags1, "sync_name")); // 7:30
303 events.push_back(CreateScreenStateChangedEvent(
304 bucketStartTimeNs + 540 * NS_PER_SEC,
305 android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 9:10
306 events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 570 * NS_PER_SEC, attributionUids1,
307 attributionTags1, "sync_name")); // 9:40
308
309 // Send log events to StatsLogProcessor.
310 for (auto& event : events) {
311 processor->OnLogEvent(event.get());
312 }
313
314 // Check dump report.
315 vector<uint8_t> buffer;
316 ConfigMetricsReportList reports;
317 processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
318 FAST, &buffer);
319 EXPECT_GT(buffer.size(), 0);
320 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
321 backfillDimensionPath(&reports);
322 backfillStringInReport(&reports);
323 backfillStartEndTimestamp(&reports);
324
325 EXPECT_EQ(1, reports.reports_size());
326 EXPECT_EQ(1, reports.reports(0).metrics_size());
327 EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
Tej Singh5d823b32019-05-21 20:13:21 -0700328 StatsLogReport::CountMetricDataWrapper countMetrics;
329 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
330 EXPECT_EQ(3, countMetrics.data_size());
tsaichristine7747d372020-02-28 17:36:59 -0800331
332 // For each CountMetricData, check StateValue info is correct and buckets
333 // have correct counts.
Tej Singh5d823b32019-05-21 20:13:21 -0700334 auto data = countMetrics.data(0);
tsaichristine7747d372020-02-28 17:36:59 -0800335 EXPECT_EQ(1, data.slice_by_state_size());
336 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
337 EXPECT_TRUE(data.slice_by_state(0).has_value());
338 EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
339 EXPECT_EQ(1, data.bucket_info_size());
340 EXPECT_EQ(1, data.bucket_info(0).count());
341
Tej Singh5d823b32019-05-21 20:13:21 -0700342 data = countMetrics.data(1);
tsaichristine7747d372020-02-28 17:36:59 -0800343 EXPECT_EQ(1, data.slice_by_state_size());
344 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
345 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
Tej Singh5d823b32019-05-21 20:13:21 -0700346 EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
tsaichristine7747d372020-02-28 17:36:59 -0800347 EXPECT_EQ(2, data.bucket_info_size());
348 EXPECT_EQ(1, data.bucket_info(0).count());
349 EXPECT_EQ(1, data.bucket_info(1).count());
Tej Singh5d823b32019-05-21 20:13:21 -0700350
351 data = countMetrics.data(2);
352 EXPECT_EQ(1, data.slice_by_state_size());
353 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
354 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
355 EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
356 EXPECT_EQ(2, data.bucket_info_size());
357 EXPECT_EQ(4, data.bucket_info(0).count());
358 EXPECT_EQ(2, data.bucket_info(1).count());
tsaichristine7747d372020-02-28 17:36:59 -0800359}
360
361/**
362* Test a count metric that has one slice_by_state with a primary field.
363
364* Once the CountMetricProducer is initialized, it should have one
365* MetricStateLink stored. State querying using a non-empty primary key
366* should also work as intended.
367*/
368TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields) {
369 // Initialize config.
370 StatsdConfig config;
371 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
372
373 auto appCrashMatcher =
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700374 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
tsaichristine7747d372020-02-28 17:36:59 -0800375 *config.add_atom_matcher() = appCrashMatcher;
376
377 auto state = CreateUidProcessState();
378 *config.add_state() = state;
379
380 // Create count metric that slices by uid process state.
381 int64_t metricId = 123456;
382 auto countMetric = config.add_count_metric();
383 countMetric->set_id(metricId);
384 countMetric->set_what(appCrashMatcher.id());
385 countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
386 countMetric->add_slice_by_state(state.id());
387 MetricStateLink* stateLink = countMetric->add_state_link();
388 stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
389 auto fieldsInWhat = stateLink->mutable_fields_in_what();
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700390 *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
tsaichristine7747d372020-02-28 17:36:59 -0800391 auto fieldsInState = stateLink->mutable_fields_in_state();
392 *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
393
394 // Initialize StatsLogProcessor.
395 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
396 const uint64_t bucketSizeNs =
397 TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
398 int uid = 12345;
399 int64_t cfgId = 98765;
400 ConfigKey cfgKey(uid, cfgId);
401 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
402
403 // Check that StateTrackers were initialized correctly.
404 EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
405 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
406
407 // Check that CountMetricProducer was initialized correctly.
408 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
409 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
410 EXPECT_TRUE(metricsManager->isConfigValid());
411 EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
412 sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
413 EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
414 EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
415 EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
416 EXPECT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
417
418 /*
419 NOTE: "1" or "2" represents the uid associated with the state/app crash event
420 bucket #1 bucket #2
421 | 1 2 3 4 5 6 7 8 9 10
422 |------------------------|-------------------------|--
423 1 1 1 1 1 2 1 1 2 (AppCrashEvents)
424 -----------------------------------------------------PROCESS STATE events
425 1 2 (TopEvent = 1002)
426 1 1 (ForegroundServiceEvent = 1003)
427 2 (ImportantBackgroundEvent = 1006)
428 1 1 1 (ImportantForegroundEvent = 1005)
429
430 Based on the diagram above, an AppCrashEvent querying for process state value would return:
431 - StateTracker::kStateUnknown
432 - Important foreground
433 - Top
434 - Important foreground
435 - Foreground service
436 - Top (both the app crash and state still have matching uid = 2)
437
438 - Foreground service
439 - Foreground service
440 - Important background
441 */
442 // Initialize log events - first bucket.
443 std::vector<std::unique_ptr<LogEvent>> events;
444 events.push_back(
445 CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30
446 events.push_back(CreateUidProcessStateChangedEvent(
447 bucketStartTimeNs + 30 * NS_PER_SEC, 1 /*uid*/,
448 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:40
449 events.push_back(
450 CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10
451 events.push_back(CreateUidProcessStateChangedEvent(
452 bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
453 android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 1:40
454 events.push_back(
455 CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/)); // 2:10
456 events.push_back(CreateUidProcessStateChangedEvent(
457 bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
458 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 2:40
459 events.push_back(
460 CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/)); // 3:30
461 events.push_back(CreateUidProcessStateChangedEvent(
462 bucketStartTimeNs + 210 * NS_PER_SEC, 1 /*uid*/,
463 android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 3:40
464 events.push_back(
465 CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/)); // 4:20
466 events.push_back(CreateUidProcessStateChangedEvent(
467 bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
468 android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 4:50
469 events.push_back(
470 CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/)); // 4:55
471
472 // Initialize log events - second bucket.
473 events.push_back(
474 CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/)); // 6:10
475 events.push_back(CreateUidProcessStateChangedEvent(
476 bucketStartTimeNs + 390 * NS_PER_SEC, 1 /*uid*/,
477 android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 6:40
478 events.push_back(CreateUidProcessStateChangedEvent(
479 bucketStartTimeNs + 430 * NS_PER_SEC, 2 /*uid*/,
480 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 7:20
481 events.push_back(
482 CreateAppCrashOccurredEvent(bucketStartTimeNs + 440 * NS_PER_SEC, 1 /*uid*/)); // 7:30
483 events.push_back(CreateUidProcessStateChangedEvent(
484 bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
485 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 9:10
486 events.push_back(
487 CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/)); // 9:40
488
489 // Send log events to StatsLogProcessor.
490 for (auto& event : events) {
491 processor->OnLogEvent(event.get());
492 }
493
494 // Check dump report.
495 vector<uint8_t> buffer;
496 ConfigMetricsReportList reports;
497 processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
498 FAST, &buffer);
499 EXPECT_GT(buffer.size(), 0);
500 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
501 backfillDimensionPath(&reports);
502 backfillStringInReport(&reports);
503 backfillStartEndTimestamp(&reports);
504
505 EXPECT_EQ(1, reports.reports_size());
506 EXPECT_EQ(1, reports.reports(0).metrics_size());
507 EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
Tej Singh5d823b32019-05-21 20:13:21 -0700508 StatsLogReport::CountMetricDataWrapper countMetrics;
509 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
510 EXPECT_EQ(5, countMetrics.data_size());
tsaichristine7747d372020-02-28 17:36:59 -0800511
512 // For each CountMetricData, check StateValue info is correct and buckets
513 // have correct counts.
Tej Singh5d823b32019-05-21 20:13:21 -0700514 auto data = countMetrics.data(0);
tsaichristine7747d372020-02-28 17:36:59 -0800515 EXPECT_EQ(1, data.slice_by_state_size());
516 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
517 EXPECT_TRUE(data.slice_by_state(0).has_value());
518 EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700519 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800520 EXPECT_EQ(1, data.bucket_info(0).count());
521
Tej Singh5d823b32019-05-21 20:13:21 -0700522 data = countMetrics.data(1);
tsaichristine7747d372020-02-28 17:36:59 -0800523 EXPECT_EQ(1, data.slice_by_state_size());
524 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
525 EXPECT_TRUE(data.slice_by_state(0).has_value());
526 EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700527 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800528 EXPECT_EQ(2, data.bucket_info(0).count());
529
Tej Singh5d823b32019-05-21 20:13:21 -0700530 data = countMetrics.data(2);
tsaichristine7747d372020-02-28 17:36:59 -0800531 EXPECT_EQ(1, data.slice_by_state_size());
532 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
533 EXPECT_TRUE(data.slice_by_state(0).has_value());
534 EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700535 ASSERT_EQ(2, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800536 EXPECT_EQ(1, data.bucket_info(0).count());
537 EXPECT_EQ(2, data.bucket_info(1).count());
Tej Singh5d823b32019-05-21 20:13:21 -0700538
539 data = countMetrics.data(3);
540 EXPECT_EQ(1, data.slice_by_state_size());
541 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
542 EXPECT_TRUE(data.slice_by_state(0).has_value());
543 EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
544 ASSERT_EQ(1, data.bucket_info_size());
545 EXPECT_EQ(2, data.bucket_info(0).count());
546
547 data = countMetrics.data(4);
548 EXPECT_EQ(1, data.slice_by_state_size());
549 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
550 EXPECT_TRUE(data.slice_by_state(0).has_value());
551 EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
552 ASSERT_EQ(1, data.bucket_info_size());
553 EXPECT_EQ(1, data.bucket_info(0).count());
tsaichristine7747d372020-02-28 17:36:59 -0800554}
555
556TEST(CountMetricE2eTest, TestMultipleSlicedStates) {
557 // Initialize config.
558 StatsdConfig config;
559 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
560
561 auto appCrashMatcher =
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700562 CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
tsaichristine7747d372020-02-28 17:36:59 -0800563 *config.add_atom_matcher() = appCrashMatcher;
564
Tej Singh5d823b32019-05-21 20:13:21 -0700565 int64_t screenOnId = 4444;
566 int64_t screenOffId = 9876;
567 auto state1 = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
tsaichristine7747d372020-02-28 17:36:59 -0800568 *config.add_state() = state1;
569 auto state2 = CreateUidProcessState();
570 *config.add_state() = state2;
571
572 // Create count metric that slices by screen state with on/off map and
573 // slices by uid process state.
574 int64_t metricId = 123456;
575 auto countMetric = config.add_count_metric();
576 countMetric->set_id(metricId);
577 countMetric->set_what(appCrashMatcher.id());
578 countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
579 countMetric->add_slice_by_state(state1.id());
580 countMetric->add_slice_by_state(state2.id());
581 MetricStateLink* stateLink = countMetric->add_state_link();
582 stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
583 auto fieldsInWhat = stateLink->mutable_fields_in_what();
Jeffrey Huang3eb84d42020-03-17 10:31:22 -0700584 *fieldsInWhat = CreateDimensions(util::APP_CRASH_OCCURRED, {1 /*uid*/});
tsaichristine7747d372020-02-28 17:36:59 -0800585 auto fieldsInState = stateLink->mutable_fields_in_state();
586 *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /*uid*/});
587
588 // Initialize StatsLogProcessor.
589 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
590 const uint64_t bucketSizeNs =
591 TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
592 int uid = 12345;
593 int64_t cfgId = 98765;
594 ConfigKey cfgKey(uid, cfgId);
595 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
596
597 // Check that StateTrackers were properly initialized.
598 EXPECT_EQ(2, StateManager::getInstance().getStateTrackersCount());
599 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
600 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
601
602 // Check that CountMetricProducer was initialized correctly.
603 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
604 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
605 EXPECT_TRUE(metricsManager->isConfigValid());
606 EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
607 sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
608 EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
609 EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
610 EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(1), UID_PROCESS_STATE_ATOM_ID);
611 EXPECT_EQ(metricProducer->mStateGroupMap.size(), 1);
612 EXPECT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
613
614 StateMap map = state1.map();
615 for (auto group : map.group()) {
616 for (auto value : group.value()) {
617 EXPECT_EQ(metricProducer->mStateGroupMap[SCREEN_STATE_ATOM_ID][value],
618 group.group_id());
619 }
620 }
621
622 /*
623 bucket #1 bucket #2
624 | 1 2 3 4 5 6 7 8 9 10 (minutes)
625 |------------------------|------------------------|--
626 1 1 1 1 1 2 1 1 2 (AppCrashEvents)
627 ---------------------------------------------------SCREEN_OFF events
628 | (ScreenUnknownEvent = 0)
629 | | (ScreenOffEvent = 1)
630 | (ScreenDozeEvent = 3)
631 ---------------------------------------------------SCREEN_ON events
632 | | (ScreenOnEvent = 2)
633 | (ScreenOnSuspendEvent = 6)
634 ---------------------------------------------------PROCESS STATE events
635 1 2 (TopEvent = 1002)
636 1 (ForegroundServiceEvent = 1003)
637 2 (ImportantBackgroundEvent = 1006)
638 1 1 1 (ImportantForegroundEvent = 1005)
639
640 Based on the diagram above, Screen State / Process State pairs for each
641 AppCrashEvent are:
642 - StateTracker::kStateUnknown / important foreground
643 - off / important foreground
644 - off / Top
645 - on / important foreground
646 - off / important foreground
647 - off / top
648
649 - off / important foreground
650 - off / foreground service
651 - on / important background
652
653 */
654 // Initialize log events - first bucket.
655 std::vector<std::unique_ptr<LogEvent>> events;
656 events.push_back(CreateUidProcessStateChangedEvent(
657 bucketStartTimeNs + 5 * NS_PER_SEC, 1 /*uid*/,
658 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 0:15
659 events.push_back(
660 CreateAppCrashOccurredEvent(bucketStartTimeNs + 20 * NS_PER_SEC, 1 /*uid*/)); // 0:30
661 events.push_back(CreateScreenStateChangedEvent(
662 bucketStartTimeNs + 30 * NS_PER_SEC,
663 android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN)); // 0:40
664 events.push_back(
665 CreateAppCrashOccurredEvent(bucketStartTimeNs + 60 * NS_PER_SEC, 1 /*uid*/)); // 1:10
666 events.push_back(CreateUidProcessStateChangedEvent(
667 bucketStartTimeNs + 90 * NS_PER_SEC, 1 /*uid*/,
668 android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 1:40
669 events.push_back(CreateScreenStateChangedEvent(
670 bucketStartTimeNs + 90 * NS_PER_SEC,
671 android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 1:40
672 events.push_back(
673 CreateAppCrashOccurredEvent(bucketStartTimeNs + 120 * NS_PER_SEC, 1 /*uid*/)); // 2:10
674 events.push_back(CreateUidProcessStateChangedEvent(
675 bucketStartTimeNs + 150 * NS_PER_SEC, 1 /*uid*/,
676 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 2:40
677 events.push_back(CreateScreenStateChangedEvent(
678 bucketStartTimeNs + 160 * NS_PER_SEC,
679 android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 2:50
680 events.push_back(
681 CreateAppCrashOccurredEvent(bucketStartTimeNs + 200 * NS_PER_SEC, 1 /*uid*/)); // 3:30
682 events.push_back(CreateScreenStateChangedEvent(
683 bucketStartTimeNs + 210 * NS_PER_SEC,
684 android::view::DisplayStateEnum::DISPLAY_STATE_DOZE)); // 3:40
685 events.push_back(
686 CreateAppCrashOccurredEvent(bucketStartTimeNs + 250 * NS_PER_SEC, 1 /*uid*/)); // 4:20
687 events.push_back(CreateUidProcessStateChangedEvent(
688 bucketStartTimeNs + 280 * NS_PER_SEC, 2 /*uid*/,
689 android::app::ProcessStateEnum::PROCESS_STATE_TOP)); // 4:50
690 events.push_back(
691 CreateAppCrashOccurredEvent(bucketStartTimeNs + 285 * NS_PER_SEC, 2 /*uid*/)); // 4:55
692
693 // Initialize log events - second bucket.
694 events.push_back(
695 CreateAppCrashOccurredEvent(bucketStartTimeNs + 360 * NS_PER_SEC, 1 /*uid*/)); // 6:10
696 events.push_back(CreateUidProcessStateChangedEvent(
697 bucketStartTimeNs + 380 * NS_PER_SEC, 1 /*uid*/,
698 android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE)); // 6:30
699 events.push_back(CreateScreenStateChangedEvent(
700 bucketStartTimeNs + 390 * NS_PER_SEC,
701 android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND)); // 6:40
702 events.push_back(CreateUidProcessStateChangedEvent(
703 bucketStartTimeNs + 420 * NS_PER_SEC, 2 /*uid*/,
704 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND)); // 7:10
705 events.push_back(CreateScreenStateChangedEvent(
706 bucketStartTimeNs + 440 * NS_PER_SEC,
707 android::view::DisplayStateEnum::DISPLAY_STATE_OFF)); // 7:30
708 events.push_back(
709 CreateAppCrashOccurredEvent(bucketStartTimeNs + 450 * NS_PER_SEC, 1 /*uid*/)); // 7:40
710 events.push_back(CreateScreenStateChangedEvent(
711 bucketStartTimeNs + 520 * NS_PER_SEC,
712 android::view::DisplayStateEnum::DISPLAY_STATE_ON)); // 8:50
713 events.push_back(CreateUidProcessStateChangedEvent(
714 bucketStartTimeNs + 540 * NS_PER_SEC, 1 /*uid*/,
715 android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND)); // 9:10
716 events.push_back(
717 CreateAppCrashOccurredEvent(bucketStartTimeNs + 570 * NS_PER_SEC, 2 /*uid*/)); // 9:40
718
719 // Send log events to StatsLogProcessor.
720 for (auto& event : events) {
721 processor->OnLogEvent(event.get());
722 }
723
724 // Check dump report.
725 vector<uint8_t> buffer;
726 ConfigMetricsReportList reports;
727 processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
728 FAST, &buffer);
729 EXPECT_GT(buffer.size(), 0);
730 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
731 backfillDimensionPath(&reports);
732 backfillStringInReport(&reports);
733 backfillStartEndTimestamp(&reports);
734
735 EXPECT_EQ(1, reports.reports_size());
736 EXPECT_EQ(1, reports.reports(0).metrics_size());
737 EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
Tej Singh5d823b32019-05-21 20:13:21 -0700738 StatsLogReport::CountMetricDataWrapper countMetrics;
739 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
740 EXPECT_EQ(6, countMetrics.data_size());
tsaichristine7747d372020-02-28 17:36:59 -0800741
742 // For each CountMetricData, check StateValue info is correct and buckets
743 // have correct counts.
Tej Singh5d823b32019-05-21 20:13:21 -0700744 auto data = countMetrics.data(0);
tsaichristine7747d372020-02-28 17:36:59 -0800745 EXPECT_EQ(2, data.slice_by_state_size());
746 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
747 EXPECT_TRUE(data.slice_by_state(0).has_value());
748 EXPECT_EQ(-1, data.slice_by_state(0).value());
749 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
750 EXPECT_TRUE(data.slice_by_state(1).has_value());
751 EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700752 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800753 EXPECT_EQ(1, data.bucket_info(0).count());
754
Tej Singh5d823b32019-05-21 20:13:21 -0700755 data = countMetrics.data(1);
tsaichristine7747d372020-02-28 17:36:59 -0800756 EXPECT_EQ(2, data.slice_by_state_size());
757 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
758 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
Tej Singh5d823b32019-05-21 20:13:21 -0700759 EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
tsaichristine7747d372020-02-28 17:36:59 -0800760 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
761 EXPECT_TRUE(data.slice_by_state(1).has_value());
762 EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700763 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800764 EXPECT_EQ(1, data.bucket_info(0).count());
765
Tej Singh5d823b32019-05-21 20:13:21 -0700766 data = countMetrics.data(2);
tsaichristine7747d372020-02-28 17:36:59 -0800767 EXPECT_EQ(2, data.slice_by_state_size());
768 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
769 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
Tej Singh5d823b32019-05-21 20:13:21 -0700770 EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
tsaichristine7747d372020-02-28 17:36:59 -0800771 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
772 EXPECT_TRUE(data.slice_by_state(1).has_value());
773 EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(1).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700774 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800775 EXPECT_EQ(1, data.bucket_info(0).count());
776
Tej Singh5d823b32019-05-21 20:13:21 -0700777 data = countMetrics.data(3);
tsaichristine7747d372020-02-28 17:36:59 -0800778 EXPECT_EQ(2, data.slice_by_state_size());
779 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
780 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
Tej Singh5d823b32019-05-21 20:13:21 -0700781 EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
tsaichristine7747d372020-02-28 17:36:59 -0800782 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
783 EXPECT_TRUE(data.slice_by_state(1).has_value());
784 EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(1).value());
Tej Singh5d823b32019-05-21 20:13:21 -0700785 ASSERT_EQ(1, data.bucket_info_size());
tsaichristine7747d372020-02-28 17:36:59 -0800786 EXPECT_EQ(2, data.bucket_info(0).count());
Tej Singh5d823b32019-05-21 20:13:21 -0700787
788 data = countMetrics.data(4);
789 EXPECT_EQ(2, data.slice_by_state_size());
790 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
791 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
792 EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
793 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
794 EXPECT_TRUE(data.slice_by_state(1).has_value());
795 EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
796 ASSERT_EQ(1, data.bucket_info_size());
797 EXPECT_EQ(1, data.bucket_info(0).count());
798
799 data = countMetrics.data(5);
800 EXPECT_EQ(2, data.slice_by_state_size());
801 EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
802 EXPECT_TRUE(data.slice_by_state(0).has_group_id());
803 EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
804 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
805 EXPECT_TRUE(data.slice_by_state(1).has_value());
806 EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
807 ASSERT_EQ(2, data.bucket_info_size());
808 EXPECT_EQ(2, data.bucket_info(0).count());
809 EXPECT_EQ(1, data.bucket_info(1).count());
tsaichristine7747d372020-02-28 17:36:59 -0800810}
tsaichristined21aacf2019-10-07 14:47:38 -0700811
812} // namespace statsd
813} // namespace os
814} // namespace android
815#else
816GTEST_LOG_(INFO) << "This test does nothing.\n";
817#endif