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