in tools/device_broker/java/com/google/android/apps/common/testing/broker/AdbController.java [1221:1342]
private List<ExecutedTest> runTest(
Instrumentation instrumentation,
String testMethodTarget,
boolean collectCodeCoverage,
@Nullable String coverageDataPath,
boolean enableDebug,
HostTestSize size,
boolean dumpHProfData,
boolean withAnimation,
Map<String, String> extraInstrumentationOptions) {
List<String> adbArgs = Lists.newArrayList();
if (installBasicServices) {
// We exec the instrumentation through a wrapper launcher defined in basic_services.apk to
// allow test code to execute shell commands with root|shell user privileges.
adbArgs.add("CLASSPATH=" + getClassPathForTestServices());
adbArgs.add("SM_EXIT=1");
adbArgs.add("app_process / androidx.test.services.shellexecutor.ShellMain");
}
adbArgs.add("am");
adbArgs.add("instrument");
if (collectCodeCoverage) {
adbArgs.addAll(Lists.newArrayList("-e", "coverage", "true"));
adbArgs.addAll(Lists.newArrayList(
"-e", "coverageDataPath", coverageDataPath));
}
if (enableDebug) {
adbArgs.addAll(Lists.newArrayList("-e", "debug", "true"));
}
if (dumpHProfData) {
adbArgs.addAll(Lists.newArrayList("-e", "hprofDataFile", "hprof.dump"));
}
for (String key : extraInstrumentationOptions.keySet()) {
adbArgs.add("-e");
adbArgs.add(ShellUtils.shellEscape(key));
adbArgs.add(ShellUtils.shellEscape(extraInstrumentationOptions.get(key)));
}
if (!withAnimation) {
if (device.getApiVersion() >= 10) {
adbArgs.add("--no_window_animation");
} // not supported for less then gingerbread.
}
long testTimeout = size.getTestTimeout(TimeUnit.SECONDS);
if (testTimeoutOverride.isPresent()) {
testTimeout = testTimeoutOverride.get();
}
adbArgs.addAll(
Lists.newArrayList(
"-e", "testTimeoutSeconds", String.valueOf(testTimeout)));
boolean runTestsThroughOrchestrator = installBasicServices
&& ORCHESTRATOR_ENABLED_RUNNERS.contains(instrumentation.getInstrumentationClass());
if (runTestsThroughOrchestrator) {
adbArgs.addAll(
Lists.newArrayList(
"-r",
"-w",
"-e",
"class",
ShellUtils.shellEscape(testMethodTarget),
"-e",
"targetInstrumentation",
instrumentation.getFullName(),
ORCHESTRATOR_COMPONENT_NAME));
} else {
adbArgs.addAll(
Lists.newArrayList(
"-r",
"-w",
"-e",
"class",
ShellUtils.shellEscape(testMethodTarget),
instrumentation.getFullName()));
}
if (installBasicServices) {
// adb shell commands _may_ return their exit code from the device - if they are run on the
// right system image and the host machine has the right version of adb installed
// otherwise they wont. SM_EXIT kills itself at the end, so we do not want that
// exit code bubbling up.
adbArgs.add("||");
adbArgs.add("true");
}
InstrumentationTestRunnerProcessor stdoutProcessor =
new InstrumentationTestRunnerProcessor(new EventBus());
SimpleLineListProcessor stderrProcessor = new SimpleLineListProcessor();
SubprocessCommunicator.Builder builder = communicatorBuilderProvider.get();
builder
.withStdoutProcessor(stdoutProcessor)
.withStderrProcessor(stderrProcessor);
String shellArgs = Joiner.on(" ").join(adbArgs);
List<String> partialArgs = Lists.newArrayList("shell", shellArgs);
try {
makeCheckedCall(builder,
prefixArgsWithDeviceSerial(partialArgs.toArray(new String[partialArgs.size()])),
testTimeout);
} catch (IllegalStateException e) {
StringBuilder allLines = new StringBuilder();
for (ExecutedTest executedTest : stdoutProcessor.getResult()) {
allLines.append(executedTest.getAllLines());
}
throw new RuntimeException(String.format(
"Error when executing adb.\n STDOUT: %s\n STDERR: %s",
allLines,
Joiner.on("\n").join(stderrProcessor.getResult())), e);
}
return stdoutProcessor.getResult();
}