1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.cts.statsd.metric;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import android.cts.statsd.atom.DeviceAtomTestCase;
21 
22 import com.android.internal.os.StatsdConfigProto;
23 import com.android.internal.os.StatsdConfigProto.ActivationType;
24 import com.android.internal.os.StatsdConfigProto.AtomMatcher;
25 import com.android.internal.os.StatsdConfigProto.EventActivation;
26 import com.android.internal.os.StatsdConfigProto.EventMetric;
27 import com.android.internal.os.StatsdConfigProto.GaugeMetric;
28 import com.android.internal.os.StatsdConfigProto.MetricActivation;
29 import com.android.internal.os.StatsdConfigProto.StatsdConfig;
30 import com.android.os.AtomsProto.AppBreadcrumbReported;
31 import com.android.os.AtomsProto.Atom;
32 import com.android.os.StatsLog.ConfigMetricsReport;
33 import com.android.os.StatsLog.ConfigMetricsReportList;
34 import com.android.os.StatsLog.EventMetricData;
35 import com.android.os.StatsLog.StatsLogReport;
36 import com.android.tradefed.log.LogUtil;
37 
38 import java.util.ArrayList;
39 import java.util.List;
40 
41 /**
42  * Test Statsd Metric activations and deactivations
43  */
44 public class MetricActivationTests extends DeviceAtomTestCase {
45     private final long metric1Id = 1L;
46     private final int metric1MatcherId = 1;
47 
48     private final long metric2Id = 2L;
49     private final int metric2MatcherId = 2;
50 
51     private final long metric3Id = 3L;
52     private final int metric3MatcherId = 3;
53 
54     private final int act1MatcherId = 10;
55     private final int act1CancelMatcherId = -10;
56 
57     private final int act2MatcherId = 20;
58     private final int act2CancelMatcherId = -20;
59 
60 
createConfig(final int act1TtlSecs, final int act2TtlSecs)61     private StatsdConfig.Builder createConfig(final int act1TtlSecs, final int act2TtlSecs) {
62         AtomMatcher metric1Matcher =
63                 MetricsUtils.simpleAtomMatcher(metric1MatcherId, metric1MatcherId);
64         AtomMatcher metric2Matcher =
65                 MetricsUtils.simpleAtomMatcher(metric2MatcherId, metric2MatcherId);
66         AtomMatcher metric3Matcher =
67                 MetricsUtils.simpleAtomMatcher(metric3MatcherId, metric3MatcherId);
68         AtomMatcher act1Matcher =
69                 MetricsUtils.simpleAtomMatcher(act1MatcherId, act1MatcherId);
70         AtomMatcher act1CancelMatcher =
71                 MetricsUtils.simpleAtomMatcher(act1CancelMatcherId, act1CancelMatcherId);
72         AtomMatcher act2Matcher =
73                 MetricsUtils.simpleAtomMatcher(act2MatcherId, act2MatcherId);
74         AtomMatcher act2CancelMatcher =
75                 MetricsUtils.simpleAtomMatcher(act2CancelMatcherId, act2CancelMatcherId);
76 
77         EventMetric metric1 = EventMetric.newBuilder()
78                 .setId(metric1Id)
79                 .setWhat(metric1MatcherId)
80                 .build();
81 
82         EventMetric metric2 = EventMetric.newBuilder()
83                 .setId(metric2Id)
84                 .setWhat(metric2MatcherId)
85                 .build();
86 
87         EventMetric metric3 = EventMetric.newBuilder()
88                 .setId(metric3Id)
89                 .setWhat(metric3MatcherId)
90                 .build();
91 
92         EventActivation metric1Act1 =
93                 MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
94                     .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
95                     .build();
96 
97         EventActivation metric1Act2 =
98                 MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
99                     .setActivationType(ActivationType.ACTIVATE_ON_BOOT)
100                     .build();
101 
102         EventActivation metric2Act1 =
103                 MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
104                     .setActivationType(ActivationType.ACTIVATE_ON_BOOT)
105                     .build();
106 
107         EventActivation metric2Act2 =
108                 MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
109                     .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
110                     .build();
111 
112         MetricActivation metric1Activation = MetricActivation.newBuilder()
113                 .setMetricId(metric1Id)
114                 .addEventActivation(metric1Act1)
115                 .addEventActivation(metric1Act2)
116                 .build();
117 
118         MetricActivation metric2Activation = MetricActivation.newBuilder()
119                 .setMetricId(metric2Id)
120                 .addEventActivation(metric2Act1)
121                 .addEventActivation(metric2Act2)
122                 .build();
123 
124         return createConfigBuilder()
125                 .addAtomMatcher(metric1Matcher)
126                 .addAtomMatcher(metric2Matcher)
127                 .addAtomMatcher(metric3Matcher)
128                 .addAtomMatcher(act1Matcher)
129                 .addAtomMatcher(act1CancelMatcher)
130                 .addAtomMatcher(act2Matcher)
131                 .addAtomMatcher(act2CancelMatcher)
132                 .addEventMetric(metric1)
133                 .addEventMetric(metric2)
134                 .addEventMetric(metric3)
135                 .addMetricActivation(metric1Activation)
136                 .addMetricActivation(metric2Activation);
137     }
138 
139     /**
140      * Metric 1:
141      *     Activation 1:
142      *         - Ttl: 5 seconds
143      *         - Type: IMMEDIATE
144      *     Activation 2:
145      *         - Ttl: 8 seconds
146      *         - Type: ON_BOOT
147      *
148      * Metric 2:
149      *     Activation 1:
150      *         - Ttl: 5 seconds
151      *         - Type: ON_BOOT
152      *     Activation 2:
153      *         - Ttl: 8 seconds
154      *         - Type: IMMEDIATE
155      *
156      * Metric 3: No activations; always active
157      **/
testCancellation()158     public void testCancellation() throws Exception {
159         final int act1TtlSecs = 5;
160         final int act2TtlSecs = 8;
161         uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
162 
163         // Ignored, metric not active.
164         doAppBreadcrumbReported(metric1MatcherId);
165         Thread.sleep(10L);
166 
167         // Trigger cancel for already inactive event activation 1.
168         doAppBreadcrumbReported(act1CancelMatcherId);
169         Thread.sleep(10L);
170 
171         // Trigger event activation 1.
172         doAppBreadcrumbReported(act1MatcherId);
173         Thread.sleep(10L);
174 
175         // First logged event.
176         doAppBreadcrumbReported(metric1MatcherId);
177         Thread.sleep(10L);
178 
179         // Second logged event.
180         doAppBreadcrumbReported(metric1MatcherId);
181         Thread.sleep(10L);
182 
183         // Cancel event activation 1.
184         doAppBreadcrumbReported(act1CancelMatcherId);
185         Thread.sleep(10L);
186 
187         // Ignored, metric not active.
188         doAppBreadcrumbReported(metric1MatcherId);
189         Thread.sleep(10L);
190 
191         // Trigger event activation 1.
192         doAppBreadcrumbReported(act1MatcherId);
193         Thread.sleep(10L);
194 
195         // Trigger event activation 2.
196         doAppBreadcrumbReported(act2MatcherId);
197         Thread.sleep(10L);
198 
199         // Third logged event.
200         doAppBreadcrumbReported(metric1MatcherId);
201         Thread.sleep(10L);
202 
203         // Cancel event activation 2.
204         doAppBreadcrumbReported(act2CancelMatcherId);
205         Thread.sleep(10L);
206 
207         // Fourth logged event.
208         doAppBreadcrumbReported(metric1MatcherId);
209         Thread.sleep(10L);
210 
211         // Expire event activation 1
212         Thread.sleep(act1TtlSecs * 1000);
213 
214         // Ignored, metric 1 not active. Activation 1 expired and Activation 2 was cancelled.
215         doAppBreadcrumbReported(metric1MatcherId);
216         Thread.sleep(10L);
217 
218         // Trigger event activation 2.
219         doAppBreadcrumbReported(act2MatcherId);
220         Thread.sleep(10L);
221 
222         // Metric 1 log ignored, Activation 1 expired and Activation 2 needs reboot to activate.
223         doAppBreadcrumbReported(metric1MatcherId);
224         Thread.sleep(10L);
225 
226         // First logged event for Metric 3.
227         doAppBreadcrumbReported(metric3MatcherId);
228         Thread.sleep(10L);
229 
230         ConfigMetricsReportList reportList = getReportList();
231         List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
232         ConfigMetricsReport report = reports.get(0);
233         verifyMetrics(report, 4, 0, 1);
234     }
235 
236     /**
237      * Metric 1:
238      *     Activation 1:
239      *         - Ttl: 100 seconds
240      *         - Type: IMMEDIATE
241      *     Activation 2:
242      *         - Ttl: 200 seconds
243      *         - Type: ON_BOOT
244      *
245      * Metric 2:
246      *     Activation 1:
247      *         - Ttl: 100 seconds
248      *         - Type: ON_BOOT
249      *     Activation 2:
250      *         - Ttl: 200 seconds
251      *         - Type: IMMEDIATE
252      *
253      * Metric 3: No activations; always active
254      **/
testRestart()255     public void testRestart() throws Exception {
256         final int act1TtlSecs = 200;
257         final int act2TtlSecs = 400;
258         uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
259 
260         // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
261         // Time remaining:
262         // Metric 1 Activation 1: 200 seconds
263         // Metric 1 Activation 2: 0 seconds
264         // Metric 2 Activation 1: 0 seconds (will activate after boot)
265         // Metric 2 Activation 2: 0 seconds
266         doAppBreadcrumbReported(act1MatcherId);
267         Thread.sleep(10L);
268 
269         // First logged event for Metric 1.
270         // Metric 2 event ignored, will activate after boot.
271         // First logged event for Metric 3.
272         logAllMetrics();
273 
274         // Time remaining:
275         // Metric 1 Activation 1: 200 seconds
276         // Metric 1 Activation 2: 0 seconds
277         // Metric 2 Activation 1: 200 seconds
278         // Metric 2 Activation 2: 0 seconds
279         rebootDeviceAndWaitUntilReady();
280 
281         // Second logged event for Metric 1.
282         // First logged event for Metric 2.
283         // Second logged event for Metric 3.
284         logAllMetrics();
285 
286         // Time remaining:
287         // Metric 1 Activation 1: 0 seconds
288         // Metric 1 Activation 2: 0 seconds
289         // Metric 2 Activation 1: 0 seconds
290         // Metric 2 Activation 2: 0 seconds
291         Thread.sleep(act1TtlSecs * 1000L);
292 
293         // Metric 1 event ignored, Activation 1 expired.
294         // Metric 2 event ignored, Activation 1 expired.
295         // Third logged event for Metric 3.
296         logAllMetrics();
297 
298         // Trigger Metric 1 Activation 2 and Metric 2 Activation 2.
299         // Time remaining:
300         // Metric 1 Activation 1: 0 seconds
301         // Metric 1 Activation 2: 0 seconds (will activate after boot)
302         // Metric 2 Activation 1: 0 seconds
303         // Metric 2 Activation 2: 400 seconds
304         doAppBreadcrumbReported(act2MatcherId);
305         Thread.sleep(10L);
306 
307         // Metric 1 event ignored, will activate after boot.
308         // Second logged event for Metric 2.
309         // Fourth logged event for Metric 3.
310         logAllMetrics();
311 
312         // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
313         // Time remaining:
314         // Metric 1 Activation 1: 200 seconds
315         // Metric 1 Activation 2: 0 seconds (will activate after boot)
316         // Metric 2 Activation 1: 0 seconds (will activate after boot)
317         // Metric 2 Activation 2: 400 seconds
318         doAppBreadcrumbReported(act1MatcherId);
319         Thread.sleep(10L);
320 
321         // Third logged event for Metric 1.
322         // Third logged event for Metric 2.
323         // Fifth logged event for Metric 3.
324         logAllMetrics();
325 
326         // Time remaining:
327         // Metric 1 Activation 1: 100 seconds
328         // Metric 1 Activation 2: 0 seconds (will activate after boot)
329         // Metric 2 Activation 1: 0 seconds (will activate after boot)
330         // Metric 2 Activation 2: 300 seconds
331         Thread.sleep(act1TtlSecs * 1000L / 2);
332 
333         // Time remaining:
334         // Metric 1 Activation 1: 100 seconds
335         // Metric 1 Activation 2: 400 seconds
336         // Metric 2 Activation 1: 200 seconds
337         // Metric 2 Activation 2: 300 seconds
338         rebootDeviceAndWaitUntilReady();
339 
340         // Fourth logged event for Metric 1.
341         // Fourth logged event for Metric 2.
342         // Sixth logged event for Metric 3.
343         logAllMetrics();
344 
345         // Expire Metric 1 Activation 1.
346         // Time remaining:
347         // Metric 1 Activation 1: 0 seconds
348         // Metric 1 Activation 2: 300 seconds
349         // Metric 2 Activation 1: 100 seconds
350         // Metric 2 Activation 2: 200 seconds
351         Thread.sleep(act1TtlSecs * 1000L / 2);
352 
353         // Fifth logged event for Metric 1.
354         // Fifth logged event for Metric 2.
355         // Seventh logged event for Metric 3.
356         logAllMetrics();
357 
358         // Expire all activations.
359         // Time remaining:
360         // Metric 1 Activation 1: 0 seconds
361         // Metric 1 Activation 2: 0 seconds
362         // Metric 2 Activation 1: 0 seconds
363         // Metric 2 Activation 2: 0 seconds
364         Thread.sleep(act2TtlSecs * 1000L);
365 
366         // Metric 1 event ignored.
367         // Metric 2 event ignored.
368         // Eighth logged event for Metric 3.
369         logAllMetrics();
370 
371         ConfigMetricsReportList reportList = getReportList();
372         List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
373         assertThat(reports).hasSize(3);
374 
375         // Report before restart.
376         ConfigMetricsReport report = reports.get(0);
377         verifyMetrics(report, 1, 0, 1);
378 
379         // Report after first restart.
380         report = reports.get(1);
381         verifyMetrics(report, 2, 3, 4);
382 
383         // Report after second restart.
384         report = reports.get(2);
385         verifyMetrics(report, 2, 2, 3);
386     }
387 
388     /**
389      * Metric 1:
390      *     Activation 1:
391      *         - Ttl: 100 seconds
392      *         - Type: IMMEDIATE
393      *     Activation 2:
394      *         - Ttl: 200 seconds
395      *         - Type: ON_BOOT
396      *
397      * Metric 2:
398      *     Activation 1:
399      *         - Ttl: 100 seconds
400      *         - Type: ON_BOOT
401      *     Activation 2:
402      *         - Ttl: 200 seconds
403      *         - Type: IMMEDIATE
404      *
405      * Metric 3: No activations; always active
406      **/
testMultipleActivations()407     public void testMultipleActivations() throws Exception {
408         final int act1TtlSecs = 200;
409         final int act2TtlSecs = 400;
410         uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
411 
412         // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
413         // Time remaining:
414         // Metric 1 Activation 1: 200 seconds
415         // Metric 1 Activation 2: 0 seconds
416         // Metric 2 Activation 1: 0 seconds (will activate after boot)
417         // Metric 2 Activation 2: 0 seconds
418         doAppBreadcrumbReported(act1MatcherId);
419         Thread.sleep(10L);
420 
421         // First logged event for Metric 1.
422         // Metric 2 event ignored, will activate after boot.
423         // First logged event for Metric 3.
424         logAllMetrics();
425 
426         // Time remaining:
427         // Metric 1 Activation 1: 100 seconds
428         // Metric 1 Activation 2: 0 seconds
429         // Metric 2 Activation 1: 0 seconds (will activate after boot)
430         // Metric 2 Activation 2: 0 seconds
431         Thread.sleep(act1TtlSecs * 1000L / 2);
432 
433         // Second logged event for Metric 1.
434         // Metric 2 event ignored, will activate after boot.
435         // Second logged event for Metric 3.
436         logAllMetrics();
437 
438         // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
439         // Time remaining:
440         // Metric 1 Activation 1: 200 seconds
441         // Metric 1 Activation 2: 0 seconds
442         // Metric 2 Activation 1: 0 seconds (will activate after boot)
443         // Metric 2 Activation 2: 0 seconds
444         doAppBreadcrumbReported(act1MatcherId);
445         Thread.sleep(10L);
446 
447         // Third logged event for Metric 1.
448         // Metric 2 event ignored, will activate after boot.
449         // Third logged event for Metric 3.
450         logAllMetrics();
451 
452         // Time remaining:
453         // Metric 1 Activation 1: 200 seconds
454         // Metric 1 Activation 2: 0 seconds
455         // Metric 2 Activation 1: 200 seconds
456         // Metric 2 Activation 2: 0 seconds
457         rebootDeviceAndWaitUntilReady();
458 
459         // Fourth logged event for Metric 1.
460         // First logged event for Metric 2.
461         // Fourth logged event for Metric 3.
462         logAllMetrics();
463 
464         // Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
465         // Time remaining:
466         // Metric 1 Activation 1: 200 seconds
467         // Metric 1 Activation 2: 0 seconds
468         // Metric 2 Activation 1: 200 seconds
469         // Metric 2 Activation 2: 0 seconds
470         doAppBreadcrumbReported(act1MatcherId);
471         Thread.sleep(10L);
472 
473         // Fifth logged event for Metric 1.
474         // Second logged event for Metric 2.
475         // Fifth logged event for Metric 3.
476         logAllMetrics();
477 
478         // Expire all activations.
479         // Time remaining:
480         // Metric 1 Activation 1: 0 seconds
481         // Metric 1 Activation 2: 0 seconds
482         // Metric 2 Activation 1: 0 seconds
483         // Metric 2 Activation 2: 0 seconds
484         Thread.sleep(act1TtlSecs * 1000L);
485 
486         // Metric 1 event ignored.
487         // Metric 2 event ignored.
488         // Sixth logged event for Metric 3.
489         logAllMetrics();
490 
491         // Time remaining:
492         // Metric 1 Activation 1: 0 seconds
493         // Metric 1 Activation 2: 0 seconds
494         // Metric 2 Activation 1: 0 seconds
495         // Metric 2 Activation 2: 0 seconds
496         rebootDeviceAndWaitUntilReady();
497 
498         // Metric 1 event ignored.
499         // Metric 2 event ignored.
500         // Seventh logged event for Metric 3.
501         logAllMetrics();
502 
503         ConfigMetricsReportList reportList = getReportList();
504         List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
505         assertThat(reports).hasSize(3);
506 
507         // Report before restart.
508         ConfigMetricsReport report = reports.get(0);
509         verifyMetrics(report, 3, 0, 3);
510 
511         // Report after first restart.
512         report = reports.get(1);
513         verifyMetrics(report, 2, 2, 3);
514 
515         // Report after second restart.
516         report = reports.get(2);
517         verifyMetrics(report, 0, 0, 1);
518     }
519 
logAllMetrics()520     private void logAllMetrics() throws Exception {
521         doAppBreadcrumbReported(metric1MatcherId);
522         Thread.sleep(10L);
523 
524         doAppBreadcrumbReported(metric2MatcherId);
525         Thread.sleep(10L);
526 
527         doAppBreadcrumbReported(metric3MatcherId);
528         Thread.sleep(10L);
529     }
530 
verifyMetrics(ConfigMetricsReport report, int metric1Count, int metric2Count, int metric3Count)531     private void verifyMetrics(ConfigMetricsReport report, int metric1Count, int metric2Count,
532             int metric3Count) throws Exception {
533         assertThat(report.getMetricsCount()).isEqualTo(3);
534 
535         verifyMetric(
536                 report.getMetrics(0),   // StatsLogReport
537                 1,                      // Metric Id
538                 1,                      // Metric what atom matcher label
539                 metric1Count            // Data count
540         );
541         verifyMetric(
542                 report.getMetrics(1),   // StatsLogReport
543                 2,                      // Metric Id
544                 2,                      // Metric what atom matcher label
545                 metric2Count            // Data count
546         );
547         verifyMetric(
548                 report.getMetrics(2),   // StatsLogReport
549                 3,                      // Metric Id
550                 3,                      // Metric what atom matcher label
551                 metric3Count            // Data count
552         );
553     }
554 
verifyMetric(StatsLogReport metricReport, long metricId, int metricMatcherLabel, int dataCount)555     private void verifyMetric(StatsLogReport metricReport, long metricId, int metricMatcherLabel,
556             int dataCount) {
557         LogUtil.CLog.d("Got the following event metric data: " + metricReport.toString());
558         assertThat(metricReport.getMetricId()).isEqualTo(metricId);
559         assertThat(metricReport.hasEventMetrics()).isEqualTo(dataCount > 0);
560 
561         StatsLogReport.EventMetricDataWrapper eventData = metricReport.getEventMetrics();
562         List<EventMetricData> eventMetricDataList = new ArrayList<>();
563         for (EventMetricData eventMetricData : eventData.getDataList()) {
564             eventMetricDataList.addAll(backfillAggregatedAtomsInEventMetric(eventMetricData));
565         }
566         assertThat(eventMetricDataList).hasSize(dataCount);
567         for (EventMetricData eventMetricData : eventMetricDataList) {
568             AppBreadcrumbReported atom = eventMetricData.getAtom().getAppBreadcrumbReported();
569             assertThat(atom.getLabel()).isEqualTo(metricMatcherLabel);
570         }
571     }
572 }
573