1 /* 2 * Copyright (C) 2012 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.tradefed.testtype; 17 18 import com.android.tradefed.config.ArgsOptionParser; 19 import com.android.tradefed.device.DeviceNotAvailableException; 20 import com.android.tradefed.device.ITestDevice; 21 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 22 import com.android.tradefed.result.ITestInvocationListener; 23 24 import junit.framework.TestCase; 25 26 import org.easymock.Capture; 27 import org.easymock.EasyMock; 28 import org.easymock.IAnswer; 29 30 import java.util.ArrayList; 31 import java.util.HashMap; 32 import java.util.List; 33 34 /** Unit tests for {@link InstalledInstrumentationsTest}. */ 35 public class InstalledInstrumentationsTestTest extends TestCase { 36 37 private static final String TEST_PKG = "com.example.tests"; 38 private static final String TEST_COVERAGE_TARGET = "com.example"; 39 private static final String TEST_RUNNER = "android.support.runner.AndroidJUnitRunner"; 40 private static final String ABI = "forceMyAbiSettingPlease"; 41 private static final String INSTR_OUTPUT_FORMAT = "instrumentation:%s/%s (target=%s)\r\n"; 42 private static final String PM_LIST_ERROR_OUTPUT = "Error: Could not access the Package " 43 + "Manager. Is the system running?"; 44 private ITestDevice mMockTestDevice; 45 private ITestInvocationListener mMockListener; 46 private List<MockInstrumentationTest> mMockInstrumentationTests; 47 private InstalledInstrumentationsTest mInstalledInstrTest; 48 49 /** 50 * {@inheritDoc} 51 */ 52 @Override 53 protected void setUp() throws Exception { 54 super.setUp(); 55 56 mMockTestDevice = EasyMock.createMock(ITestDevice.class); 57 EasyMock.expect(mMockTestDevice.getSerialNumber()).andStubReturn("foo"); 58 mMockListener = EasyMock.createMock(ITestInvocationListener.class); 59 mMockInstrumentationTests = new ArrayList<MockInstrumentationTest>(); 60 mInstalledInstrTest = createInstalledInstrumentationsTest(); 61 mInstalledInstrTest.setDevice(mMockTestDevice); 62 } 63 64 /** 65 * Test the run normal case. Simple verification that expected data is passed along, etc. 66 */ 67 public void testRun() throws Exception { 68 injectShellResponse(String.format(INSTR_OUTPUT_FORMAT, TEST_PKG, TEST_RUNNER, 69 TEST_COVERAGE_TARGET), 1); 70 71 mMockListener.testRunStarted(TEST_PKG, 0); 72 Capture<HashMap<String, Metric>> captureMetrics = new Capture<>(); 73 mMockListener.testRunEnded(EasyMock.anyLong(), EasyMock.capture(captureMetrics)); 74 ArgsOptionParser p = new ArgsOptionParser(mInstalledInstrTest); 75 p.parse("--size", "small", "--force-abi", ABI); 76 mInstalledInstrTest.setSendCoverage(true); 77 EasyMock.replay(mMockTestDevice, mMockListener); 78 mInstalledInstrTest.run(mMockListener); 79 assertEquals(1, mMockInstrumentationTests.size()); 80 MockInstrumentationTest mockInstrumentationTest = mMockInstrumentationTests.get(0); 81 assertEquals(mMockListener, mockInstrumentationTest.getListener()); 82 assertEquals(TEST_PKG, mockInstrumentationTest.getPackageName()); 83 assertEquals(TEST_RUNNER, mockInstrumentationTest.getRunnerName()); 84 assertEquals( 85 TEST_COVERAGE_TARGET, 86 captureMetrics 87 .getValue() 88 .get(InstalledInstrumentationsTest.COVERAGE_TARGET_KEY) 89 .getMeasurements() 90 .getSingleString()); 91 assertEquals("small", mockInstrumentationTest.getTestSize()); 92 assertEquals(ABI, mockInstrumentationTest.getForceAbi()); 93 94 EasyMock.verify(mMockListener, mMockTestDevice); 95 } 96 97 /** 98 * Tests the run of sharded InstalledInstrumentationsTests. 99 */ 100 public void testShardedRun() throws Exception { 101 final String shardableRunner = "android.support.test.runner.AndroidJUnitRunner"; 102 final String nonshardableRunner = "android.test.InstrumentationTestRunner"; 103 104 final String shardableTestPkg = "com.example.shardabletest"; 105 final String nonshardableTestPkg1 = "com.example.nonshardabletest1"; 106 final String nonshardableTestPkg2 = "com.example.nonshardabletest2"; 107 108 109 String shardableInstr = String.format(INSTR_OUTPUT_FORMAT, shardableTestPkg, 110 shardableRunner, TEST_COVERAGE_TARGET); 111 String nonshardableInstr1 = String.format(INSTR_OUTPUT_FORMAT, nonshardableTestPkg1, 112 nonshardableRunner, TEST_COVERAGE_TARGET); 113 String nonshardableInstr2 = String.format(INSTR_OUTPUT_FORMAT, nonshardableTestPkg2, 114 nonshardableRunner, TEST_COVERAGE_TARGET); 115 116 injectShellResponse(String.format("%s%s%s", shardableInstr, 117 nonshardableInstr1, nonshardableInstr2), 2); 118 119 // Instantiate InstalledInstrumentationTest shards 120 EasyMock.replay(mMockTestDevice, mMockListener); 121 InstalledInstrumentationsTest shard0 = createInstalledInstrumentationsTest(); 122 shard0.setDevice(mMockTestDevice); 123 shard0.setShardIndex(0); 124 shard0.setTotalShards(2); 125 InstalledInstrumentationsTest shard1 = createInstalledInstrumentationsTest(); 126 shard1.setDevice(mMockTestDevice); 127 shard1.setShardIndex(1); 128 shard1.setTotalShards(2); 129 130 // Run tests in first shard. There should be only two tests run: a test shard, and a 131 // nonshardable test. 132 133 shard0.run(mMockListener); 134 assertEquals(2, mMockInstrumentationTests.size()); 135 assertEquals(nonshardableTestPkg1, mMockInstrumentationTests.get(0).getPackageName()); 136 assertEquals(shardableTestPkg, mMockInstrumentationTests.get(1).getPackageName()); 137 assertEquals("0", mMockInstrumentationTests.get(1).getInstrumentationArg("shardIndex")); 138 assertEquals("2", mMockInstrumentationTests.get(1).getInstrumentationArg("numShards")); 139 mMockInstrumentationTests.clear(); 140 141 // Run tests in second shard. All tests should be accounted for. 142 shard1.run(mMockListener); 143 assertEquals(2, mMockInstrumentationTests.size()); 144 assertEquals(nonshardableTestPkg2, mMockInstrumentationTests.get(0).getPackageName()); 145 assertEquals(shardableTestPkg, mMockInstrumentationTests.get(1).getPackageName()); 146 assertEquals("1", mMockInstrumentationTests.get(1).getInstrumentationArg("shardIndex")); 147 assertEquals("2", mMockInstrumentationTests.get(1).getInstrumentationArg("numShards")); 148 149 EasyMock.verify(mMockListener, mMockTestDevice); 150 } 151 152 /** 153 * Method to mock the executeShellCommand response 154 * 155 * @param shellResponse value to be returned by executeShellCommand 156 * @param numExpectedCalls number of invocation expected 157 * @throws DeviceNotAvailableException 158 */ 159 private void injectShellResponse(final String shellResponse, int numExpectedCalls) 160 throws DeviceNotAvailableException { 161 IAnswer<Object> shellAnswer = new IAnswer<Object>() { 162 @Override 163 public String answer() throws Throwable { 164 return shellResponse; 165 } 166 }; 167 mMockTestDevice.executeShellCommand(EasyMock.<String> anyObject()); 168 EasyMock.expectLastCall().andAnswer(shellAnswer).times(numExpectedCalls); 169 } 170 171 /** 172 * Utility method for creating an InstalledInstrumentationsTest for testing. 173 * 174 * InstalledInstrumentationsTests need to create a MockInstrumentationTest, and we need to be 175 * able to keep track of all mocks created in this manner. 176 */ 177 private InstalledInstrumentationsTest createInstalledInstrumentationsTest() { 178 InstalledInstrumentationsTest test = new InstalledInstrumentationsTest() { 179 @Override 180 InstrumentationTest createInstrumentationTest() { 181 MockInstrumentationTest test = new MockInstrumentationTest(); 182 mMockInstrumentationTests.add(test); 183 return test; 184 } 185 }; 186 return test; 187 } 188 189 /** 190 * Test that IllegalArgumentException is thrown when attempting run without setting device. 191 */ 192 public void testRun_noDevice() throws Exception { 193 mInstalledInstrTest.setDevice(null); 194 try { 195 mInstalledInstrTest.run(mMockListener); 196 fail("IllegalArgumentException not thrown"); 197 } catch (IllegalArgumentException e) { 198 // expected 199 } 200 } 201 202 /** 203 * Test that IllegalArgumentException is thrown when attempting run when no instrumentations 204 * are present. 205 */ 206 public void testRun_noInstr() throws Exception { 207 injectShellResponse(PM_LIST_ERROR_OUTPUT, 1); 208 EasyMock.replay(mMockTestDevice, mMockListener); 209 try { 210 mInstalledInstrTest.run(mMockListener); 211 fail("IllegalArgumentException not thrown"); 212 } catch (IllegalArgumentException e) { 213 // expected 214 } 215 } 216 } 217