1 // Copyright (C) 2017 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <android/binder_interface_utils.h>
16 #include <gtest/gtest.h>
17
18 #include <vector>
19
20 #include "src/StatsLogProcessor.h"
21 #include "src/stats_log_util.h"
22 #include "tests/statsd_test_util.h"
23
24 using ::ndk::SharedRefBase;
25
26 namespace android {
27 namespace os {
28 namespace statsd {
29
30 #ifdef __ANDROID__
31
32 namespace {
33
34 const int64_t metricId = 123456;
35
CreateStatsdConfig(bool useCondition=true)36 StatsdConfig CreateStatsdConfig(bool useCondition = true) {
37 StatsdConfig config;
38 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
39 config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
40 auto pulledAtomMatcher =
41 CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
42 *config.add_atom_matcher() = pulledAtomMatcher;
43 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
44 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
45
46 auto screenIsOffPredicate = CreateScreenIsOffPredicate();
47 *config.add_predicate() = screenIsOffPredicate;
48
49 auto valueMetric = config.add_value_metric();
50 valueMetric->set_id(metricId);
51 valueMetric->set_what(pulledAtomMatcher.id());
52 if (useCondition) {
53 valueMetric->set_condition(screenIsOffPredicate.id());
54 }
55 *valueMetric->mutable_value_field() =
56 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
57 *valueMetric->mutable_dimensions_in_what() =
58 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
59 valueMetric->set_bucket(FIVE_MINUTES);
60 valueMetric->set_use_absolute_value_on_reset(true);
61 valueMetric->set_skip_zero_diff_output(false);
62 valueMetric->set_max_pull_delay_sec(INT_MAX);
63 valueMetric->set_split_bucket_for_app_upgrade(true);
64 valueMetric->set_min_bucket_size_nanos(1000);
65 return config;
66 }
67
CreateStatsdConfigWithStates()68 StatsdConfig CreateStatsdConfigWithStates() {
69 StatsdConfig config;
70 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
71 config.add_default_pull_packages("AID_ROOT"); // Fake puller is registered with root.
72
73 auto pulledAtomMatcher = CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
74 *config.add_atom_matcher() = pulledAtomMatcher;
75 *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
76 *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
77 *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
78 *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
79
80 auto screenOnPredicate = CreateScreenIsOnPredicate();
81 *config.add_predicate() = screenOnPredicate;
82
83 auto screenOffPredicate = CreateScreenIsOffPredicate();
84 *config.add_predicate() = screenOffPredicate;
85
86 auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
87 *config.add_predicate() = deviceUnpluggedPredicate;
88
89 auto screenOnOnBatteryPredicate = config.add_predicate();
90 screenOnOnBatteryPredicate->set_id(StringToId("screenOnOnBatteryPredicate"));
91 screenOnOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
92 addPredicateToPredicateCombination(screenOnPredicate, screenOnOnBatteryPredicate);
93 addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOnOnBatteryPredicate);
94
95 auto screenOffOnBatteryPredicate = config.add_predicate();
96 screenOffOnBatteryPredicate->set_id(StringToId("ScreenOffOnBattery"));
97 screenOffOnBatteryPredicate->mutable_combination()->set_operation(LogicalOperation::AND);
98 addPredicateToPredicateCombination(screenOffPredicate, screenOffOnBatteryPredicate);
99 addPredicateToPredicateCombination(deviceUnpluggedPredicate, screenOffOnBatteryPredicate);
100
101 const State screenState =
102 CreateScreenStateWithSimpleOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
103 *config.add_state() = screenState;
104
105 // ValueMetricSubsystemSleepWhileScreenOnOnBattery
106 auto valueMetric1 = config.add_value_metric();
107 valueMetric1->set_id(metricId);
108 valueMetric1->set_what(pulledAtomMatcher.id());
109 valueMetric1->set_condition(screenOnOnBatteryPredicate->id());
110 *valueMetric1->mutable_value_field() =
111 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
112 valueMetric1->set_bucket(FIVE_MINUTES);
113 valueMetric1->set_use_absolute_value_on_reset(true);
114 valueMetric1->set_skip_zero_diff_output(false);
115 valueMetric1->set_max_pull_delay_sec(INT_MAX);
116
117 // ValueMetricSubsystemSleepWhileScreenOffOnBattery
118 ValueMetric* valueMetric2 = config.add_value_metric();
119 valueMetric2->set_id(StringToId("ValueMetricSubsystemSleepWhileScreenOffOnBattery"));
120 valueMetric2->set_what(pulledAtomMatcher.id());
121 valueMetric2->set_condition(screenOffOnBatteryPredicate->id());
122 *valueMetric2->mutable_value_field() =
123 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
124 valueMetric2->set_bucket(FIVE_MINUTES);
125 valueMetric2->set_use_absolute_value_on_reset(true);
126 valueMetric2->set_skip_zero_diff_output(false);
127 valueMetric2->set_max_pull_delay_sec(INT_MAX);
128
129 // ValueMetricSubsystemSleepWhileOnBatterySliceScreen
130 ValueMetric* valueMetric3 = config.add_value_metric();
131 valueMetric3->set_id(StringToId("ValueMetricSubsystemSleepWhileOnBatterySliceScreen"));
132 valueMetric3->set_what(pulledAtomMatcher.id());
133 valueMetric3->set_condition(deviceUnpluggedPredicate.id());
134 *valueMetric3->mutable_value_field() =
135 CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
136 valueMetric3->add_slice_by_state(screenState.id());
137 valueMetric3->set_bucket(FIVE_MINUTES);
138 valueMetric3->set_use_absolute_value_on_reset(true);
139 valueMetric3->set_skip_zero_diff_output(false);
140 valueMetric3->set_max_pull_delay_sec(INT_MAX);
141 return config;
142 }
143
144 } // namespace
145
146 /**
147 * Tests the initial condition and condition after the first log events for
148 * value metrics with either a combination condition or simple condition.
149 *
150 * Metrics should be initialized with condition kUnknown (given that the
151 * predicate is using the default InitialValue of UNKNOWN). The condition should
152 * be updated to either kFalse or kTrue if a condition event is logged for all
153 * children conditions.
154 */
TEST(ValueMetricE2eTest,TestInitialConditionChanges)155 TEST(ValueMetricE2eTest, TestInitialConditionChanges) {
156 StatsdConfig config = CreateStatsdConfigWithStates();
157 int64_t baseTimeNs = getElapsedRealtimeNs();
158 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
159 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
160
161 ConfigKey cfgKey;
162 int32_t tagId = util::SUBSYSTEM_SLEEP_STATE;
163 auto processor =
164 CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
165 SharedRefBase::make<FakeSubsystemSleepCallback>(), tagId);
166
167 EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
168 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
169 EXPECT_TRUE(metricsManager->isConfigValid());
170 EXPECT_EQ(3, metricsManager->mAllMetricProducers.size());
171
172 // Combination condition metric - screen on and device unplugged
173 sp<MetricProducer> metricProducer1 = metricsManager->mAllMetricProducers[0];
174 // Simple condition metric - device unplugged
175 sp<MetricProducer> metricProducer2 = metricsManager->mAllMetricProducers[2];
176
177 EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
178 EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
179
180 auto screenOnEvent =
181 CreateScreenStateChangedEvent(configAddedTimeNs + 30, android::view::DISPLAY_STATE_ON);
182 processor->OnLogEvent(screenOnEvent.get());
183 EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
184 EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
185
186 auto screenOffEvent =
187 CreateScreenStateChangedEvent(configAddedTimeNs + 40, android::view::DISPLAY_STATE_OFF);
188 processor->OnLogEvent(screenOffEvent.get());
189 EXPECT_EQ(ConditionState::kUnknown, metricProducer1->mCondition);
190 EXPECT_EQ(ConditionState::kUnknown, metricProducer2->mCondition);
191
192 auto pluggedUsbEvent = CreateBatteryStateChangedEvent(
193 configAddedTimeNs + 50, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB);
194 processor->OnLogEvent(pluggedUsbEvent.get());
195 EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
196 EXPECT_EQ(ConditionState::kFalse, metricProducer2->mCondition);
197
198 auto pluggedNoneEvent = CreateBatteryStateChangedEvent(
199 configAddedTimeNs + 70, BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE);
200 processor->OnLogEvent(pluggedNoneEvent.get());
201 EXPECT_EQ(ConditionState::kFalse, metricProducer1->mCondition);
202 EXPECT_EQ(ConditionState::kTrue, metricProducer2->mCondition);
203 }
204
TEST(ValueMetricE2eTest,TestPulledEvents)205 TEST(ValueMetricE2eTest, TestPulledEvents) {
206 auto config = CreateStatsdConfig();
207 int64_t baseTimeNs = getElapsedRealtimeNs();
208 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
209 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
210
211 ConfigKey cfgKey;
212 auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
213 SharedRefBase::make<FakeSubsystemSleepCallback>(),
214 util::SUBSYSTEM_SLEEP_STATE);
215 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
216 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
217 processor->mPullerManager->ForceClearPullerCache();
218
219 int startBucketNum = processor->mMetricsManagers.begin()
220 ->second->mAllMetricProducers[0]
221 ->getCurrentBucketNum();
222 EXPECT_GT(startBucketNum, (int64_t)0);
223
224 // When creating the config, the value metric producer should register the alarm at the
225 // end of the current bucket.
226 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
227 EXPECT_EQ(bucketSizeNs,
228 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
229 int64_t& expectedPullTimeNs =
230 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
231 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
232
233 auto screenOffEvent =
234 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
235 processor->OnLogEvent(screenOffEvent.get());
236
237 auto screenOnEvent =
238 CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
239 processor->OnLogEvent(screenOnEvent.get());
240
241 screenOffEvent =
242 CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
243 processor->OnLogEvent(screenOffEvent.get());
244
245 // Pulling alarm arrives on time and reset the sequential pulling alarm.
246 processor->informPullAlarmFired(expectedPullTimeNs + 1);
247 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
248
249 processor->informPullAlarmFired(expectedPullTimeNs + 1);
250
251 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 2 * bucketSizeNs + 15,
252 android::view::DISPLAY_STATE_ON);
253 processor->OnLogEvent(screenOnEvent.get());
254
255 processor->informPullAlarmFired(expectedPullTimeNs + 1);
256
257 processor->informPullAlarmFired(expectedPullTimeNs + 1);
258
259 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 11,
260 android::view::DISPLAY_STATE_OFF);
261 processor->OnLogEvent(screenOffEvent.get());
262
263 processor->informPullAlarmFired(expectedPullTimeNs + 1);
264
265 processor->informPullAlarmFired(expectedPullTimeNs + 1);
266
267 ConfigMetricsReportList reports;
268 vector<uint8_t> buffer;
269 processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
270 ADB_DUMP, FAST, &buffer);
271 EXPECT_TRUE(buffer.size() > 0);
272 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
273 backfillDimensionPath(&reports);
274 backfillStringInReport(&reports);
275 backfillStartEndTimestamp(&reports);
276 ASSERT_EQ(1, reports.reports_size());
277 ASSERT_EQ(1, reports.reports(0).metrics_size());
278 StatsLogReport::ValueMetricDataWrapper valueMetrics;
279 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
280 ASSERT_GT((int)valueMetrics.data_size(), 1);
281
282 auto data = valueMetrics.data(0);
283 EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
284 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
285 EXPECT_EQ(1 /* subsystem name field */,
286 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
287 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
288 // We have 4 buckets, the first one was incomplete since the condition was unknown.
289 ASSERT_EQ(4, data.bucket_info_size());
290
291 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
292 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
293 ASSERT_EQ(1, data.bucket_info(0).values_size());
294
295 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
296 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
297 ASSERT_EQ(1, data.bucket_info(1).values_size());
298
299 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
300 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
301 ASSERT_EQ(1, data.bucket_info(2).values_size());
302
303 EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
304 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
305 ASSERT_EQ(1, data.bucket_info(3).values_size());
306
307 valueMetrics = reports.reports(0).metrics(0).value_metrics();
308 ASSERT_EQ(2, valueMetrics.skipped_size());
309
310 StatsLogReport::SkippedBuckets skipped = valueMetrics.skipped(0);
311 EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, skipped.drop_event(0).drop_reason());
312 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 2 * bucketSizeNs)),
313 skipped.start_bucket_elapsed_nanos());
314 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 3 * bucketSizeNs)),
315 skipped.end_bucket_elapsed_nanos());
316
317 skipped = valueMetrics.skipped(1);
318 EXPECT_EQ(BucketDropReason::NO_DATA, skipped.drop_event(0).drop_reason());
319 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
320 skipped.start_bucket_elapsed_nanos());
321 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 6 * bucketSizeNs)),
322 skipped.end_bucket_elapsed_nanos());
323 }
324
TEST(ValueMetricE2eTest,TestPulledEvents_LateAlarm)325 TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
326 auto config = CreateStatsdConfig();
327 int64_t baseTimeNs = getElapsedRealtimeNs();
328 // 10 mins == 2 bucket durations.
329 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
330 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
331
332 ConfigKey cfgKey;
333 auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
334 SharedRefBase::make<FakeSubsystemSleepCallback>(),
335 util::SUBSYSTEM_SLEEP_STATE);
336 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
337 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
338 processor->mPullerManager->ForceClearPullerCache();
339
340 int startBucketNum = processor->mMetricsManagers.begin()
341 ->second->mAllMetricProducers[0]
342 ->getCurrentBucketNum();
343 EXPECT_GT(startBucketNum, (int64_t)0);
344
345 // When creating the config, the value metric producer should register the alarm at the
346 // end of the current bucket.
347 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
348 EXPECT_EQ(bucketSizeNs,
349 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
350 int64_t& expectedPullTimeNs =
351 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
352 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
353
354 // Screen off/on/off events.
355 auto screenOffEvent =
356 CreateScreenStateChangedEvent(configAddedTimeNs + 55, android::view::DISPLAY_STATE_OFF);
357 processor->OnLogEvent(screenOffEvent.get());
358
359 auto screenOnEvent =
360 CreateScreenStateChangedEvent(configAddedTimeNs + 65, android::view::DISPLAY_STATE_ON);
361 processor->OnLogEvent(screenOnEvent.get());
362
363 screenOffEvent =
364 CreateScreenStateChangedEvent(configAddedTimeNs + 75, android::view::DISPLAY_STATE_OFF);
365 processor->OnLogEvent(screenOffEvent.get());
366
367 // Pulling alarm arrives late by 2 buckets and 1 ns. 2 buckets late is too far away in the
368 // future, data will be skipped.
369 processor->informPullAlarmFired(expectedPullTimeNs + 2 * bucketSizeNs + 1);
370 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
371
372 // This screen state change will start a new bucket.
373 screenOnEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 4 * bucketSizeNs + 65,
374 android::view::DISPLAY_STATE_ON);
375 processor->OnLogEvent(screenOnEvent.get());
376
377 // The alarm is delayed but we already created a bucket thanks to the screen state condition.
378 // This bucket does not have to be skipped since the alarm arrives in time for the next bucket.
379 processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
380 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
381
382 screenOffEvent = CreateScreenStateChangedEvent(configAddedTimeNs + 6 * bucketSizeNs + 31,
383 android::view::DISPLAY_STATE_OFF);
384 processor->OnLogEvent(screenOffEvent.get());
385
386 processor->informPullAlarmFired(expectedPullTimeNs + bucketSizeNs + 21);
387 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 8 * bucketSizeNs, expectedPullTimeNs);
388
389 processor->informPullAlarmFired(expectedPullTimeNs + 1);
390 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 9 * bucketSizeNs, expectedPullTimeNs);
391
392 ConfigMetricsReportList reports;
393 vector<uint8_t> buffer;
394 processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
395 ADB_DUMP, FAST, &buffer);
396 EXPECT_TRUE(buffer.size() > 0);
397 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
398 backfillDimensionPath(&reports);
399 backfillStringInReport(&reports);
400 backfillStartEndTimestamp(&reports);
401 ASSERT_EQ(1, reports.reports_size());
402 ASSERT_EQ(1, reports.reports(0).metrics_size());
403 StatsLogReport::ValueMetricDataWrapper valueMetrics;
404 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
405 ASSERT_GT((int)valueMetrics.data_size(), 1);
406
407 auto data = valueMetrics.data(0);
408 EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
409 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
410 EXPECT_EQ(1 /* subsystem name field */,
411 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
412 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
413 ASSERT_EQ(3, data.bucket_info_size());
414
415 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
416 EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
417 ASSERT_EQ(1, data.bucket_info(0).values_size());
418
419 EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
420 EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
421 ASSERT_EQ(1, data.bucket_info(1).values_size());
422
423 EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
424 EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
425 ASSERT_EQ(1, data.bucket_info(2).values_size());
426
427 valueMetrics = reports.reports(0).metrics(0).value_metrics();
428 ASSERT_EQ(3, valueMetrics.skipped_size());
429
430 StatsLogReport::SkippedBuckets skipped = valueMetrics.skipped(0);
431 EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, skipped.drop_event(0).drop_reason());
432 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 2 * bucketSizeNs)),
433 skipped.start_bucket_elapsed_nanos());
434 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
435 skipped.end_bucket_elapsed_nanos());
436
437 skipped = valueMetrics.skipped(1);
438 EXPECT_EQ(BucketDropReason::NO_DATA, skipped.drop_event(0).drop_reason());
439 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 6 * bucketSizeNs)),
440 skipped.start_bucket_elapsed_nanos());
441 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 7 * bucketSizeNs)),
442 skipped.end_bucket_elapsed_nanos());
443
444 skipped = valueMetrics.skipped(2);
445 EXPECT_EQ(BucketDropReason::NO_DATA, skipped.drop_event(0).drop_reason());
446 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 7 * bucketSizeNs)),
447 skipped.start_bucket_elapsed_nanos());
448 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 8 * bucketSizeNs)),
449 skipped.end_bucket_elapsed_nanos());
450 }
451
TEST(ValueMetricE2eTest,TestPulledEvents_WithActivation)452 TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
453 auto config = CreateStatsdConfig(false);
454 int64_t baseTimeNs = getElapsedRealtimeNs();
455 int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
456 int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000;
457
458 auto batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
459 *config.add_atom_matcher() = batterySaverStartMatcher;
460 const int64_t ttlNs = 2 * bucketSizeNs; // Two buckets.
461 auto metric_activation = config.add_metric_activation();
462 metric_activation->set_metric_id(metricId);
463 metric_activation->set_activation_type(ACTIVATE_IMMEDIATELY);
464 auto event_activation = metric_activation->add_event_activation();
465 event_activation->set_atom_matcher_id(batterySaverStartMatcher.id());
466 event_activation->set_ttl_seconds(ttlNs / 1000000000);
467
468 StatsdStats::getInstance().reset();
469
470 ConfigKey cfgKey;
471 auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
472 SharedRefBase::make<FakeSubsystemSleepCallback>(),
473 util::SUBSYSTEM_SLEEP_STATE);
474 ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
475 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
476 processor->mPullerManager->ForceClearPullerCache();
477
478 const int startBucketNum = processor->mMetricsManagers.begin()
479 ->second->mAllMetricProducers[0]
480 ->getCurrentBucketNum();
481 EXPECT_EQ(startBucketNum, 2);
482 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
483
484 // When creating the config, the value metric producer should register the alarm at the
485 // end of the current bucket.
486 ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
487 EXPECT_EQ(bucketSizeNs,
488 processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
489 int64_t& expectedPullTimeNs =
490 processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs;
491 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs);
492
493 // Initialize metric.
494 const int64_t metricInitTimeNs = configAddedTimeNs + 1; // 10 mins + 1 ns.
495 processor->onStatsdInitCompleted(metricInitTimeNs);
496
497 // Check no pull occurred since metric not active.
498 StatsdStatsReport_PulledAtomStats pulledAtomStats =
499 getPulledAtomStats(util::SUBSYSTEM_SLEEP_STATE);
500 EXPECT_EQ(pulledAtomStats.atom_id(), util::SUBSYSTEM_SLEEP_STATE);
501 EXPECT_EQ(pulledAtomStats.total_pull(), 0);
502
503 // Check skip bucket is not added when metric is not active.
504 int64_t dumpReportTimeNs = metricInitTimeNs + 1; // 10 mins + 2 ns.
505 vector<uint8_t> buffer;
506 processor->onDumpReport(cfgKey, dumpReportTimeNs, true /* include_current_partial_bucket */,
507 true /* erase_data */, ADB_DUMP, FAST, &buffer);
508 ConfigMetricsReportList reports;
509 EXPECT_TRUE(buffer.size() > 0);
510 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
511 ASSERT_EQ(1, reports.reports_size());
512 ASSERT_EQ(1, reports.reports(0).metrics_size());
513 StatsLogReport::ValueMetricDataWrapper valueMetrics =
514 reports.reports(0).metrics(0).value_metrics();
515 EXPECT_EQ(valueMetrics.skipped_size(), 0);
516
517 // App upgrade.
518 const int64_t appUpgradeTimeNs = dumpReportTimeNs + 1; // 10 mins + 3 ns.
519 processor->notifyAppUpgrade(appUpgradeTimeNs, "appName", 1000 /* uid */, 2 /* version */);
520
521 // Check no pull occurred since metric not active.
522 pulledAtomStats = getPulledAtomStats(util::SUBSYSTEM_SLEEP_STATE);
523 EXPECT_EQ(pulledAtomStats.atom_id(), util::SUBSYSTEM_SLEEP_STATE);
524 EXPECT_EQ(pulledAtomStats.total_pull(), 0);
525
526 // Check skip bucket is not added when metric is not active.
527 dumpReportTimeNs = appUpgradeTimeNs + 1; // 10 mins + 4 ns.
528 buffer.clear();
529 processor->onDumpReport(cfgKey, dumpReportTimeNs, true /* include_current_partial_bucket */,
530 true /* erase_data */, ADB_DUMP, FAST, &buffer);
531 EXPECT_TRUE(buffer.size() > 0);
532 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
533 ASSERT_EQ(1, reports.reports_size());
534 ASSERT_EQ(1, reports.reports(0).metrics_size());
535 valueMetrics = reports.reports(0).metrics(0).value_metrics();
536 EXPECT_EQ(valueMetrics.skipped_size(), 0);
537
538 // Dump report with a pull. The pull should not happen because metric is inactive.
539 dumpReportTimeNs = dumpReportTimeNs + 1; // 10 mins + 6 ns.
540 buffer.clear();
541 processor->onDumpReport(cfgKey, dumpReportTimeNs, true /* include_current_partial_bucket */,
542 true /* erase_data */, ADB_DUMP, NO_TIME_CONSTRAINTS, &buffer);
543 pulledAtomStats = getPulledAtomStats(util::SUBSYSTEM_SLEEP_STATE);
544 EXPECT_EQ(pulledAtomStats.atom_id(), util::SUBSYSTEM_SLEEP_STATE);
545 EXPECT_EQ(pulledAtomStats.total_pull(), 0);
546
547 // Check skipped bucket is not added from the dump operation when metric is not active.
548 EXPECT_TRUE(buffer.size() > 0);
549 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
550 ASSERT_EQ(1, reports.reports_size());
551 ASSERT_EQ(1, reports.reports(0).metrics_size());
552 valueMetrics = reports.reports(0).metrics(0).value_metrics();
553 EXPECT_EQ(valueMetrics.skipped_size(), 0);
554
555 // Pulling alarm arrives on time and reset the sequential pulling alarm. This bucket is skipped.
556 processor->informPullAlarmFired(expectedPullTimeNs + 1); // 15 mins + 1 ns.
557 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 2 * bucketSizeNs, expectedPullTimeNs);
558 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
559
560 // Activate the metric. A pull occurs here that sets the base.
561 // 15 mins + 2 ms
562 const int64_t activationNs = configAddedTimeNs + bucketSizeNs + (2 * 1000 * 1000); // 2 millis.
563 auto batterySaverOnEvent = CreateBatterySaverOnEvent(activationNs);
564 processor->OnLogEvent(batterySaverOnEvent.get()); // 15 mins + 2 ms.
565 EXPECT_TRUE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
566
567 // This bucket should be kept. 1 total
568 processor->informPullAlarmFired(expectedPullTimeNs + 1); // 20 mins + 1 ns.
569 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 3 * bucketSizeNs, expectedPullTimeNs);
570
571 // 25 mins + 2 ns.
572 // This bucket should be kept. 2 total
573 processor->informPullAlarmFired(expectedPullTimeNs + 2); // 25 mins + 2 ns.
574 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 4 * bucketSizeNs, expectedPullTimeNs);
575
576 // Create random event to deactivate metric.
577 // A pull occurs here and a partial bucket is created. The bucket ending here is kept. 3 total.
578 // 25 mins + 2 ms + 1 ns.
579 const int64_t deactivationNs = activationNs + ttlNs + 1;
580 auto deactivationEvent = CreateScreenBrightnessChangedEvent(deactivationNs, 50);
581 processor->OnLogEvent(deactivationEvent.get());
582 EXPECT_FALSE(processor->mMetricsManagers.begin()->second->mAllMetricProducers[0]->isActive());
583
584 // 30 mins + 3 ns. This bucket is skipped.
585 processor->informPullAlarmFired(expectedPullTimeNs + 3);
586 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 5 * bucketSizeNs, expectedPullTimeNs);
587
588 // 35 mins + 4 ns. This bucket is skipped
589 processor->informPullAlarmFired(expectedPullTimeNs + 4);
590 EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + 6 * bucketSizeNs, expectedPullTimeNs);
591
592 dumpReportTimeNs = configAddedTimeNs + 6 * bucketSizeNs + 10;
593 buffer.clear();
594 // 40 mins + 10 ns.
595 processor->onDumpReport(cfgKey, dumpReportTimeNs, false /* include_current_partial_bucket */,
596 true /* erase_data */, ADB_DUMP, FAST, &buffer);
597 EXPECT_TRUE(buffer.size() > 0);
598 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
599 backfillDimensionPath(&reports);
600 backfillStringInReport(&reports);
601 backfillStartEndTimestamp(&reports);
602 ASSERT_EQ(1, reports.reports_size());
603 ASSERT_EQ(1, reports.reports(0).metrics_size());
604 valueMetrics = StatsLogReport::ValueMetricDataWrapper();
605 sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
606 ASSERT_GT((int)valueMetrics.data_size(), 0);
607
608 auto data = valueMetrics.data(0);
609 EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
610 ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
611 EXPECT_EQ(1 /* subsystem name field */,
612 data.dimensions_in_what().value_tuple().dimensions_value(0).field());
613 EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
614 // We have 3 full buckets, the two surrounding the activation are dropped.
615 ASSERT_EQ(3, data.bucket_info_size());
616
617 auto bucketInfo = data.bucket_info(0);
618 EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
619 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
620 ASSERT_EQ(1, bucketInfo.values_size());
621
622 bucketInfo = data.bucket_info(1);
623 EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
624 EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
625 ASSERT_EQ(1, bucketInfo.values_size());
626
627 bucketInfo = data.bucket_info(2);
628 EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
629 bucketInfo.start_bucket_elapsed_nanos());
630 EXPECT_EQ(MillisToNano(NanoToMillis(deactivationNs)), bucketInfo.end_bucket_elapsed_nanos());
631 ASSERT_EQ(1, bucketInfo.values_size());
632
633 // Check skipped bucket is not added after deactivation.
634 dumpReportTimeNs = configAddedTimeNs + 7 * bucketSizeNs + 10;
635 buffer.clear();
636 // 45 mins + 10 ns.
637 processor->onDumpReport(cfgKey, dumpReportTimeNs, true /* include_current_partial_bucket */,
638 true /* erase_data */, ADB_DUMP, FAST, &buffer);
639 EXPECT_TRUE(buffer.size() > 0);
640 EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
641 ASSERT_EQ(1, reports.reports_size());
642 ASSERT_EQ(1, reports.reports(0).metrics_size());
643 valueMetrics = reports.reports(0).metrics(0).value_metrics();
644 EXPECT_EQ(valueMetrics.skipped_size(), 0);
645 }
646
647 /**
648 * Test initialization of a simple value metric that is sliced by a state.
649 *
650 * ValueCpuUserTimePerScreenState
651 */
TEST(ValueMetricE2eTest,TestInitWithSlicedState)652 TEST(ValueMetricE2eTest, TestInitWithSlicedState) {
653 // Create config.
654 StatsdConfig config;
655 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
656
657 auto pulledAtomMatcher =
658 CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
659 *config.add_atom_matcher() = pulledAtomMatcher;
660
661 auto screenState = CreateScreenState();
662 *config.add_state() = screenState;
663
664 // Create value metric that slices by screen state without a map.
665 int64_t metricId = 123456;
666 auto valueMetric = config.add_value_metric();
667 valueMetric->set_id(metricId);
668 valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
669 valueMetric->set_what(pulledAtomMatcher.id());
670 *valueMetric->mutable_value_field() =
671 CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
672 valueMetric->add_slice_by_state(screenState.id());
673 valueMetric->set_max_pull_delay_sec(INT_MAX);
674
675 // Initialize StatsLogProcessor.
676 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
677 const uint64_t bucketSizeNs =
678 TimeUnitToBucketSizeInMillis(config.value_metric(0).bucket()) * 1000000LL;
679 int uid = 12345;
680 int64_t cfgId = 98765;
681 ConfigKey cfgKey(uid, cfgId);
682
683 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
684
685 // Check that StateTrackers were initialized correctly.
686 EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
687 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
688
689 // Check that NumericValueMetricProducer was initialized correctly.
690 ASSERT_EQ(1U, processor->mMetricsManagers.size());
691 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
692 EXPECT_TRUE(metricsManager->isConfigValid());
693 ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
694 sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
695 ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
696 EXPECT_EQ(SCREEN_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
697 ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
698 }
699
700 /**
701 * Test initialization of a value metric that is sliced by state and has
702 * dimensions_in_what.
703 *
704 * ValueCpuUserTimePerUidPerUidProcessState
705 */
TEST(ValueMetricE2eTest,TestInitWithSlicedState_WithDimensions)706 TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions) {
707 // Create config.
708 StatsdConfig config;
709 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
710
711 auto cpuTimePerUidMatcher =
712 CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
713 *config.add_atom_matcher() = cpuTimePerUidMatcher;
714
715 auto uidProcessState = CreateUidProcessState();
716 *config.add_state() = uidProcessState;
717
718 // Create value metric that slices by screen state with a complete map.
719 int64_t metricId = 123456;
720 auto valueMetric = config.add_value_metric();
721 valueMetric->set_id(metricId);
722 valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
723 valueMetric->set_what(cpuTimePerUidMatcher.id());
724 *valueMetric->mutable_value_field() =
725 CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
726 *valueMetric->mutable_dimensions_in_what() =
727 CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
728 valueMetric->add_slice_by_state(uidProcessState.id());
729 MetricStateLink* stateLink = valueMetric->add_state_link();
730 stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
731 auto fieldsInWhat = stateLink->mutable_fields_in_what();
732 *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
733 auto fieldsInState = stateLink->mutable_fields_in_state();
734 *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
735 valueMetric->set_max_pull_delay_sec(INT_MAX);
736
737 // Initialize StatsLogProcessor.
738 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
739 int uid = 12345;
740 int64_t cfgId = 98765;
741 ConfigKey cfgKey(uid, cfgId);
742
743 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
744
745 // Check that StateTrackers were initialized correctly.
746 EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
747 EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
748
749 // Check that NumericValueMetricProducer was initialized correctly.
750 ASSERT_EQ(1U, processor->mMetricsManagers.size());
751 sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
752 EXPECT_TRUE(metricsManager->isConfigValid());
753 ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
754 sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
755 ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
756 EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
757 ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
758 }
759
760 /**
761 * Test initialization of a value metric that is sliced by state and has
762 * dimensions_in_what.
763 *
764 * ValueCpuUserTimePerUidPerUidProcessState
765 */
TEST(ValueMetricE2eTest,TestInitWithSlicedState_WithIncorrectDimensions)766 TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions) {
767 // Create config.
768 StatsdConfig config;
769 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
770
771 auto cpuTimePerUidMatcher =
772 CreateSimpleAtomMatcher("CpuTimePerUidMatcher", util::CPU_TIME_PER_UID);
773 *config.add_atom_matcher() = cpuTimePerUidMatcher;
774
775 auto uidProcessState = CreateUidProcessState();
776 *config.add_state() = uidProcessState;
777
778 // Create value metric that slices by screen state with a complete map.
779 int64_t metricId = 123456;
780 auto valueMetric = config.add_value_metric();
781 valueMetric->set_id(metricId);
782 valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
783 valueMetric->set_what(cpuTimePerUidMatcher.id());
784 *valueMetric->mutable_value_field() =
785 CreateDimensions(util::CPU_TIME_PER_UID, {2 /* user_time_micros */});
786 valueMetric->add_slice_by_state(uidProcessState.id());
787 MetricStateLink* stateLink = valueMetric->add_state_link();
788 stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
789 auto fieldsInWhat = stateLink->mutable_fields_in_what();
790 *fieldsInWhat = CreateDimensions(util::CPU_TIME_PER_UID, {1 /* uid */});
791 auto fieldsInState = stateLink->mutable_fields_in_state();
792 *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
793 valueMetric->set_max_pull_delay_sec(INT_MAX);
794
795 // Initialize StatsLogProcessor.
796 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
797 int uid = 12345;
798 int64_t cfgId = 98765;
799 ConfigKey cfgKey(uid, cfgId);
800 auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
801
802 // No StateTrackers are initialized.
803 EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
804
805 // Config initialization fails.
806 ASSERT_EQ(0, processor->mMetricsManagers.size());
807 }
808
TEST(ValueMetricE2eTest,TestInitWithValueFieldPositionALL)809 TEST(ValueMetricE2eTest, TestInitWithValueFieldPositionALL) {
810 // Create config.
811 StatsdConfig config;
812 config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
813
814 AtomMatcher testAtomReportedMatcher =
815 CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
816 *config.add_atom_matcher() = testAtomReportedMatcher;
817
818 // Create value metric.
819 int64_t metricId = 123456;
820 ValueMetric* valueMetric = config.add_value_metric();
821 valueMetric->set_id(metricId);
822 valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
823 valueMetric->set_what(testAtomReportedMatcher.id());
824 *valueMetric->mutable_value_field() = CreateRepeatedDimensions(
825 util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
826
827 // Initialize StatsLogProcessor.
828 const uint64_t bucketStartTimeNs = 10000000000; // 0:10
829 int uid = 12345;
830 int64_t cfgId = 98765;
831 ConfigKey cfgKey(uid, cfgId);
832 sp<StatsLogProcessor> processor =
833 CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
834
835 // Config initialization fails.
836 ASSERT_EQ(0, processor->mMetricsManagers.size());
837 }
838
839 #else
840 GTEST_LOG_(INFO) << "This test does nothing.\n";
841 #endif
842
843 } // namespace statsd
844 } // namespace os
845 } // namespace android
846