• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ibinder.h>
16 #include <android/binder_interface_utils.h>
17 #include <gtest/gtest.h>
18 
19 #include <vector>
20 
21 #include "src/StatsLogProcessor.h"
22 #include "src/StatsService.h"
23 #include "src/packages/UidMap.h"
24 #include "src/stats_log_util.h"
25 #include "tests/statsd_test_util.h"
26 
27 using ::ndk::SharedRefBase;
28 using std::shared_ptr;
29 
30 namespace android {
31 namespace os {
32 namespace statsd {
33 
34 #ifdef __ANDROID__
35 namespace {
36 const string kApp1 = "app1.sharing.1";
37 
MakeCountMetricConfig(const std::optional<bool> splitBucket)38 StatsdConfig MakeCountMetricConfig(const std::optional<bool> splitBucket) {
39     StatsdConfig config;
40     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
41 
42     auto appCrashMatcher = CreateProcessCrashAtomMatcher();
43     *config.add_atom_matcher() = appCrashMatcher;
44     auto countMetric = config.add_count_metric();
45     countMetric->set_id(StringToId("AppCrashes"));
46     countMetric->set_what(appCrashMatcher.id());
47     countMetric->set_bucket(FIVE_MINUTES);
48     if (splitBucket.has_value()) {
49         countMetric->set_split_bucket_for_app_upgrade(splitBucket.value());
50     }
51     return config;
52 }
53 
MakeValueMetricConfig(int64_t minTime)54 StatsdConfig MakeValueMetricConfig(int64_t minTime) {
55     StatsdConfig config;
56     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
57     config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
58 
59     auto pulledAtomMatcher =
60             CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
61     *config.add_atom_matcher() = pulledAtomMatcher;
62     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
63     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
64 
65     auto valueMetric = config.add_value_metric();
66     valueMetric->set_id(123456);
67     valueMetric->set_what(pulledAtomMatcher.id());
68     *valueMetric->mutable_value_field() =
69             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {4 /* time sleeping field */});
70     *valueMetric->mutable_dimensions_in_what() =
71             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
72     valueMetric->set_bucket(FIVE_MINUTES);
73     valueMetric->set_min_bucket_size_nanos(minTime);
74     valueMetric->set_use_absolute_value_on_reset(true);
75     valueMetric->set_skip_zero_diff_output(false);
76     valueMetric->set_split_bucket_for_app_upgrade(true);
77     return config;
78 }
79 
MakeGaugeMetricConfig(int64_t minTime)80 StatsdConfig MakeGaugeMetricConfig(int64_t minTime) {
81     StatsdConfig config;
82     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
83     config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
84 
85     auto pulledAtomMatcher =
86                 CreateSimpleAtomMatcher("TestMatcher", util::SUBSYSTEM_SLEEP_STATE);
87     *config.add_atom_matcher() = pulledAtomMatcher;
88     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
89     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
90 
91     auto gaugeMetric = config.add_gauge_metric();
92     gaugeMetric->set_id(123456);
93     gaugeMetric->set_what(pulledAtomMatcher.id());
94     gaugeMetric->mutable_gauge_fields_filter()->set_include_all(true);
95     *gaugeMetric->mutable_dimensions_in_what() =
96             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
97     gaugeMetric->set_bucket(FIVE_MINUTES);
98     gaugeMetric->set_min_bucket_size_nanos(minTime);
99     gaugeMetric->set_split_bucket_for_app_upgrade(true);
100     return config;
101 }
102 }  // anonymous namespace
103 
104 // Setup for test fixture.
105 class PartialBucketE2eTest : public StatsServiceConfigTest {};
106 
TEST_F(PartialBucketE2eTest,TestCountMetricWithoutSplit)107 TEST_F(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
108     sendConfig(MakeCountMetricConfig({true}));
109     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
110                                              // initialized with.
111 
112     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
113     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 2, 100).get());
114 
115     ConfigMetricsReport report = getReports(service->mProcessor, start + 3);
116     // Expect no metrics since the bucket has not finished yet.
117     ASSERT_EQ(1, report.metrics_size());
118     ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
119 }
120 
TEST_F(PartialBucketE2eTest,TestCountMetricNoSplitOnNewApp)121 TEST_F(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
122     sendConfig(MakeCountMetricConfig({true}));
123     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
124                                              // initialized with.
125 
126     // Force the uidmap to update at timestamp 2.
127     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
128     // This is a new installation, so there shouldn't be a split (should be same as the without
129     // split case).
130     service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
131                                 String16(""), /* certificateHash */ {});
132     // Goes into the second bucket.
133     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
134 
135     ConfigMetricsReport report = getReports(service->mProcessor, start + 4);
136     ASSERT_EQ(1, report.metrics_size());
137     ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
138 }
139 
TEST_F(PartialBucketE2eTest,TestCountMetricSplitOnUpgrade)140 TEST_F(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
141     sendConfig(MakeCountMetricConfig({true}));
142     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
143                                              // initialized with.
144     service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
145                                 {String16("")}, /* certificateHash */ {{}});
146 
147     // Force the uidmap to update at timestamp 2.
148     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
149     service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
150                                 String16(""), /* certificateHash */ {});
151     // Goes into the second bucket.
152     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
153 
154     ConfigMetricsReport report = getReports(service->mProcessor, start + 4);
155     backfillStartEndTimestamp(&report);
156 
157     ASSERT_EQ(1, report.metrics_size());
158     ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
159     ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
160     EXPECT_TRUE(report.metrics(0)
161                         .count_metrics()
162                         .data(0)
163                         .bucket_info(0)
164                         .has_start_bucket_elapsed_nanos());
165     EXPECT_TRUE(report.metrics(0)
166                         .count_metrics()
167                         .data(0)
168                         .bucket_info(0)
169                         .has_end_bucket_elapsed_nanos());
170     EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
171 }
172 
TEST_F(PartialBucketE2eTest,TestCountMetricSplitOnRemoval)173 TEST_F(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
174     sendConfig(MakeCountMetricConfig({true}));
175     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
176                                              // initialized with.
177     service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
178                                 {String16("")}, /* certificateHash */ {{}});
179 
180     // Force the uidmap to update at timestamp 2.
181     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
182     service->mUidMap->removeApp(start + 2, String16(kApp1.c_str()), 1);
183     // Goes into the second bucket.
184     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
185 
186     ConfigMetricsReport report = getReports(service->mProcessor, start + 4);
187     backfillStartEndTimestamp(&report);
188 
189     ASSERT_EQ(1, report.metrics_size());
190     ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
191     ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
192     EXPECT_TRUE(report.metrics(0)
193                         .count_metrics()
194                         .data(0)
195                         .bucket_info(0)
196                         .has_start_bucket_elapsed_nanos());
197     EXPECT_TRUE(report.metrics(0)
198                         .count_metrics()
199                         .data(0)
200                         .bucket_info(0)
201                         .has_end_bucket_elapsed_nanos());
202     EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
203 }
204 
TEST_F(PartialBucketE2eTest,TestCountMetricSplitOnBoot)205 TEST_F(PartialBucketE2eTest, TestCountMetricSplitOnBoot) {
206     sendConfig(MakeCountMetricConfig(std::nullopt));
207     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
208                                              // initialized with.
209 
210     // Goes into the first bucket
211     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + NS_PER_SEC, 100).get());
212     int64_t bootCompleteTimeNs = start + 2 * NS_PER_SEC;
213     service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
214     // Goes into the second bucket.
215     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3 * NS_PER_SEC, 100).get());
216 
217     ConfigMetricsReport report = getReports(service->mProcessor, start + 4 * NS_PER_SEC);
218     backfillStartEndTimestamp(&report);
219 
220     ASSERT_EQ(1, report.metrics_size());
221     ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
222     ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
223     EXPECT_TRUE(report.metrics(0)
224                         .count_metrics()
225                         .data(0)
226                         .bucket_info(0)
227                         .has_start_bucket_elapsed_nanos());
228     EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
229               report.metrics(0).count_metrics().data(0).bucket_info(0).end_bucket_elapsed_nanos());
230     EXPECT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info(0).count());
231 }
232 
TEST_F(PartialBucketE2eTest,TestCountMetricNoSplitOnUpgradeWhenDisabled)233 TEST_F(PartialBucketE2eTest, TestCountMetricNoSplitOnUpgradeWhenDisabled) {
234     StatsdConfig config = MakeCountMetricConfig({false});
235     sendConfig(config);
236     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
237                                              // initialized with.
238     service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
239                                 {String16("")}, /* certificateHash */ {{}});
240 
241     // Force the uidmap to update at timestamp 2.
242     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
243     service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
244                                 String16(""), /* certificateHash */ {});
245     // Still goes into the first bucket.
246     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
247 
248     ConfigMetricsReport report =
249             getReports(service->mProcessor, start + 4, /*include_current=*/true);
250     backfillStartEndTimestamp(&report);
251 
252     ASSERT_EQ(1, report.metrics_size());
253     ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
254     ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
255     const CountBucketInfo& bucketInfo = report.metrics(0).count_metrics().data(0).bucket_info(0);
256     EXPECT_EQ(bucketInfo.end_bucket_elapsed_nanos(), MillisToNano(NanoToMillis(start + 4)));
257     EXPECT_EQ(bucketInfo.count(), 2);
258 }
259 
TEST_F(PartialBucketE2eTest,TestValueMetricWithoutMinPartialBucket)260 TEST_F(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
261     service->mPullerManager->RegisterPullAtomCallback(
262             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
263             SharedRefBase::make<FakeSubsystemSleepCallback>());
264     // Partial buckets don't occur when app is first installed.
265     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""),
266                                 /* certificateHash */ {});
267     sendConfig(MakeValueMetricConfig(0));
268     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
269                                              // initialized with.
270 
271     service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
272     int64_t appUpgradeTimeNs = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
273     service->mUidMap->updateApp(appUpgradeTimeNs, String16(kApp1.c_str()), 1, 2, String16("v2"),
274                                 String16(""), /* certificateHash */ {});
275 
276     ConfigMetricsReport report =
277             getReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
278     backfillStartEndTimestamp(&report);
279 
280     ASSERT_EQ(1, report.metrics_size());
281     ASSERT_EQ(0, report.metrics(0).value_metrics().skipped_size());
282 
283     // The fake subsystem state sleep puller returns two atoms.
284     ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
285     ASSERT_EQ(2, report.metrics(0).value_metrics().data(0).bucket_info_size());
286     EXPECT_EQ(MillisToNano(NanoToMillis(appUpgradeTimeNs)),
287               report.metrics(0).value_metrics().data(0).bucket_info(1).end_bucket_elapsed_nanos());
288 }
289 
TEST_F(PartialBucketE2eTest,TestValueMetricWithMinPartialBucket)290 TEST_F(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
291     service->mPullerManager->RegisterPullAtomCallback(
292             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
293             SharedRefBase::make<FakeSubsystemSleepCallback>());
294     // Partial buckets don't occur when app is first installed.
295     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""),
296                                 /* certificateHash */ {});
297     sendConfig(MakeValueMetricConfig(60 * NS_PER_SEC /* One minute */));
298     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
299                                              // initialized with.
300 
301     const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2 * NS_PER_SEC;
302     service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
303     service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
304                                 String16(""), /* certificateHash */ {});
305 
306     ConfigMetricsReport report =
307             getReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
308     backfillStartEndTimestamp(&report);
309 
310     ASSERT_EQ(1, report.metrics_size());
311     ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
312     EXPECT_TRUE(report.metrics(0).value_metrics().skipped(0).has_start_bucket_elapsed_nanos());
313     // Can't test the start time since it will be based on the actual time when the pulling occurs.
314     EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
315               report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
316 
317     ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
318     ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
319 }
320 
TEST_F(PartialBucketE2eTest,TestValueMetricOnBootWithoutMinPartialBucket)321 TEST_F(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) {
322     // Initial pull will fail since puller is not registered.
323     sendConfig(MakeValueMetricConfig(0));
324     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
325                                              // initialized with.
326 
327     service->mPullerManager->RegisterPullAtomCallback(
328             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
329             SharedRefBase::make<FakeSubsystemSleepCallback>());
330 
331     int64_t bootCompleteTimeNs = start + NS_PER_SEC;
332     service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
333 
334     service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
335 
336     ConfigMetricsReport report = getReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
337     backfillStartEndTimestamp(&report);
338 
339     // First bucket is dropped due to the initial pull failing
340     ASSERT_EQ(1, report.metrics_size());
341     ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
342     EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
343               report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
344 
345     // The fake subsystem state sleep puller returns two atoms.
346     ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
347     ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
348     EXPECT_EQ(
349             MillisToNano(NanoToMillis(bootCompleteTimeNs)),
350             report.metrics(0).value_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
351 }
352 
TEST_F(PartialBucketE2eTest,TestGaugeMetricWithoutMinPartialBucket)353 TEST_F(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
354     service->mPullerManager->RegisterPullAtomCallback(
355             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
356             SharedRefBase::make<FakeSubsystemSleepCallback>());
357     // Partial buckets don't occur when app is first installed.
358     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""),
359                                 /* certificateHash */ {});
360     sendConfig(MakeGaugeMetricConfig(0));
361     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
362                                              // initialized with.
363 
364     service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
365     service->mUidMap->updateApp(5 * 60 * NS_PER_SEC + start + 2, String16(kApp1.c_str()), 1, 2,
366                                 String16("v2"), String16(""), /* certificateHash */ {});
367 
368     ConfigMetricsReport report = getReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
369     backfillStartEndTimestamp(&report);
370     ASSERT_EQ(1, report.metrics_size());
371     ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
372     // The fake subsystem state sleep puller returns two atoms.
373     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
374     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
375 }
376 
TEST_F(PartialBucketE2eTest,TestGaugeMetricWithMinPartialBucket)377 TEST_F(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
378     // Partial buckets don't occur when app is first installed.
379     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""),
380                                 /* certificateHash */ {});
381     service->mPullerManager->RegisterPullAtomCallback(
382             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
383             SharedRefBase::make<FakeSubsystemSleepCallback>());
384     sendConfig(MakeGaugeMetricConfig(60 * NS_PER_SEC /* One minute */));
385     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
386                                              // initialized with.
387 
388     const int64_t endSkipped = 5 * 60 * NS_PER_SEC + start + 2;
389     service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
390     service->mUidMap->updateApp(endSkipped, String16(kApp1.c_str()), 1, 2, String16("v2"),
391                                 String16(""), /* certificateHash */ {});
392 
393     ConfigMetricsReport report =
394             getReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
395     backfillStartEndTimestamp(&report);
396     ASSERT_EQ(1, report.metrics_size());
397     ASSERT_EQ(1, report.metrics(0).gauge_metrics().skipped_size());
398     // Can't test the start time since it will be based on the actual time when the pulling occurs.
399     EXPECT_TRUE(report.metrics(0).gauge_metrics().skipped(0).has_start_bucket_elapsed_nanos());
400     EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
401               report.metrics(0).gauge_metrics().skipped(0).end_bucket_elapsed_nanos());
402     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
403     ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
404 }
405 
TEST_F(PartialBucketE2eTest,TestGaugeMetricOnBootWithoutMinPartialBucket)406 TEST_F(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) {
407     // Initial pull will fail since puller hasn't been registered.
408     sendConfig(MakeGaugeMetricConfig(0));
409     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
410                                              // initialized with.
411 
412     service->mPullerManager->RegisterPullAtomCallback(
413             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
414             SharedRefBase::make<FakeSubsystemSleepCallback>());
415 
416     int64_t bootCompleteTimeNs = start + NS_PER_SEC;
417     service->mProcessor->onStatsdInitCompleted(bootCompleteTimeNs);
418 
419     service->mProcessor->informPullAlarmFired(5 * 60 * NS_PER_SEC + start);
420 
421     ConfigMetricsReport report = getReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
422     backfillStartEndTimestamp(&report);
423 
424     ASSERT_EQ(1, report.metrics_size());
425     ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
426     // The fake subsystem state sleep puller returns two atoms.
427     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
428     // No data in the first bucket, so nothing is reported
429     ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
430     EXPECT_EQ(
431             MillisToNano(NanoToMillis(bootCompleteTimeNs)),
432             report.metrics(0).gauge_metrics().data(0).bucket_info(0).start_bucket_elapsed_nanos());
433 }
434 
TEST_F(PartialBucketE2eTest,TestCountMetricNoSplitByDefault)435 TEST_F(PartialBucketE2eTest, TestCountMetricNoSplitByDefault) {
436     StatsdConfig config = MakeCountMetricConfig({nullopt});  // Do not set the value in the metric.
437     sendConfig(config);
438     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
439                                              // initialized with.
440     service->mUidMap->updateMap(start, {1}, {1}, {String16("v1")}, {String16(kApp1.c_str())},
441                                 {String16("")}, /* certificateHash */ {{}});
442 
443     // Force the uidmap to update at timestamp 2.
444     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 1, 100).get());
445     service->mUidMap->updateApp(start + 2, String16(kApp1.c_str()), 1, 2, String16("v2"),
446                                 String16(""), /* certificateHash */ {});
447     // Still goes into the first bucket.
448     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
449 
450     ConfigMetricsReport report =
451             getReports(service->mProcessor, start + 4, /*include_current=*/true);
452     backfillStartEndTimestamp(&report);
453 
454     ASSERT_EQ(1, report.metrics_size());
455     ASSERT_EQ(1, report.metrics(0).count_metrics().data_size());
456     ASSERT_EQ(1, report.metrics(0).count_metrics().data(0).bucket_info_size());
457     const CountBucketInfo& bucketInfo = report.metrics(0).count_metrics().data(0).bucket_info(0);
458     EXPECT_EQ(bucketInfo.end_bucket_elapsed_nanos(), MillisToNano(NanoToMillis(start + 4)));
459     EXPECT_EQ(bucketInfo.count(), 2);
460 }
461 
462 #else
463 GTEST_LOG_(INFO) << "This test does nothing.\n";
464 #endif
465 
466 }  // namespace statsd
467 }  // namespace os
468 }  // namespace android
469