1 /* 2 * Copyright (C) 2010 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.framework.tests; 18 19 import com.android.tradefed.config.Option; 20 import com.android.tradefed.config.Option.Importance; 21 import com.android.tradefed.log.LogUtil.CLog; 22 import com.android.tradefed.testtype.DeviceTestCase; 23 import com.android.tradefed.util.FileUtil; 24 25 import java.io.File; 26 27 /** Set of tests that verify host side stress scenarios (large apps, multiple upgrades, etc.) */ 28 public class PackageManagerStressHostTests extends DeviceTestCase { 29 30 private PackageManagerHostTestUtils mPMHostUtils = null; 31 32 // Path to the app repository and various subdirectories of it 33 // Note: These stress tests require large apks that cannot be checked into the tree. 34 // These variables define static locations that point to existing APKs (not built from 35 // the tree) which can be used by the stress tests in this file. 36 private static final String LARGE_APPS_DIRECTORY_NAME = "largeApps"; 37 private static final String MISC_APPS_DIRECTORY_NAME = "miscApps"; 38 private static final String VERSIONED_APPS_DIRECTORY_NAME = "versionedApps"; 39 private static final String MANY_APPS_DIRECTORY_NAME = "manyApps"; 40 41 // Large apps (>1mb) - filenames and their corresponding package names: 42 private static enum APK { 43 FILENAME, 44 PACKAGENAME; 45 } 46 47 private static final String[][] LARGE_APPS = { 48 {"External1mb.apk", "com.appsonsd.mytests.External1mb"}, 49 {"External2mb.apk", "com.appsonsd.mytests.External2mb"}, 50 {"External3mb.apk", "com.appsonsd.mytests.External3mb"}, 51 {"External4mb.apk", "com.appsonsd.mytests.External4mb"}, 52 {"External5mb.apk", "com.appsonsd.mytests.External5mb"}, 53 {"External6mb.apk", "com.appsonsd.mytests.External6mb"}, 54 {"External7mb.apk", "com.appsonsd.mytests.External7mb"}, 55 {"External8mb.apk", "com.appsonsd.mytests.External8mb"}, 56 {"External9mb.apk", "com.appsonsd.mytests.External9mb"}, 57 {"External10mb.apk", "com.appsonsd.mytests.External10mb"}, 58 {"External16mb.apk", "com.appsonsd.mytests.External16mb"}, 59 {"External28mb.apk", "com.appsonsd.mytests.External28mb"}, 60 {"External34mb.apk", "com.appsonsd.mytests.External34mb"}, 61 {"External46mb.apk", "com.appsonsd.mytests.External46mb"}, 62 {"External58mb.apk", "com.appsonsd.mytests.External58mb"}, 63 {"External65mb.apk", "com.appsonsd.mytests.External65mb"}, 64 {"External72mb.apk", "com.appsonsd.mytests.External72mb"}, 65 {"External79mb.apk", "com.appsonsd.mytests.External79mb"}, 66 {"External86mb.apk", "com.appsonsd.mytests.External86mb"}, 67 {"External93mb.apk", "com.appsonsd.mytests.External93mb"} 68 }; 69 70 // Various test files and their corresponding package names 71 private static final String EXTERNAL_LOC_APK = "External931kb.apk"; 72 private static final String EXTERNAL_LOC_PKG = "com.appsonsd.mytests.External931kb"; 73 74 // Versioned test apps 75 private static final String VERSIONED_APPS_FILENAME_PREFIX = "External455kb_v"; 76 private static final String VERSIONED_APPS_PKG = "com.appsonsd.mytests.External455kb"; 77 private static final int VERSIONED_APPS_START_VERSION = 1; // inclusive 78 private static final int VERSIONED_APPS_END_VERSION = 250; // inclusive 79 80 // Large number of app installs 81 // @TODO: increase the max when we can install more apps 82 private static final int MANY_APPS_START = 1; 83 private static final int MANY_APPS_END = 100; 84 private static final String MANY_APPS_PKG_PREFIX = "com.appsonsd.mytests.External49kb_"; 85 private static final String MANY_APPS_APK_PREFIX = "External49kb_"; 86 private static final int DEFAULT_ITERATION_COUNT = 100; 87 88 @Option( 89 name = "app-repository-path", 90 description = "path to the app repository containing large apks.", 91 importance = Importance.IF_UNSET) 92 private File mAppRepositoryPath = null; 93 94 @Option( 95 name = "stress-iteration-count", 96 description = "Number of iterations to run the package manager stress test for.", 97 importance = Importance.IF_UNSET) 98 private int mIterationCount = DEFAULT_ITERATION_COUNT; 99 100 @Override setUp()101 protected void setUp() throws Exception { 102 super.setUp(); 103 // setup the PackageManager host tests utilities class, and get various paths we'll need... 104 mPMHostUtils = new PackageManagerHostTestUtils(getDevice()); 105 // ensure apk path has been set before test is run 106 assertNotNull("Missing --app-repository-path option", mAppRepositoryPath); 107 } 108 109 /** 110 * Get the {@link File} of repository test app with given filename 111 * 112 * @param fileName the file name of the test app apk 113 * @return {@link File} 114 */ getRepositoryTestAppFilePath(String fileDirectory, String fileName)115 private File getRepositoryTestAppFilePath(String fileDirectory, String fileName) { 116 return FileUtil.getFileForPath(mAppRepositoryPath, fileDirectory, fileName); 117 } 118 119 /** 120 * Stress test to verify that we can update an app multiple times on the SD card. 121 * 122 * <p>Assumes adb is running as root in device under test. 123 */ testUpdateAppManyTimesOnSD()124 public void testUpdateAppManyTimesOnSD() throws Exception { 125 CLog.i("Test updating an app on SD numerous times"); 126 // cleanup test app just in case it already exists 127 mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG); 128 try { 129 for (int i = VERSIONED_APPS_START_VERSION; i <= VERSIONED_APPS_END_VERSION; ++i) { 130 String currentApkName = 131 String.format("%s%d.apk", VERSIONED_APPS_FILENAME_PREFIX, i); 132 CLog.i("Installing app " + currentApkName); 133 mPMHostUtils.installFile( 134 getRepositoryTestAppFilePath(VERSIONED_APPS_DIRECTORY_NAME, currentApkName), 135 true); 136 mPMHostUtils.waitForPackageManager(); 137 assertTrue(mPMHostUtils.doesAppExistOnSDCard(VERSIONED_APPS_PKG)); 138 assertTrue(mPMHostUtils.doesPackageExist(VERSIONED_APPS_PKG)); 139 } 140 } finally { 141 // cleanup test app 142 mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG); 143 } 144 } 145 146 /** 147 * Stress test to verify that an app can be installed, uninstalled, and reinstalled on SD many 148 * times. 149 * 150 * <p>Assumes adb is running as root in device under test. 151 */ testUninstallReinstallAppOnSDManyTimes()152 public void testUninstallReinstallAppOnSDManyTimes() throws Exception { 153 CLog.i("Test updating an app on the SD card stays on the SD card"); 154 // cleanup test app just in case it was already exists 155 mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG); 156 for (int i = 0; i < mIterationCount; ++i) { 157 CLog.i("Installing app %s (%d)", EXTERNAL_LOC_PKG, i); 158 try { 159 // install the app 160 mPMHostUtils.installFile( 161 getRepositoryTestAppFilePath(MISC_APPS_DIRECTORY_NAME, EXTERNAL_LOC_APK), 162 false); 163 mPMHostUtils.waitForPackageManager(); 164 assertTrue(mPMHostUtils.doesAppExistOnSDCard(EXTERNAL_LOC_PKG)); 165 assertTrue(mPMHostUtils.doesPackageExist(EXTERNAL_LOC_PKG)); 166 } finally { 167 // now uninstall the app 168 CLog.i("Uninstalling app %s (%d)", EXTERNAL_LOC_PKG, i); 169 mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG); 170 } 171 } 172 } 173 174 /** 175 * Stress test to verify that we can install, 20 large apps (>1mb each) 176 * 177 * <p>Assumes adb is running as root in device under test. 178 */ testInstallManyLargeAppsOnSD()179 public void testInstallManyLargeAppsOnSD() throws Exception { 180 CLog.i("Test installing %d large apps onto the sd card", LARGE_APPS.length); 181 try { 182 // Install all the large apps 183 for (int i = 0; i < LARGE_APPS.length; ++i) { 184 String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()]; 185 String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()]; 186 // cleanup test app just in case it already exists 187 mPMHostUtils.uninstallApp(pkgName); 188 CLog.i("Installing app " + apkName); 189 // install the app 190 mPMHostUtils.installFile( 191 getRepositoryTestAppFilePath(LARGE_APPS_DIRECTORY_NAME, apkName), false); 192 mPMHostUtils.waitForPackageManager(); 193 assertTrue(mPMHostUtils.doesAppExistOnSDCard(pkgName)); 194 assertTrue(mPMHostUtils.doesPackageExist(pkgName)); 195 } 196 } finally { 197 // Cleanup - ensure we uninstall all large apps if they were installed 198 for (int i = 0; i < LARGE_APPS.length; ++i) { 199 String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()]; 200 String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()]; 201 CLog.i("Uninstalling app " + apkName); 202 // cleanup test app just in case it was accidently installed 203 mPMHostUtils.uninstallApp(pkgName); 204 assertFalse(mPMHostUtils.doesAppExistOnSDCard(pkgName)); 205 } 206 } 207 } 208 209 /** 210 * Stress test to verify that we can install many small apps onto SD. 211 * 212 * <p>Assumes adb is running as root in device under test. 213 */ testInstallManyAppsOnSD()214 public void testInstallManyAppsOnSD() throws Exception { 215 CLog.i("Test installing %d small apps onto SD", MANY_APPS_END); 216 try { 217 for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) { 218 String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i); 219 // cleanup test app just in case it already exists 220 mPMHostUtils.uninstallApp(currentPkgName); 221 String currentApkName = String.format("%s%d.apk", MANY_APPS_APK_PREFIX, i); 222 CLog.i("Installing app " + currentApkName); 223 mPMHostUtils.installFile( 224 getRepositoryTestAppFilePath(MANY_APPS_DIRECTORY_NAME, currentApkName), 225 true); 226 mPMHostUtils.waitForPackageManager(); 227 assertTrue(mPMHostUtils.doesAppExistOnSDCard(currentPkgName)); 228 assertTrue(mPMHostUtils.doesPackageExist(currentPkgName)); 229 } 230 } finally { 231 for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) { 232 String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i); 233 // cleanup test app 234 mPMHostUtils.uninstallApp(currentPkgName); 235 } 236 } 237 } 238 } 239