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.internal.os.StatsdConfigProto.AtomMatcher; 22 import com.android.internal.os.StatsdConfigProto.FieldMatcher; 23 import com.android.internal.os.StatsdConfigProto.FieldValueMatcher; 24 import com.android.internal.os.StatsdConfigProto.Position; 25 import com.android.internal.os.StatsdConfigProto.Predicate; 26 import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher; 27 import com.android.internal.os.StatsdConfigProto.SimplePredicate; 28 import com.android.os.AtomsProto.AppBreadcrumbReported; 29 import com.android.os.AtomsProto.Atom; 30 import com.android.os.StatsLog.ConfigMetricsReport; 31 import com.android.os.StatsLog.ConfigMetricsReportList; 32 import com.android.os.StatsLog.DurationBucketInfo; 33 import com.android.os.StatsLog.StatsLogReport; 34 import com.android.tradefed.device.DeviceNotAvailableException; 35 36 import java.util.List; 37 38 public class DurationMetricsTests extends DeviceAtomTestCase { 39 40 private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0; 41 private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1; 42 private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2; 43 private static final int APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID = 3; 44 45 public void testDurationMetric() throws Exception { 46 if (statsdDisabled()) { 47 return; 48 } 49 // Add AtomMatcher's. 50 AtomMatcher startAtomMatcher = 51 MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID); 52 AtomMatcher stopAtomMatcher = 53 MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID); 54 55 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder(); 56 builder.addAtomMatcher(startAtomMatcher); 57 builder.addAtomMatcher(stopAtomMatcher); 58 59 // Add Predicate's. 60 SimplePredicate simplePredicate = SimplePredicate.newBuilder() 61 .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID) 62 .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID) 63 .build(); 64 Predicate predicate = Predicate.newBuilder() 65 .setId(MetricsUtils.StringToId("Predicate")) 66 .setSimplePredicate(simplePredicate) 67 .build(); 68 builder.addPredicate(predicate); 69 70 // Add DurationMetric. 71 builder.addDurationMetric( 72 StatsdConfigProto.DurationMetric.newBuilder() 73 .setId(MetricsUtils.DURATION_METRIC_ID) 74 .setWhat(predicate.getId()) 75 .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM) 76 .setBucket(StatsdConfigProto.TimeUnit.CTS)); 77 78 // Upload config. 79 uploadConfig(builder); 80 81 // Create AppBreadcrumbReported Start/Stop events. 82 doAppBreadcrumbReportedStart(1); 83 Thread.sleep(2000); 84 doAppBreadcrumbReportedStop(1); 85 86 // Wait for the metrics to propagate to statsd. 87 Thread.sleep(2000); 88 89 StatsLogReport metricReport = getStatsLogReport(); 90 assertEquals(MetricsUtils.DURATION_METRIC_ID, metricReport.getMetricId()); 91 assertTrue(metricReport.hasDurationMetrics()); 92 StatsLogReport.DurationMetricDataWrapper durationData 93 = metricReport.getDurationMetrics(); 94 assertTrue(durationData.getDataCount() == 1); 95 assertTrue(durationData.getData(0).getBucketInfo(0).getDurationNanos() > 0); 96 assertTrue(durationData.getData(0).getBucketInfo(0).getDurationNanos() < 1e10); 97 } 98 99 public void testDurationMetricWithDimension() throws Exception { 100 if (statsdDisabled()) { 101 return; 102 } 103 // Add AtomMatcher's. 104 AtomMatcher startAtomMatcherA = 105 MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID); 106 AtomMatcher stopAtomMatcherA = 107 MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID); 108 AtomMatcher startAtomMatcherB = 109 MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID); 110 AtomMatcher stopAtomMatcherB = 111 MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID); 112 113 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder(); 114 builder.addAtomMatcher(startAtomMatcherA); 115 builder.addAtomMatcher(stopAtomMatcherA); 116 builder.addAtomMatcher(startAtomMatcherB); 117 builder.addAtomMatcher(stopAtomMatcherB); 118 119 // Add Predicate's. 120 SimplePredicate simplePredicateA = SimplePredicate.newBuilder() 121 .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID) 122 .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID) 123 .build(); 124 Predicate predicateA = Predicate.newBuilder() 125 .setId(MetricsUtils.StringToId("Predicate_A")) 126 .setSimplePredicate(simplePredicateA) 127 .build(); 128 builder.addPredicate(predicateA); 129 130 FieldMatcher.Builder dimensionsBuilder = FieldMatcher.newBuilder() 131 .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER); 132 dimensionsBuilder.addChild(FieldMatcher.newBuilder() 133 .setField(AppBreadcrumbReported.LABEL_FIELD_NUMBER) 134 .setPosition(Position.FIRST) 135 .addChild(FieldMatcher.newBuilder().setField( 136 AppBreadcrumbReported.LABEL_FIELD_NUMBER))); 137 Predicate predicateB = 138 Predicate.newBuilder() 139 .setId(MetricsUtils.StringToId("Predicate_B")) 140 .setSimplePredicate(SimplePredicate.newBuilder() 141 .setStart(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID) 142 .setStop(APP_BREADCRUMB_REPORTED_B_MATCH_STOP_ID) 143 .setDimensions(dimensionsBuilder.build()) 144 .build()) 145 .build(); 146 builder.addPredicate(predicateB); 147 148 // Add DurationMetric. 149 builder.addDurationMetric( 150 StatsdConfigProto.DurationMetric.newBuilder() 151 .setId(MetricsUtils.DURATION_METRIC_ID) 152 .setWhat(predicateB.getId()) 153 .setCondition(predicateA.getId()) 154 .setAggregationType(StatsdConfigProto.DurationMetric.AggregationType.SUM) 155 .setBucket(StatsdConfigProto.TimeUnit.CTS) 156 .setDimensionsInWhat( 157 FieldMatcher.newBuilder() 158 .setField(Atom.BATTERY_SAVER_MODE_STATE_CHANGED_FIELD_NUMBER) 159 .addChild(FieldMatcher.newBuilder() 160 .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER) 161 .setPosition(Position.FIRST) 162 .addChild(FieldMatcher.newBuilder().setField( 163 AppBreadcrumbReported.LABEL_FIELD_NUMBER))))); 164 165 // Upload config. 166 uploadConfig(builder); 167 168 // Trigger events. 169 doAppBreadcrumbReportedStart(1); 170 Thread.sleep(2000); 171 doAppBreadcrumbReportedStart(2); 172 Thread.sleep(2000); 173 doAppBreadcrumbReportedStop(1); 174 Thread.sleep(2000); 175 doAppBreadcrumbReportedStop(2); 176 177 // Wait for the metrics to propagate to statsd. 178 Thread.sleep(2000); 179 180 StatsLogReport metricReport = getStatsLogReport(); 181 assertEquals(MetricsUtils.DURATION_METRIC_ID, metricReport.getMetricId()); 182 assertTrue(metricReport.hasDurationMetrics()); 183 StatsLogReport.DurationMetricDataWrapper durationData 184 = metricReport.getDurationMetrics(); 185 assertTrue(durationData.getDataCount() == 1); 186 assertTrue(durationData.getData(0).getBucketInfoList().size() > 1); 187 for (DurationBucketInfo bucketInfo : durationData.getData(0).getBucketInfoList()) { 188 assertTrue(bucketInfo.getDurationNanos() > 0); 189 assertTrue(bucketInfo.getDurationNanos() < 1e10); 190 } 191 } 192 } 193