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.app.tests; 17 18 import com.android.ddmlib.testrunner.TestIdentifier; 19 import com.android.tradefed.build.IAppBuildInfo; 20 import com.android.tradefed.build.IBuildInfo; 21 import com.android.tradefed.build.VersionedFile; 22 import com.android.tradefed.device.DeviceNotAvailableException; 23 import com.android.tradefed.device.ITestDevice; 24 import com.android.tradefed.result.ITestInvocationListener; 25 import com.android.tradefed.result.InputStreamSource; 26 import com.android.tradefed.result.LogDataType; 27 import com.android.tradefed.testtype.IBuildReceiver; 28 import com.android.tradefed.testtype.IDeviceTest; 29 import com.android.tradefed.testtype.IRemoteTest; 30 import com.android.tradefed.testtype.InstrumentationTest; 31 import com.android.tradefed.util.AaptParser; 32 import com.android.tradefed.util.FileUtil; 33 34 import org.junit.Assert; 35 36 import java.io.File; 37 import java.util.Collections; 38 39 /** 40 * A harness that installs and launches an app on device and verifies it doesn't crash. 41 * <p/> 42 * Requires a {@link IAppBuildInfo} and 'aapt' being present in path. Assume the AppLaunch 43 * test app is already present on device. 44 */ 45 public class AppLaunchTest implements IDeviceTest, IRemoteTest, IBuildReceiver { 46 47 private static final String RUN_NAME = "AppLaunch"; 48 private ITestDevice mDevice; 49 private IBuildInfo mBuild; 50 51 /** 52 * {@inheritDoc} 53 */ 54 @Override 55 public void setDevice(ITestDevice device) { 56 mDevice = device; 57 } 58 59 /** 60 * {@inheritDoc} 61 */ 62 @Override 63 public ITestDevice getDevice() { 64 return mDevice; 65 } 66 67 /** 68 * {@inheritDoc} 69 */ 70 @Override 71 public void setBuild(IBuildInfo buildInfo) { 72 mBuild = buildInfo; 73 } 74 75 /** 76 * Installs all apks listed in {@link IAppBuildInfo}, then attempts to run the package in the 77 * first apk. Note that this does <emph>not</emph> attempt to uninstall the apks, and requires 78 * external cleanup. 79 * <p /> 80 * {@inheritDoc} 81 */ 82 @Override 83 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 84 long startTime = System.currentTimeMillis(); 85 listener.testRunStarted(RUN_NAME, 2); 86 try { 87 Assert.assertTrue(mBuild instanceof IAppBuildInfo); 88 IAppBuildInfo appBuild = (IAppBuildInfo)mBuild; 89 Assert.assertFalse(appBuild.getAppPackageFiles().isEmpty()); 90 91 // We assume that the first apk is the one to be executed, and any others are to be 92 // installed and uninstalled. 93 File appApkFile = appBuild.getAppPackageFiles().get(0).getFile(); 94 AaptParser p = AaptParser.parse(appApkFile); 95 Assert.assertNotNull(p); 96 String packageName = p.getPackageName(); 97 Assert.assertNotNull(String.format("Failed to parse package name from %s", 98 appApkFile.getAbsolutePath()), packageName); 99 100 for (final VersionedFile apkVersionedFile : appBuild.getAppPackageFiles()) { 101 final File apkFile = apkVersionedFile.getFile(); 102 performInstallTest(apkFile, listener); 103 } 104 105 performLaunchTest(packageName, listener); 106 } catch (AssertionError e) { 107 listener.testRunFailed(e.toString()); 108 } finally { 109 listener.testRunEnded(System.currentTimeMillis() - startTime, 110 Collections.<String, String> emptyMap()); 111 } 112 113 } 114 115 private void performInstallTest(File apkFile, ITestInvocationListener listener) 116 throws DeviceNotAvailableException { 117 TestIdentifier installTest = new TestIdentifier("com.android.app.tests.InstallTest", 118 FileUtil.getBaseName(apkFile.getName())); 119 listener.testStarted(installTest); 120 String result = getDevice().installPackage(apkFile, true); 121 if (result != null) { 122 listener.testFailed(installTest, result); 123 } 124 listener.testEnded(installTest, Collections.<String, String> emptyMap()); 125 } 126 127 private void performLaunchTest(String packageName, ITestInvocationListener listener) 128 throws DeviceNotAvailableException { 129 InstrumentationTest i = new InstrumentationTest(); 130 i.setRunName(RUN_NAME); 131 i.setPackageName("com.android.applaunchtest"); 132 i.setRunnerName("com.android.applaunchtest.AppLaunchRunner"); 133 i.setDevice(getDevice()); 134 i.addInstrumentationArg("packageName", packageName); 135 i.run(listener); 136 try (InputStreamSource s = getDevice().getScreenshot()) { 137 listener.testLog("screenshot", LogDataType.PNG, s); 138 } 139 } 140 } 141