• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.csuite.tests;
18 
19 import com.android.csuite.core.ApkInstaller;
20 import com.android.csuite.core.ApkInstaller.ApkInstallerException;
21 import com.android.csuite.core.DeviceUtils;
22 import com.android.csuite.core.DeviceUtils.DeviceTimestamp;
23 import com.android.csuite.core.DeviceUtils.DeviceUtilsException;
24 import com.android.csuite.core.TestUtils;
25 import com.android.tradefed.config.Option;
26 import com.android.tradefed.device.DeviceNotAvailableException;
27 import com.android.tradefed.log.LogUtil.CLog;
28 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
29 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestLogData;
30 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
31 import com.android.tradefed.util.RunUtil;
32 
33 import com.google.common.annotations.VisibleForTesting;
34 
35 import org.junit.After;
36 import org.junit.Assert;
37 import org.junit.Before;
38 import org.junit.Rule;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 
42 import java.io.File;
43 import java.io.IOException;
44 import java.util.ArrayList;
45 import java.util.List;
46 import java.util.stream.Collectors;
47 
48 /** A test that verifies that a single app can be successfully launched. */
49 @RunWith(DeviceJUnit4ClassRunner.class)
50 public class AppLaunchTest extends BaseHostJUnit4Test {
51     @VisibleForTesting static final String SCREENSHOT_AFTER_LAUNCH = "screenshot-after-launch";
52     @VisibleForTesting static final String COLLECT_APP_VERSION = "collect-app-version";
53     @VisibleForTesting static final String COLLECT_GMS_VERSION = "collect-gms-version";
54     @VisibleForTesting static final String RECORD_SCREEN = "record-screen";
55     @Rule public TestLogData mLogData = new TestLogData();
56     private ApkInstaller mApkInstaller;
57     private boolean mIsLastTestPass;
58     private boolean mIsApkSaved = false;
59 
60     @Option(name = RECORD_SCREEN, description = "Whether to record screen during test.")
61     private boolean mRecordScreen;
62 
63     @Option(
64             name = SCREENSHOT_AFTER_LAUNCH,
65             description = "Whether to take a screenshost after a package is launched.")
66     private boolean mScreenshotAfterLaunch;
67 
68     @Option(
69             name = COLLECT_APP_VERSION,
70             description =
71                     "Whether to collect package version information and store the information in"
72                             + " test log files.")
73     private boolean mCollectAppVersion;
74 
75     @Option(
76             name = COLLECT_GMS_VERSION,
77             description =
78                     "Whether to collect GMS core version information and store the information in"
79                             + " test log files.")
80     private boolean mCollectGmsVersion;
81 
82     @Option(
83             name = "install-apk",
84             description =
85                     "The path to an apk file or a directory of apk files of a singe package to be"
86                             + " installed on device. Can be repeated.")
87     private final List<File> mApkPaths = new ArrayList<>();
88 
89     @Option(
90             name = "install-arg",
91             description = "Arguments for the 'adb install-multiple' package installation command.")
92     private final List<String> mInstallArgs = new ArrayList<>();
93 
94     @Option(
95             name = "save-apk-when",
96             description = "When to save apk files to the test result artifacts.")
97     private TestUtils.TakeEffectWhen mSaveApkWhen = TestUtils.TakeEffectWhen.NEVER;
98 
99     @Option(name = "package-name", description = "Package name of testing app.")
100     private String mPackageName;
101 
102     @Option(
103             name = "app-launch-timeout-ms",
104             description = "Time to wait for app to launch in msecs.")
105     private int mAppLaunchTimeoutMs = 15000;
106 
107     @Before
setUp()108     public void setUp() throws DeviceNotAvailableException, ApkInstallerException, IOException {
109         Assert.assertNotNull("Package name cannot be null", mPackageName);
110         mIsLastTestPass = false;
111 
112         DeviceUtils deviceUtils = DeviceUtils.getInstance(getDevice());
113         TestUtils testUtils = TestUtils.getInstance(getTestInformation(), mLogData);
114 
115         mApkInstaller = ApkInstaller.getInstance(getDevice());
116         mApkInstaller.install(
117                 mApkPaths.stream().map(File::toPath).collect(Collectors.toList()), mInstallArgs);
118 
119         if (mCollectGmsVersion) {
120             testUtils.collectGmsVersion(mPackageName);
121         }
122 
123         if (mCollectAppVersion) {
124             testUtils.collectAppVersion(mPackageName);
125         }
126 
127         deviceUtils.freezeRotation();
128     }
129 
130     @Test
testAppCrash()131     public void testAppCrash() throws DeviceNotAvailableException {
132         TestUtils testUtils = TestUtils.getInstance(getTestInformation(), mLogData);
133 
134         if (mRecordScreen) {
135             testUtils.collectScreenRecord(
136                     () -> {
137                         launchPackageAndCheckForCrash();
138                     },
139                     mPackageName);
140         } else {
141             launchPackageAndCheckForCrash();
142         }
143         mIsLastTestPass = true;
144     }
145 
146     @After
tearDown()147     public void tearDown() throws DeviceNotAvailableException, ApkInstallerException {
148         DeviceUtils deviceUtils = DeviceUtils.getInstance(getDevice());
149         TestUtils testUtils = TestUtils.getInstance(getTestInformation(), mLogData);
150 
151         if (!mIsApkSaved) {
152             mIsApkSaved =
153                     testUtils.saveApks(mSaveApkWhen, mIsLastTestPass, mPackageName, mApkPaths);
154         }
155 
156         if (mScreenshotAfterLaunch) {
157             testUtils.collectScreenshot(mPackageName);
158         }
159 
160         deviceUtils.stopPackage(mPackageName);
161         deviceUtils.unfreezeRotation();
162 
163         mApkInstaller.uninstallAllInstalledPackages();
164     }
165 
launchPackageAndCheckForCrash()166     private void launchPackageAndCheckForCrash() throws DeviceNotAvailableException {
167         CLog.d("Launching package: %s.", mPackageName);
168 
169         DeviceUtils deviceUtils = DeviceUtils.getInstance(getDevice());
170         TestUtils testUtils = TestUtils.getInstance(getTestInformation(), mLogData);
171 
172         try {
173             if (!deviceUtils.isPackageInstalled(mPackageName)) {
174                 Assert.fail(
175                         "Package "
176                                 + mPackageName
177                                 + " is not installed on the device. Aborting the test.");
178             }
179         } catch (DeviceUtilsException e) {
180             Assert.fail("Failed to check the installed package list: " + e.getMessage());
181         }
182 
183         DeviceTimestamp startTime = deviceUtils.currentTimeMillis();
184         try {
185             deviceUtils.launchPackage(mPackageName);
186         } catch (DeviceUtilsException e) {
187             Assert.fail("Failed to launch package " + mPackageName + ": " + e.getMessage());
188         }
189 
190         CLog.d("Waiting %s milliseconds for the app to launch fully.", mAppLaunchTimeoutMs);
191         RunUtil.getDefault().sleep(mAppLaunchTimeoutMs);
192 
193         CLog.d("Completed launching package: %s", mPackageName);
194 
195         try {
196             String crashLog = testUtils.getDropboxPackageCrashLog(mPackageName, startTime, true);
197             Assert.assertNull(crashLog, crashLog);
198         } catch (IOException e) {
199             Assert.fail("Error while getting dropbox crash log: " + e);
200         }
201     }
202 }
203