blob: 339970acc463329857318c93970f55329c03d3f8 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.cts.statsd.metric;
import static com.google.common.truth.Truth.assertThat;
import android.cts.statsd.atom.DeviceAtomTestCase;
import com.android.internal.os.StatsdConfigProto;
import com.android.internal.os.StatsdConfigProto.ActivationType;
import com.android.internal.os.StatsdConfigProto.AtomMatcher;
import com.android.internal.os.StatsdConfigProto.EventActivation;
import com.android.internal.os.StatsdConfigProto.EventMetric;
import com.android.internal.os.StatsdConfigProto.GaugeMetric;
import com.android.internal.os.StatsdConfigProto.MetricActivation;
import com.android.internal.os.StatsdConfigProto.StatsdConfig;
import com.android.os.AtomsProto.AppBreadcrumbReported;
import com.android.os.AtomsProto.Atom;
import com.android.os.StatsLog.ConfigMetricsReport;
import com.android.os.StatsLog.ConfigMetricsReportList;
import com.android.os.StatsLog.StatsLogReport;
import com.android.tradefed.log.LogUtil;
import java.util.List;
/**
* Test Statsd Metric activations and deactivations
*/
public class MetricActivationTests extends DeviceAtomTestCase {
private final long metric1Id = 1L;
private final int metric1MatcherId = 1;
private final long metric2Id = 2L;
private final int metric2MatcherId = 2;
private final long metric3Id = 3L;
private final int metric3MatcherId = 3;
private final int act1MatcherId = 10;
private final int act1CancelMatcherId = -10;
private final int act2MatcherId = 20;
private final int act2CancelMatcherId = -20;
private StatsdConfig.Builder createConfig(final int act1TtlSecs, final int act2TtlSecs) {
AtomMatcher metric1Matcher =
MetricsUtils.simpleAtomMatcher(metric1MatcherId, metric1MatcherId);
AtomMatcher metric2Matcher =
MetricsUtils.simpleAtomMatcher(metric2MatcherId, metric2MatcherId);
AtomMatcher metric3Matcher =
MetricsUtils.simpleAtomMatcher(metric3MatcherId, metric3MatcherId);
AtomMatcher act1Matcher =
MetricsUtils.simpleAtomMatcher(act1MatcherId, act1MatcherId);
AtomMatcher act1CancelMatcher =
MetricsUtils.simpleAtomMatcher(act1CancelMatcherId, act1CancelMatcherId);
AtomMatcher act2Matcher =
MetricsUtils.simpleAtomMatcher(act2MatcherId, act2MatcherId);
AtomMatcher act2CancelMatcher =
MetricsUtils.simpleAtomMatcher(act2CancelMatcherId, act2CancelMatcherId);
EventMetric metric1 = EventMetric.newBuilder()
.setId(metric1Id)
.setWhat(metric1MatcherId)
.build();
EventMetric metric2 = EventMetric.newBuilder()
.setId(metric2Id)
.setWhat(metric2MatcherId)
.build();
EventMetric metric3 = EventMetric.newBuilder()
.setId(metric3Id)
.setWhat(metric3MatcherId)
.build();
EventActivation metric1Act1 =
MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
.setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
.build();
EventActivation metric1Act2 =
MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
.setActivationType(ActivationType.ACTIVATE_ON_BOOT)
.build();
EventActivation metric2Act1 =
MetricsUtils.createEventActivation(act1TtlSecs, act1MatcherId, act1CancelMatcherId)
.setActivationType(ActivationType.ACTIVATE_ON_BOOT)
.build();
EventActivation metric2Act2 =
MetricsUtils.createEventActivation(act2TtlSecs, act2MatcherId, act2CancelMatcherId)
.setActivationType(ActivationType.ACTIVATE_IMMEDIATELY)
.build();
MetricActivation metric1Activation = MetricActivation.newBuilder()
.setMetricId(metric1Id)
.addEventActivation(metric1Act1)
.addEventActivation(metric1Act2)
.build();
MetricActivation metric2Activation = MetricActivation.newBuilder()
.setMetricId(metric2Id)
.addEventActivation(metric2Act1)
.addEventActivation(metric2Act2)
.build();
return createConfigBuilder()
.addAtomMatcher(metric1Matcher)
.addAtomMatcher(metric2Matcher)
.addAtomMatcher(metric3Matcher)
.addAtomMatcher(act1Matcher)
.addAtomMatcher(act1CancelMatcher)
.addAtomMatcher(act2Matcher)
.addAtomMatcher(act2CancelMatcher)
.addEventMetric(metric1)
.addEventMetric(metric2)
.addEventMetric(metric3)
.addMetricActivation(metric1Activation)
.addMetricActivation(metric2Activation);
}
/**
* Metric 1:
* Activation 1:
* - Ttl: 5 seconds
* - Type: IMMEDIATE
* Activation 2:
* - Ttl: 8 seconds
* - Type: ON_BOOT
*
* Metric 2:
* Activation 1:
* - Ttl: 5 seconds
* - Type: ON_BOOT
* Activation 2:
* - Ttl: 8 seconds
* - Type: IMMEDIATE
*
* Metric 3: No activations; always active
**/
public void testCancellation() throws Exception {
final int act1TtlSecs = 5;
final int act2TtlSecs = 8;
uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
// Ignored, metric not active.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Trigger cancel for already inactive event activation 1.
doAppBreadcrumbReported(act1CancelMatcherId);
Thread.sleep(10L);
// Trigger event activation 1.
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// First logged event.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Second logged event.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Cancel event activation 1.
doAppBreadcrumbReported(act1CancelMatcherId);
Thread.sleep(10L);
// Ignored, metric not active.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Trigger event activation 1.
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// Trigger event activation 2.
doAppBreadcrumbReported(act2MatcherId);
Thread.sleep(10L);
// Third logged event.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Cancel event activation 2.
doAppBreadcrumbReported(act2CancelMatcherId);
Thread.sleep(10L);
// Fourth logged event.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Expire event activation 1
Thread.sleep(act1TtlSecs * 1000);
// Ignored, metric 1 not active. Activation 1 expired and Activation 2 was cancelled.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// Trigger event activation 2.
doAppBreadcrumbReported(act2MatcherId);
Thread.sleep(10L);
// Metric 1 log ignored, Activation 1 expired and Activation 2 needs reboot to activate.
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
// First logged event for Metric 3.
doAppBreadcrumbReported(metric3MatcherId);
Thread.sleep(10L);
ConfigMetricsReportList reportList = getReportList();
List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
ConfigMetricsReport report = reports.get(0);
verifyMetrics(report, 4, 0, 1);
}
/**
* Metric 1:
* Activation 1:
* - Ttl: 100 seconds
* - Type: IMMEDIATE
* Activation 2:
* - Ttl: 200 seconds
* - Type: ON_BOOT
*
* Metric 2:
* Activation 1:
* - Ttl: 100 seconds
* - Type: ON_BOOT
* Activation 2:
* - Ttl: 200 seconds
* - Type: IMMEDIATE
*
* Metric 3: No activations; always active
**/
public void testRestart() throws Exception {
final int act1TtlSecs = 200;
final int act2TtlSecs = 400;
uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
// Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds (will activate after boot)
// Metric 2 Activation 2: 0 seconds
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// First logged event for Metric 1.
// Metric 2 event ignored, will activate after boot.
// First logged event for Metric 3.
logAllMetrics();
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 200 seconds
// Metric 2 Activation 2: 0 seconds
rebootDeviceAndWaitUntilReady();
// Second logged event for Metric 1.
// First logged event for Metric 2.
// Second logged event for Metric 3.
logAllMetrics();
// Time remaining:
// Metric 1 Activation 1: 0 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds
// Metric 2 Activation 2: 0 seconds
Thread.sleep(act1TtlSecs * 1000L);
// Metric 1 event ignored, Activation 1 expired.
// Metric 2 event ignored, Activation 1 expired.
// Third logged event for Metric 3.
logAllMetrics();
// Trigger Metric 1 Activation 2 and Metric 2 Activation 2.
// Time remaining:
// Metric 1 Activation 1: 0 seconds
// Metric 1 Activation 2: 0 seconds (will activate after boot)
// Metric 2 Activation 1: 0 seconds
// Metric 2 Activation 2: 400 seconds
doAppBreadcrumbReported(act2MatcherId);
Thread.sleep(10L);
// Metric 1 event ignored, will activate after boot.
// Second logged event for Metric 2.
// Fourth logged event for Metric 3.
logAllMetrics();
// Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds (will activate after boot)
// Metric 2 Activation 1: 0 seconds (will activate after boot)
// Metric 2 Activation 2: 400 seconds
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// Third logged event for Metric 1.
// Third logged event for Metric 2.
// Fifth logged event for Metric 3.
logAllMetrics();
// Time remaining:
// Metric 1 Activation 1: 100 seconds
// Metric 1 Activation 2: 0 seconds (will activate after boot)
// Metric 2 Activation 1: 0 seconds (will activate after boot)
// Metric 2 Activation 2: 300 seconds
Thread.sleep(act1TtlSecs * 1000L / 2);
// Time remaining:
// Metric 1 Activation 1: 100 seconds
// Metric 1 Activation 2: 400 seconds
// Metric 2 Activation 1: 200 seconds
// Metric 2 Activation 2: 300 seconds
rebootDeviceAndWaitUntilReady();
// Fourth logged event for Metric 1.
// Fourth logged event for Metric 2.
// Sixth logged event for Metric 3.
logAllMetrics();
// Expire Metric 1 Activation 1.
// Time remaining:
// Metric 1 Activation 1: 0 seconds
// Metric 1 Activation 2: 300 seconds
// Metric 2 Activation 1: 100 seconds
// Metric 2 Activation 2: 200 seconds
Thread.sleep(act1TtlSecs * 1000L / 2);
// Fifth logged event for Metric 1.
// Fifth logged event for Metric 2.
// Seventh logged event for Metric 3.
logAllMetrics();
// Expire all activations.
// Time remaining:
// Metric 1 Activation 1: 0 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds
// Metric 2 Activation 2: 0 seconds
Thread.sleep(act2TtlSecs * 1000L);
// Metric 1 event ignored.
// Metric 2 event ignored.
// Eighth logged event for Metric 3.
logAllMetrics();
ConfigMetricsReportList reportList = getReportList();
List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
assertThat(reports).hasSize(3);
// Report before restart.
ConfigMetricsReport report = reports.get(0);
verifyMetrics(report, 1, 0, 1);
// Report after first restart.
report = reports.get(1);
verifyMetrics(report, 2, 3, 4);
// Report after second restart.
report = reports.get(2);
verifyMetrics(report, 2, 2, 3);
}
/**
* Metric 1:
* Activation 1:
* - Ttl: 100 seconds
* - Type: IMMEDIATE
* Activation 2:
* - Ttl: 200 seconds
* - Type: ON_BOOT
*
* Metric 2:
* Activation 1:
* - Ttl: 100 seconds
* - Type: ON_BOOT
* Activation 2:
* - Ttl: 200 seconds
* - Type: IMMEDIATE
*
* Metric 3: No activations; always active
**/
public void testMultipleActivations() throws Exception {
final int act1TtlSecs = 200;
final int act2TtlSecs = 400;
uploadConfig(createConfig(act1TtlSecs, act2TtlSecs));
// Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds (will activate after boot)
// Metric 2 Activation 2: 0 seconds
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// First logged event for Metric 1.
// Metric 2 event ignored, will activate after boot.
// First logged event for Metric 3.
logAllMetrics();
// Time remaining:
// Metric 1 Activation 1: 100 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds (will activate after boot)
// Metric 2 Activation 2: 0 seconds
Thread.sleep(act1TtlSecs * 1000L / 2);
// Second logged event for Metric 1.
// Metric 2 event ignored, will activate after boot.
// Second logged event for Metric 3.
logAllMetrics();
// Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds (will activate after boot)
// Metric 2 Activation 2: 0 seconds
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// Third logged event for Metric 1.
// Metric 2 event ignored, will activate after boot.
// Third logged event for Metric 3.
logAllMetrics();
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 200 seconds
// Metric 2 Activation 2: 0 seconds
rebootDeviceAndWaitUntilReady();
// Fourth logged event for Metric 1.
// First logged event for Metric 2.
// Fourth logged event for Metric 3.
logAllMetrics();
// Trigger Metric 1 Activation 1 and Metric 2 Activation 1.
// Time remaining:
// Metric 1 Activation 1: 200 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 200 seconds
// Metric 2 Activation 2: 0 seconds
doAppBreadcrumbReported(act1MatcherId);
Thread.sleep(10L);
// Fifth logged event for Metric 1.
// Second logged event for Metric 2.
// Fifth logged event for Metric 3.
logAllMetrics();
// Expire all activations.
// Time remaining:
// Metric 1 Activation 1: 0 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds
// Metric 2 Activation 2: 0 seconds
Thread.sleep(act1TtlSecs * 1000L);
// Metric 1 event ignored.
// Metric 2 event ignored.
// Sixth logged event for Metric 3.
logAllMetrics();
// Time remaining:
// Metric 1 Activation 1: 0 seconds
// Metric 1 Activation 2: 0 seconds
// Metric 2 Activation 1: 0 seconds
// Metric 2 Activation 2: 0 seconds
rebootDeviceAndWaitUntilReady();
// Metric 1 event ignored.
// Metric 2 event ignored.
// Seventh logged event for Metric 3.
logAllMetrics();
ConfigMetricsReportList reportList = getReportList();
List<ConfigMetricsReport> reports = getSortedConfigMetricsReports(reportList);
assertThat(reports).hasSize(3);
// Report before restart.
ConfigMetricsReport report = reports.get(0);
verifyMetrics(report, 3, 0, 3);
// Report after first restart.
report = reports.get(1);
verifyMetrics(report, 2, 2, 3);
// Report after second restart.
report = reports.get(2);
verifyMetrics(report, 0, 0, 1);
}
private void logAllMetrics() throws Exception {
doAppBreadcrumbReported(metric1MatcherId);
Thread.sleep(10L);
doAppBreadcrumbReported(metric2MatcherId);
Thread.sleep(10L);
doAppBreadcrumbReported(metric3MatcherId);
Thread.sleep(10L);
}
private void verifyMetrics(ConfigMetricsReport report, int metric1Count, int metric2Count,
int metric3Count) throws Exception {
assertThat(report.getMetricsCount()).isEqualTo(3);
verifyMetric(
report.getMetrics(0), // StatsLogReport
1, // Metric Id
1, // Metric what atom matcher label
metric1Count // Data count
);
verifyMetric(
report.getMetrics(1), // StatsLogReport
2, // Metric Id
2, // Metric what atom matcher label
metric2Count // Data count
);
verifyMetric(
report.getMetrics(2), // StatsLogReport
3, // Metric Id
3, // Metric what atom matcher label
metric3Count // Data count
);
}
private void verifyMetric(StatsLogReport metricReport, long metricId, int metricMatcherLabel,
int dataCount) {
LogUtil.CLog.d("Got the following event metric data: " + metricReport.toString());
assertThat(metricReport.getMetricId()).isEqualTo(metricId);
assertThat(metricReport.hasEventMetrics()).isEqualTo(dataCount > 0);
StatsLogReport.EventMetricDataWrapper eventData = metricReport.getEventMetrics();
assertThat(eventData.getDataCount()).isEqualTo(dataCount);
for (int i = 0; i < eventData.getDataCount(); i++) {
AppBreadcrumbReported atom = eventData.getData(i).getAtom().getAppBreadcrumbReported();
assertThat(atom.getLabel()).isEqualTo(metricMatcherLabel);
}
}
}