Merge "Add test name as the file prefix for different test cases. Test: forret run"
diff --git a/harness/src/main/java/com/android/csuite/core/ApkInstaller.java b/harness/src/main/java/com/android/csuite/core/ApkInstaller.java
index 70a6105..54df8f4 100644
--- a/harness/src/main/java/com/android/csuite/core/ApkInstaller.java
+++ b/harness/src/main/java/com/android/csuite/core/ApkInstaller.java
@@ -198,17 +198,15 @@
.filter(path -> path.toString().toLowerCase().endsWith(".obb"))
.forEach(
path -> {
+ String dest =
+ "/sdcard/Android/obb/" + packageName + "/" + path.getFileName();
cmds.add(
new String[] {
- "adb",
- "-s",
- deviceSerial,
- "push",
- path.toString(),
- "/sdcard/Android/obb/"
- + packageName
- + "/"
- + path.getFileName()
+ "adb", "-s", deviceSerial, "shell", "rm", "-f", dest
+ });
+ cmds.add(
+ new String[] {
+ "adb", "-s", deviceSerial, "push", path.toString(), dest
});
});
@@ -221,6 +219,7 @@
deviceSerial,
"shell",
"mkdir",
+ "-p",
"/sdcard/Android/obb/" + packageName
});
}
diff --git a/harness/src/main/java/com/android/csuite/core/AppCrawlTester.java b/harness/src/main/java/com/android/csuite/core/AppCrawlTester.java
index 320be19..258b374 100644
--- a/harness/src/main/java/com/android/csuite/core/AppCrawlTester.java
+++ b/harness/src/main/java/com/android/csuite/core/AppCrawlTester.java
@@ -17,6 +17,7 @@
package com.android.csuite.core;
import com.android.csuite.core.DeviceUtils.DeviceTimestamp;
+import com.android.csuite.core.TestUtils.TestUtilsException;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.LogUtil.CLog;
@@ -36,11 +37,12 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@@ -64,6 +66,7 @@
private Path mRoboscriptFile;
private Path mCrawlGuidanceProtoFile;
private Path mLoginConfigDir;
+ private FileSystem mFileSystem;
/**
* Creates an {@link AppCrawlTester} instance.
@@ -78,14 +81,20 @@
return new AppCrawlTester(
packageName,
TestUtils.getInstance(testInformation, testLogData),
- () -> new RunUtil());
+ () -> new RunUtil(),
+ FileSystems.getDefault());
}
@VisibleForTesting
- AppCrawlTester(String packageName, TestUtils testUtils, RunUtilProvider runUtilProvider) {
+ AppCrawlTester(
+ String packageName,
+ TestUtils testUtils,
+ RunUtilProvider runUtilProvider,
+ FileSystem fileSystem) {
mRunUtilProvider = runUtilProvider;
mPackageName = packageName;
mTestUtils = testUtils;
+ mFileSystem = fileSystem;
}
/** An exception class representing crawler test failures. */
@@ -188,17 +197,34 @@
throw new CrawlerException("Failed to create temp directory for output.", e);
}
- String[] command = createCrawlerRunCommand(mTestUtils.getTestInformation());
-
- CLog.d("Launching package: %s.", mPackageName);
-
IRunUtil runUtil = mRunUtilProvider.get();
-
+ AtomicReference<String[]> command = new AtomicReference<>();
AtomicReference<CommandResult> commandResult = new AtomicReference<>();
- runUtil.setEnvVariable(
- "GOOGLE_APPLICATION_CREDENTIALS",
- AppCrawlTesterHostPreparer.getCredentialPath(mTestUtils.getTestInformation())
- .toString());
+
+ CLog.d("Start to crawl package: %s.", mPackageName);
+
+ Path bin =
+ mFileSystem.getPath(
+ AppCrawlTesterHostPreparer.getCrawlerBinPath(
+ mTestUtils.getTestInformation()));
+ boolean isUtpClient = false;
+ if (Files.exists(bin.resolve("utp-cli-android_deploy.jar"))) {
+ command.set(createUtpCrawlerRunCommand(mTestUtils.getTestInformation()));
+ runUtil.setEnvVariable(
+ "ANDROID_SDK",
+ AppCrawlTesterHostPreparer.getSdkPath(mTestUtils.getTestInformation())
+ .toString());
+ isUtpClient = true;
+ } else if (Files.exists(bin.resolve("crawl_launcher_deploy.jar"))) {
+ command.set(createCrawlerRunCommand(mTestUtils.getTestInformation()));
+ runUtil.setEnvVariable(
+ "GOOGLE_APPLICATION_CREDENTIALS",
+ AppCrawlTesterHostPreparer.getCredentialPath(mTestUtils.getTestInformation())
+ .toString());
+ } else {
+ throw new CrawlerException(
+ "Crawler executable binaries not found in " + bin.toString());
+ }
if (mCollectGmsVersion) {
mTestUtils.collectGmsVersion(mPackageName);
@@ -212,11 +238,11 @@
if (mRecordScreen) {
mTestUtils.collectScreenRecord(
() -> {
- commandResult.set(runUtil.runTimedCmd(commandTimeout, command));
+ commandResult.set(runUtil.runTimedCmd(commandTimeout, command.get()));
},
mPackageName);
} else {
- commandResult.set(runUtil.runTimedCmd(commandTimeout, command));
+ commandResult.set(runUtil.runTimedCmd(commandTimeout, command.get()));
}
// Must be done after the crawler run because the app is installed by the crawler.
@@ -225,9 +251,10 @@
}
collectOutputZip();
- collectCrawlStepScreenshots();
+ collectCrawlStepScreenshots(isUtpClient);
- if (!commandResult.get().getStatus().equals(CommandStatus.SUCCESS)) {
+ if (!commandResult.get().getStatus().equals(CommandStatus.SUCCESS)
+ || commandResult.get().getStdout().contains("Unknown options:")) {
throw new CrawlerException("Crawler command failed: " + commandResult.get());
}
@@ -235,13 +262,16 @@
}
/** Copys the step screenshots into test outputs for easier access. */
- private void collectCrawlStepScreenshots() {
+ private void collectCrawlStepScreenshots(boolean isUtpClient) {
if (mOutput == null) {
CLog.e("Output directory is not created yet. Skipping collecting step screenshots.");
return;
}
- Path subDir = mOutput.resolve("app_firebase_test_lab");
+ Path subDir =
+ isUtpClient
+ ? mOutput.resolve("output").resolve("artifacts")
+ : mOutput.resolve("app_firebase_test_lab");
if (!Files.exists(subDir)) {
CLog.e(
"The crawler output directory is not complete, skipping collecting step"
@@ -285,81 +315,107 @@
}
}
- /**
- * Generates a list of APK paths where the base.apk of split apk files are always on the first
- * index if exists.
- *
- * <p>If the apk path is a single apk, then the apk is returned. If the apk path is a directory
- * containing only one non-split apk file, the apk file is returned. If the apk path is a
- * directory containing split apk files for one package, then the list of apks are returned and
- * the base.apk sits on the first index. If the apk path does not contain any apk files, or
- * multiple apk files without base.apk, then an IOException is thrown.
- *
- * @return A list of APK paths.
- * @throws CrawlerException If failed to read the apk path or unexpected number of apk files are
- * found under the path.
- */
- private static List<Path> getApks(Path root) throws CrawlerException {
- // The apk path points to a non-split apk file.
- if (Files.isRegularFile(root)) {
- if (!root.toString().endsWith(".apk")) {
- throw new CrawlerException(
- "The file on the given apk path is not an apk file: " + root);
- }
- return List.of(root);
- }
-
- List<Path> apks;
- CLog.d("APK path = " + root);
- try (Stream<Path> fileTree = Files.walk(root)) {
- apks =
- fileTree.filter(Files::isRegularFile)
- .filter(path -> path.getFileName().toString().endsWith(".apk"))
- .collect(Collectors.toList());
- } catch (IOException e) {
- throw new CrawlerException("Failed to list apk files.", e);
- }
-
- if (apks.isEmpty()) {
- throw new CrawlerException("The apk directory does not contain any apk files");
- }
-
- // The apk path contains a single non-split apk or the base.apk of a split-apk.
- if (apks.size() == 1) {
- return apks;
- }
-
- if (apks.stream().map(path -> path.getParent().toString()).distinct().count() != 1) {
- throw new CrawlerException(
- "Apk files are not all in the same folder: "
- + Arrays.deepToString(apks.toArray(new Path[apks.size()])));
- }
-
- if (apks.stream().filter(path -> path.getFileName().toString().equals("base.apk")).count()
- == 0) {
- throw new CrawlerException(
- "Multiple non-split apk files detected: "
- + Arrays.deepToString(apks.toArray(new Path[apks.size()])));
- }
-
- Collections.sort(
- apks,
- (first, second) -> first.getFileName().toString().equals("base.apk") ? -1 : 0);
-
- return apks;
- }
-
@VisibleForTesting
- String[] createCrawlerRunCommand(TestInformation testInfo) throws CrawlerException {
+ String[] createUtpCrawlerRunCommand(TestInformation testInfo) throws CrawlerException {
+ Path bin =
+ mFileSystem.getPath(
+ AppCrawlTesterHostPreparer.getCrawlerBinPath(
+ mTestUtils.getTestInformation()));
ArrayList<String> cmd = new ArrayList<>();
cmd.addAll(
Arrays.asList(
"java",
"-jar",
- AppCrawlTesterHostPreparer.getCrawlerBinPath(testInfo)
- .resolve("crawl_launcher_deploy.jar")
+ bin.resolve("utp-cli-android_deploy.jar").toString(),
+ "android",
+ "robo",
+ "--device-id",
+ testInfo.getDevice().getSerialNumber(),
+ "--app-id",
+ mPackageName,
+ "--controller-endpoint",
+ "PROD",
+ "--utp-binaries-dir",
+ bin.toString(),
+ "--key-file",
+ AppCrawlTesterHostPreparer.getCredentialPath(
+ mTestUtils.getTestInformation())
.toString(),
+ "--base-crawler-apk",
+ bin.resolve("crawler_app.apk").toString(),
+ "--stub-crawler-apk",
+ bin.resolve("crawler_stubapp_androidx.apk").toString(),
+ "--tmp-dir",
+ mOutput.toString()));
+
+ if (mTimeoutSec > 0) {
+ cmd.add("--crawler-flag");
+ cmd.add("crawlDurationSec=" + Integer.toString(mTimeoutSec));
+ }
+
+ if (mUiAutomatorMode) {
+ cmd.addAll(Arrays.asList("--ui-automator-mode", "--app-installed-on-device"));
+ } else {
+ Preconditions.checkNotNull(
+ mApkRoot, "Apk file path is required when not running in UIAutomator mode");
+
+ List<Path> apks;
+ try {
+ apks =
+ TestUtils.listApks(mApkRoot).stream()
+ .filter(
+ path ->
+ path.getFileName()
+ .toString()
+ .toLowerCase()
+ .endsWith(".apk"))
+ .collect(Collectors.toList());
+ } catch (TestUtilsException e) {
+ throw new CrawlerException(e);
+ }
+
+ cmd.add("--apks-to-crawl");
+ cmd.add(apks.stream().map(Path::toString).collect(Collectors.joining(",")));
+ }
+
+ if (mRoboscriptFile != null) {
+ Assert.assertTrue(
+ "Please provide a valid roboscript file.",
+ Files.isRegularFile(mRoboscriptFile));
+ cmd.add("--crawler-asset");
+ cmd.add("robo.script=" + mRoboscriptFile.toString());
+ }
+
+ if (mCrawlGuidanceProtoFile != null) {
+ Assert.assertTrue(
+ "Please provide a valid CrawlGuidance file.",
+ Files.isRegularFile(mCrawlGuidanceProtoFile));
+ cmd.add("--crawl-guidance-proto-path");
+ cmd.add(mCrawlGuidanceProtoFile.toString());
+ }
+
+ if (mLoginConfigDir != null) {
+ RoboLoginConfigProvider configProvider = new RoboLoginConfigProvider(mLoginConfigDir);
+ cmd.addAll(configProvider.findConfigFor(mPackageName, true).getLoginArgs());
+ }
+
+ return cmd.toArray(new String[cmd.size()]);
+ }
+
+ @VisibleForTesting
+ String[] createCrawlerRunCommand(TestInformation testInfo) throws CrawlerException {
+
+ Path bin =
+ mFileSystem.getPath(
+ AppCrawlTesterHostPreparer.getCrawlerBinPath(
+ mTestUtils.getTestInformation()));
+ ArrayList<String> cmd = new ArrayList<>();
+ cmd.addAll(
+ Arrays.asList(
+ "java",
+ "-jar",
+ bin.resolve("crawl_launcher_deploy.jar").toString(),
"--android-sdk-path",
AppCrawlTesterHostPreparer.getSdkPath(testInfo).toString(),
"--device-serial-code",
@@ -368,9 +424,7 @@
mOutput.toString(),
"--key-store-file",
// Using the publicly known default file name of the debug keystore.
- AppCrawlTesterHostPreparer.getCrawlerBinPath(testInfo)
- .resolve("debug.keystore")
- .toString(),
+ bin.resolve("debug.keystore").toString(),
"--key-store-password",
// Using the publicly known default password of the debug keystore.
"android"));
@@ -385,7 +439,20 @@
Preconditions.checkNotNull(
mApkRoot, "Apk file path is required when not running in UIAutomator mode");
- List<Path> apks = getApks(mApkRoot);
+ List<Path> apks;
+ try {
+ apks =
+ TestUtils.listApks(mApkRoot).stream()
+ .filter(
+ path ->
+ path.getFileName()
+ .toString()
+ .toLowerCase()
+ .endsWith(".apk"))
+ .collect(Collectors.toList());
+ } catch (TestUtilsException e) {
+ throw new CrawlerException(e);
+ }
cmd.add("--apk-file");
cmd.add(apks.get(0).toString());
@@ -417,8 +484,7 @@
if (mLoginConfigDir != null) {
RoboLoginConfigProvider configProvider = new RoboLoginConfigProvider(mLoginConfigDir);
- RoboLoginConfig loginConfig = configProvider.findConfigFor(mPackageName);
- cmd.addAll(loginConfig.getLoginArgs());
+ cmd.addAll(configProvider.findConfigFor(mPackageName, false).getLoginArgs());
}
return cmd.toArray(new String[cmd.size()]);
diff --git a/harness/src/main/java/com/android/csuite/core/AppCrawlTesterHostPreparer.java b/harness/src/main/java/com/android/csuite/core/AppCrawlTesterHostPreparer.java
index 4be78f7..abb3de3 100644
--- a/harness/src/main/java/com/android/csuite/core/AppCrawlTesterHostPreparer.java
+++ b/harness/src/main/java/com/android/csuite/core/AppCrawlTesterHostPreparer.java
@@ -31,6 +31,8 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -44,6 +46,7 @@
@VisibleForTesting static final String SDK_TAR_OPTION = "sdk-tar";
@VisibleForTesting static final String CRAWLER_BIN_OPTION = "crawler-bin";
@VisibleForTesting static final String CREDENTIAL_JSON_OPTION = "credential-json";
+ private final FileSystem mFileSystem;
@Option(
name = SDK_TAR_OPTION,
@@ -66,12 +69,13 @@
private RunUtilProvider mRunUtilProvider;
public AppCrawlTesterHostPreparer() {
- this(() -> new RunUtil());
+ this(() -> new RunUtil(), FileSystems.getDefault());
}
@VisibleForTesting
- AppCrawlTesterHostPreparer(RunUtilProvider runUtilProvider) {
+ AppCrawlTesterHostPreparer(RunUtilProvider runUtilProvider, FileSystem fileSystem) {
mRunUtilProvider = runUtilProvider;
+ mFileSystem = fileSystem;
}
/**
@@ -80,7 +84,7 @@
* @param testInfo The test info where the path is stored in.
* @return The path to Android SDK; Null if not set.
*/
- public static Path getSdkPath(TestInformation testInfo) {
+ public static String getSdkPath(TestInformation testInfo) {
return getPathFromBuildInfo(testInfo, SDK_PATH_KEY);
}
@@ -90,7 +94,7 @@
* @param testInfo The test info where the path is stored in.
* @return The path to the crawler binaries folder; Null if not set.
*/
- public static Path getCrawlerBinPath(TestInformation testInfo) {
+ public static String getCrawlerBinPath(TestInformation testInfo) {
return getPathFromBuildInfo(testInfo, CRAWLER_BIN_PATH_KEY);
}
@@ -100,7 +104,7 @@
* @param testInfo The test info where the path is stored in.
* @return The path to the crawler credential json file.
*/
- public static Path getCredentialPath(TestInformation testInfo) {
+ public static String getCredentialPath(TestInformation testInfo) {
return getPathFromBuildInfo(testInfo, CREDENTIAL_PATH_KEY);
}
@@ -114,9 +118,8 @@
return testInfo.getBuildInfo().getBuildAttributes().get(IS_READY_KEY) != null;
}
- private static Path getPathFromBuildInfo(TestInformation testInfo, String key) {
- String path = testInfo.getBuildInfo().getBuildAttributes().get(key);
- return path == null ? null : Path.of(path);
+ private static String getPathFromBuildInfo(TestInformation testInfo, String key) {
+ return testInfo.getBuildInfo().getBuildAttributes().get(key);
}
@VisibleForTesting
@@ -154,9 +157,13 @@
setSdkPath(testInfo, sdkPath);
+ Path jar = mCrawlerBin.toPath().resolve("crawl_launcher_deploy.jar");
+ if (!Files.exists(jar)) {
+ jar = mCrawlerBin.toPath().resolve("utp-cli-android_deploy.jar");
+ }
+
// Make the crawler binary executable.
- String chmodCmd =
- "chmod 555 " + mCrawlerBin.toPath().resolve("crawl_launcher_deploy.jar").toString();
+ String chmodCmd = "chmod 555 " + jar.toString();
CommandResult chmodRes = runUtil.runTimedCmd(COMMAND_TIMEOUT_MILLIS, chmodCmd.split(" "));
if (!chmodRes.getStatus().equals(CommandStatus.SUCCESS)) {
throw new TargetSetupError(
@@ -173,7 +180,7 @@
@Override
public void tearDown(TestInformation testInfo, Throwable e) {
try {
- cleanUp(getSdkPath(testInfo));
+ cleanUp(mFileSystem.getPath(getSdkPath(testInfo)));
} catch (IOException ioException) {
CLog.e(ioException);
}
diff --git a/harness/src/main/java/com/android/csuite/core/DeviceUtils.java b/harness/src/main/java/com/android/csuite/core/DeviceUtils.java
index c075408..3528fe8 100644
--- a/harness/src/main/java/com/android/csuite/core/DeviceUtils.java
+++ b/harness/src/main/java/com/android/csuite/core/DeviceUtils.java
@@ -219,6 +219,11 @@
recordingProcess.destroyForcibly();
}
}
+
+ CommandResult result = mDevice.executeShellV2Command("ls -sh " + videoPath);
+ if (result != null && result.getStatus() == CommandStatus.SUCCESS) {
+ CLog.d("Completed screenrecord %s, video size: %s", videoPath, result.getStdout());
+ }
// Try to pull, handle, and delete the video file from the device anyway.
handler.handleScreenRecordFile(mDevice.pullFile(videoPath));
mDevice.deleteFile(videoPath);
diff --git a/harness/src/main/java/com/android/csuite/core/RoboLoginConfig.java b/harness/src/main/java/com/android/csuite/core/RoboLoginConfig.java
deleted file mode 100644
index 0a37b3a..0000000
--- a/harness/src/main/java/com/android/csuite/core/RoboLoginConfig.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.csuite.core;
-
-import com.google.common.collect.ImmutableList;
-
-/*
- * A class returned by RoboLoginConfigProvider that contains the login arguments
- * to be passed to the crawler.
- */
-public final class RoboLoginConfig {
- private final ImmutableList<String> mLoginArgs;
-
- public RoboLoginConfig(ImmutableList<String> loginArgs) {
- this.mLoginArgs = loginArgs;
- }
-
- /* Returns the login arguments for this config which can be passed to the crawler. */
- public ImmutableList<String> getLoginArgs() {
- return mLoginArgs;
- }
-}
diff --git a/harness/src/main/java/com/android/csuite/core/RoboLoginConfigProvider.java b/harness/src/main/java/com/android/csuite/core/RoboLoginConfigProvider.java
index 944e50f..2cfb4d0 100644
--- a/harness/src/main/java/com/android/csuite/core/RoboLoginConfigProvider.java
+++ b/harness/src/main/java/com/android/csuite/core/RoboLoginConfigProvider.java
@@ -45,20 +45,48 @@
* directory should contain only one config file per package name. If both Roboscript and
* CrawlGuidance files are present, only the Roboscript file will be used."
*/
- public RoboLoginConfig findConfigFor(String packageName) {
+ public RoboLoginConfig findConfigFor(String packageName, boolean isUtpClient) {
Path crawlGuidanceFile = mLoginFilesDir.resolve(packageName + CRAWL_GUIDANCE_FILE_SUFFIX);
Path roboScriptFile = mLoginFilesDir.resolve(packageName + ROBOSCRIPT_FILE_SUFFIX);
- if (Files.exists(roboScriptFile)) {
+ if (Files.exists(roboScriptFile) && !isUtpClient) {
return new RoboLoginConfig(
ImmutableList.of(ROBOSCRIPT_CMD_FLAG, roboScriptFile.toString()));
}
- if (Files.exists(crawlGuidanceFile)) {
+ if (Files.exists(crawlGuidanceFile) && !isUtpClient) {
return new RoboLoginConfig(
ImmutableList.of(CRAWL_GUIDANCE_CMD_FLAG, crawlGuidanceFile.toString()));
}
+ if (Files.exists(roboScriptFile) && isUtpClient) {
+ return new RoboLoginConfig(
+ ImmutableList.of(
+ "--crawler-asset", "robo.script=" + roboScriptFile.toString()));
+ }
+
+ if (Files.exists(crawlGuidanceFile) && isUtpClient) {
+ return new RoboLoginConfig(
+ ImmutableList.of("--crawl-guidance-proto-path", crawlGuidanceFile.toString()));
+ }
+
return new RoboLoginConfig(ImmutableList.of());
}
+
+ /*
+ * A class returned by RoboLoginConfigProvider that contains the login arguments
+ * to be passed to the crawler.
+ */
+ public static final class RoboLoginConfig {
+ private final ImmutableList<String> mLoginArgs;
+
+ public RoboLoginConfig(ImmutableList<String> loginArgs) {
+ this.mLoginArgs = loginArgs;
+ }
+
+ /* Returns the login arguments for this config which can be passed to the crawler. */
+ public ImmutableList<String> getLoginArgs() {
+ return mLoginArgs;
+ }
+ }
}
diff --git a/harness/src/test/java/com/android/csuite/core/ApkInstallerTest.java b/harness/src/test/java/com/android/csuite/core/ApkInstallerTest.java
index 7f99e36..c26b9d7 100644
--- a/harness/src/test/java/com/android/csuite/core/ApkInstallerTest.java
+++ b/harness/src/test/java/com/android/csuite/core/ApkInstallerTest.java
@@ -16,6 +16,8 @@
package com.android.csuite.core;
import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyLong;
import com.android.csuite.core.ApkInstaller.ApkInstallerException;
import com.android.tradefed.util.CommandResult;
@@ -27,6 +29,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
@@ -34,6 +37,7 @@
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.List;
@RunWith(JUnit4.class)
public final class ApkInstallerTest {
@@ -96,6 +100,29 @@
assertThrows(ApkInstallerException.class, () -> sut.install(root));
}
+ @Test
+ public void install_obbExists_installObb() throws Exception {
+ Path root = mFileSystem.getPath("apk");
+ Files.createDirectories(root);
+ Path apkPath = root.resolve("base.apk");
+ Files.createFile(apkPath);
+ Path obbPath = root.resolve("main.obb");
+ Files.createFile(obbPath);
+ IRunUtil runUtil = Mockito.mock(IRunUtil.class);
+ Mockito.when(runUtil.runTimedCmd(Mockito.anyLong(), ArgumentMatchers.<String>any()))
+ .thenReturn(createSuccessfulCommandResultWithStdout(""));
+ ApkInstaller sut = new ApkInstaller("serial", runUtil, apk -> "package.name");
+
+ sut.install(root);
+
+ ArgumentCaptor<String> cmdCaptor = ArgumentCaptor.forClass(String.class);
+ Mockito.verify(runUtil, Mockito.atLeastOnce()).runTimedCmd(anyLong(), cmdCaptor.capture());
+ List<String> capturedArgs = cmdCaptor.getAllValues();
+ assertTrue(capturedArgs.stream().anyMatch(arg -> arg.contains("push")));
+ assertTrue(capturedArgs.stream().anyMatch(arg -> arg.contains("rm")));
+ assertTrue(capturedArgs.stream().anyMatch(arg -> arg.contains("mkdir")));
+ }
+
private static CommandResult createSuccessfulCommandResultWithStdout(String stdout) {
CommandResult commandResult = new CommandResult(CommandStatus.SUCCESS);
commandResult.setExitCode(0);
diff --git a/harness/src/test/java/com/android/csuite/core/AppCrawlTesterHostPreparerTest.java b/harness/src/test/java/com/android/csuite/core/AppCrawlTesterHostPreparerTest.java
index 87762ea..7a060ea 100644
--- a/harness/src/test/java/com/android/csuite/core/AppCrawlTesterHostPreparerTest.java
+++ b/harness/src/test/java/com/android/csuite/core/AppCrawlTesterHostPreparerTest.java
@@ -56,14 +56,14 @@
Path path = Path.of("some");
AppCrawlTesterHostPreparer.setSdkPath(mTestInfo, path);
- Path result = AppCrawlTesterHostPreparer.getSdkPath(mTestInfo);
+ String result = AppCrawlTesterHostPreparer.getSdkPath(mTestInfo);
- assertThat(result.toString()).isEqualTo(path.toString());
+ assertThat(result).isEqualTo(path.toString());
}
@Test
public void getSdkPath_wasNotSet_returnsNull() {
- Path result = AppCrawlTesterHostPreparer.getSdkPath(mTestInfo);
+ String result = AppCrawlTesterHostPreparer.getSdkPath(mTestInfo);
assertNull(result);
}
@@ -73,14 +73,14 @@
Path path = Path.of("some");
AppCrawlTesterHostPreparer.setCrawlerBinPath(mTestInfo, path);
- Path result = AppCrawlTesterHostPreparer.getCrawlerBinPath(mTestInfo);
+ String result = AppCrawlTesterHostPreparer.getCrawlerBinPath(mTestInfo);
- assertThat(result.toString()).isEqualTo(path.toString());
+ assertThat(result).isEqualTo(path.toString());
}
@Test
public void getCrawlerBinPath_wasNotSet_returnsNull() {
- Path result = AppCrawlTesterHostPreparer.getCrawlerBinPath(mTestInfo);
+ String result = AppCrawlTesterHostPreparer.getCrawlerBinPath(mTestInfo);
assertNull(result);
}
@@ -90,14 +90,14 @@
Path path = Path.of("some");
AppCrawlTesterHostPreparer.setCredentialPath(mTestInfo, path);
- Path result = AppCrawlTesterHostPreparer.getCredentialPath(mTestInfo);
+ String result = AppCrawlTesterHostPreparer.getCredentialPath(mTestInfo);
- assertThat(result.toString()).isEqualTo(path.toString());
+ assertThat(result).isEqualTo(path.toString());
}
@Test
public void getCredentialPath_wasNotSet_returnsNull() {
- Path result = AppCrawlTesterHostPreparer.getCredentialPath(mTestInfo);
+ String result = AppCrawlTesterHostPreparer.getCredentialPath(mTestInfo);
assertNull(result);
}
@@ -143,7 +143,8 @@
}
private AppCrawlTesterHostPreparer createTestSubject() throws Exception {
- AppCrawlTesterHostPreparer suj = new AppCrawlTesterHostPreparer(() -> mRunUtil);
+ AppCrawlTesterHostPreparer suj =
+ new AppCrawlTesterHostPreparer(() -> mRunUtil, mFileSystem);
OptionSetter optionSetter = new OptionSetter(suj);
optionSetter.setOptionValue(
AppCrawlTesterHostPreparer.SDK_TAR_OPTION,
diff --git a/harness/src/test/java/com/android/csuite/core/AppCrawlTesterTest.java b/harness/src/test/java/com/android/csuite/core/AppCrawlTesterTest.java
index 6907307..67ff1cf 100644
--- a/harness/src/test/java/com/android/csuite/core/AppCrawlTesterTest.java
+++ b/harness/src/test/java/com/android/csuite/core/AppCrawlTesterTest.java
@@ -55,6 +55,7 @@
@RunWith(JUnit4.class)
public final class AppCrawlTesterTest {
+ private static final String PACKAGE_NAME = "package.name";
private final TestArtifactReceiver mTestArtifactReceiver =
Mockito.mock(TestArtifactReceiver.class);
private final FileSystem mFileSystem =
@@ -228,14 +229,13 @@
}
@Test
- public void start_credentialIsProvidedToCrawler() throws Exception {
+ public void start_sdkPathIsProvidedToCrawler() throws Exception {
AppCrawlTester suj = createPreparedTestSubject();
suj.setApkPath(createApkPathWithSplitApks());
suj.start();
- Mockito.verify(mRunUtil)
- .setEnvVariable(Mockito.eq("GOOGLE_APPLICATION_CREDENTIALS"), Mockito.anyString());
+ Mockito.verify(mRunUtil).setEnvVariable(Mockito.eq("ANDROID_SDK"), Mockito.anyString());
}
@Test
@@ -361,7 +361,7 @@
}
@Test
- public void createCrawlerRunCommand_containsRequiredCrawlerParams() throws Exception {
+ public void createUtpCrawlerRunCommand_containsRequiredCrawlerParams() throws Exception {
Path apkRoot = mFileSystem.getPath("apk");
Files.createDirectories(apkRoot);
Files.createFile(apkRoot.resolve("some.apk"));
@@ -369,16 +369,20 @@
suj.setApkPath(apkRoot);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().contains("--key-store-file");
- assertThat(result).asList().contains("--key-store-password");
- assertThat(result).asList().contains("--device-serial-code");
- assertThat(result).asList().contains("--apk-file");
+ assertThat(result).asList().contains("android");
+ assertThat(result).asList().contains("robo");
+ assertThat(result).asList().contains("--device-id");
+ assertThat(result).asList().contains("--app-id");
+ assertThat(result).asList().contains("--utp-binaries-dir");
+ assertThat(result).asList().contains("--key-file");
+ assertThat(result).asList().contains("--base-crawler-apk");
+ assertThat(result).asList().contains("--stub-crawler-apk");
}
@Test
- public void createCrawlerRunCommand_containsRoboscriptFileWhenProvided() throws Exception {
+ public void createUtpCrawlerRunCommand_containsRoboscriptFileWhenProvided() throws Exception {
AppCrawlTester suj = createPreparedTestSubject();
Path roboDir = mFileSystem.getPath("/robo");
Files.createDirectory(roboDir);
@@ -387,27 +391,15 @@
suj.setRoboscriptFile(roboFile);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().contains("--robo-script-file");
+ assertThat(result).asList().contains("--crawler-asset");
+ assertThat(result).asList().contains("robo.script=" + roboFile.toString());
}
@Test
- public void createCrawlerRunCommand_containsEndpointWhenProvided() throws Exception {
- AppCrawlTester suj = createPreparedTestSubject();
- suj.setUiAutomatorMode(true);
- String endpoint = "abc@efg";
- suj.setCrawlControllerEndpoint(endpoint);
- suj.start();
-
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
-
- assertThat(result).asList().contains("--endpoint");
- assertThat(result).asList().contains(endpoint);
- }
-
- @Test
- public void createCrawlerRunCommand_containsCrawlGuidanceFileWhenProvided() throws Exception {
+ public void createUtpCrawlerRunCommand_containsCrawlGuidanceFileWhenProvided()
+ throws Exception {
AppCrawlTester suj = createPreparedTestSubject();
Path crawlGuideDir = mFileSystem.getPath("/cg");
Files.createDirectory(crawlGuideDir);
@@ -416,73 +408,71 @@
suj.setUiAutomatorMode(true);
suj.setCrawlGuidanceProtoFile(crawlGuideFile);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().contains("--text-guide-file");
+ assertThat(result).asList().contains("--crawl-guidance-proto-path");
}
@Test
- public void createCrawlerRunCommand_loginDirContainsOnlyCrawlGuidanceFile_addsFilePath()
+ public void createUtpCrawlerRunCommand_loginDirContainsOnlyCrawlGuidanceFile_addsFilePath()
throws Exception {
- String packageName = "app.package";
- AppCrawlTester suj = createPreparedTestSubject(packageName);
+ AppCrawlTester suj = createPreparedTestSubject();
Path loginFilesDir = mFileSystem.getPath("/login");
Files.createDirectory(loginFilesDir);
Path crawlGuideFile =
- Files.createFile(loginFilesDir.resolve(packageName + CRAWL_GUIDANCE_FILE_SUFFIX));
+ Files.createFile(loginFilesDir.resolve(PACKAGE_NAME + CRAWL_GUIDANCE_FILE_SUFFIX));
suj.setUiAutomatorMode(true);
suj.setLoginConfigDir(loginFilesDir);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().contains("--text-guide-file");
+ assertThat(result).asList().contains("--crawl-guidance-proto-path");
assertThat(result).asList().contains(crawlGuideFile.toString());
}
@Test
- public void createCrawlerRunCommand_loginDirContainsOnlyRoboscriptFile_addsFilePath()
+ public void createUtpCrawlerRunCommand_loginDirContainsOnlyRoboscriptFile_addsFilePath()
throws Exception {
- String packageName = "app.package";
- AppCrawlTester suj = createPreparedTestSubject(packageName);
+ AppCrawlTester suj = createPreparedTestSubject();
Path loginFilesDir = mFileSystem.getPath("/login");
Files.createDirectory(loginFilesDir);
Path roboscriptFile =
- Files.createFile(loginFilesDir.resolve(packageName + ROBOSCRIPT_FILE_SUFFIX));
+ Files.createFile(loginFilesDir.resolve(PACKAGE_NAME + ROBOSCRIPT_FILE_SUFFIX));
suj.setUiAutomatorMode(true);
suj.setLoginConfigDir(loginFilesDir);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().contains("--robo-script-file");
- assertThat(result).asList().contains(roboscriptFile.toString());
+ assertThat(result).asList().contains("--crawler-asset");
+ assertThat(result).asList().contains("robo.script=" + roboscriptFile.toString());
}
@Test
- public void createCrawlerRunCommand_loginDirContainsMultipleLoginFiles_addsRoboscriptFilePath()
- throws Exception {
- String packageName = "app.package";
- AppCrawlTester suj = createPreparedTestSubject(packageName);
+ public void
+ createUtpCrawlerRunCommand_loginDirContainsMultipleLoginFiles_addsRoboscriptFilePath()
+ throws Exception {
+ AppCrawlTester suj = createPreparedTestSubject();
Path loginFilesDir = mFileSystem.getPath("/login");
Files.createDirectory(loginFilesDir);
Path roboscriptFile =
- Files.createFile(loginFilesDir.resolve(packageName + ROBOSCRIPT_FILE_SUFFIX));
+ Files.createFile(loginFilesDir.resolve(PACKAGE_NAME + ROBOSCRIPT_FILE_SUFFIX));
Path crawlGuideFile =
- Files.createFile(loginFilesDir.resolve(packageName + CRAWL_GUIDANCE_FILE_SUFFIX));
+ Files.createFile(loginFilesDir.resolve(PACKAGE_NAME + CRAWL_GUIDANCE_FILE_SUFFIX));
suj.setUiAutomatorMode(true);
suj.setLoginConfigDir(loginFilesDir);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().contains("--robo-script-file");
- assertThat(result).asList().contains(roboscriptFile.toString());
+ assertThat(result).asList().contains("--crawler-asset");
+ assertThat(result).asList().contains("robo.script=" + roboscriptFile.toString());
assertThat(result).asList().doesNotContain(crawlGuideFile.toString());
}
@Test
- public void createCrawlerRunCommand_loginDirEmpty_doesNotAddFlag() throws Exception {
+ public void createUtpCrawlerRunCommand_loginDirEmpty_doesNotAddFlag() throws Exception {
AppCrawlTester suj = createPreparedTestSubject();
Path loginFilesDir = mFileSystem.getPath("/login");
Files.createDirectory(loginFilesDir);
@@ -490,14 +480,14 @@
suj.setUiAutomatorMode(true);
suj.setLoginConfigDir(loginFilesDir);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(result).asList().doesNotContain("--robo-script-file");
- assertThat(result).asList().doesNotContain("--text-guide-file");
+ assertThat(result).asList().doesNotContain("--crawler-asset");
+ assertThat(result).asList().doesNotContain("--crawl-guidance-proto-path");
}
@Test
- public void createCrawlerRunCommand_crawlerIsExecutedThroughJavaJar() throws Exception {
+ public void createUtpCrawlerRunCommand_crawlerIsExecutedThroughJavaJar() throws Exception {
Path apkRoot = mFileSystem.getPath("apk");
Files.createDirectories(apkRoot);
Files.createFile(apkRoot.resolve("some.apk"));
@@ -505,14 +495,14 @@
suj.setApkPath(apkRoot);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
assertThat(result).asList().contains("java");
assertThat(result).asList().contains("-jar");
}
@Test
- public void createCrawlerRunCommand_splitApksProvided_useApkFileAndSplitApkFilesParams()
+ public void createUtpCrawlerRunCommand_splitApksProvided_useApkFileAndSplitApkFilesParams()
throws Exception {
Path apkRoot = mFileSystem.getPath("apk");
Files.createDirectories(apkRoot);
@@ -523,19 +513,16 @@
suj.setApkPath(apkRoot);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(Arrays.asList(result).stream().filter(s -> s.equals("--apk-file")).count())
+ assertThat(Arrays.asList(result).stream().filter(s -> s.equals("--apks-to-crawl")).count())
.isEqualTo(1);
- assertThat(
- Arrays.asList(result).stream()
- .filter(s -> s.equals("--split-apk-files"))
- .count())
- .isEqualTo(2);
+ assertThat(Arrays.asList(result).stream().filter(s -> s.contains("config1.apk")).count())
+ .isEqualTo(1);
}
@Test
- public void createCrawlerRunCommand_uiAutomatorModeEnabled_doesNotContainApks()
+ public void createUtpCrawlerRunCommand_uiAutomatorModeEnabled_doesNotContainApks()
throws Exception {
Path apkRoot = mFileSystem.getPath("apk");
Files.createDirectories(apkRoot);
@@ -547,19 +534,14 @@
suj.setUiAutomatorMode(true);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
- assertThat(Arrays.asList(result).stream().filter(s -> s.equals("--apk-file")).count())
- .isEqualTo(0);
- assertThat(
- Arrays.asList(result).stream()
- .filter(s -> s.equals("--split-apk-files"))
- .count())
+ assertThat(Arrays.asList(result).stream().filter(s -> s.equals("--apks-to-crawl")).count())
.isEqualTo(0);
}
@Test
- public void createCrawlerRunCommand_uiAutomatorModeEnabled_containsUiAutomatorParam()
+ public void createUtpCrawlerRunCommand_uiAutomatorModeEnabled_containsUiAutomatorParam()
throws Exception {
Path apkRoot = mFileSystem.getPath("apk");
Files.createDirectories(apkRoot);
@@ -571,7 +553,7 @@
suj.setUiAutomatorMode(true);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
assertThat(
Arrays.asList(result).stream()
@@ -580,13 +562,13 @@
.isEqualTo(1);
assertThat(
Arrays.asList(result).stream()
- .filter(s -> s.equals("--app-package-name"))
+ .filter(s -> s.equals("--app-installed-on-device"))
.count())
.isEqualTo(1);
}
@Test
- public void createCrawlerRunCommand_doesNotContainNullOrEmptyStrings() throws Exception {
+ public void createUtpCrawlerRunCommand_doesNotContainNullOrEmptyStrings() throws Exception {
Path apkRoot = mFileSystem.getPath("apk");
Files.createDirectories(apkRoot);
Files.createFile(apkRoot.resolve("base.apk"));
@@ -596,10 +578,9 @@
suj.setApkPath(apkRoot);
suj.start();
- String[] result = suj.createCrawlerRunCommand(mTestInfo);
+ String[] result = suj.createUtpCrawlerRunCommand(mTestInfo);
assertThat(Arrays.asList(result).stream().filter(s -> s == null).count()).isEqualTo(0);
-
assertThat(Arrays.asList(result).stream().map(String::trim).filter(String::isEmpty).count())
.isEqualTo(0);
}
@@ -609,17 +590,20 @@
IRunUtil runUtil = Mockito.mock(IRunUtil.class);
Mockito.when(runUtil.runTimedCmd(Mockito.anyLong(), ArgumentMatchers.<String>any()))
.thenReturn(createSuccessfulCommandResult());
- AppCrawlTesterHostPreparer preparer = new AppCrawlTesterHostPreparer(() -> runUtil);
+ AppCrawlTesterHostPreparer preparer =
+ new AppCrawlTesterHostPreparer(() -> runUtil, mFileSystem);
OptionSetter optionSetter = new OptionSetter(preparer);
+
+ Path bin = Files.createDirectories(mFileSystem.getPath("/bin"));
+ Files.createFile(bin.resolve("utp-cli-android_deploy.jar"));
+
optionSetter.setOptionValue(
AppCrawlTesterHostPreparer.SDK_TAR_OPTION,
- Files.createDirectories(mFileSystem.getPath("sdk")).toString());
- optionSetter.setOptionValue(
- AppCrawlTesterHostPreparer.CRAWLER_BIN_OPTION,
- Files.createDirectories(mFileSystem.getPath("bin")).toString());
+ Files.createDirectories(mFileSystem.getPath("/sdk")).toString());
+ optionSetter.setOptionValue(AppCrawlTesterHostPreparer.CRAWLER_BIN_OPTION, bin.toString());
optionSetter.setOptionValue(
AppCrawlTesterHostPreparer.CREDENTIAL_JSON_OPTION,
- Files.createDirectories(mFileSystem.getPath("cred.json")).toString());
+ Files.createDirectories(mFileSystem.getPath("/cred.json")).toString());
preparer.setUp(mTestInfo);
}
@@ -627,23 +611,14 @@
Mockito.when(mRunUtil.runTimedCmd(Mockito.anyLong(), ArgumentMatchers.<String>any()))
.thenReturn(createSuccessfulCommandResult());
Mockito.when(mDevice.getSerialNumber()).thenReturn("serial");
- return new AppCrawlTester("package.name", mTestUtils, () -> mRunUtil);
+ return new AppCrawlTester(PACKAGE_NAME, mTestUtils, () -> mRunUtil, mFileSystem);
}
-
private AppCrawlTester createPreparedTestSubject()
throws IOException, ConfigurationException, TargetSetupError {
simulatePreparerWasExecutedSuccessfully();
Mockito.when(mRunUtil.runTimedCmd(Mockito.anyLong(), ArgumentMatchers.<String>any()))
.thenReturn(createSuccessfulCommandResult());
- return new AppCrawlTester("package.name", mTestUtils, () -> mRunUtil);
- }
-
- private AppCrawlTester createPreparedTestSubject(String packageName)
- throws IOException, ConfigurationException, TargetSetupError {
- simulatePreparerWasExecutedSuccessfully();
- Mockito.when(mRunUtil.runTimedCmd(Mockito.anyLong(), ArgumentMatchers.<String>any()))
- .thenReturn(createSuccessfulCommandResult());
- return new AppCrawlTester(packageName, mTestUtils, () -> mRunUtil);
+ return new AppCrawlTester(PACKAGE_NAME, mTestUtils, () -> mRunUtil, mFileSystem);
}
private TestUtils createTestUtils() throws DeviceNotAvailableException {
diff --git a/test_scripts/src/main/java/com/android/webview/lib/GcloudCli.java b/test_scripts/src/main/java/com/android/webview/lib/GcloudCli.java
deleted file mode 100644
index 1595339..0000000
--- a/test_scripts/src/main/java/com/android/webview/lib/GcloudCli.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.webview.tests;
-
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.RunUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-/**
- * The WebView installer tool uses gsutil to download WebView apk's from GCS. The GcloudCli class
- * can be used to authenticate the host for using gsutil. This class does this by running 'gcloud
- * init' on the host machine. When the host machine runs the command, gcloud uses the application
- * default credentials to authenticate gsutil.
- */
-public class GcloudCli {
- private static final long COMMAND_TIMEOUT_MILLIS = 5 * 60 * 1000;
- private File mGcloudCliDir;
-
- private RunUtil mRunUtil;
-
- private GcloudCli(File gcloudCliDir, RunUtil runUtil) {
- mRunUtil = runUtil;
- mGcloudCliDir = gcloudCliDir;
- }
-
- public static GcloudCli buildFromZipArchive(File gcloudCliZipArchive) throws IOException {
- Path gcloudCliDir = Files.createTempDirectory(null);
- try {
- CommandResult unzipRes =
- RunUtil.getDefault()
- .runTimedCmd(
- COMMAND_TIMEOUT_MILLIS,
- "unzip",
- gcloudCliZipArchive.getAbsolutePath(),
- "-d",
- gcloudCliDir.toFile().getAbsolutePath());
- Assert.assertEquals(
- "Unable to unzip the gcloud cli zip archive",
- unzipRes.getStatus(),
- CommandStatus.SUCCESS);
- RunUtil runUtil = new RunUtil();
- // The 'gcloud init' command creates configuration files for gsutil and other
- // applications that use the gcloud sdk in the home directory. We can isolate
- // the effects of these configuration files to the processes that run the
- // gcloud and gsutil executables tracked by this class by setting the home
- // directory for processes that run those executables to a temporary directory
- // also tracked by this class.
- runUtil.setEnvVariable("HOME", gcloudCliDir.toFile().getAbsolutePath());
- File gcloudBin =
- gcloudCliDir.resolve(Paths.get("google-cloud-sdk", "bin", "gcloud")).toFile();
- String gcloudInitScript =
- String.format(
- "printf \"1\\n1\" | %s init --console-only",
- gcloudBin.getAbsolutePath());
- CommandResult gcloudInitRes =
- runUtil.runTimedCmd(
- COMMAND_TIMEOUT_MILLIS,
- System.out,
- System.out,
- "sh",
- "-c",
- gcloudInitScript);
- Assert.assertEquals(
- "gcloud cli initialization failed",
- gcloudInitRes.getStatus(),
- CommandStatus.SUCCESS);
- return new GcloudCli(gcloudCliDir.toFile(), runUtil);
- } catch (Exception e) {
- RunUtil.getDefault()
- .runTimedCmd(
- COMMAND_TIMEOUT_MILLIS,
- "rm",
- "-rf",
- gcloudCliDir.toFile().getAbsolutePath());
- throw e;
- }
- }
-
- public File getGsutilExecutable() {
- return mGcloudCliDir
- .toPath()
- .resolve(Paths.get("google-cloud-sdk", "bin", "gsutil"))
- .toFile();
- }
-
- public RunUtil getRunUtil() {
- return mRunUtil;
- }
-
- public void tearDown() {
- RunUtil.getDefault()
- .runTimedCmd(COMMAND_TIMEOUT_MILLIS, "rm", "-rf", mGcloudCliDir.getAbsolutePath());
- }
-}
diff --git a/test_scripts/src/main/java/com/android/webview/lib/WebviewInstallerToolPreparer.java b/test_scripts/src/main/java/com/android/webview/lib/WebviewInstallerToolPreparer.java
new file mode 100644
index 0000000..52e5c94
--- /dev/null
+++ b/test_scripts/src/main/java/com/android/webview/lib/WebviewInstallerToolPreparer.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.webview.tests;
+
+import com.android.tradefed.config.Option;
+import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.RunUtil;
+
+import org.junit.Assert;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+public class WebviewInstallerToolPreparer implements ITargetPreparer {
+ private static final long COMMAND_TIMEOUT_MILLIS = 5 * 60 * 1000;
+ private static final String WEBVIEW_INSTALLER_TOOL_PATH = "WEBVIEW_INSTALLER_TOOL_PATH";
+ private static final String GCLOUD_CLI_PATH = "GCLOUD_CLI_PATH";
+
+ private File mGcloudCliDir;
+ private RunUtilProvider mRunUtilProvider;
+
+ @Option(
+ name = "gcloud-cli-zip-archive",
+ description = "Path to the google cli zip archive.",
+ importance = Importance.ALWAYS)
+ private File mGcloudCliZipArchive;
+
+ @Option(
+ name = "webview-installer-tool",
+ description = "Path to the webview installer executable.",
+ importance = Importance.ALWAYS)
+ private File mWebviewInstallerTool;
+
+ public WebviewInstallerToolPreparer(RunUtilProvider runUtilProvider) {
+ mRunUtilProvider = runUtilProvider;
+ }
+
+ public WebviewInstallerToolPreparer() {
+ this(() -> new RunUtil());
+ }
+
+ public static CommandResult runWebviewInstallerToolCommand(
+ TestInformation testInformation,
+ @Nullable String webviewVersion,
+ @Nullable String releaseChannel,
+ List<String> extraArgs) {
+ RunUtil runUtil = new RunUtil();
+ runUtil.setEnvVariable("HOME", getGcloudCliPath(testInformation));
+
+ List<String> commandLineArgs =
+ new ArrayList<>(
+ Arrays.asList(
+ getWebviewInstallerToolPath(testInformation),
+ "--non-next",
+ "--serial",
+ testInformation.getDevice().getSerialNumber(),
+ "-vvv",
+ "--gsutil",
+ Paths.get(
+ getGcloudCliPath(testInformation),
+ "google-cloud-sdk",
+ "bin",
+ "gsutil")
+ .toFile()
+ .getAbsolutePath()));
+ commandLineArgs.addAll(extraArgs);
+
+ if (webviewVersion != null) {
+ commandLineArgs.addAll(Arrays.asList("--chrome-version", webviewVersion));
+ }
+
+ if (releaseChannel != null) {
+ commandLineArgs.addAll(Arrays.asList("--channel", releaseChannel));
+ }
+
+ return runUtil.runTimedCmd(
+ COMMAND_TIMEOUT_MILLIS,
+ System.out,
+ System.out,
+ commandLineArgs.toArray(new String[0]));
+ }
+
+ public static void setGcloudCliPath(TestInformation testInformation, File gcloudCliDir) {
+ testInformation
+ .getBuildInfo()
+ .addBuildAttribute(GCLOUD_CLI_PATH, gcloudCliDir.getAbsolutePath());
+ }
+
+ public static void setWebviewInstallerToolPath(
+ TestInformation testInformation, File webviewInstallerTool) {
+ testInformation
+ .getBuildInfo()
+ .addBuildAttribute(
+ WEBVIEW_INSTALLER_TOOL_PATH, webviewInstallerTool.getAbsolutePath());
+ }
+
+ public static String getWebviewInstallerToolPath(TestInformation testInformation) {
+ return testInformation.getBuildInfo().getBuildAttributes().get(WEBVIEW_INSTALLER_TOOL_PATH);
+ }
+
+ public static String getGcloudCliPath(TestInformation testInformation) {
+ return testInformation.getBuildInfo().getBuildAttributes().get(GCLOUD_CLI_PATH);
+ }
+
+ @Override
+ public void setUp(TestInformation testInfo) throws TargetSetupError {
+ Assert.assertNotEquals(
+ "Argument --webview-installer-tool must be used.", mWebviewInstallerTool, null);
+ Assert.assertNotEquals(
+ "Argument --gcloud-cli-zip must be used.", mGcloudCliZipArchive, null);
+ try {
+ RunUtil runUtil = mRunUtilProvider.get();
+ mGcloudCliDir = Files.createTempDirectory(null).toFile();
+ CommandResult unzipRes =
+ runUtil.runTimedCmd(
+ COMMAND_TIMEOUT_MILLIS,
+ "unzip",
+ mGcloudCliZipArchive.getAbsolutePath(),
+ "-d",
+ mGcloudCliDir.getAbsolutePath());
+
+ Assert.assertEquals(
+ "Unable to unzip the gcloud cli zip archive",
+ unzipRes.getStatus(),
+ CommandStatus.SUCCESS);
+
+ // The 'gcloud init' command creates configuration files for gsutil and other
+ // applications that use the gcloud sdk in the home directory. We can isolate
+ // the effects of these configuration files to the processes that run the
+ // gcloud and gsutil executables tracked by this class by setting the home
+ // directory for processes that run those executables to a temporary directory
+ // also tracked by this class.
+ runUtil.setEnvVariable("HOME", mGcloudCliDir.getAbsolutePath());
+ File gcloudBin =
+ mGcloudCliDir
+ .toPath()
+ .resolve(Paths.get("google-cloud-sdk", "bin", "gcloud"))
+ .toFile();
+ String gcloudInitScript =
+ String.format(
+ "printf \"1\\n1\" | %s init --console-only",
+ gcloudBin.getAbsolutePath());
+ CommandResult gcloudInitRes =
+ runUtil.runTimedCmd(
+ COMMAND_TIMEOUT_MILLIS,
+ System.out,
+ System.out,
+ "sh",
+ "-c",
+ gcloudInitScript);
+ Assert.assertEquals(
+ "gcloud cli initialization failed",
+ gcloudInitRes.getStatus(),
+ CommandStatus.SUCCESS);
+
+ CommandResult chmodRes =
+ runUtil.runTimedCmd(
+ COMMAND_TIMEOUT_MILLIS,
+ System.out,
+ System.out,
+ "chmod",
+ "755",
+ "-v",
+ mWebviewInstallerTool.getAbsolutePath());
+
+ Assert.assertEquals(
+ "The 'chmod 755 -v <WebView installer tool>' command failed",
+ chmodRes.getStatus(),
+ CommandStatus.SUCCESS);
+
+ } catch (Exception ex) {
+ throw new TargetSetupError("Caught an exception during setup:\n" + ex);
+ }
+ setGcloudCliPath(testInfo, mGcloudCliDir);
+ setWebviewInstallerToolPath(testInfo, mWebviewInstallerTool);
+ }
+
+ @Override
+ public void tearDown(TestInformation testInfo, Throwable e) {
+ // Clean up some files.
+ mRunUtilProvider
+ .get()
+ .runTimedCmd(COMMAND_TIMEOUT_MILLIS, "rm", "-rf", mGcloudCliDir.getAbsolutePath());
+ }
+
+ interface RunUtilProvider {
+ RunUtil get();
+ }
+}
diff --git a/test_scripts/src/main/java/com/android/webview/lib/WebviewUtils.java b/test_scripts/src/main/java/com/android/webview/lib/WebviewUtils.java
new file mode 100644
index 0000000..2d47066
--- /dev/null
+++ b/test_scripts/src/main/java/com/android/webview/lib/WebviewUtils.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.webview.tests;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
+
+import org.junit.Assert;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class WebviewUtils {
+ private TestInformation mTestInformation;
+
+ public WebviewUtils(TestInformation testInformation) {
+ mTestInformation = testInformation;
+ }
+
+ public WebviewPackage installWebview(String webviewVersion, String releaseChannel)
+ throws IOException, InterruptedException, DeviceNotAvailableException {
+ List<String> extraArgs = new ArrayList<>();
+ if (webviewVersion == null
+ && Arrays.asList("beta", "stable").contains(releaseChannel.toLowerCase())) {
+ // Get current version of WebView in the stable or beta release channels.
+ CLog.i(
+ "Getting the latest nightly official release version of the %s branch",
+ releaseChannel);
+ String releaseChannelVersion = getNightlyBranchBuildVersion(releaseChannel);
+ Assert.assertNotNull(
+ String.format(
+ "Could not retrieve the latest "
+ + "nightly release version of the %s channel",
+ releaseChannel),
+ releaseChannelVersion);
+ // Install the latest official build compiled for the beta or stable branches.
+ extraArgs.addAll(
+ Arrays.asList("--milestone", releaseChannelVersion.split("\\.", 2)[0]));
+ }
+ CommandResult commandResult =
+ WebviewInstallerToolPreparer.runWebviewInstallerToolCommand(
+ mTestInformation, webviewVersion, releaseChannel, extraArgs);
+
+ Assert.assertEquals(
+ "The WebView installer tool failed to install WebView:\n"
+ + commandResult.toString(),
+ commandResult.getStatus(),
+ CommandStatus.SUCCESS);
+
+ printWebviewVersion();
+ return getCurrentWebviewPackage();
+ }
+
+ private static String getNightlyBranchBuildVersion(String releaseChannel)
+ throws IOException, MalformedURLException {
+ final URL omahaProxyUrl = new URL("https://omahaproxy.appspot.com/all?os=webview");
+ try (BufferedReader bufferedReader =
+ new BufferedReader(
+ new InputStreamReader(omahaProxyUrl.openConnection().getInputStream()))) {
+ String csvLine = null;
+ while ((csvLine = bufferedReader.readLine()) != null) {
+ String[] csvLineValues = csvLine.split(",");
+ if (csvLineValues[1].toLowerCase().equals(releaseChannel.toLowerCase())) {
+ return csvLineValues[2];
+ }
+ }
+ }
+ return null;
+ }
+
+ public void uninstallWebview(
+ WebviewPackage webviewPackage, WebviewPackage preInstalledWebviewPackage)
+ throws DeviceNotAvailableException {
+ Assert.assertNotEquals(
+ "Test is attempting to uninstall the preinstalled WebView provider",
+ webviewPackage,
+ preInstalledWebviewPackage);
+ updateWebviewImplementation(preInstalledWebviewPackage.getPackageName());
+ mTestInformation
+ .getDevice()
+ .executeAdbCommand("uninstall", webviewPackage.getPackageName());
+ printWebviewVersion();
+ }
+
+ private void updateWebviewImplementation(String webviewPackageName)
+ throws DeviceNotAvailableException {
+ CommandResult res =
+ mTestInformation
+ .getDevice()
+ .executeShellV2Command(
+ String.format(
+ "cmd webviewupdate set-webview-implementation %s",
+ webviewPackageName));
+ Assert.assertEquals(
+ "Failed to set webview update: " + res, res.getStatus(), CommandStatus.SUCCESS);
+ }
+
+ public WebviewPackage getCurrentWebviewPackage() throws DeviceNotAvailableException {
+ String dumpsys = mTestInformation.getDevice().executeShellCommand("dumpsys webviewupdate");
+ return WebviewPackage.buildFromDumpsys(dumpsys);
+ }
+
+ public void printWebviewVersion() throws DeviceNotAvailableException {
+ WebviewPackage currentWebview = getCurrentWebviewPackage();
+ printWebviewVersion(currentWebview);
+ }
+
+ public void printWebviewVersion(WebviewPackage currentWebview)
+ throws DeviceNotAvailableException {
+ CLog.i("Current webview implementation: %s", currentWebview.getPackageName());
+ CLog.i("Current webview version: %s", currentWebview.getVersion());
+ }
+}
diff --git a/test_scripts/src/main/java/com/android/webview/tests/WebviewAppLaunchTest.java b/test_scripts/src/main/java/com/android/webview/tests/WebviewAppLaunchTest.java
index aba4a93..a8f72d1 100644
--- a/test_scripts/src/main/java/com/android/webview/tests/WebviewAppLaunchTest.java
+++ b/test_scripts/src/main/java/com/android/webview/tests/WebviewAppLaunchTest.java
@@ -23,14 +23,11 @@
import com.android.csuite.core.DeviceUtils.DeviceUtilsException;
import com.android.csuite.core.TestUtils;
import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestLogData;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.RunUtil;
import org.junit.After;
@@ -40,17 +37,11 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.MalformedURLException;
-import java.net.URL;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
-import javax.annotation.Nullable;
/** A test that verifies that a single app can be successfully launched. */
@RunWith(DeviceJUnit4ClassRunner.class)
@@ -58,21 +49,13 @@
@Rule public TestLogData mLogData = new TestLogData();
private static final long COMMAND_TIMEOUT_MILLIS = 5 * 60 * 1000;
-
- private ApkInstaller mApkInstaller;
- private final List<WebviewPackage> mOrderedWebviews = new ArrayList<>();
+ private WebviewUtils mWebviewUtils;
private WebviewPackage mPreInstalledWebview;
- private WebviewPackage mCurrentWebview;
- private GcloudCli mGcloudCli;
+ private ApkInstaller mApkInstaller;
@Option(name = "record-screen", description = "Whether to record screen during test.")
private boolean mRecordScreen;
- @Option(
- name = "webview-installer-tool",
- description = "Path to the webview installer executable.")
- private File mWebviewInstallerTool;
-
@Option(name = "webview-version-to-test", description = "Version of Webview to test.")
private String mWebviewVersionToTest;
@@ -101,44 +84,17 @@
description = "Time to wait for an app to launch in msecs.")
private int mAppLaunchTimeoutMs = 20000;
- @Option(
- name = "gcloud-cli-zip-archive",
- description = "Path to the google cli zip archive.",
- importance = Importance.ALWAYS)
- private File mGcloudCliZipArchive;
-
@Before
public void setUp() throws DeviceNotAvailableException, ApkInstallerException, IOException {
- mCurrentWebview = mPreInstalledWebview = getCurrentWebviewPackage();
-
Assert.assertNotNull("Package name cannot be null", mPackageName);
Assert.assertTrue(
"Either the --release-channel or --webview-version-to-test arguments "
+ "must be used",
mWebviewVersionToTest != null || mReleaseChannel != null);
- Assert.assertNotEquals(
- "Argument --webview-installer-tool must be used when "
- + "using the --webview-version-to-test argument.",
- mWebviewInstallerTool,
- null);
- Assert.assertNotEquals(
- "Argument --gcloud-cli-zip must be used when "
- + "using the --webview-version-to-test argument.",
- mGcloudCliZipArchive,
- null);
-
- mGcloudCli = GcloudCli.buildFromZipArchive(mGcloudCliZipArchive);
- RunUtil.getDefault()
- .runTimedCmd(
- COMMAND_TIMEOUT_MILLIS,
- System.out,
- System.out,
- "chmod",
- "755",
- "-v",
- mWebviewInstallerTool.getAbsolutePath());
mApkInstaller = ApkInstaller.getInstance(getDevice());
+ mWebviewUtils = new WebviewUtils(getTestInformation());
+ mPreInstalledWebview = mWebviewUtils.getCurrentWebviewPackage();
for (File apkPath : mApkPaths) {
CLog.d("Installing " + apkPath);
@@ -146,8 +102,7 @@
}
DeviceUtils.getInstance(getDevice()).freezeRotation();
-
- printWebviewVersion(mPreInstalledWebview);
+ mWebviewUtils.printWebviewVersion();
}
@Test
@@ -155,19 +110,15 @@
throws DeviceNotAvailableException, InterruptedException, ApkInstallerException,
IOException {
AssertionError lastError = null;
- WebviewPackage lastWebviewInstalled;
- if (mWebviewVersionToTest != null) {
- lastWebviewInstalled = installVersionOfWebview(mWebviewVersionToTest, mReleaseChannel);
- } else {
- lastWebviewInstalled = installReleaseChannelVersionOfWebview(mReleaseChannel);
- }
+ WebviewPackage lastWebviewInstalled =
+ mWebviewUtils.installWebview(mWebviewVersionToTest, mReleaseChannel);
try {
assertAppLaunchNoCrash();
} catch (AssertionError e) {
lastError = e;
} finally {
- uninstallWebview();
+ mWebviewUtils.uninstallWebview(lastWebviewInstalled, mPreInstalledWebview);
}
// If the app doesn't crash, complete the test.
@@ -203,131 +154,7 @@
deviceUtils.unfreezeRotation();
mApkInstaller.uninstallAllInstalledPackages();
- printWebviewVersion();
-
- mGcloudCli.tearDown();
- }
-
- private void printWebviewVersion(WebviewPackage currentWebview)
- throws DeviceNotAvailableException {
- CLog.i("Current webview implementation: %s", currentWebview.getPackageName());
- CLog.i("Current webview version: %s", currentWebview.getVersion());
- }
-
- private void printWebviewVersion() throws DeviceNotAvailableException {
- WebviewPackage currentWebview = getCurrentWebviewPackage();
- printWebviewVersion(currentWebview);
- }
-
- private WebviewPackage installReleaseChannelVersionOfWebview(String releaseChannel)
- throws IOException, InterruptedException, DeviceNotAvailableException {
- List<String> commandLineArgs = new ArrayList<>(Arrays.asList("--channel", releaseChannel));
- if (Arrays.asList("beta", "stable").contains(releaseChannel.toLowerCase())) {
- // Get current version of WebView in the stable or beta release channels.
- CLog.i(
- "Getting the latest nightly official release version of the %s branch",
- releaseChannel);
- String webviewVersion = getNightlyBranchBuildVersion(releaseChannel);
- Assert.assertNotNull(
- String.format(
- "Could not retrieve the latest "
- + "nightly release version of the %s channel",
- releaseChannel),
- webviewVersion);
- // Install the latest official build compiled for the beta or stable branches.
- commandLineArgs.addAll(Arrays.asList("--milestone", webviewVersion.split("\\.", 2)[0]));
- }
- return installWebviewWithInstallerTool(commandLineArgs);
- }
-
- private String getNightlyBranchBuildVersion(String releaseChannel)
- throws IOException, MalformedURLException {
- final URL omahaProxyUrl = new URL("https://omahaproxy.appspot.com/all?os=webview");
- try (BufferedReader bufferedReader =
- new BufferedReader(
- new InputStreamReader(omahaProxyUrl.openConnection().getInputStream()))) {
- String csvLine = null;
- while ((csvLine = bufferedReader.readLine()) != null) {
- String[] csvLineValues = csvLine.split(",");
- if (csvLineValues[1].toLowerCase().equals(releaseChannel.toLowerCase())) {
- return csvLineValues[2];
- }
- }
- }
- return null;
- }
-
- private WebviewPackage installVersionOfWebview(
- String webviewVersion, @Nullable String releaseChannel)
- throws IOException, InterruptedException, DeviceNotAvailableException {
- List<String> commandLineArgs = Arrays.asList("--chrome-version", webviewVersion);
- if (releaseChannel != null) {
- commandLineArgs.addAll(Arrays.asList("--channel", releaseChannel));
- }
- return installWebviewWithInstallerTool(commandLineArgs);
- }
-
- private WebviewPackage installWebviewWithInstallerTool(List<String> extraArgs)
- throws IOException, InterruptedException, DeviceNotAvailableException {
- // TODO(rmhasan): Remove the --non-next command line argument after
- // crbug.com/1002673 is resolved.
- List<String> fullCommandLineArgs =
- new ArrayList<>(
- Arrays.asList(
- mWebviewInstallerTool.getAbsolutePath(),
- "--non-next",
- "--serial",
- getDevice().getSerialNumber(),
- "-vvv",
- "--gsutil",
- mGcloudCli.getGsutilExecutable().getAbsolutePath()));
- fullCommandLineArgs.addAll(extraArgs);
-
- CommandResult installWebViewRes =
- mGcloudCli
- .getRunUtil()
- .runTimedCmd(
- COMMAND_TIMEOUT_MILLIS,
- System.out,
- System.out,
- fullCommandLineArgs.toArray(new String[0]));
- Assert.assertEquals(
- "The WebView installer tool failed to install WebView:\n"
- + installWebViewRes.toString(),
- installWebViewRes.getStatus(),
- CommandStatus.SUCCESS);
-
- mCurrentWebview = getCurrentWebviewPackage();
- printWebviewVersion(mCurrentWebview);
- return mCurrentWebview;
- }
-
- private void uninstallWebview() throws DeviceNotAvailableException {
- Assert.assertNotEquals(
- "Test is attempting to uninstall the preinstalled WebView provider",
- mCurrentWebview,
- mPreInstalledWebview);
- updateWebviewImplementation(mPreInstalledWebview.getPackageName());
- getDevice().executeAdbCommand("uninstall", mCurrentWebview.getPackageName());
- mCurrentWebview = mPreInstalledWebview;
- printWebviewVersion(mCurrentWebview);
- }
-
- private void updateWebviewImplementation(String webviewPackageName)
- throws DeviceNotAvailableException {
- CommandResult res =
- getDevice()
- .executeShellV2Command(
- String.format(
- "cmd webviewupdate set-webview-implementation %s",
- webviewPackageName));
- Assert.assertEquals(
- "Failed to set webview update: " + res, res.getStatus(), CommandStatus.SUCCESS);
- }
-
- private WebviewPackage getCurrentWebviewPackage() throws DeviceNotAvailableException {
- String dumpsys = getDevice().executeShellCommand("dumpsys webviewupdate");
- return WebviewPackage.buildFromDumpsys(dumpsys);
+ mWebviewUtils.printWebviewVersion();
}
private void assertAppLaunchNoCrash() throws DeviceNotAvailableException {
diff --git a/test_targets/pixel-app-launch-lock-recentapp/template.xml b/test_targets/pixel-app-launch-lock-recentapp/template.xml
index 718da9c..6f546a7 100644
--- a/test_targets/pixel-app-launch-lock-recentapp/template.xml
+++ b/test_targets/pixel-app-launch-lock-recentapp/template.xml
@@ -23,7 +23,6 @@
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
<!-- repeatable: The key of the DIRECTORY to pull -->
<option name = "directory-keys" value = "/sdcard/logData" />
- <option name="collect-on-run-ended-only" value="true" />
</metrics_collector>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
diff --git a/test_targets/webview-app-launch/Android.bp b/test_targets/webview-app-launch/Android.bp
index 3658018..8d54421 100644
--- a/test_targets/webview-app-launch/Android.bp
+++ b/test_targets/webview-app-launch/Android.bp
@@ -18,5 +18,6 @@
csuite_test {
name: "webview-app-launch",
+ test_plan_include: "plan.xml",
test_config_template: "default.xml",
}
diff --git a/test_targets/webview-app-launch/plan.xml b/test_targets/webview-app-launch/plan.xml
new file mode 100644
index 0000000..5d3c48f
--- /dev/null
+++ b/test_targets/webview-app-launch/plan.xml
@@ -0,0 +1,3 @@
+<configuration description="WebView C-Suite Crawler Test Plan">
+ <target_preparer class="com.android.webview.tests.WebviewInstallerToolPreparer"/>
+</configuration>