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 import static com.google.common.truth.Truth.assertWithMessage; 20 21 import android.cts.statsdatom.lib.AtomTestUtils; 22 import android.cts.statsdatom.lib.ConfigUtils; 23 import android.cts.statsdatom.lib.DeviceUtils; 24 import android.cts.statsdatom.lib.ReportUtils; 25 26 import com.android.internal.os.StatsdConfigProto; 27 import com.android.internal.os.StatsdConfigProto.FieldMatcher; 28 import com.android.internal.os.StatsdConfigProto.Position; 29 import com.android.os.AtomsProto.Atom; 30 import com.android.os.AtomsProto.AppBreadcrumbReported; 31 import com.android.os.AtomsProto.WakelockStateChanged; 32 import com.android.os.AttributionNode; 33 import com.android.os.StatsLog.ConfigMetricsReport; 34 import com.android.os.StatsLog.ConfigMetricsReportList; 35 import com.android.os.StatsLog.CountBucketInfo; 36 import com.android.os.StatsLog.CountMetricData; 37 import com.android.os.StatsLog.StatsLogReport; 38 import com.android.tradefed.build.IBuildInfo; 39 import com.android.tradefed.log.LogUtil; 40 import com.android.tradefed.testtype.DeviceTestCase; 41 import com.android.tradefed.testtype.IBuildReceiver; 42 import com.android.tradefed.util.RunUtil; 43 44 import com.google.protobuf.ExtensionRegistry; 45 46 import java.util.List; 47 import java.util.stream.Collectors; 48 import java.util.stream.IntStream; 49 50 public class CountMetricsTests extends DeviceTestCase implements IBuildReceiver { 51 52 private IBuildInfo mCtsBuild; 53 54 @Override setUp()55 protected void setUp() throws Exception { 56 super.setUp(); 57 assertThat(mCtsBuild).isNotNull(); 58 ConfigUtils.removeConfig(getDevice()); 59 ReportUtils.clearReports(getDevice()); 60 DeviceUtils.installTestApp(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_APK, 61 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, mCtsBuild); 62 RunUtil.getDefault().sleep(1000); 63 } 64 65 @Override tearDown()66 protected void tearDown() throws Exception { 67 ConfigUtils.removeConfig(getDevice()); 68 ReportUtils.clearReports(getDevice()); 69 DeviceUtils.uninstallTestApp(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 70 super.tearDown(); 71 } 72 73 @Override setBuild(IBuildInfo buildInfo)74 public void setBuild(IBuildInfo buildInfo) { 75 mCtsBuild = buildInfo; 76 } 77 testSimpleEventCountMetric()78 public void testSimpleEventCountMetric() throws Exception { 79 int matcherId = 1; 80 StatsdConfigProto.StatsdConfig.Builder builder = ConfigUtils.createConfigBuilder( 81 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE); 82 builder.addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 83 .setId(MetricsUtils.COUNT_METRIC_ID) 84 .setBucket(StatsdConfigProto.TimeUnit.ONE_MINUTE) 85 .setWhat(matcherId)) 86 .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId)); 87 ConfigUtils.uploadConfig(getDevice(), builder); 88 89 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 90 AppBreadcrumbReported.State.START.getNumber(), 0); 91 RunUtil.getDefault().sleep(100); 92 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 93 AppBreadcrumbReported.State.STOP.getNumber(), 0); 94 RunUtil.getDefault().sleep(2000); // Wait for the metrics to propagate to statsd. 95 96 StatsLogReport metricReport = ReportUtils.getStatsLogReport(getDevice(), 97 ExtensionRegistry.getEmptyRegistry()); 98 LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString()); 99 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID); 100 assertThat(metricReport.hasCountMetrics()).isTrue(); 101 102 StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics(); 103 104 assertThat(countData.getDataCount()).isGreaterThan(0); 105 assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(2); 106 } 107 testEventCountWithCondition()108 public void testEventCountWithCondition() throws Exception { 109 int startMatcherId = 1; 110 int endMatcherId = 2; 111 int whatMatcherId = 3; 112 int conditionId = 4; 113 114 StatsdConfigProto.AtomMatcher whatMatcher = 115 MetricsUtils.unspecifiedAtomMatcher(whatMatcherId); 116 117 StatsdConfigProto.AtomMatcher predicateStartMatcher = 118 MetricsUtils.startAtomMatcher(startMatcherId); 119 120 StatsdConfigProto.AtomMatcher predicateEndMatcher = 121 MetricsUtils.stopAtomMatcher(endMatcherId); 122 123 StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder() 124 .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder() 125 .setStart(startMatcherId) 126 .setStop(endMatcherId) 127 .setCountNesting(false)) 128 .setId(conditionId) 129 .build(); 130 131 StatsdConfigProto.StatsdConfig.Builder builder = ConfigUtils.createConfigBuilder( 132 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE) 133 .addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 134 .setId(MetricsUtils.COUNT_METRIC_ID) 135 .setBucket(StatsdConfigProto.TimeUnit.CTS) 136 .setWhat(whatMatcherId) 137 .setCondition(conditionId)) 138 .addAtomMatcher(whatMatcher) 139 .addAtomMatcher(predicateStartMatcher) 140 .addAtomMatcher(predicateEndMatcher) 141 .addPredicate(p); 142 143 ConfigUtils.uploadConfig(getDevice(), builder); 144 145 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 146 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), 0); 147 RunUtil.getDefault().sleep(10); 148 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 149 AppBreadcrumbReported.State.START.getNumber(), 0); 150 RunUtil.getDefault().sleep(10); 151 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 152 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), 0); 153 RunUtil.getDefault().sleep(10); 154 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 155 AppBreadcrumbReported.State.STOP.getNumber(), 0); 156 RunUtil.getDefault().sleep(10); 157 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 158 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), 0); 159 RunUtil.getDefault().sleep(2000); // Wait for the metrics to propagate to statsd. 160 161 StatsLogReport metricReport = ReportUtils.getStatsLogReport(getDevice(), 162 ExtensionRegistry.getEmptyRegistry()); 163 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID); 164 assertThat(metricReport.hasCountMetrics()).isTrue(); 165 166 StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics(); 167 168 assertThat(countData.getDataCount()).isGreaterThan(0); 169 assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(1); 170 } 171 testEventCountWithConditionAndActivation()172 public void testEventCountWithConditionAndActivation() throws Exception { 173 int startMatcherId = 1; 174 int startMatcherLabel = 1; 175 int endMatcherId = 2; 176 int endMatcherLabel = 2; 177 int whatMatcherId = 3; 178 int whatMatcherLabel = 3; 179 int conditionId = 4; 180 int activationMatcherId = 5; 181 int activationMatcherLabel = 5; 182 int ttlSec = 5; 183 184 StatsdConfigProto.AtomMatcher whatMatcher = 185 MetricsUtils.appBreadcrumbMatcherWithLabel(whatMatcherId, whatMatcherLabel); 186 187 StatsdConfigProto.AtomMatcher predicateStartMatcher = 188 MetricsUtils.startAtomMatcherWithLabel(startMatcherId, startMatcherLabel); 189 190 StatsdConfigProto.AtomMatcher predicateEndMatcher = 191 MetricsUtils.stopAtomMatcherWithLabel(endMatcherId, endMatcherLabel); 192 193 StatsdConfigProto.AtomMatcher activationMatcher = 194 MetricsUtils.appBreadcrumbMatcherWithLabel(activationMatcherId, 195 activationMatcherLabel); 196 197 StatsdConfigProto.Predicate p = StatsdConfigProto.Predicate.newBuilder() 198 .setSimplePredicate(StatsdConfigProto.SimplePredicate.newBuilder() 199 .setStart(startMatcherId) 200 .setStop(endMatcherId) 201 .setCountNesting(false)) 202 .setId(conditionId) 203 .build(); 204 205 StatsdConfigProto.StatsdConfig.Builder builder = ConfigUtils.createConfigBuilder( 206 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE) 207 .addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 208 .setId(MetricsUtils.COUNT_METRIC_ID) 209 .setBucket(StatsdConfigProto.TimeUnit.ONE_MINUTE) 210 .setWhat(whatMatcherId) 211 .setCondition(conditionId) 212 ) 213 .addAtomMatcher(whatMatcher) 214 .addAtomMatcher(predicateStartMatcher) 215 .addAtomMatcher(predicateEndMatcher) 216 .addAtomMatcher(activationMatcher) 217 .addPredicate(p) 218 .addMetricActivation(StatsdConfigProto.MetricActivation.newBuilder() 219 .setMetricId(MetricsUtils.COUNT_METRIC_ID) 220 .setActivationType(StatsdConfigProto.ActivationType.ACTIVATE_IMMEDIATELY) 221 .addEventActivation(StatsdConfigProto.EventActivation.newBuilder() 222 .setAtomMatcherId(activationMatcherId) 223 .setTtlSeconds(ttlSec))); 224 225 ConfigUtils.uploadConfig(getDevice(), builder); 226 227 // Activate the metric. 228 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 229 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), activationMatcherLabel); 230 RunUtil.getDefault().sleep(10); 231 232 // Set the condition to true. 233 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 234 AppBreadcrumbReported.State.START.getNumber(), startMatcherLabel); 235 RunUtil.getDefault().sleep(10); 236 237 // Log an event that should be counted. Bucket 1 Count 1. 238 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 239 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 240 RunUtil.getDefault().sleep(10); 241 242 // Log an event that should be counted. Bucket 1 Count 2. 243 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 244 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 245 RunUtil.getDefault().sleep(10); 246 247 // Set the condition to false. 248 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 249 AppBreadcrumbReported.State.STOP.getNumber(), endMatcherLabel); 250 RunUtil.getDefault().sleep(10); 251 252 // Log an event that should not be counted because condition is false. 253 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 254 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 255 RunUtil.getDefault().sleep(10); 256 257 // Let the metric deactivate. 258 RunUtil.getDefault().sleep(ttlSec * 1000); 259 260 // Log an event that should not be counted. 261 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 262 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 263 RunUtil.getDefault().sleep(10); 264 265 // Condition to true again. 266 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 267 AppBreadcrumbReported.State.START.getNumber(), startMatcherLabel); 268 RunUtil.getDefault().sleep(10); 269 270 // Event should not be counted, metric is still not active. 271 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 272 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 273 RunUtil.getDefault().sleep(10); 274 275 // Activate the metric. 276 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 277 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), activationMatcherLabel); 278 RunUtil.getDefault().sleep(10); 279 280 // Log an event that should be counted. 281 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 282 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 283 RunUtil.getDefault().sleep(10); 284 285 // Let the metric deactivate. 286 RunUtil.getDefault().sleep(ttlSec * 1000); 287 288 // Log an event that should not be counted. 289 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 290 AppBreadcrumbReported.State.UNSPECIFIED.getNumber(), whatMatcherLabel); 291 RunUtil.getDefault().sleep(10); 292 293 // Wait for the metrics to propagate to statsd. 294 RunUtil.getDefault().sleep(2000); 295 296 StatsLogReport metricReport = ReportUtils.getStatsLogReport(getDevice(), 297 ExtensionRegistry.getEmptyRegistry()); 298 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID); 299 LogUtil.CLog.d("Received the following data: " + metricReport.toString()); 300 assertThat(metricReport.hasCountMetrics()).isTrue(); 301 assertThat(metricReport.getIsActive()).isFalse(); 302 303 StatsLogReport.CountMetricDataWrapper countData = metricReport.getCountMetrics(); 304 assertThat(countData.getDataCount()).isEqualTo(1); 305 assertThat(countData.getData(0).getBucketInfoCount()).isEqualTo(2); 306 assertThat(countData.getData(0).getBucketInfo(0).getCount()).isEqualTo(2); 307 assertThat(countData.getData(0).getBucketInfo(1).getCount()).isEqualTo(1); 308 } 309 testPartialBucketCountMetric()310 public void testPartialBucketCountMetric() throws Exception { 311 int matcherId = 1; 312 StatsdConfigProto.StatsdConfig.Builder builder = ConfigUtils.createConfigBuilder( 313 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE) 314 .addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 315 .setId(MetricsUtils.COUNT_METRIC_ID) 316 .setBucket(StatsdConfigProto.TimeUnit.ONE_DAY) // Ensures partial bucket. 317 .setWhat(matcherId) 318 .setSplitBucketForAppUpgrade(true)) 319 .addAtomMatcher(MetricsUtils.simpleAtomMatcher(matcherId)); 320 ConfigUtils.uploadConfig(getDevice(), builder); 321 322 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 323 AppBreadcrumbReported.State.START.getNumber(), 0); 324 325 builder.getCountMetricBuilder(0).setBucket(StatsdConfigProto.TimeUnit.CTS); 326 ConfigUtils.uploadConfig(getDevice(), builder); // The count metric had a partial bucket. 327 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 328 AppBreadcrumbReported.State.START.getNumber(), 0); 329 RunUtil.getDefault().sleep(10); 330 AtomTestUtils.sendAppBreadcrumbReportedAtom(getDevice(), 331 AppBreadcrumbReported.State.START.getNumber(), 0); 332 RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_LONG); // Finish the current bucket. 333 334 ConfigMetricsReportList reports = ReportUtils.getReportList(getDevice(), 335 ExtensionRegistry.getEmptyRegistry()); 336 LogUtil.CLog.d("Got following report list: " + reports.toString()); 337 338 assertThat(reports.getReportsCount()).isEqualTo(2); 339 boolean inOrder = reports.getReports(0).getCurrentReportWallClockNanos() < 340 reports.getReports(1).getCurrentReportWallClockNanos(); 341 342 // Only 1 metric, so there should only be 1 StatsLogReport. 343 for (ConfigMetricsReport report : reports.getReportsList()) { 344 assertThat(report.getMetricsCount()).isEqualTo(1); 345 assertThat(report.getMetrics(0).getCountMetrics().getDataCount()).isEqualTo(1); 346 } 347 CountMetricData data1 = 348 reports.getReports(inOrder ? 0 : 1).getMetrics(0).getCountMetrics().getData(0); 349 CountMetricData data2 = 350 reports.getReports(inOrder ? 1 : 0).getMetrics(0).getCountMetrics().getData(0); 351 // Data1 should have only 1 bucket, and it should be a partial bucket. 352 // The count should be 1. 353 assertThat(data1.getBucketInfoCount()).isEqualTo(1); 354 CountBucketInfo bucketInfo = data1.getBucketInfo(0); 355 assertThat(bucketInfo.getCount()).isEqualTo(1); 356 assertWithMessage("First report's bucket should be less than 1 day") 357 .that(bucketInfo.getEndBucketElapsedNanos()) 358 .isLessThan(bucketInfo.getStartBucketElapsedNanos() + 359 1_000_000_000L * 60L * 60L * 24L); 360 361 //Second report should have a count of 2. 362 assertThat(data2.getBucketInfoCount()).isAtMost(2); 363 int totalCount = 0; 364 for (CountBucketInfo bucket : data2.getBucketInfoList()) { 365 totalCount += bucket.getCount(); 366 } 367 assertThat(totalCount).isEqualTo(2); 368 } 369 370 public void testSlicedStateCountMetricNoReset() throws Exception { 371 int whatMatcherId = 3; 372 int stateId = 4; 373 int onStateGroupId = 5; 374 int offStateGroupId = 6; 375 376 // Atom 9998 { 377 // repeated AttributionNode attribution_node = 1; 378 // optional WakeLockLevelEnum type = 2; 379 // optional string tag = 3; 380 // } 381 int whatAtomId = 9_998; 382 383 StatsdConfigProto.AtomMatcher whatMatcher = 384 MetricsUtils.getAtomMatcher(whatAtomId) 385 .setId(whatMatcherId) 386 .build(); 387 388 StatsdConfigProto.State state = StatsdConfigProto.State.newBuilder() 389 .setId(stateId) 390 .setAtomId(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER) 391 .setMap(StatsdConfigProto.StateMap.newBuilder() 392 .addGroup(StatsdConfigProto.StateMap.StateGroup.newBuilder() 393 .setGroupId(onStateGroupId) 394 .addValue(WakelockStateChanged.State.ACQUIRE_VALUE) 395 .addValue(WakelockStateChanged.State.CHANGE_ACQUIRE_VALUE) 396 ) 397 .addGroup(StatsdConfigProto.StateMap.StateGroup.newBuilder() 398 .setGroupId(offStateGroupId) 399 .addValue(WakelockStateChanged.State.RELEASE_VALUE) 400 .addValue(WakelockStateChanged.State.CHANGE_RELEASE_VALUE) 401 ) 402 ) 403 .build(); 404 405 StatsdConfigProto.MetricStateLink stateLink = StatsdConfigProto.MetricStateLink.newBuilder() 406 .setStateAtomId(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER) 407 .setFieldsInWhat(FieldMatcher.newBuilder() 408 .setField(whatAtomId) 409 .addChild(FieldMatcher.newBuilder() 410 .setField(1) 411 .setPosition(Position.FIRST) 412 .addChild(FieldMatcher.newBuilder() 413 .setField(AttributionNode.UID_FIELD_NUMBER) 414 ) 415 ) 416 .addChild(FieldMatcher.newBuilder() 417 .setField(2) 418 ) 419 .addChild(FieldMatcher.newBuilder() 420 .setField(3) 421 ) 422 ) 423 .setFieldsInState(FieldMatcher.newBuilder() 424 .setField(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER) 425 .addChild(FieldMatcher.newBuilder() 426 .setField(WakelockStateChanged.ATTRIBUTION_NODE_FIELD_NUMBER) 427 .setPosition(Position.FIRST) 428 .addChild(FieldMatcher.newBuilder() 429 .setField(AttributionNode.UID_FIELD_NUMBER) 430 ) 431 ) 432 .addChild(FieldMatcher.newBuilder() 433 .setField(WakelockStateChanged.TYPE_FIELD_NUMBER) 434 ) 435 .addChild(FieldMatcher.newBuilder() 436 .setField(WakelockStateChanged.TAG_FIELD_NUMBER) 437 ) 438 ) 439 .build(); 440 441 StatsdConfigProto.StatsdConfig.Builder builder = ConfigUtils.createConfigBuilder( 442 MetricsUtils.DEVICE_SIDE_TEST_PACKAGE) 443 .addCountMetric(StatsdConfigProto.CountMetric.newBuilder() 444 .setId(MetricsUtils.COUNT_METRIC_ID) 445 .setBucket(StatsdConfigProto.TimeUnit.CTS) 446 .setWhat(whatMatcherId) 447 .addSliceByState(stateId) 448 .addStateLink(stateLink) 449 .setDimensionsInWhat( 450 FieldMatcher.newBuilder() 451 .setField(whatAtomId) 452 .addChild(FieldMatcher.newBuilder() 453 .setField(1) 454 .setPosition(Position.FIRST) 455 .addChild(FieldMatcher.newBuilder() 456 .setField(AttributionNode.UID_FIELD_NUMBER) 457 ) 458 ) 459 .addChild(FieldMatcher.newBuilder() 460 .setField(2) 461 ) 462 .addChild(FieldMatcher.newBuilder() 463 .setField(3) 464 ) 465 ) 466 ) 467 .addAtomMatcher(whatMatcher) 468 .addState(state); 469 ConfigUtils.uploadConfig(getDevice(), builder); 470 471 DeviceUtils.runDeviceTests(getDevice(), MetricsUtils.DEVICE_SIDE_TEST_PACKAGE, ".AtomTests", 472 "testSliceByWakelockState"); 473 474 StatsLogReport metricReport = ReportUtils.getStatsLogReport(getDevice(), 475 ExtensionRegistry.getEmptyRegistry()); 476 LogUtil.CLog.d("Got the following stats log report: \n" + metricReport.toString()); 477 assertThat(metricReport.getMetricId()).isEqualTo(MetricsUtils.COUNT_METRIC_ID); 478 assertThat(metricReport.hasCountMetrics()).isTrue(); 479 480 StatsLogReport.CountMetricDataWrapper dataWrapper = metricReport.getCountMetrics(); 481 assertThat(dataWrapper.getDataCount()).isEqualTo(2); 482 483 484 List<CountMetricData> sortedDataList = IntStream.range(0, dataWrapper.getDataCount()) 485 .mapToObj(i -> { 486 CountMetricData data = dataWrapper.getData(i); 487 assertWithMessage("Unexpected SliceByState count for data[%s]", "" + i) 488 .that(data.getSliceByStateCount()).isEqualTo(1); 489 return data; 490 }) 491 .sorted((data1, data2) -> 492 Long.compare(data1.getSliceByState(0).getGroupId(), 493 data2.getSliceByState(0).getGroupId()) 494 ) 495 .collect(Collectors.toList()); 496 497 CountMetricData data = sortedDataList.get(0); 498 assertThat(data.getSliceByState(0).getAtomId()) 499 .isEqualTo(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER); 500 assertThat(data.getSliceByState(0).getGroupId()) 501 .isEqualTo(onStateGroupId); 502 long totalCount = data.getBucketInfoList().stream() 503 .mapToLong(CountBucketInfo::getCount) 504 .sum(); 505 assertThat(totalCount).isEqualTo(6); 506 507 data = sortedDataList.get(1); 508 assertThat(data.getSliceByState(0).getAtomId()) 509 .isEqualTo(Atom.WAKELOCK_STATE_CHANGED_FIELD_NUMBER); 510 assertThat(data.getSliceByState(0).getGroupId()) 511 .isEqualTo(offStateGroupId); 512 totalCount = data.getBucketInfoList().stream() 513 .mapToLong(CountBucketInfo::getCount) 514 .sum(); 515 assertThat(totalCount).isEqualTo(3); 516 } 517 } 518