1 /* 2 * Copyright (C) 2017 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 17 package com.android.tradefed.targetprep; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertTrue; 21 import static org.junit.Assert.fail; 22 23 import com.android.tradefed.build.IBuildInfo; 24 import com.android.tradefed.build.IDeviceBuildInfo; 25 import com.android.tradefed.command.remote.DeviceDescriptor; 26 import com.android.tradefed.config.OptionSetter; 27 import com.android.tradefed.device.ITestDevice; 28 import com.android.tradefed.util.FileUtil; 29 30 import org.easymock.EasyMock; 31 import org.junit.After; 32 import org.junit.Before; 33 import org.junit.Test; 34 import org.junit.runner.RunWith; 35 import org.junit.runners.JUnit4; 36 37 import java.io.File; 38 39 /** Unit tests for {@link TestAppInstallSetup} */ 40 @RunWith(JUnit4.class) 41 public class TestAppInstallSetupTest { 42 43 private static final String SERIAL = "SERIAL"; 44 private static final String PACKAGE_NAME = "PACKAGE_NAME"; 45 private static final String APK_NAME = "fakeApk.apk"; 46 private File fakeApk; 47 private File mFakeBuildApk; 48 private TestAppInstallSetup mPrep; 49 private IDeviceBuildInfo mMockBuildInfo; 50 private ITestDevice mMockTestDevice; 51 private File mTestDir; 52 private File mBuildTestDir; 53 private OptionSetter mSetter; 54 55 @Before 56 public void setUp() throws Exception { 57 mTestDir = FileUtil.createTempDir("TestAppSetupTest"); 58 mBuildTestDir = FileUtil.createTempDir("TestAppBuildTestDir"); 59 // fake hierarchy of directory and files 60 fakeApk = FileUtil.createTempFile("fakeApk", ".apk", mTestDir); 61 FileUtil.copyFile(fakeApk, new File(mTestDir, APK_NAME)); 62 fakeApk = new File(mTestDir, APK_NAME); 63 64 mFakeBuildApk = FileUtil.createTempFile("fakeApk", ".apk", mBuildTestDir); 65 new File(mBuildTestDir, "DATA/app").mkdirs(); 66 FileUtil.copyFile(mFakeBuildApk, new File(mBuildTestDir, "DATA/app/" + APK_NAME)); 67 mFakeBuildApk = new File(mBuildTestDir, "/DATA/app/" + APK_NAME); 68 69 mPrep = 70 new TestAppInstallSetup() { 71 @Override 72 protected String parsePackageName( 73 File testAppFile, DeviceDescriptor deviceDescriptor) { 74 return PACKAGE_NAME; 75 } 76 77 @Override 78 protected File getLocalPathForFilename( 79 IBuildInfo buildInfo, String apkFileName, ITestDevice device) 80 throws TargetSetupError { 81 return fakeApk; 82 } 83 }; 84 mPrep.addTestFileName(APK_NAME); 85 86 mSetter = new OptionSetter(mPrep); 87 mSetter.setOptionValue("cleanup-apks", "true"); 88 mMockBuildInfo = EasyMock.createMock(IDeviceBuildInfo.class); 89 mMockTestDevice = EasyMock.createMock(ITestDevice.class); 90 EasyMock.expect(mMockTestDevice.getSerialNumber()).andStubReturn(SERIAL); 91 EasyMock.expect(mMockTestDevice.getDeviceDescriptor()).andStubReturn(null); 92 } 93 94 @After 95 public void tearDown() throws Exception { 96 FileUtil.recursiveDelete(mTestDir); 97 FileUtil.recursiveDelete(mBuildTestDir); 98 } 99 100 @Test 101 public void testSetupAndTeardown() throws Exception { 102 EasyMock.expect( 103 mMockTestDevice.installPackage( 104 (File) EasyMock.anyObject(), EasyMock.eq(true))) 105 .andReturn(null); 106 EasyMock.replay(mMockBuildInfo, mMockTestDevice); 107 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 108 EasyMock.verify(mMockBuildInfo, mMockTestDevice); 109 } 110 111 @Test 112 public void testSetup_instantMode() throws Exception { 113 OptionSetter setter = new OptionSetter(mPrep); 114 setter.setOptionValue("instant-mode", "true"); 115 EasyMock.expect( 116 mMockTestDevice.installPackage( 117 (File) EasyMock.anyObject(), 118 EasyMock.eq(true), 119 EasyMock.eq("--instant"))) 120 .andReturn(null); 121 EasyMock.replay(mMockBuildInfo, mMockTestDevice); 122 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 123 EasyMock.verify(mMockBuildInfo, mMockTestDevice); 124 } 125 126 /** 127 * If force-install-mode is set, we ignore "instant-mode". This allow some preparer to receive 128 * options as part of the same Tf config but keep their behavior. 129 */ 130 @Test 131 public void testSetup_forceMode() throws Exception { 132 OptionSetter setter = new OptionSetter(mPrep); 133 setter.setOptionValue("instant-mode", "true"); 134 setter.setOptionValue("force-install-mode", "FULL"); 135 EasyMock.expect( 136 mMockTestDevice.installPackage( 137 (File) EasyMock.anyObject(), EasyMock.eq(true))) 138 .andReturn(null); 139 EasyMock.replay(mMockBuildInfo, mMockTestDevice); 140 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 141 EasyMock.verify(mMockBuildInfo, mMockTestDevice); 142 } 143 144 @Test 145 public void testInstallFailure() throws Exception { 146 final String failure = "INSTALL_PARSE_FAILED_MANIFEST_MALFORMED"; 147 EasyMock.expect( 148 mMockTestDevice.installPackage( 149 (File) EasyMock.anyObject(), EasyMock.eq(true))) 150 .andReturn(failure); 151 EasyMock.replay(mMockBuildInfo, mMockTestDevice); 152 try { 153 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 154 fail("Expected TargetSetupError"); 155 } catch (TargetSetupError e) { 156 String expected = 157 String.format( 158 "Failed to install %s on %s. Reason: '%s' " + "null", 159 "fakeApk.apk", SERIAL, failure); 160 assertEquals(expected, e.getMessage()); 161 } 162 EasyMock.verify(mMockBuildInfo, mMockTestDevice); 163 } 164 165 @Test 166 public void testInstallFailedUpdateIncompatible() throws Exception { 167 final String failure = "INSTALL_FAILED_UPDATE_INCOMPATIBLE"; 168 EasyMock.expect( 169 mMockTestDevice.installPackage( 170 (File) EasyMock.anyObject(), EasyMock.eq(true))) 171 .andReturn(failure); 172 EasyMock.expect(mMockTestDevice.uninstallPackage(PACKAGE_NAME)).andReturn(null); 173 EasyMock.expect( 174 mMockTestDevice.installPackage( 175 (File) EasyMock.anyObject(), EasyMock.eq(true))) 176 .andReturn(null); 177 EasyMock.replay(mMockBuildInfo, mMockTestDevice); 178 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 179 EasyMock.verify(mMockBuildInfo, mMockTestDevice); 180 } 181 182 /** 183 * Test {@link TestAppInstallSetup#setUp(ITestDevice, IBuildInfo)} with a missing apk. 184 * TargetSetupError expected. 185 */ 186 @Test 187 public void testMissingApk() throws Exception { 188 fakeApk = null; // Apk doesn't exist 189 190 try { 191 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 192 fail("TestAppInstallSetup#setUp() did not raise TargetSetupError with missing apk."); 193 } catch (TargetSetupError e) { 194 assertTrue(e.getMessage().contains("not found")); 195 } 196 } 197 198 /** 199 * Test {@link TestAppInstallSetup#setUp(ITestDevice, IBuildInfo)} with an unreadable apk. 200 * TargetSetupError expected. 201 */ 202 @Test 203 public void testUnreadableApk() throws Exception { 204 fakeApk = new File("/not/a/real/path"); // Apk cannot be read 205 206 try { 207 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 208 fail("TestAppInstallSetup#setUp() did not raise TargetSetupError with unreadable apk."); 209 } catch (TargetSetupError e) { 210 assertTrue(e.getMessage().contains("not read")); 211 } 212 } 213 214 /** 215 * Test {@link TestAppInstallSetup#setUp(ITestDevice, IBuildInfo)} with a missing apk and 216 * ThrowIfNoFile=False. Silent skip expected. 217 */ 218 @Test 219 public void testMissingApk_silent() throws Exception { 220 fakeApk = null; // Apk doesn't exist 221 mSetter.setOptionValue("throw-if-not-found", "false"); 222 223 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 224 } 225 226 /** 227 * Test {@link TestAppInstallSetup#setUp(ITestDevice, IBuildInfo)} with an unreadable apk and 228 * ThrowIfNoFile=False. Silent skip expected. 229 */ 230 @Test 231 public void testUnreadableApk_silent() throws Exception { 232 fakeApk = new File("/not/a/real/path"); // Apk cannot be read 233 mSetter.setOptionValue("throw-if-not-found", "false"); 234 235 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 236 } 237 238 /** 239 * Tests that when in OVERRIDE mode we install first from alt-dirs, then from BuildInfo if not 240 * found. 241 */ 242 @Test 243 public void testFindApk_override() throws Exception { 244 mPrep = 245 new TestAppInstallSetup() { 246 @Override 247 protected String parsePackageName( 248 File testAppFile, DeviceDescriptor deviceDescriptor) { 249 return PACKAGE_NAME; 250 } 251 }; 252 mPrep.addTestFileName("fakeApk.apk"); 253 OptionSetter setter = new OptionSetter(mPrep); 254 setter.setOptionValue("alt-dir-behavior", "OVERRIDE"); 255 setter.setOptionValue("alt-dir", mTestDir.getAbsolutePath()); 256 setter.setOptionValue("install-arg", "-d"); 257 258 EasyMock.expect(mMockTestDevice.getDeviceDescriptor()).andStubReturn(null); 259 EasyMock.expect(mMockBuildInfo.getTestsDir()).andStubReturn(mBuildTestDir); 260 261 EasyMock.expect( 262 mMockTestDevice.installPackage( 263 EasyMock.eq(fakeApk), EasyMock.anyBoolean(), EasyMock.eq("-d"))) 264 .andReturn(null); 265 266 EasyMock.replay(mMockTestDevice, mMockBuildInfo); 267 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 268 EasyMock.verify(mMockTestDevice, mMockBuildInfo); 269 } 270 271 /** 272 * Test when OVERRIDE is set but there is not alt-dir, in this case we still use the BuildInfo. 273 */ 274 @Test 275 public void testFindApk_override_onlyInBuild() throws Exception { 276 mPrep = 277 new TestAppInstallSetup() { 278 @Override 279 protected String parsePackageName( 280 File testAppFile, DeviceDescriptor deviceDescriptor) { 281 return PACKAGE_NAME; 282 } 283 }; 284 mPrep.addTestFileName("fakeApk.apk"); 285 OptionSetter setter = new OptionSetter(mPrep); 286 setter.setOptionValue("alt-dir-behavior", "OVERRIDE"); 287 setter.setOptionValue("install-arg", "-d"); 288 289 EasyMock.expect(mMockTestDevice.getDeviceDescriptor()).andStubReturn(null); 290 EasyMock.expect(mMockBuildInfo.getTestsDir()).andStubReturn(mBuildTestDir); 291 292 EasyMock.expect( 293 mMockTestDevice.installPackage( 294 EasyMock.eq(mFakeBuildApk), 295 EasyMock.anyBoolean(), 296 EasyMock.eq("-d"))) 297 .andReturn(null); 298 299 EasyMock.replay(mMockTestDevice, mMockBuildInfo); 300 mPrep.setUp(mMockTestDevice, mMockBuildInfo); 301 EasyMock.verify(mMockTestDevice, mMockBuildInfo); 302 } 303 } 304