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 "src/guardrail/StatsdStats.h"
16 #include "statslog.h"
17 #include "tests/statsd_test_util.h"
18 
19 #include <gtest/gtest.h>
20 #include <vector>
21 
22 #ifdef __ANDROID__
23 
24 namespace android {
25 namespace os {
26 namespace statsd {
27 
28 using std::vector;
29 
TEST(StatsdStatsTest,TestValidConfigAdd)30 TEST(StatsdStatsTest, TestValidConfigAdd) {
31     StatsdStats stats;
32     ConfigKey key(0, 12345);
33     const int metricsCount = 10;
34     const int conditionsCount = 20;
35     const int matchersCount = 30;
36     const int alertsCount = 10;
37     stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
38                              true /*valid config*/);
39     vector<uint8_t> output;
40     stats.dumpStats(&output, false /*reset stats*/);
41 
42     StatsdStatsReport report;
43     bool good = report.ParseFromArray(&output[0], output.size());
44     EXPECT_TRUE(good);
45     EXPECT_EQ(1, report.config_stats_size());
46     const auto& configReport = report.config_stats(0);
47     EXPECT_EQ(0, configReport.uid());
48     EXPECT_EQ(12345, configReport.id());
49     EXPECT_EQ(metricsCount, configReport.metric_count());
50     EXPECT_EQ(conditionsCount, configReport.condition_count());
51     EXPECT_EQ(matchersCount, configReport.matcher_count());
52     EXPECT_EQ(alertsCount, configReport.alert_count());
53     EXPECT_EQ(true, configReport.is_valid());
54     EXPECT_FALSE(configReport.has_deletion_time_sec());
55 }
56 
TEST(StatsdStatsTest,TestInvalidConfigAdd)57 TEST(StatsdStatsTest, TestInvalidConfigAdd) {
58     StatsdStats stats;
59     ConfigKey key(0, 12345);
60     const int metricsCount = 10;
61     const int conditionsCount = 20;
62     const int matchersCount = 30;
63     const int alertsCount = 10;
64     stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
65                              false /*bad config*/);
66     vector<uint8_t> output;
67     stats.dumpStats(&output, false);
68 
69     StatsdStatsReport report;
70     bool good = report.ParseFromArray(&output[0], output.size());
71     EXPECT_TRUE(good);
72     EXPECT_EQ(1, report.config_stats_size());
73     const auto& configReport = report.config_stats(0);
74     // The invalid config should be put into icebox with a deletion time.
75     EXPECT_TRUE(configReport.has_deletion_time_sec());
76 }
77 
TEST(StatsdStatsTest,TestConfigRemove)78 TEST(StatsdStatsTest, TestConfigRemove) {
79     StatsdStats stats;
80     ConfigKey key(0, 12345);
81     const int metricsCount = 10;
82     const int conditionsCount = 20;
83     const int matchersCount = 30;
84     const int alertsCount = 10;
85     stats.noteConfigReceived(key, metricsCount, conditionsCount, matchersCount, alertsCount, {},
86                              true);
87     vector<uint8_t> output;
88     stats.dumpStats(&output, false);
89     StatsdStatsReport report;
90     bool good = report.ParseFromArray(&output[0], output.size());
91     EXPECT_TRUE(good);
92     EXPECT_EQ(1, report.config_stats_size());
93     const auto& configReport = report.config_stats(0);
94     EXPECT_FALSE(configReport.has_deletion_time_sec());
95 
96     stats.noteConfigRemoved(key);
97     stats.dumpStats(&output, false);
98     good = report.ParseFromArray(&output[0], output.size());
99     EXPECT_TRUE(good);
100     EXPECT_EQ(1, report.config_stats_size());
101     const auto& configReport2 = report.config_stats(0);
102     EXPECT_TRUE(configReport2.has_deletion_time_sec());
103 }
104 
TEST(StatsdStatsTest,TestSubStats)105 TEST(StatsdStatsTest, TestSubStats) {
106     StatsdStats stats;
107     ConfigKey key(0, 12345);
108     stats.noteConfigReceived(key, 2, 3, 4, 5, {std::make_pair(123, 456)}, true);
109 
110     stats.noteMatcherMatched(key, StringToId("matcher1"));
111     stats.noteMatcherMatched(key, StringToId("matcher1"));
112     stats.noteMatcherMatched(key, StringToId("matcher2"));
113 
114     stats.noteConditionDimensionSize(key, StringToId("condition1"), 250);
115     stats.noteConditionDimensionSize(key, StringToId("condition1"), 240);
116 
117     stats.noteMetricDimensionSize(key, StringToId("metric1"), 201);
118     stats.noteMetricDimensionSize(key, StringToId("metric1"), 202);
119 
120     stats.noteAnomalyDeclared(key, StringToId("alert1"));
121     stats.noteAnomalyDeclared(key, StringToId("alert1"));
122     stats.noteAnomalyDeclared(key, StringToId("alert2"));
123 
124     // broadcast-> 2
125     stats.noteBroadcastSent(key);
126     stats.noteBroadcastSent(key);
127 
128     // data drop -> 1
129     stats.noteDataDropped(key, 123);
130 
131     // dump report -> 3
132     stats.noteMetricsReportSent(key, 0);
133     stats.noteMetricsReportSent(key, 0);
134     stats.noteMetricsReportSent(key, 0);
135 
136     // activation_time_sec -> 2
137     stats.noteActiveStatusChanged(key, true);
138     stats.noteActiveStatusChanged(key, true);
139 
140     // deactivation_time_sec -> 1
141     stats.noteActiveStatusChanged(key, false);
142 
143     vector<uint8_t> output;
144     stats.dumpStats(&output, true);  // Dump and reset stats
145     StatsdStatsReport report;
146     bool good = report.ParseFromArray(&output[0], output.size());
147     EXPECT_TRUE(good);
148     EXPECT_EQ(1, report.config_stats_size());
149     const auto& configReport = report.config_stats(0);
150     EXPECT_EQ(2, configReport.broadcast_sent_time_sec_size());
151     EXPECT_EQ(1, configReport.data_drop_time_sec_size());
152     EXPECT_EQ(1, configReport.data_drop_bytes_size());
153     EXPECT_EQ(123, configReport.data_drop_bytes(0));
154     EXPECT_EQ(3, configReport.dump_report_time_sec_size());
155     EXPECT_EQ(3, configReport.dump_report_data_size_size());
156     EXPECT_EQ(2, configReport.activation_time_sec_size());
157     EXPECT_EQ(1, configReport.deactivation_time_sec_size());
158     EXPECT_EQ(1, configReport.annotation_size());
159     EXPECT_EQ(123, configReport.annotation(0).field_int64());
160     EXPECT_EQ(456, configReport.annotation(0).field_int32());
161 
162     EXPECT_EQ(2, configReport.matcher_stats_size());
163     // matcher1 is the first in the list
164     if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
165         EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
166         EXPECT_EQ(1, configReport.matcher_stats(1).matched_times());
167         EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(1).id());
168     } else {
169         // matcher1 is the second in the list.
170         EXPECT_EQ(1, configReport.matcher_stats(0).matched_times());
171         EXPECT_EQ(StringToId("matcher2"), configReport.matcher_stats(0).id());
172 
173         EXPECT_EQ(2, configReport.matcher_stats(1).matched_times());
174         EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
175     }
176 
177     EXPECT_EQ(2, configReport.alert_stats_size());
178     bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
179     EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
180     EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
181     EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
182     EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
183 
184     EXPECT_EQ(1, configReport.condition_stats_size());
185     EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
186     EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
187 
188     EXPECT_EQ(1, configReport.metric_stats_size());
189     EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
190     EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
191 
192     // after resetting the stats, some new events come
193     stats.noteMatcherMatched(key, StringToId("matcher99"));
194     stats.noteConditionDimensionSize(key, StringToId("condition99"), 300);
195     stats.noteMetricDimensionSize(key, StringToId("metric99tion99"), 270);
196     stats.noteAnomalyDeclared(key, StringToId("alert99"));
197 
198     // now the config stats should only contain the stats about the new event.
199     stats.dumpStats(&output, false);
200     good = report.ParseFromArray(&output[0], output.size());
201     EXPECT_TRUE(good);
202     EXPECT_EQ(1, report.config_stats_size());
203     const auto& configReport2 = report.config_stats(0);
204     EXPECT_EQ(1, configReport2.matcher_stats_size());
205     EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
206     EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
207 
208     EXPECT_EQ(1, configReport2.condition_stats_size());
209     EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
210     EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
211 
212     EXPECT_EQ(1, configReport2.metric_stats_size());
213     EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
214     EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
215 
216     EXPECT_EQ(1, configReport2.alert_stats_size());
217     EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
218     EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
219 }
220 
TEST(StatsdStatsTest,TestAtomLog)221 TEST(StatsdStatsTest, TestAtomLog) {
222     StatsdStats stats;
223     time_t now = time(nullptr);
224     // old event, we get it from the stats buffer. should be ignored.
225     stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, 1000);
226 
227     stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 1);
228     stats.noteAtomLogged(android::util::SENSOR_STATE_CHANGED, now + 2);
229     stats.noteAtomLogged(android::util::APP_CRASH_OCCURRED, now + 3);
230 
231     vector<uint8_t> output;
232     stats.dumpStats(&output, false);
233     StatsdStatsReport report;
234     bool good = report.ParseFromArray(&output[0], output.size());
235     EXPECT_TRUE(good);
236 
237     EXPECT_EQ(2, report.atom_stats_size());
238     bool sensorAtomGood = false;
239     bool dropboxAtomGood = false;
240 
241     for (const auto& atomStats : report.atom_stats()) {
242         if (atomStats.tag() == android::util::SENSOR_STATE_CHANGED && atomStats.count() == 3) {
243             sensorAtomGood = true;
244         }
245         if (atomStats.tag() == android::util::APP_CRASH_OCCURRED && atomStats.count() == 1) {
246             dropboxAtomGood = true;
247         }
248     }
249 
250     EXPECT_TRUE(dropboxAtomGood);
251     EXPECT_TRUE(sensorAtomGood);
252 }
253 
TEST(StatsdStatsTest,TestNonPlatformAtomLog)254 TEST(StatsdStatsTest, TestNonPlatformAtomLog) {
255     StatsdStats stats;
256     time_t now = time(nullptr);
257     int newAtom1 = android::util::kMaxPushedAtomId + 1;
258     int newAtom2 = android::util::kMaxPushedAtomId + 2;
259 
260     stats.noteAtomLogged(newAtom1, now + 1);
261     stats.noteAtomLogged(newAtom1, now + 2);
262     stats.noteAtomLogged(newAtom2, now + 3);
263 
264     vector<uint8_t> output;
265     stats.dumpStats(&output, false);
266     StatsdStatsReport report;
267     bool good = report.ParseFromArray(&output[0], output.size());
268     EXPECT_TRUE(good);
269 
270     EXPECT_EQ(2, report.atom_stats_size());
271     bool newAtom1Good = false;
272     bool newAtom2Good = false;
273 
274     for (const auto& atomStats : report.atom_stats()) {
275         if (atomStats.tag() == newAtom1 && atomStats.count() == 2) {
276             newAtom1Good = true;
277         }
278         if (atomStats.tag() == newAtom2 && atomStats.count() == 1) {
279             newAtom2Good = true;
280         }
281     }
282 
283     EXPECT_TRUE(newAtom1Good);
284     EXPECT_TRUE(newAtom2Good);
285 }
286 
TEST(StatsdStatsTest,TestPullAtomStats)287 TEST(StatsdStatsTest, TestPullAtomStats) {
288     StatsdStats stats;
289 
290     stats.updateMinPullIntervalSec(android::util::DISK_SPACE, 3333L);
291     stats.updateMinPullIntervalSec(android::util::DISK_SPACE, 2222L);
292     stats.updateMinPullIntervalSec(android::util::DISK_SPACE, 4444L);
293 
294     stats.notePull(android::util::DISK_SPACE);
295     stats.notePullTime(android::util::DISK_SPACE, 1111L);
296     stats.notePullDelay(android::util::DISK_SPACE, 1111L);
297     stats.notePull(android::util::DISK_SPACE);
298     stats.notePullTime(android::util::DISK_SPACE, 3333L);
299     stats.notePullDelay(android::util::DISK_SPACE, 3335L);
300     stats.notePull(android::util::DISK_SPACE);
301     stats.notePullFromCache(android::util::DISK_SPACE);
302     stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
303     stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, false);
304     stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
305 
306 
307     vector<uint8_t> output;
308     stats.dumpStats(&output, false);
309     StatsdStatsReport report;
310     bool good = report.ParseFromArray(&output[0], output.size());
311     EXPECT_TRUE(good);
312 
313     EXPECT_EQ(1, report.pulled_atom_stats_size());
314 
315     EXPECT_EQ(android::util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
316     EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
317     EXPECT_EQ(1, report.pulled_atom_stats(0).total_pull_from_cache());
318     EXPECT_EQ(2222L, report.pulled_atom_stats(0).min_pull_interval_sec());
319     EXPECT_EQ(2222L, report.pulled_atom_stats(0).average_pull_time_nanos());
320     EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
321     EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
322     EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
323     EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
324     EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
325 }
326 
TEST(StatsdStatsTest,TestAtomMetricsStats)327 TEST(StatsdStatsTest, TestAtomMetricsStats) {
328     StatsdStats stats;
329     time_t now = time(nullptr);
330     // old event, we get it from the stats buffer. should be ignored.
331     stats.noteBucketDropped(1000L);
332 
333     stats.noteBucketBoundaryDelayNs(1000L, -1L);
334     stats.noteBucketBoundaryDelayNs(1000L, -10L);
335     stats.noteBucketBoundaryDelayNs(1000L, 2L);
336 
337     stats.noteBucketBoundaryDelayNs(1001L, 1L);
338 
339     vector<uint8_t> output;
340     stats.dumpStats(&output, false);
341     StatsdStatsReport report;
342     bool good = report.ParseFromArray(&output[0], output.size());
343     EXPECT_TRUE(good);
344 
345     EXPECT_EQ(2, report.atom_metric_stats().size());
346 
347     auto atomStats = report.atom_metric_stats(0);
348     EXPECT_EQ(1000L, atomStats.metric_id());
349     EXPECT_EQ(1L, atomStats.bucket_dropped());
350     EXPECT_EQ(-10L, atomStats.min_bucket_boundary_delay_ns());
351     EXPECT_EQ(2L, atomStats.max_bucket_boundary_delay_ns());
352 
353     auto atomStats2 = report.atom_metric_stats(1);
354     EXPECT_EQ(1001L, atomStats2.metric_id());
355     EXPECT_EQ(0L, atomStats2.bucket_dropped());
356     EXPECT_EQ(0L, atomStats2.min_bucket_boundary_delay_ns());
357     EXPECT_EQ(1L, atomStats2.max_bucket_boundary_delay_ns());
358 }
359 
TEST(StatsdStatsTest,TestAnomalyMonitor)360 TEST(StatsdStatsTest, TestAnomalyMonitor) {
361     StatsdStats stats;
362     stats.noteRegisteredAnomalyAlarmChanged();
363     stats.noteRegisteredAnomalyAlarmChanged();
364 
365     vector<uint8_t> output;
366     stats.dumpStats(&output, false);
367     StatsdStatsReport report;
368     bool good = report.ParseFromArray(&output[0], output.size());
369     EXPECT_TRUE(good);
370 
371     EXPECT_EQ(2, report.anomaly_alarm_stats().alarms_registered());
372 }
373 
TEST(StatsdStatsTest,TestTimestampThreshold)374 TEST(StatsdStatsTest, TestTimestampThreshold) {
375     StatsdStats stats;
376     vector<int32_t> timestamps;
377     for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
378         timestamps.push_back(i);
379     }
380     ConfigKey key(0, 12345);
381     stats.noteConfigReceived(key, 2, 3, 4, 5, {}, true);
382 
383     for (int i = 0; i < StatsdStats::kMaxTimestampCount; i++) {
384         stats.noteDataDropped(key, timestamps[i]);
385         stats.noteBroadcastSent(key, timestamps[i]);
386         stats.noteMetricsReportSent(key, 0, timestamps[i]);
387         stats.noteActiveStatusChanged(key, true, timestamps[i]);
388         stats.noteActiveStatusChanged(key, false, timestamps[i]);
389     }
390 
391     int32_t newTimestamp = 10000;
392 
393     // now it should trigger removing oldest timestamp
394     stats.noteDataDropped(key, 123, 10000);
395     stats.noteBroadcastSent(key, 10000);
396     stats.noteMetricsReportSent(key, 0, 10000);
397     stats.noteActiveStatusChanged(key, true, 10000);
398     stats.noteActiveStatusChanged(key, false, 10000);
399 
400     EXPECT_TRUE(stats.mConfigStats.find(key) != stats.mConfigStats.end());
401     const auto& configStats = stats.mConfigStats[key];
402 
403     size_t maxCount = StatsdStats::kMaxTimestampCount;
404     EXPECT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
405     EXPECT_EQ(maxCount, configStats->data_drop_time_sec.size());
406     EXPECT_EQ(maxCount, configStats->dump_report_stats.size());
407     EXPECT_EQ(maxCount, configStats->activation_time_sec.size());
408     EXPECT_EQ(maxCount, configStats->deactivation_time_sec.size());
409 
410     // the oldest timestamp is the second timestamp in history
411     EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
412     EXPECT_EQ(1, configStats->data_drop_bytes.front());
413     EXPECT_EQ(1, configStats->dump_report_stats.front().first);
414     EXPECT_EQ(1, configStats->activation_time_sec.front());
415     EXPECT_EQ(1, configStats->deactivation_time_sec.front());
416 
417     // the last timestamp is the newest timestamp.
418     EXPECT_EQ(newTimestamp, configStats->broadcast_sent_time_sec.back());
419     EXPECT_EQ(newTimestamp, configStats->data_drop_time_sec.back());
420     EXPECT_EQ(123, configStats->data_drop_bytes.back());
421     EXPECT_EQ(newTimestamp, configStats->dump_report_stats.back().first);
422     EXPECT_EQ(newTimestamp, configStats->activation_time_sec.back());
423     EXPECT_EQ(newTimestamp, configStats->deactivation_time_sec.back());
424 }
425 
TEST(StatsdStatsTest,TestSystemServerCrash)426 TEST(StatsdStatsTest, TestSystemServerCrash) {
427     StatsdStats stats;
428     vector<int32_t> timestamps;
429     for (int i = 0; i < StatsdStats::kMaxSystemServerRestarts; i++) {
430         timestamps.push_back(i);
431         stats.noteSystemServerRestart(timestamps[i]);
432     }
433     vector<uint8_t> output;
434     stats.dumpStats(&output, false);
435     StatsdStatsReport report;
436     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
437     const int maxCount = StatsdStats::kMaxSystemServerRestarts;
438     EXPECT_EQ(maxCount, (int)report.system_restart_sec_size());
439 
440     stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
441     output.clear();
442     stats.dumpStats(&output, false);
443     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
444     EXPECT_EQ(maxCount, (int)report.system_restart_sec_size());
445     EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
446 }
447 
TEST(StatsdStatsTest,TestActivationBroadcastGuardrailHit)448 TEST(StatsdStatsTest, TestActivationBroadcastGuardrailHit) {
449     StatsdStats stats;
450     int uid1 = 1;
451     int uid2 = 2;
452     stats.noteActivationBroadcastGuardrailHit(uid1, 10);
453     stats.noteActivationBroadcastGuardrailHit(uid1, 20);
454 
455     // Test that we only keep 20 timestamps.
456     for (int i = 0; i < 100; i++) {
457         stats.noteActivationBroadcastGuardrailHit(uid2, i);
458     }
459 
460     vector<uint8_t> output;
461     stats.dumpStats(&output, false);
462     StatsdStatsReport report;
463     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
464 
465     EXPECT_EQ(2, report.activation_guardrail_stats_size());
466     bool uid1Good = false;
467     bool uid2Good = false;
468     for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
469         if (uid1 == guardrailTimes.uid()) {
470             uid1Good = true;
471             EXPECT_EQ(2, guardrailTimes.guardrail_met_sec_size());
472             EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
473             EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
474         } else if (uid2 == guardrailTimes.uid()) {
475             int maxCount = StatsdStats::kMaxTimestampCount;
476             uid2Good = true;
477             EXPECT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
478             for (int i = 0; i < maxCount; i++) {
479                 EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
480             }
481         } else {
482             FAIL() << "Unexpected uid.";
483         }
484     }
485     EXPECT_TRUE(uid1Good);
486     EXPECT_TRUE(uid2Good);
487 }
488 
489 }  // namespace statsd
490 }  // namespace os
491 }  // namespace android
492 #else
493 GTEST_LOG_(INFO) << "This test does nothing.\n";
494 #endif
495