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 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.FieldFilter; 27 import com.android.internal.os.StatsdConfigProto.FieldMatcher; 28 import com.android.internal.os.StatsdConfigProto.FieldValueMatcher; 29 import com.android.internal.os.StatsdConfigProto.GaugeMetric; 30 import com.android.internal.os.StatsdConfigProto.MetricActivation; 31 import com.android.internal.os.StatsdConfigProto.Predicate; 32 import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher; 33 import com.android.internal.os.StatsdConfigProto.SimplePredicate; 34 import com.android.internal.os.StatsdConfigProto.StatsdConfig; 35 import com.android.internal.os.StatsdConfigProto.TimeUnit; 36 import com.android.os.AtomsProto.AppBreadcrumbReported; 37 import com.android.os.AtomsProto.Atom; 38 import com.android.os.StatsLog.GaugeBucketInfo; 39 import com.android.os.StatsLog.GaugeMetricData; 40 import com.android.os.StatsLog.StatsLogReport; 41 import com.android.tradefed.log.LogUtil; 42 43 public class GaugeMetricsTests extends DeviceAtomTestCase { 44 45 private static final int APP_BREADCRUMB_REPORTED_A_MATCH_START_ID = 0; 46 private static final int APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID = 1; 47 private static final int APP_BREADCRUMB_REPORTED_B_MATCH_START_ID = 2; 48 testGaugeMetric()49 public void testGaugeMetric() throws Exception { 50 // Add AtomMatcher's. 51 AtomMatcher startAtomMatcher = 52 MetricsUtils.startAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID); 53 AtomMatcher stopAtomMatcher = 54 MetricsUtils.stopAtomMatcher(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID); 55 AtomMatcher atomMatcher = 56 MetricsUtils.simpleAtomMatcher(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID); 57 58 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder(); 59 builder.addAtomMatcher(startAtomMatcher); 60 builder.addAtomMatcher(stopAtomMatcher); 61 builder.addAtomMatcher(atomMatcher); 62 63 // Add Predicate's. 64 SimplePredicate simplePredicate = SimplePredicate.newBuilder() 65 .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID) 66 .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID) 67 .build(); 68 Predicate predicate = Predicate.newBuilder() 69 .setId(MetricsUtils.StringToId("Predicate")) 70 .setSimplePredicate(simplePredicate) 71 .build(); 72 builder.addPredicate(predicate); 73 74 // Add GaugeMetric. 75 FieldMatcher fieldMatcher = 76 FieldMatcher.newBuilder().setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID).build(); 77 builder.addGaugeMetric( 78 StatsdConfigProto.GaugeMetric.newBuilder() 79 .setId(MetricsUtils.GAUGE_METRIC_ID) 80 .setWhat(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID) 81 .setCondition(predicate.getId()) 82 .setGaugeFieldsFilter( 83 FieldFilter.newBuilder().setIncludeAll(false).setFields(fieldMatcher).build()) 84 .setDimensionsInWhat( 85 FieldMatcher.newBuilder() 86 .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID) 87 .addChild(FieldMatcher.newBuilder() 88 .setField(AppBreadcrumbReported.STATE_FIELD_NUMBER) 89 .build()) 90 .build()) 91 .setBucket(StatsdConfigProto.TimeUnit.CTS) 92 .build()); 93 94 // Upload config. 95 uploadConfig(builder); 96 97 // Create AppBreadcrumbReported Start/Stop events. 98 doAppBreadcrumbReportedStart(0); 99 Thread.sleep(10); 100 doAppBreadcrumbReportedStart(1); 101 Thread.sleep(10); 102 doAppBreadcrumbReportedStart(2); 103 Thread.sleep(2000); 104 doAppBreadcrumbReportedStop(2); 105 Thread.sleep(10); 106 doAppBreadcrumbReportedStop(0); 107 Thread.sleep(10); 108 doAppBreadcrumbReportedStop(1); 109 doAppBreadcrumbReportedStart(2); 110 Thread.sleep(10); 111 doAppBreadcrumbReportedStart(1); 112 Thread.sleep(2000); 113 doAppBreadcrumbReportedStop(2); 114 Thread.sleep(10); 115 doAppBreadcrumbReportedStop(1); 116 117 // Wait for the metrics to propagate to statsd. 118 Thread.sleep(2000); 119 120 StatsLogReport metricReport = getStatsLogReport(); 121 LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString()); 122 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID); 123 assertThat(metricReport.hasGaugeMetrics()).isTrue(); 124 StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics(); 125 gaugeData = backfillGaugeMetricData(gaugeData); 126 assertThat(gaugeData.getDataCount()).isEqualTo(1); 127 128 int bucketCount = gaugeData.getData(0).getBucketInfoCount(); 129 GaugeMetricData data = gaugeData.getData(0); 130 assertThat(bucketCount).isGreaterThan(2); 131 MetricsUtils.assertBucketTimePresent(data.getBucketInfo(0)); 132 assertThat(data.getBucketInfo(0).getAtomCount()).isEqualTo(1); 133 assertThat(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getLabel()) 134 .isEqualTo(0); 135 assertThat(data.getBucketInfo(0).getAtom(0).getAppBreadcrumbReported().getState()) 136 .isEqualTo(AppBreadcrumbReported.State.START); 137 138 MetricsUtils.assertBucketTimePresent(data.getBucketInfo(1)); 139 assertThat(data.getBucketInfo(1).getAtomCount()).isEqualTo(1); 140 141 MetricsUtils.assertBucketTimePresent(data.getBucketInfo(bucketCount-1)); 142 assertThat(data.getBucketInfo(bucketCount-1).getAtomCount()).isEqualTo(1); 143 assertThat(data.getBucketInfo(bucketCount-1).getAtom(0).getAppBreadcrumbReported().getLabel()) 144 .isEqualTo(2); 145 assertThat(data.getBucketInfo(bucketCount-1).getAtom(0).getAppBreadcrumbReported().getState()) 146 .isEqualTo(AppBreadcrumbReported.State.STOP); 147 } 148 testPulledGaugeMetricWithActivation()149 public void testPulledGaugeMetricWithActivation() throws Exception { 150 // Add AtomMatcher's. 151 int activationAtomMatcherId = 1; 152 int activationAtomMatcherLabel = 1; 153 154 int systemUptimeMatcherId = 2; 155 AtomMatcher activationAtomMatcher = 156 MetricsUtils.appBreadcrumbMatcherWithLabel( 157 activationAtomMatcherId, activationAtomMatcherLabel); 158 AtomMatcher systemUptimeMatcher = 159 AtomMatcher.newBuilder() 160 .setId(systemUptimeMatcherId) 161 .setSimpleAtomMatcher( 162 SimpleAtomMatcher.newBuilder().setAtomId(Atom.SYSTEM_UPTIME_FIELD_NUMBER)) 163 .build(); 164 165 StatsdConfigProto.StatsdConfig.Builder builder = createConfigBuilder(); 166 builder.addAtomMatcher(activationAtomMatcher); 167 builder.addAtomMatcher(systemUptimeMatcher); 168 169 // Add GaugeMetric. 170 builder.addGaugeMetric( 171 StatsdConfigProto.GaugeMetric.newBuilder() 172 .setId(MetricsUtils.GAUGE_METRIC_ID) 173 .setWhat(systemUptimeMatcherId) 174 .setGaugeFieldsFilter( 175 FieldFilter.newBuilder().setIncludeAll(true).build()) 176 .setBucket(StatsdConfigProto.TimeUnit.CTS) 177 .build()); 178 179 // Add activation. 180 builder.addMetricActivation(MetricActivation.newBuilder() 181 .setMetricId(MetricsUtils.GAUGE_METRIC_ID) 182 .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY) 183 .addEventActivation(EventActivation.newBuilder() 184 .setAtomMatcherId(activationAtomMatcherId) 185 .setTtlSeconds(5))); 186 187 // Upload config. 188 uploadConfig(builder); 189 190 // Plenty of time to pull, but we should not keep the data since we are not active. 191 Thread.sleep(20_000); 192 193 StatsLogReport metricReport = getStatsLogReport(); 194 LogUtil.CLog.d("Got the following gauge metric data: " + metricReport.toString()); 195 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID); 196 assertThat(metricReport.hasGaugeMetrics()).isFalse(); 197 } 198 testPulledGaugeMetricWithConditionAndActivation()199 public void testPulledGaugeMetricWithConditionAndActivation() throws Exception { 200 final int conditionLabel = 2; 201 final int activationMatcherId = 5; 202 final int activationMatcherLabel = 5; 203 final int whatMatcherId = 8; 204 final int ttlSec = 5; 205 206 // Add AtomMatchers. 207 AtomMatcher conditionStartAtomMatcher = MetricsUtils.startAtomMatcherWithLabel( 208 APP_BREADCRUMB_REPORTED_A_MATCH_START_ID, conditionLabel); 209 AtomMatcher conditionStopAtomMatcher = MetricsUtils.stopAtomMatcherWithLabel( 210 APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID, conditionLabel); 211 AtomMatcher activationMatcher = 212 MetricsUtils.startAtomMatcherWithLabel( 213 activationMatcherId, activationMatcherLabel); 214 AtomMatcher whatMatcher = 215 MetricsUtils.unspecifiedAtomMatcher(whatMatcherId); 216 217 StatsdConfig.Builder builder = createConfigBuilder() 218 .addAtomMatcher(conditionStartAtomMatcher) 219 .addAtomMatcher(conditionStopAtomMatcher) 220 .addAtomMatcher(whatMatcher) 221 .addAtomMatcher(activationMatcher); 222 223 // Add Predicates. 224 SimplePredicate simplePredicate = SimplePredicate.newBuilder() 225 .setStart(APP_BREADCRUMB_REPORTED_A_MATCH_START_ID) 226 .setStop(APP_BREADCRUMB_REPORTED_A_MATCH_STOP_ID) 227 .build(); 228 Predicate predicate = Predicate.newBuilder() 229 .setId(MetricsUtils.StringToId("Predicate")) 230 .setSimplePredicate(simplePredicate) 231 .build(); 232 builder.addPredicate(predicate); 233 234 // Add GaugeMetric. 235 builder 236 .addGaugeMetric(GaugeMetric.newBuilder() 237 .setId(MetricsUtils.GAUGE_METRIC_ID) 238 .setWhat(whatMatcher.getId()) 239 .setBucket(TimeUnit.CTS) 240 .setCondition(predicate.getId()) 241 .setGaugeFieldsFilter( 242 FieldFilter.newBuilder().setIncludeAll(false).setFields( 243 FieldMatcher.newBuilder() 244 .setField(APP_BREADCRUMB_REPORTED_B_MATCH_START_ID) 245 ) 246 ) 247 .setDimensionsInWhat(FieldMatcher.newBuilder().setField(whatMatcherId)) 248 ) 249 .addMetricActivation(MetricActivation.newBuilder() 250 .setMetricId(MetricsUtils.GAUGE_METRIC_ID) 251 .addEventActivation(EventActivation.newBuilder() 252 .setAtomMatcherId(activationMatcherId) 253 .setActivationType(ActivationType.ACTIVATE_IMMEDIATELY) 254 .setTtlSeconds(ttlSec) 255 ) 256 ); 257 258 uploadConfig(builder); 259 260 // Activate the metric. 261 doAppBreadcrumbReportedStart(activationMatcherLabel); 262 Thread.sleep(10); 263 264 // Set the condition to true. 265 doAppBreadcrumbReportedStart(conditionLabel); 266 Thread.sleep(10); 267 268 // This value is collected. 269 doAppBreadcrumbReported(10); 270 Thread.sleep(10); 271 272 // Ignored; value already collected. 273 doAppBreadcrumbReported(20); 274 Thread.sleep(10); 275 276 // Set the condition to false. 277 doAppBreadcrumbReportedStop(conditionLabel); 278 Thread.sleep(10); 279 280 // Value not updated because condition is false. 281 doAppBreadcrumbReported(30); 282 Thread.sleep(10); 283 284 // Let the metric deactivate. 285 Thread.sleep(ttlSec * 1000); 286 287 // Value not collected. 288 doAppBreadcrumbReported(40); 289 Thread.sleep(10); 290 291 // Condition to true again. 292 doAppBreadcrumbReportedStart(conditionLabel); 293 Thread.sleep(10); 294 295 // Value not collected. 296 doAppBreadcrumbReported(50); 297 Thread.sleep(10); 298 299 // Activate the metric. 300 doAppBreadcrumbReportedStart(activationMatcherLabel); 301 Thread.sleep(10); 302 303 // Value collected. 304 doAppBreadcrumbReported(60); 305 Thread.sleep(10); 306 307 // Let the metric deactivate. 308 Thread.sleep(ttlSec * 1000); 309 310 // Value not collected. 311 doAppBreadcrumbReported(70); 312 Thread.sleep(10); 313 314 // Wait for the metrics to propagate to statsd. 315 Thread.sleep(2000); 316 317 StatsLogReport metricReport = getStatsLogReport(); 318 LogUtil.CLog.d("Received the following data: " + metricReport.toString()); 319 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.GAUGE_METRIC_ID); 320 assertThat(metricReport.hasGaugeMetrics()).isTrue(); 321 assertThat(metricReport.getIsActive()).isFalse(); 322 323 StatsLogReport.GaugeMetricDataWrapper gaugeData = metricReport.getGaugeMetrics(); 324 gaugeData = backfillGaugeMetricData(gaugeData); 325 assertThat(gaugeData.getDataCount()).isEqualTo(1); 326 assertThat(gaugeData.getData(0).getBucketInfoCount()).isEqualTo(2); 327 328 GaugeBucketInfo bucketInfo = gaugeData.getData(0).getBucketInfo(0); 329 MetricsUtils.assertBucketTimePresent(bucketInfo); 330 assertThat(bucketInfo.getAtomCount()).isEqualTo(1); 331 assertThat(bucketInfo.getAtom(0).getAppBreadcrumbReported().getLabel()).isEqualTo(10); 332 333 bucketInfo = gaugeData.getData(0).getBucketInfo(1); 334 MetricsUtils.assertBucketTimePresent(bucketInfo); 335 assertThat(bucketInfo.getAtomCount()).isEqualTo(1); 336 assertThat(bucketInfo.getAtom(0).getAppBreadcrumbReported().getLabel()).isEqualTo(60); 337 } 338 } 339