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 android.cts.statsd.metric; 17 18 import android.cts.statsd.atom.DeviceAtomTestCase; 19 20 import com.android.internal.os.StatsdConfigProto; 21 import com.android.os.AtomsProto.Atom; 22 import com.android.os.AtomsProto.AppBreadcrumbReported; 23 import com.android.os.StatsLog; 24 import com.android.os.StatsLog.ConfigMetricsReport; 25 import com.android.os.StatsLog.ConfigMetricsReportList; 26 import com.android.os.StatsLog.CountBucketInfo; 27 import com.android.os.StatsLog.CountMetricData; 28 import com.android.os.StatsLog.StatsLogReport; 29 import com.android.tradefed.device.DeviceNotAvailableException; 30 import com.android.tradefed.log.LogUtil; 31 32 import java.util.Arrays; 33 import java.util.List; 34 35 public class CountMetricsTests extends DeviceAtomTestCase { 36 37 public void testSimpleEventCountMetric() throws Exception { 38 if (statsdDisabled()) { 39 return; 40 } 41 int matcherId = 1; 42 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder(); 43 builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 44 .setId(MetricsUtils.COUNT_METRIC_ID) 45 .setBucket(StatsdConfigProto.TimeUnit.CTS) 46 .setWhat(matcherId)) 47 .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId)); 48 uploadConfig(builder); 49 50 doAppBreadcrumbReportedStart(0); 51 doAppBreadcrumbReportedStop(0); 52 Thread.sleep(2000); // Wait for the metrics to propagate to statsd. 53 54 StatsLogReport metricReport = getStatsLogReport(); 55 LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString()); 56 assertEquals(MetricsUtils.COUNT_METRIC_ID, metricReport.getMetricId()); 57 assertTrue(metricReport.hasCountMetrics()); 58 59 StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics(); 60 61 assertTrue(countData.getDataCount() > 0); 62 assertEquals(2, countData.getData(0).getBucketInfo(0).getCount()); 63 } 64 public void testEventCountWithCondition() throws Exception { 65 if (statsdDisabled()) { 66 return; 67 } 68 int startMatcherId = 1; 69 int endMatcherId = 2; 70 int whatMatcherId = 3; 71 int conditionId = 4; 72 73 StatsdConfigProto.AtomMatcher whatMatcher = 74 MetricsUtils.unspecifiedAtomMatcher(whatMatcherId); 75 76 StatsdConfigProto.AtomMatcher predicateStartMatcher = 77 MetricsUtils.startAtomMatcher(startMatcherId); 78 79 StatsdConfigProto.AtomMatcher predicateEndMatcher = 80 MetricsUtils.stopAtomMatcher(endMatcherId); 81 82 StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder() 83 .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder() 84 .setStart(startMatcherId) 85 .setStop(endMatcherId) 86 .setCountNesting(false)) 87 .setId(conditionId) 88 .build(); 89 90 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder() 91 .addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 92 .setId(MetricsUtils.COUNT_METRIC_ID) 93 .setBucket(StatsdConfigProto.TimeUnit.CTS) 94 .setWhat(whatMatcherId) 95 .setCondition(conditionId)) 96 .addAtomMatcher(whatMatcher) 97 .addAtomMatcher(predicateStartMatcher) 98 .addAtomMatcher(predicateEndMatcher) 99 .addPredicate(p); 100 101 uploadConfig(builder); 102 103 doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal()); 104 Thread.sleep(10); 105 doAppBreadcrumbReportedStart(0); 106 Thread.sleep(10); 107 doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal()); 108 Thread.sleep(10); 109 doAppBreadcrumbReportedStop(0); 110 Thread.sleep(10); 111 doAppBreadcrumbReported(0, AppBreadcrumbReported.State.UNSPECIFIED.ordinal()); 112 Thread.sleep(2000); // Wait for the metrics to propagate to statsd. 113 114 StatsLogReport metricReport = getStatsLogReport(); 115 assertEquals(MetricsUtils.COUNT_METRIC_ID, metricReport.getMetricId()); 116 assertTrue(metricReport.hasCountMetrics()); 117 118 StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics(); 119 120 assertTrue(countData.getDataCount() > 0); 121 assertEquals(1, countData.getData(0).getBucketInfo(0).getCount()); 122 } 123 124 public void testPartialBucketCountMetric() throws Exception { 125 if (statsdDisabled()) { 126 return; 127 } 128 int matcherId = 1; 129 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder(); 130 builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 131 .setId(MetricsUtils.COUNT_METRIC_ID) 132 .setBucket(StatsdConfigProto.TimeUnit.ONE_DAY) // Should ensure partial bucket. 133 .setWhat(matcherId)) 134 .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId)); 135 uploadConfig(builder); 136 137 doAppBreadcrumbReportedStart(0); 138 139 builder.getCountMetricBuilder(0).setBucket(StatsdConfigProto.TimeUnit.CTS); 140 uploadConfig(builder); // The count metric had a partial bucket. 141 doAppBreadcrumbReportedStart(0); 142 Thread.sleep(10); 143 doAppBreadcrumbReportedStart(0); 144 Thread.sleep(WAIT_TIME_LONG); // Finish the current bucket. 145 146 ConfigMetricsReportList reports = getReportList(); 147 LogUtil.CLog.d("Got following report list: " + reports.toString()); 148 149 assertEquals("Expected 2 reports, got " + reports.getReportsCount(), 150 2, reports.getReportsCount()); 151 boolean inOrder = reports.getReports(0).getCurrentReportWallClockNanos() < 152 reports.getReports(1).getCurrentReportWallClockNanos(); 153 154 // Only 1 metric, so there should only be 1 StatsLogReport. 155 for (ConfigMetricsReport report : reports.getReportsList()) { 156 assertEquals("Expected 1 StatsLogReport in each ConfigMetricsReport", 157 1, report.getMetricsCount()); 158 assertEquals("Expected 1 CountMetricData in each report", 159 1, report.getMetrics(0).getCountMetrics().getDataCount()); 160 } 161 CountMetricData data1 = 162 reports.getReports(inOrder? 0 : 1).getMetrics(0).getCountMetrics().getData(0); 163 CountMetricData data2 = 164 reports.getReports(inOrder? 1 : 0).getMetrics(0).getCountMetrics().getData(0); 165 // Data1 should have only 1 bucket, and it should be a partial bucket. 166 // The count should be 1. 167 assertEquals("First report should only have 1 bucket", 1, data1.getBucketInfoCount()); 168 CountBucketInfo bucketInfo = data1.getBucketInfo(0); 169 assertEquals("First report should have a count of 1", 1, bucketInfo.getCount()); 170 assertTrue("First report's bucket should be less than 1 day", 171 bucketInfo.getEndBucketElapsedNanos() < 172 (bucketInfo.getStartBucketElapsedNanos() + 1_000_000_000L * 60L * 60L * 24L)); 173 174 //Second report should have a count of 2. 175 assertTrue("Second report should have at most 2 buckets", data2.getBucketInfoCount() < 3); 176 int totalCount = 0; 177 for (CountBucketInfo bucket : data2.getBucketInfoList()) { 178 totalCount += bucket.getCount(); 179 } 180 assertEquals("Second report should have a count of 2", 2, totalCount); 181 } 182 } 183