void runGoogleAndroidTestCase()

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;
        }
      }
    }
  }