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.device.collectors; 17 18 import android.device.collectors.annotations.OptionClass; 19 import android.os.Bundle; 20 21 import androidx.annotation.VisibleForTesting; 22 23 import org.junit.runner.Description; 24 import org.junit.runner.Result; 25 import org.junit.runner.notification.Failure; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 /** 31 * A {@link PerfettoListener} that captures the perfetto trace during each test method and save the 32 * perfetto trace files under 33 * <root>/<test_name>/PerfettoTracingStrategy/<test_name>-<invocation_count>.perfetto-trace 34 */ 35 @OptionClass(alias = "perfetto-collector") 36 public class PerfettoListener extends BaseMetricListener { 37 public static final String COLLECT_PER_RUN = "per_run"; 38 public static final String COLLECT_PER_CLASS = "per_class"; 39 public static final String COLLECT_BEFORE_AFTER = "perfetto_before_after_test"; 40 41 private List<PerfettoTracingStrategy> mTracingStrategies; 42 PerfettoListener()43 public PerfettoListener() { 44 super(); 45 } 46 47 /** 48 * Constructor to simulate receiving the instrumentation arguments. Should not be used except 49 * for testing. 50 */ 51 @VisibleForTesting PerfettoListener(Bundle args, List<PerfettoTracingStrategy> strategies)52 public PerfettoListener(Bundle args, List<PerfettoTracingStrategy> strategies) { 53 super(args); 54 mTracingStrategies = strategies; 55 } 56 57 @Override onTestRunStart(DataRecord runData, Description description)58 public void onTestRunStart(DataRecord runData, Description description) { 59 mTracingStrategies.forEach(strategy -> strategy.testRunStart(runData, description)); 60 } 61 62 @Override onTestStart(DataRecord testData, Description description)63 public void onTestStart(DataRecord testData, Description description) { 64 final int iteration = getIteration(description); 65 mTracingStrategies.forEach(strategy -> strategy.testStart(testData, description, 66 iteration)); 67 } 68 69 @Override onTestFail(DataRecord testData, Description description, Failure failure)70 public void onTestFail(DataRecord testData, Description description, Failure failure) { 71 mTracingStrategies.forEach(strategy -> strategy.testFail(testData, description, failure)); 72 } 73 74 @Override onTestEnd(DataRecord testData, Description description)75 public void onTestEnd(DataRecord testData, Description description) { 76 final int iteration = getIteration(description); 77 mTracingStrategies.forEach(strategy -> strategy.testEnd(testData, description, iteration)); 78 } 79 80 @Override onTestRunEnd(DataRecord runData, Result result)81 public void onTestRunEnd(DataRecord runData, Result result) { 82 mTracingStrategies.forEach(strategy -> strategy.testRunEnd(runData, result)); 83 } 84 85 @Override setupAdditionalArgs()86 public void setupAdditionalArgs() { 87 Bundle args = getArgsBundle(); 88 89 if (mTracingStrategies == null) { 90 initTracingStrategies(args); 91 } 92 93 mTracingStrategies.forEach(strategy -> strategy.setup(args)); 94 } 95 initTracingStrategies(Bundle args)96 private void initTracingStrategies(Bundle args) { 97 mTracingStrategies = new ArrayList<>(); 98 99 // Whether to collect the for the entire test run, per test, or per class. 100 if (Boolean.parseBoolean(args.getString(COLLECT_PER_RUN))) { 101 mTracingStrategies.add(new PerfettoTracingPerRunStrategy(getInstrumentation())); 102 } else if (Boolean.parseBoolean(args.getString(COLLECT_PER_CLASS))) { 103 mTracingStrategies.add(new PerfettoTracingPerClassStrategy(getInstrumentation())); 104 } else { 105 mTracingStrategies.add(new PerfettoTracingPerTestStrategy(getInstrumentation())); 106 } 107 108 if (Boolean.parseBoolean(args.getString(COLLECT_BEFORE_AFTER))) { 109 mTracingStrategies.add( 110 new PerfettoTracingBeforeAfterTestStrategy(getInstrumentation())); 111 } 112 } 113 114 @VisibleForTesting getTestFileName(Description description)115 String getTestFileName(Description description) { 116 return PerfettoTracingStrategy.getTestFileName(description); 117 } 118 119 @VisibleForTesting runWithWakeLock(Runnable runnable)120 void runWithWakeLock(Runnable runnable) { 121 mTracingStrategies.forEach(strategy -> strategy.runWithWakeLock(runnable)); 122 } 123 } 124