1 /*
2  * Copyright (C) 2018 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 package com.android.helpers;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertTrue;
21 
22 import androidx.test.runner.AndroidJUnit4;
23 
24 import com.android.os.nano.StatsLog;
25 
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 
29 import java.util.Map;
30 
31 /**
32  * Android Unit tests for {@link StatsdStatsHelper}.
33  *
34  * <p>To run: Disable SELinux: adb shell setenforce 0; if this fails with "permission denied", try
35  * Build and install Development apk. "adb shell su 0 setenforce 0" atest
36  * CollectorsHelperTest:com.android.helpers.StatsdStatsTest
37  */
38 @RunWith(AndroidJUnit4.class)
39 public class StatsdStatsHelperTest {
40 
41     private static class TestNonEmptyStatsdHelper implements StatsdStatsHelper.IStatsdHelper {
42 
43         StatsLog.StatsdStatsReport testReport = new StatsLog.StatsdStatsReport();
44 
45         static final int ATOM_STATS_COUNT = 2;
46         static final int CONFIG_STATS_COUNT = 1;
47         static final int CONFIG_STATS_METRIC_COUNT = 2;
48         static final int CONFIG_STATS_CONDITION_COUNT = 2;
49         static final int CONFIG_STATS_ALERT_COUNT = 2;
50         static final int CONFIG_STATS_MATCHER_COUNT = 2;
51         static final int PULLED_ATOM_STATS_COUNT = 2;
52         static final int ATOM_METRIC_STATS_COUNT = 1;
53         static final int DETECTED_LOG_LOSS_STATS_COUNT = 1;
54 
TestNonEmptyStatsdHelper()55         public TestNonEmptyStatsdHelper() {
56             populateAtomStatsTestData(testReport);
57             populateConfigStatsTestData(testReport);
58             populateAnomalyAlarmStatsTestData(testReport);
59             populatePulledAtomStatsTestData(testReport);
60             populateAtomMetricStatsTestData(testReport);
61             populateDetectedLogLossStatsTestData(testReport);
62             populateEventQueueOverflowStatsTestData(testReport);
63         }
64 
populateAtomStatsTestData(StatsLog.StatsdStatsReport testReport)65         private static void populateAtomStatsTestData(StatsLog.StatsdStatsReport testReport) {
66             testReport.atomStats = new StatsLog.StatsdStatsReport.AtomStats[ATOM_STATS_COUNT];
67 
68             for (int i = 0; i < ATOM_STATS_COUNT; i++) {
69                 testReport.atomStats[i] = new StatsLog.StatsdStatsReport.AtomStats();
70                 int fieldValue = i + 1;
71                 testReport.atomStats[i].tag = fieldValue++;
72                 testReport.atomStats[i].count = fieldValue++;
73                 testReport.atomStats[i].errorCount = fieldValue++;
74             }
75         }
76 
populateConfigStatsTestData(StatsLog.StatsdStatsReport testReport)77         private static void populateConfigStatsTestData(StatsLog.StatsdStatsReport testReport) {
78             testReport.configStats = new StatsLog.StatsdStatsReport.ConfigStats[CONFIG_STATS_COUNT];
79             for (int i = 0; i < CONFIG_STATS_COUNT; i++) {
80                 testReport.configStats[i] = new StatsLog.StatsdStatsReport.ConfigStats();
81                 testReport.configStats[i].id = i + 1;
82                 testReport.configStats[i].metricCount = CONFIG_STATS_METRIC_COUNT;
83                 testReport.configStats[i].conditionCount = CONFIG_STATS_CONDITION_COUNT;
84                 testReport.configStats[i].alertCount = CONFIG_STATS_ALERT_COUNT;
85                 testReport.configStats[i].matcherCount = CONFIG_STATS_MATCHER_COUNT;
86 
87                 testReport.configStats[i].metricStats =
88                         populateConfigStatsMetricTestData(CONFIG_STATS_METRIC_COUNT);
89                 testReport.configStats[i].conditionStats =
90                         populateConfigStatsConditionTestData(CONFIG_STATS_CONDITION_COUNT);
91                 testReport.configStats[i].matcherStats =
92                         populateConfigStatsMatcherTestData(CONFIG_STATS_ALERT_COUNT);
93                 testReport.configStats[i].alertStats =
94                         populateConfigStatsAlertTestData(CONFIG_STATS_MATCHER_COUNT);
95             }
96         }
97 
populateConfigStatsAlertTestData( int configStatsAlertCount)98         private static StatsLog.StatsdStatsReport.AlertStats[] populateConfigStatsAlertTestData(
99                 int configStatsAlertCount) {
100             StatsLog.StatsdStatsReport.AlertStats[] alertStats =
101                     new StatsLog.StatsdStatsReport.AlertStats[configStatsAlertCount];
102 
103             for (int i = 0; i < configStatsAlertCount; i++) {
104                 alertStats[i] = new StatsLog.StatsdStatsReport.AlertStats();
105                 int fieldValue = i + 1;
106                 alertStats[i].id = fieldValue++;
107                 alertStats[i].alertedTimes = fieldValue++;
108             }
109 
110             return alertStats;
111         }
112 
populateConfigStatsMetricTestData( int configStatsMetricCount)113         private static StatsLog.StatsdStatsReport.MetricStats[] populateConfigStatsMetricTestData(
114                 int configStatsMetricCount) {
115             StatsLog.StatsdStatsReport.MetricStats[] metricStats =
116                     new StatsLog.StatsdStatsReport.MetricStats[configStatsMetricCount];
117 
118             for (int i = 0; i < configStatsMetricCount; i++) {
119                 metricStats[i] = new StatsLog.StatsdStatsReport.MetricStats();
120                 int fieldValue = i + 1;
121                 metricStats[i].id = fieldValue++;
122                 metricStats[i].maxTupleCounts = fieldValue++;
123             }
124 
125             return metricStats;
126         }
127 
128         private static StatsLog.StatsdStatsReport.ConditionStats[]
populateConfigStatsConditionTestData(int configStatsConditionCount)129                 populateConfigStatsConditionTestData(int configStatsConditionCount) {
130             StatsLog.StatsdStatsReport.ConditionStats[] conditionStats =
131                     new StatsLog.StatsdStatsReport.ConditionStats[configStatsConditionCount];
132 
133             for (int i = 0; i < configStatsConditionCount; i++) {
134                 conditionStats[i] = new StatsLog.StatsdStatsReport.ConditionStats();
135                 int fieldValue = i + 1;
136                 conditionStats[i].id = fieldValue++;
137                 conditionStats[i].maxTupleCounts = fieldValue++;
138             }
139 
140             return conditionStats;
141         }
142 
populateConfigStatsMatcherTestData( int configStatsMatcherCount)143         private static StatsLog.StatsdStatsReport.MatcherStats[] populateConfigStatsMatcherTestData(
144                 int configStatsMatcherCount) {
145             StatsLog.StatsdStatsReport.MatcherStats[] matcherStats =
146                     new StatsLog.StatsdStatsReport.MatcherStats[configStatsMatcherCount];
147 
148             for (int i = 0; i < configStatsMatcherCount; i++) {
149                 matcherStats[i] = new StatsLog.StatsdStatsReport.MatcherStats();
150                 int fieldValue = i + 1;
151                 matcherStats[i].id = fieldValue++;
152                 matcherStats[i].matchedTimes = fieldValue++;
153             }
154 
155             return matcherStats;
156         }
157 
populateAnomalyAlarmStatsTestData( StatsLog.StatsdStatsReport testReport)158         private static void populateAnomalyAlarmStatsTestData(
159                 StatsLog.StatsdStatsReport testReport) {
160             testReport.anomalyAlarmStats = new StatsLog.StatsdStatsReport.AnomalyAlarmStats();
161             testReport.anomalyAlarmStats.alarmsRegistered = 1;
162         }
163 
populatePulledAtomStatsTestData(StatsLog.StatsdStatsReport testReport)164         private static void populatePulledAtomStatsTestData(StatsLog.StatsdStatsReport testReport) {
165             testReport.pulledAtomStats =
166                     new StatsLog.StatsdStatsReport.PulledAtomStats[PULLED_ATOM_STATS_COUNT];
167 
168             for (int i = 0; i < PULLED_ATOM_STATS_COUNT; i++) {
169                 testReport.pulledAtomStats[i] = new StatsLog.StatsdStatsReport.PulledAtomStats();
170                 int fieldValue = i + 1;
171                 testReport.pulledAtomStats[i].atomId = fieldValue++;
172                 testReport.pulledAtomStats[i].totalPull = fieldValue++;
173                 testReport.pulledAtomStats[i].totalPullFromCache = fieldValue++;
174                 testReport.pulledAtomStats[i].minPullIntervalSec = fieldValue++;
175                 testReport.pulledAtomStats[i].averagePullTimeNanos = fieldValue++;
176                 testReport.pulledAtomStats[i].maxPullTimeNanos = fieldValue++;
177                 testReport.pulledAtomStats[i].averagePullDelayNanos = fieldValue++;
178                 testReport.pulledAtomStats[i].dataError = fieldValue++;
179                 testReport.pulledAtomStats[i].pullTimeout = fieldValue++;
180                 testReport.pulledAtomStats[i].pullExceedMaxDelay = fieldValue++;
181                 testReport.pulledAtomStats[i].pullFailed = fieldValue++;
182                 testReport.pulledAtomStats[i].emptyData = fieldValue++;
183                 testReport.pulledAtomStats[i].registeredCount = fieldValue++;
184                 testReport.pulledAtomStats[i].unregisteredCount = fieldValue++;
185                 testReport.pulledAtomStats[i].atomErrorCount = fieldValue++;
186                 testReport.pulledAtomStats[i].binderCallFailed = fieldValue++;
187                 testReport.pulledAtomStats[i].failedUidProviderNotFound = fieldValue++;
188                 testReport.pulledAtomStats[i].pullerNotFound = fieldValue++;
189             }
190         }
191 
populateAtomMetricStatsTestData(StatsLog.StatsdStatsReport testReport)192         private static void populateAtomMetricStatsTestData(StatsLog.StatsdStatsReport testReport) {
193             testReport.atomMetricStats =
194                     new StatsLog.StatsdStatsReport.AtomMetricStats[ATOM_METRIC_STATS_COUNT];
195             for (int i = 0; i < ATOM_METRIC_STATS_COUNT; i++) {
196                 testReport.atomMetricStats[i] = new StatsLog.StatsdStatsReport.AtomMetricStats();
197                 int fieldValue = i + 1;
198                 testReport.atomMetricStats[i].metricId = fieldValue++;
199                 testReport.atomMetricStats[i].hardDimensionLimitReached = fieldValue++;
200                 testReport.atomMetricStats[i].lateLogEventSkipped = fieldValue++;
201                 testReport.atomMetricStats[i].skippedForwardBuckets = fieldValue++;
202                 testReport.atomMetricStats[i].badValueType = fieldValue++;
203                 testReport.atomMetricStats[i].conditionChangeInNextBucket = fieldValue++;
204                 testReport.atomMetricStats[i].invalidatedBucket = fieldValue++;
205                 testReport.atomMetricStats[i].bucketDropped = fieldValue++;
206                 testReport.atomMetricStats[i].minBucketBoundaryDelayNs = fieldValue++;
207                 testReport.atomMetricStats[i].maxBucketBoundaryDelayNs = fieldValue++;
208                 testReport.atomMetricStats[i].bucketUnknownCondition = fieldValue++;
209                 testReport.atomMetricStats[i].bucketCount = fieldValue++;
210             }
211         }
212 
populateDetectedLogLossStatsTestData( StatsLog.StatsdStatsReport testReport)213         private static void populateDetectedLogLossStatsTestData(
214                 StatsLog.StatsdStatsReport testReport) {
215             testReport.detectedLogLoss =
216                     new StatsLog.StatsdStatsReport.LogLossStats[DETECTED_LOG_LOSS_STATS_COUNT];
217 
218             for (int i = 0; i < DETECTED_LOG_LOSS_STATS_COUNT; i++) {
219                 testReport.detectedLogLoss[i] = new StatsLog.StatsdStatsReport.LogLossStats();
220                 int fieldValue = i + 1;
221                 testReport.detectedLogLoss[i].detectedTimeSec = fieldValue++;
222                 testReport.detectedLogLoss[i].count = fieldValue++;
223                 testReport.detectedLogLoss[i].lastError = fieldValue++;
224                 testReport.detectedLogLoss[i].lastTag = fieldValue++;
225                 testReport.detectedLogLoss[i].uid = fieldValue++;
226                 testReport.detectedLogLoss[i].pid = fieldValue++;
227             }
228         }
229 
populateEventQueueOverflowStatsTestData( StatsLog.StatsdStatsReport testReport)230         private static void populateEventQueueOverflowStatsTestData(
231                 StatsLog.StatsdStatsReport testReport) {
232             testReport.queueOverflow = new StatsLog.StatsdStatsReport.EventQueueOverflow();
233             int fieldValue = 1;
234             testReport.queueOverflow.count = fieldValue++;
235             testReport.queueOverflow.minQueueHistoryNs = fieldValue++;
236             testReport.queueOverflow.maxQueueHistoryNs = fieldValue++;
237         }
238 
239         @Override
getStatsdStatsReport()240         public StatsLog.StatsdStatsReport getStatsdStatsReport() {
241             return testReport;
242         }
243     }
244 
245     private static class TestEmptyStatsdHelper implements StatsdStatsHelper.IStatsdHelper {
246 
247         StatsLog.StatsdStatsReport testReport = new StatsLog.StatsdStatsReport();
248 
TestEmptyStatsdHelper()249         public TestEmptyStatsdHelper() {}
250 
251         @Override
getStatsdStatsReport()252         public StatsLog.StatsdStatsReport getStatsdStatsReport() {
253             return testReport;
254         }
255     }
256 
verifyAtomStats(Map<String, Long> result, int atomsCount)257     private static void verifyAtomStats(Map<String, Long> result, int atomsCount) {
258         for (int i = 0; i < atomsCount; i++) {
259             final String metricKeyPrefix =
260                     MetricUtility.constructKey(
261                             StatsdStatsHelper.STATSDSTATS_PREFIX,
262                             StatsdStatsHelper.ATOM_STATS_PREFIX,
263                             String.valueOf(i + 1));
264             int fieldValue = i + 2;
265             assertEquals(
266                     result.get(MetricUtility.constructKey(metricKeyPrefix, "count")),
267                     Long.valueOf(fieldValue++));
268             assertEquals(
269                     result.get(MetricUtility.constructKey(metricKeyPrefix, "error_count")),
270                     Long.valueOf(fieldValue++));
271         }
272     }
273 
verifyConfigAlertStats( Map<String, Long> result, String metricKeyPrefix, long count)274     private static void verifyConfigAlertStats(
275             Map<String, Long> result, String metricKeyPrefix, long count) {
276         for (long i = 0; i < count; i++) {
277             final String metricKey =
278                     MetricUtility.constructKey(
279                             metricKeyPrefix,
280                             StatsdStatsHelper.ALERT_STATS_PREFIX,
281                             String.valueOf(i + 1),
282                             "alerted_times");
283             assertEquals(result.get(metricKey), Long.valueOf(i + 2));
284         }
285     }
286 
verifyConfigMatcherStats( Map<String, Long> result, String metricKeyPrefix, long count)287     private static void verifyConfigMatcherStats(
288             Map<String, Long> result, String metricKeyPrefix, long count) {
289         for (long i = 0; i < count; i++) {
290             final String metricKey =
291                     MetricUtility.constructKey(
292                             metricKeyPrefix,
293                             StatsdStatsHelper.MATCHER_STATS_PREFIX,
294                             String.valueOf(i + 1),
295                             "matched_times");
296             assertEquals(result.get(metricKey), Long.valueOf(i + 2));
297         }
298     }
299 
verifyConfigConditionStats( Map<String, Long> result, String metricKeyPrefix, long count)300     private static void verifyConfigConditionStats(
301             Map<String, Long> result, String metricKeyPrefix, long count) {
302         for (long i = 0; i < count; i++) {
303             final String metricKey =
304                     MetricUtility.constructKey(
305                             metricKeyPrefix,
306                             StatsdStatsHelper.CONDITION_STATS_PREFIX,
307                             String.valueOf(i + 1),
308                             "max_tuple_counts");
309             assertEquals(result.get(metricKey), Long.valueOf(i + 2));
310         }
311     }
312 
verifyConfigMetricStats( Map<String, Long> result, String metricKeyPrefix, long count)313     private static void verifyConfigMetricStats(
314             Map<String, Long> result, String metricKeyPrefix, long count) {
315         for (long i = 0; i < count; i++) {
316             final String metricKey =
317                     MetricUtility.constructKey(
318                             metricKeyPrefix,
319                             StatsdStatsHelper.METRIC_STATS_PREFIX,
320                             String.valueOf(i + 1),
321                             "max_tuple_counts");
322             assertEquals(result.get(metricKey), Long.valueOf(i + 2));
323         }
324     }
325 
verifyConfigStats( Map<String, Long> result, int configStatsCount, int configStatsMetricCount, int configStatsConditionCount, int configStatsMatcherCount, int configStatsAlertCount)326     private static void verifyConfigStats(
327             Map<String, Long> result,
328             int configStatsCount,
329             int configStatsMetricCount,
330             int configStatsConditionCount,
331             int configStatsMatcherCount,
332             int configStatsAlertCount) {
333 
334         for (int i = 0; i < configStatsCount; i++) {
335             final String metricKeyPrefix =
336                     MetricUtility.constructKey(
337                             StatsdStatsHelper.STATSDSTATS_PREFIX,
338                             StatsdStatsHelper.CONFIG_STATS_PREFIX,
339                             String.valueOf(i + 1));
340 
341             final String metricCountKey =
342                     MetricUtility.constructKey(metricKeyPrefix, "metric_count");
343             assertEquals(result.get(metricCountKey), Long.valueOf(configStatsMetricCount));
344             verifyConfigMetricStats(result, metricKeyPrefix, result.get(metricCountKey));
345             final String conditionCountKey =
346                     MetricUtility.constructKey(metricKeyPrefix, "condition_count");
347             assertEquals(result.get(conditionCountKey), Long.valueOf(configStatsConditionCount));
348             verifyConfigConditionStats(result, metricKeyPrefix, result.get(conditionCountKey));
349             final String matcherCountKey =
350                     MetricUtility.constructKey(metricKeyPrefix, "matcher_count");
351             assertEquals(result.get(matcherCountKey), Long.valueOf(configStatsMatcherCount));
352             verifyConfigMatcherStats(result, metricKeyPrefix, result.get(matcherCountKey));
353             final String alertCountKey = MetricUtility.constructKey(metricKeyPrefix, "alert_count");
354             assertEquals(result.get(alertCountKey), Long.valueOf(configStatsAlertCount));
355             verifyConfigAlertStats(result, metricKeyPrefix, result.get(alertCountKey));
356         }
357     }
358 
verifyAnomalyAlarmStats(Map<String, Long> result)359     private static void verifyAnomalyAlarmStats(Map<String, Long> result) {
360         final String metricKeyPrefix =
361                 MetricUtility.constructKey(
362                         StatsdStatsHelper.STATSDSTATS_PREFIX,
363                         StatsdStatsHelper.ANOMALY_ALARM_STATS_PREFIX);
364         final String metricKey = MetricUtility.constructKey(metricKeyPrefix, "alarms_registered");
365         assertEquals(result.get(metricKey), Long.valueOf(1));
366     }
367 
verifyPulledAtomStats(Map<String, Long> result, int pulledAtomStatsCount)368     private static void verifyPulledAtomStats(Map<String, Long> result, int pulledAtomStatsCount) {
369         for (int i = 0; i < pulledAtomStatsCount; i++) {
370             int fieldValue = i + 1;
371             final String metricKeyPrefix =
372                     MetricUtility.constructKey(
373                             StatsdStatsHelper.STATSDSTATS_PREFIX,
374                             StatsdStatsHelper.PULLED_ATOM_STATS_PREFIX,
375                             String.valueOf(fieldValue++));
376             assertEquals(
377                     result.get(MetricUtility.constructKey(metricKeyPrefix, "total_pull")),
378                     Long.valueOf(fieldValue++));
379             assertEquals(
380                     result.get(
381                             MetricUtility.constructKey(metricKeyPrefix, "total_pull_from_cache")),
382                     Long.valueOf(fieldValue++));
383             assertEquals(
384                     result.get(
385                             MetricUtility.constructKey(metricKeyPrefix, "min_pull_interval_sec")),
386                     Long.valueOf(fieldValue++));
387             assertEquals(
388                     result.get(
389                             MetricUtility.constructKey(metricKeyPrefix, "average_pull_time_nanos")),
390                     Long.valueOf(fieldValue++));
391             assertEquals(
392                     result.get(MetricUtility.constructKey(metricKeyPrefix, "max_pull_time_nanos")),
393                     Long.valueOf(fieldValue++));
394             assertEquals(
395                     result.get(
396                             MetricUtility.constructKey(
397                                     metricKeyPrefix, "average_pull_delay_nanos")),
398                     Long.valueOf(fieldValue++));
399             assertEquals(
400                     result.get(MetricUtility.constructKey(metricKeyPrefix, "data_error")),
401                     Long.valueOf(fieldValue++));
402             assertEquals(
403                     result.get(MetricUtility.constructKey(metricKeyPrefix, "pull_timeout")),
404                     Long.valueOf(fieldValue++));
405             assertEquals(
406                     result.get(
407                             MetricUtility.constructKey(metricKeyPrefix, "pull_exceed_max_delay")),
408                     Long.valueOf(fieldValue++));
409             assertEquals(
410                     result.get(MetricUtility.constructKey(metricKeyPrefix, "pull_failed")),
411                     Long.valueOf(fieldValue++));
412             assertEquals(
413                     result.get(MetricUtility.constructKey(metricKeyPrefix, "empty_data")),
414                     Long.valueOf(fieldValue++));
415             assertEquals(
416                     result.get(
417                             MetricUtility.constructKey(metricKeyPrefix, "pull_registered_count")),
418                     Long.valueOf(fieldValue++));
419             assertEquals(
420                     result.get(
421                             MetricUtility.constructKey(metricKeyPrefix, "pull_unregistered_count")),
422                     Long.valueOf(fieldValue++));
423             assertEquals(
424                     result.get(MetricUtility.constructKey(metricKeyPrefix, "atom_error_count")),
425                     Long.valueOf(fieldValue++));
426             assertEquals(
427                     result.get(MetricUtility.constructKey(metricKeyPrefix, "binder_call_failed")),
428                     Long.valueOf(fieldValue++));
429             assertEquals(
430                     result.get(
431                             MetricUtility.constructKey(
432                                     metricKeyPrefix, "failed_uid_provider_not_found")),
433                     Long.valueOf(fieldValue++));
434             assertEquals(
435                     result.get(MetricUtility.constructKey(metricKeyPrefix, "puller_not_found")),
436                     Long.valueOf(fieldValue++));
437         }
438     }
439 
verifyAtomMetricStats(Map<String, Long> result, int atomMetricCount)440     private static void verifyAtomMetricStats(Map<String, Long> result, int atomMetricCount) {
441         for (int i = 0; i < atomMetricCount; i++) {
442             int fieldValue = i + 1;
443             final String metricKeyPrefix =
444                     MetricUtility.constructKey(
445                             StatsdStatsHelper.STATSDSTATS_PREFIX,
446                             StatsdStatsHelper.ATOM_METRIC_STATS_PREFIX,
447                             String.valueOf(fieldValue++));
448             assertEquals(
449                     result.get(
450                             MetricUtility.constructKey(
451                                     metricKeyPrefix, "hard_dimension_limit_reached")),
452                     Long.valueOf(fieldValue++));
453             assertEquals(
454                     result.get(
455                             MetricUtility.constructKey(metricKeyPrefix, "late_log_event_skipped")),
456                     Long.valueOf(fieldValue++));
457             assertEquals(
458                     result.get(
459                             MetricUtility.constructKey(metricKeyPrefix, "skipped_forward_buckets")),
460                     Long.valueOf(fieldValue++));
461             assertEquals(
462                     result.get(MetricUtility.constructKey(metricKeyPrefix, "bad_value_type")),
463                     Long.valueOf(fieldValue++));
464             assertEquals(
465                     result.get(
466                             MetricUtility.constructKey(
467                                     metricKeyPrefix, "condition_change_in_next_bucket")),
468                     Long.valueOf(fieldValue++));
469             assertEquals(
470                     result.get(MetricUtility.constructKey(metricKeyPrefix, "invalidated_bucket")),
471                     Long.valueOf(fieldValue++));
472             assertEquals(
473                     result.get(MetricUtility.constructKey(metricKeyPrefix, "bucket_dropped")),
474                     Long.valueOf(fieldValue++));
475             assertEquals(
476                     result.get(
477                             MetricUtility.constructKey(
478                                     metricKeyPrefix, "min_bucket_boundary_delay_ns")),
479                     Long.valueOf(fieldValue++));
480             assertEquals(
481                     result.get(
482                             MetricUtility.constructKey(
483                                     metricKeyPrefix, "max_bucket_boundary_delay_ns")),
484                     Long.valueOf(fieldValue++));
485             assertEquals(
486                     result.get(
487                             MetricUtility.constructKey(
488                                     metricKeyPrefix, "bucket_unknown_condition")),
489                     Long.valueOf(fieldValue++));
490             assertEquals(
491                     result.get(MetricUtility.constructKey(metricKeyPrefix, "bucket_count")),
492                     Long.valueOf(fieldValue++));
493         }
494     }
495 
verifyDetectedLogLossStats( Map<String, Long> result, int logLossStatsCount)496     private static void verifyDetectedLogLossStats(
497             Map<String, Long> result, int logLossStatsCount) {
498         for (int i = 0; i < logLossStatsCount; i++) {
499             int fieldValue = i + 1;
500             final String metricKeyPrefix =
501                     MetricUtility.constructKey(
502                             StatsdStatsHelper.STATSDSTATS_PREFIX,
503                             StatsdStatsHelper.DETECTED_LOG_LOSS_STATS_PREFIX,
504                             String.valueOf(fieldValue++));
505             assertEquals(
506                     result.get(MetricUtility.constructKey(metricKeyPrefix, "count")),
507                     Long.valueOf(fieldValue++));
508             assertEquals(
509                     result.get(MetricUtility.constructKey(metricKeyPrefix, "last_error")),
510                     Long.valueOf(fieldValue++));
511             assertEquals(
512                     result.get(MetricUtility.constructKey(metricKeyPrefix, "last_tag")),
513                     Long.valueOf(fieldValue++));
514             assertEquals(
515                     result.get(MetricUtility.constructKey(metricKeyPrefix, "uid")),
516                     Long.valueOf(fieldValue++));
517             assertEquals(
518                     result.get(MetricUtility.constructKey(metricKeyPrefix, "pid")),
519                     Long.valueOf(fieldValue++));
520         }
521     }
522 
verifyEventQueueOverfowStats(Map<String, Long> result)523     private static void verifyEventQueueOverfowStats(Map<String, Long> result) {
524         final String metricKeyPrefix =
525                 MetricUtility.constructKey(
526                         StatsdStatsHelper.STATSDSTATS_PREFIX,
527                         StatsdStatsHelper.EVENT_QUEUE_OVERFLOW_STATS_PREFIX);
528 
529         int fieldValue = 1;
530         assertEquals(
531                 result.get(MetricUtility.constructKey(metricKeyPrefix, "count")),
532                 Long.valueOf(fieldValue++));
533         assertEquals(
534                 result.get(MetricUtility.constructKey(metricKeyPrefix, "min_queue_history_nanos")),
535                 Long.valueOf(fieldValue++));
536         assertEquals(
537                 result.get(MetricUtility.constructKey(metricKeyPrefix, "max_queue_history_nanos")),
538                 Long.valueOf(fieldValue++));
539     }
540 
verifySummaryMetrics(Map<String, Long> result)541     private static void verifySummaryMetrics(Map<String, Long> result) {
542         final String metrics[] = {
543             "statsdstats_atom_stats_count",
544             "statsdstats_atom_stats_error_count",
545             "statsdstats_pulled_atom_stats_pull_failed",
546             "statsdstats_pulled_atom_stats_pull_timeout",
547             "statsdstats_pulled_atom_stats_pull_exceed_max_delay",
548             "statsdstats_pulled_atom_stats_empty_data",
549             "statsdstats_pulled_atom_stats_atom_error_count",
550             "statsdstats_pulled_atom_stats_binder_call_failed",
551             "statsdstats_pulled_atom_stats_failed_uid_provider_not_found",
552             "statsdstats_pulled_atom_stats_puller_not_found",
553             "statsdstats_pulled_atom_stats_total_pull",
554             "statsdstats_pulled_atom_stats_total_pull_from_cache",
555             "statsdstats_atom_metric_stats_hard_dimension_limit_reached",
556             "statsdstats_atom_metric_stats_late_log_event_skipped",
557             "statsdstats_atom_metric_stats_skipped_forward_buckets",
558             "statsdstats_atom_metric_stats_bad_value_type",
559             "statsdstats_atom_metric_stats_condition_change_in_next_bucket",
560             "statsdstats_atom_metric_stats_invalidated_bucket",
561             "statsdstats_atom_metric_stats_bucket_dropped",
562             "statsdstats_atom_metric_stats_bucket_unknown_condition"
563         };
564         for (int i = 0; i < metrics.length; i++) {
565             assertNotNull(result.get(metrics[i]));
566         }
567     }
568 
569     @Test
testNonEmptyReport()570     public void testNonEmptyReport() throws Exception {
571         StatsdStatsHelper.IStatsdHelper statsdHelper = new TestNonEmptyStatsdHelper();
572         StatsdStatsHelper statsdStatsHelper = new StatsdStatsHelper(statsdHelper);
573 
574         assertTrue(statsdStatsHelper.startCollecting());
575         final Map<String, Long> result = statsdStatsHelper.getMetrics();
576         verifyAtomStats(result, TestNonEmptyStatsdHelper.ATOM_STATS_COUNT);
577         verifyConfigStats(
578                 result,
579                 TestNonEmptyStatsdHelper.CONFIG_STATS_COUNT,
580                 TestNonEmptyStatsdHelper.CONFIG_STATS_METRIC_COUNT,
581                 TestNonEmptyStatsdHelper.CONFIG_STATS_CONDITION_COUNT,
582                 TestNonEmptyStatsdHelper.CONFIG_STATS_MATCHER_COUNT,
583                 TestNonEmptyStatsdHelper.CONFIG_STATS_ALERT_COUNT);
584         verifyAnomalyAlarmStats(result);
585         verifyPulledAtomStats(result, TestNonEmptyStatsdHelper.PULLED_ATOM_STATS_COUNT);
586         verifyAtomMetricStats(result, TestNonEmptyStatsdHelper.ATOM_METRIC_STATS_COUNT);
587         verifyDetectedLogLossStats(result, TestNonEmptyStatsdHelper.DETECTED_LOG_LOSS_STATS_COUNT);
588         verifyEventQueueOverfowStats(result);
589         verifySummaryMetrics(result);
590         assertTrue(statsdStatsHelper.stopCollecting());
591     }
592 
593     @Test
testEmptyReport()594     public void testEmptyReport() throws Exception {
595         StatsdStatsHelper.IStatsdHelper statsdHelper = new TestEmptyStatsdHelper();
596         StatsdStatsHelper statsdStatsHelper = new StatsdStatsHelper(statsdHelper);
597 
598         assertTrue(statsdStatsHelper.startCollecting());
599         final Map<String, Long> result = statsdStatsHelper.getMetrics();
600         verifySummaryMetrics(result);
601         assertTrue(statsdStatsHelper.stopCollecting());
602     }
603 }
604