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 com.android.collectors; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.mock; 23 24 import android.service.batterystats.BatteryStatsServiceDumpProto; 25 26 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; 27 import com.android.tradefed.config.OptionSetter; 28 import com.android.tradefed.device.metric.DeviceMetricData; 29 import com.android.tradefed.device.metric.FilePullerDeviceMetricCollector; 30 import com.android.tradefed.invoker.IInvocationContext; 31 import com.android.tradefed.metrics.proto.MetricMeasurement.Measurements; 32 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 33 import com.android.tradefed.result.CollectingTestListener; 34 import com.android.tradefed.result.TestRunResult; 35 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 36 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 37 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.io.BufferedInputStream; 43 import java.io.File; 44 import java.io.FileInputStream; 45 import java.io.IOException; 46 import java.io.InputStream; 47 import java.util.Arrays; 48 import java.util.Collection; 49 50 /** 51 * Host side tests for the Batterystats collector, this ensure that we are able to use the 52 * collector in a similar way as the infra. 53 * 54 * Command: 55 * mm CollectorHostsideLibTest CollectorDeviceLibTest -j16 56 * tradefed.sh run commandAndExit template/local_min --template:map test=CollectorHostsideLibTest 57 */ 58 @RunWith(DeviceJUnit4ClassRunner.class) 59 public class BatterystatsCollectorHostTest extends BaseHostJUnit4Test { 60 private static final String TEST_APK = "CollectorDeviceLibTest.apk"; 61 private static final String PACKAGE_NAME = "android.device.collectors"; 62 private static final String AJUR_RUNNER = "androidx.test.runner.AndroidJUnitRunner"; 63 64 private static final String BATTERYSTATS_COLLECTOR = 65 "android.device.collectors.BatteryStatsListener"; 66 private static final String BATTERYSTATS_PROTO = "batterystatsproto"; 67 68 private RemoteAndroidTestRunner mTestRunner; 69 private IInvocationContext mContext; 70 71 @Before setUp()72 public void setUp() throws Exception { 73 installPackage(TEST_APK); 74 assertTrue(isPackageInstalled(PACKAGE_NAME)); 75 mTestRunner = 76 new RemoteAndroidTestRunner(PACKAGE_NAME, AJUR_RUNNER, getDevice().getIDevice()); 77 mContext = mock(IInvocationContext.class); 78 doReturn(Arrays.asList(getDevice())).when(mContext).getDevices(); 79 doReturn(Arrays.asList(getBuild())).when(mContext).getBuildInfos(); 80 } 81 82 /** 83 * Test that BatteryStatsListener collects batterystats and records to a file per run. 84 */ 85 @Test testBatteryStatsListener_perRun()86 public void testBatteryStatsListener_perRun() throws Exception { 87 mTestRunner.addInstrumentationArg("listener", BATTERYSTATS_COLLECTOR); 88 mTestRunner.addInstrumentationArg("batterystats-format", "file:batterystats-log"); 89 mTestRunner.addInstrumentationArg("batterystats-per-run", "true"); 90 mTestRunner.setClassName("android.device.collectors.BatteryStatsListenerTest"); 91 CollectingTestListener listener = new CollectingTestListener(); 92 FilePullerDeviceMetricCollector collector = new FilePullerDeviceMetricCollector() { 93 @Override 94 public void processMetricFile(String key, File metricFile, DeviceMetricData runData) { 95 assertTrue(metricFile.getName().contains(BATTERYSTATS_PROTO)); 96 97 runData.addMetric(key, Metric.newBuilder().setMeasurements( 98 Measurements.newBuilder().setSingleString(metricFile.getAbsolutePath()) 99 .build())); 100 try ( 101 InputStream is = new BufferedInputStream(new FileInputStream(metricFile)) 102 ) { 103 BatteryStatsServiceDumpProto bssdp = BatteryStatsServiceDumpProto.parseFrom(is); 104 assertTrue(bssdp.hasBatterystats()); 105 } catch (IOException e) { 106 throw new RuntimeException(e); 107 } finally { 108 assertTrue(metricFile.delete()); 109 } 110 } 111 @Override 112 public void processMetricDirectory(String key, File metricDirectory, 113 DeviceMetricData runData) { 114 } 115 }; 116 OptionSetter optionSetter = new OptionSetter(collector); 117 String pattern = String.format("%s_.*", BATTERYSTATS_COLLECTOR); 118 optionSetter.setOptionValue("pull-pattern-keys", pattern); 119 collector.init(mContext, listener); 120 assertTrue(getDevice().runInstrumentationTests(mTestRunner, collector)); 121 122 Collection<TestRunResult> results = listener.getRunResults(); 123 assertEquals(1, results.size()); 124 TestRunResult result = results.iterator().next(); 125 assertFalse(result.isRunFailure()); 126 assertFalse(result.hasFailedTests()); 127 128 assertEquals(1, result.getRunMetrics().size()); 129 String metricFileKey = result.getRunMetrics().keySet().iterator().next(); 130 assertTrue(metricFileKey.contains(BATTERYSTATS_COLLECTOR)); 131 } 132 133 /** 134 * Test that BatteryStatsListener collects batterystats and records to a file per test. 135 */ 136 @Test testBatteryStatsListener_perTest()137 public void testBatteryStatsListener_perTest() throws Exception { 138 mTestRunner.addInstrumentationArg("listener", BATTERYSTATS_COLLECTOR); 139 mTestRunner.addInstrumentationArg("batterystats-format", "file:batterystats-log"); 140 mTestRunner.addInstrumentationArg("batterystats-per-run", "false"); 141 mTestRunner.setClassName("android.device.collectors.BatteryStatsListenerTest"); 142 CollectingTestListener listener = new CollectingTestListener(); 143 FilePullerDeviceMetricCollector collector = new FilePullerDeviceMetricCollector() { 144 @Override 145 public void processMetricFile(String key, File metricFile, DeviceMetricData runData) { 146 assertTrue(metricFile.getName().contains(BATTERYSTATS_PROTO)); 147 try ( 148 InputStream is = new BufferedInputStream(new FileInputStream(metricFile)) 149 ) { 150 BatteryStatsServiceDumpProto bssdp = BatteryStatsServiceDumpProto.parseFrom(is); 151 assertTrue(bssdp.hasBatterystats()); 152 } catch (IOException e) { 153 throw new RuntimeException(e); 154 } finally { 155 assertTrue(metricFile.delete()); 156 } 157 } 158 @Override 159 public void processMetricDirectory(String key, File metricDirectory, 160 DeviceMetricData runData) { 161 } 162 }; 163 OptionSetter optionSetter = new OptionSetter(collector); 164 String pattern = String.format("%s_.*", BATTERYSTATS_COLLECTOR); 165 optionSetter.setOptionValue("pull-pattern-keys", pattern); 166 collector.init(mContext, listener); 167 assertTrue(getDevice().runInstrumentationTests(mTestRunner, collector)); 168 } 169 } 170