in tools/device_broker/java/com/google/android/apps/common/testing/suite/AndroidGoogleTest.java [264:387]
void runGoogleAndroidTestCase() throws Exception {
if (!perTestOutputDir.exists()) {
checkState(
perTestOutputDir.mkdirs(),
"Per test output dir (%s) could not be created.",
perTestOutputDir.getAbsolutePath());
}
if (brokeredDevice.getApiVersion() < 25 && buffers.size() > 1) {
fail(
"Multiple logcat buffers only supported on API 25+ "
+ "(current API level is "
+ brokeredDevice.getApiVersion()
+ ")");
}
AdbController adbController = brokeredDevice.getAdbController();
LogcatStreamer streamer = null;
try {
if (!logdRestarted && CLEAR_LOG_MAY_FAIL.contains(brokeredDevice.getApiVersion())) {
// restart logd on device to kill possible already-running logcat process on device.
// This is a workaround for one bug fixed in M with this CL:
// https://android-review.googlesource.com/#/c/119673/
// Otherwise "logcat -c" could fail if there is another logcat process running.
adbController.restartLogd();
logdRestarted = true;
}
streamer =
adbController.startLogcatStream(getTestLogcatFile(), buffers, outputFormat, testFilters);
List<ExecutedTest> results;
try {
results =
adbController.runTest(
testInstrumentation,
testMethodTarget,
testDebug,
testSize,
false /* no hprof dump */,
false /* no animation */,
Collections.emptyMap());
} catch (RuntimeException rte) {
if (rte.getCause() instanceof TimeoutException) {
throw rte;
} else {
// TestingInfrastructureUtil.reportTestingInfrastructureFailure(
// "AndroidGoogleTest", rte.getMessage());
throw rte;
}
}
if (results.size() != 2) {
throw new RuntimeException(
String.format(
"Something went wrong during test instrumentation execution "
+ "(check \""
+ String.format("logcat-%s.txt", getName())
+ "\" file below to see if your test threw any uncaught exceptions).\n"
+ "Debug Info: Instrumentation results are expected to have only 1 test, "
+ "with two parts: Test started, and Test completed (passed, failed, errored)."
+ "\nTest method: %s\nTest output: [%s]\n",
testMethodTarget,
getAllTestResults(results)));
}
Iterator<ExecutedTest> resultsIterator = results.iterator();
ExecutedTest test = resultsIterator.next();
if (test.getStatus() != ExecutedTest.Status.STARTED) {
throw new RuntimeException("Failed to start test: \n" + getAllTestResults(results));
}
test = resultsIterator.next();
testStatus = test.getStatus();
if (testStatus == ExecutedTest.Status.FAILED) {
// If the stack trace already begins with "junit.framework.AssertionFailedError", take it
// out since "fail" will report it with this prefix. It's unclear if getStackTrace is
// nullable, guarding against that just in case.
String stack = test.getStackTrace();
if (stack != null) {
stack = stack.replaceFirst("junit.framework.AssertionFailedError[:]?", "");
}
fail(stack);
}
if (testStatus == ExecutedTest.Status.ERROR) {
throw new RuntimeException(test.getStackTrace());
}
if (testStatus == ExecutedTest.Status.STARTED) {
throw new RuntimeException(
"Test result is invalid, contains two consecutive test STARTED states:\n"
+ getAllTestResults(results));
}
if (testStatus == ExecutedTest.Status.PASSED
|| testStatus == ExecutedTest.Status.ASSUMPTION_FAILURE) {
logger.info("Instrumentation stream:\n" + getAllTestResults(results));
} else {
throw new RuntimeException(
"Test result status not \"PASSED\", result contents: " + getAllTestResults(results));
}
} finally {
exportedProperties.put(nextTestOutputName(), getTestLogcatFile().getName());
if (gatherOutputs) {
pullExportedProperties(adbController);
pullAndRecordTestOutputs(adbController);
}
exportedProperties.putAll(adbController.getExportedProperties());
if (null != streamer) {
try {
streamer.stopStream();
} catch (RuntimeException rte) {
throw rte;
}
}
}
}