[automerger skipped] Merge "DO NOT MERGE Remove the placeholder test failure during preparation" into oreo-mr1-cts-dev
am: d634323640  -s ours

Change-Id: I8f900dcb8ae0cfbf1e69691ceab77106606e4d06
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..94d6256
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,56 @@
+// Copyright 2018 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.
+
+// Set of error prone rules to ensure code quality
+// PackageLocation check requires the androidCompatible=false otherwise it does not do anything.
+java_defaults {
+  name: "tradefed_errorprone_defaults",
+  errorprone: {
+    javacflags: [
+      "-XDandroidCompatible=false",
+      "-Xep:ArrayToString:ERROR",
+      "-Xep:BoxedPrimitiveConstructor:ERROR",
+      "-Xep:ConstantField:ERROR",
+      "-Xep:DeadException:ERROR",
+      "-Xep:EqualsIncompatibleType:ERROR",
+      "-Xep:FormatString:ERROR",
+      "-Xep:GetClassOnClass:ERROR",
+      "-Xep:IdentityBinaryExpression:ERROR",
+      "-Xep:JUnit3TestNotRun:ERROR",
+      "-Xep:JUnit4ClassUsedInJUnit3:ERROR",
+      "-Xep:JUnitAmbiguousTestClass:ERROR",
+      "-Xep:MissingFail:ERROR",
+      "-Xep:MissingOverride:ERROR",
+      "-Xep:MustBeClosedChecker:ERROR",
+      "-Xep:Overrides:ERROR",
+      "-Xep:PackageLocation:ERROR",
+      "-Xep:ReferenceEquality:ERROR",
+      "-Xep:RemoveUnusedImports:ERROR",
+      "-Xep:ReturnValueIgnored:ERROR",
+      "-Xep:SelfEquals:ERROR",
+      "-Xep:SizeGreaterThanOrEqualsZero:ERROR",
+      "-Xep:TryFailThrowable:ERROR",
+    ],
+  },
+}
+
+java_defaults {
+  name: "tradefed_defaults",
+  defaults: [ "tradefed_errorprone_defaults" ],
+  javacflags: [
+    "-g",
+    "-Xlint",
+  ],
+}
+
diff --git a/Android.mk b/Android.mk
index d6f9140..65d1ee6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,6 +32,10 @@
 LOCAL_JAVA_RESOURCE_DIRS := res
 
 LOCAL_JAVACFLAGS += -g -Xlint
+ifdef TARGET_OPENJDK9
+LOCAL_JAVACFLAGS += --add-modules=java.xml.bind
+endif
+
 -include tools/tradefederation/core/error_prone_rules.mk
 
 LOCAL_MODULE := tradefed
@@ -40,7 +44,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := junit-host kxml2-2.3.0 jline-1.0 tf-remote-client commons-compress-prebuilt host-libprotobuf-java-full tradefed-protos
 # emmalib is only a runtime dependency if generating code coverage reporters,
 # not a compile time dependency
-LOCAL_JAVA_LIBRARIES := emmalib jack-jacoco-reporter loganalysis tools-common-prebuilt
+LOCAL_JAVA_LIBRARIES := loganalysis tools-common-prebuilt
 
 LOCAL_JAR_MANIFEST := MANIFEST.mf
 
@@ -48,16 +52,14 @@
 
 # makefile rules to copy jars to HOST_OUT/tradefed
 # so tradefed.sh can automatically add to classpath
-DEST_JAR := $(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar
-$(DEST_JAR): $(LOCAL_BUILT_MODULE)
-	$(copy-file-to-new-target)
+deps := $(call copy-many-files,\
+  $(LOCAL_BUILT_MODULE):$(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar \
+  $(HOST_OUT_JAVA_LIBRARIES)/tools-common-prebuilt.jar:$(HOST_OUT)/tradefed/tools-common-prebuilt.jar)
 
-$(HOST_OUT)/tradefed/%.jar : $(HOST_OUT_JAVA_LIBRARIES)/%.jar
-	$(copy-file-to-new-target)
-
-# this dependency ensure the above rule will be executed if jar is built
-$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
-$(LOCAL_INSTALLED_MODULE) : $(foreach m, $(LOCAL_JAVA_LIBRARIES), $(HOST_OUT)/tradefed/$(m).jar)
+# this dependency ensures the above rule will be executed if jar is installed
+$(LOCAL_INSTALLED_MODULE) : $(deps)
+# The copy rule for loganalysis is in tools/loganalysis/Android.mk
+$(LOCAL_INSTALLED_MODULE) : $(HOST_OUT)/tradefed/loganalysis.jar
 
 #######################################################
 # intentionally skipping CLEAR_VARS
@@ -69,7 +71,6 @@
 LOCAL_JAVA_LIBRARIES += tradefed
 LOCAL_IS_HOST_MODULE:=true
 LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_ADDITIONAL_DEPENDENCIES := tradefed
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sac
 LOCAL_DROIDDOC_OPTIONS:= \
         -package \
@@ -88,7 +89,6 @@
 LOCAL_JAVA_LIBRARIES += tradefed
 LOCAL_IS_HOST_MODULE := true
 LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_ADDITIONAL_DEPENDENCIES := tradefed
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR := external/doclava/res/assets/templates-sdk
 LOCAL_DROIDDOC_OPTIONS := \
         -hdf sac true \
diff --git a/remote/Android.bp b/remote/Android.bp
new file mode 100644
index 0000000..c53f6a8
--- /dev/null
+++ b/remote/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2013 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.
+
+java_library_host {
+  name: "tf-remote-client",
+  defaults: ["tradefed_defaults"],
+
+  srcs: ["src/**/*.java"],
+
+  static_libs: [
+    "json-prebuilt",
+    "jsr305",
+    "sdklib-prebuilt",
+    "guava-18.0-prebuilt",
+    "ddmlib-prebuilt",
+    "devtools-annotations-prebuilt",
+  ],
+}
diff --git a/remote/Android.mk b/remote/Android.mk
index 8634563..7c58fc1 100644
--- a/remote/Android.mk
+++ b/remote/Android.mk
@@ -14,27 +14,12 @@
 
 LOCAL_PATH := $(call my-dir)
 
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVACFLAGS += -g -Xlint
--include tools/tradefederation/core/error_prone_rules.mk
-
-LOCAL_MODULE := tf-remote-client
-
-LOCAL_MODULE_TAGS := optional
-# only depend on ddmlib for the Log class
-LOCAL_STATIC_JAVA_LIBRARIES := json-prebuilt jsr305lib sdklib-prebuilt guava-18.0-prebuilt ddmlib-prebuilt devtools-annotations-prebuilt
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
 # makefile rules to copy jars to HOST_OUT/tradefed
 # so tradefed.sh can automatically add to classpath
-DEST_JAR := $(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar
-$(DEST_JAR): $(LOCAL_BUILT_MODULE)
+DEST_JAR := $(HOST_OUT)/tradefed/tf-remote-client.jar
+BUILT_JAR := $(call intermediates-dir-for,JAVA_LIBRARIES,tf-remote-client,HOST)/javalib.jar
+$(DEST_JAR): $(BUILT_JAR)
 	$(copy-file-to-new-target)
 
 # this dependency ensure the above rule will be executed if jar is built
-$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
+$(HOST_OUT_JAVA_LIBRARIES)/tf-remote-client.jar : $(DEST_JAR)
diff --git a/script_help.sh b/script_help.sh
index 090673c..ad87c62 100755
--- a/script_help.sh
+++ b/script_help.sh
@@ -42,9 +42,9 @@
 
 # check java version
 java_version_string=$(java -version 2>&1)
-JAVA_VERSION=$(echo "$java_version_string" | grep '[ "]1\.[8][\. "$$]')
+JAVA_VERSION=$(echo "$java_version_string" | grep 'version [ "]\(1\.8\|9\).*[ "]')
 if [ "${JAVA_VERSION}" == "" ]; then
-    echo "Wrong java version. 1.8 is required."
+    echo "Wrong java version. 1.8 or 9 is required."
     exit
 fi
 
diff --git a/src/com/android/tradefed/result/CodeCoverageReporter.java b/src/com/android/tradefed/result/CodeCoverageReporter.java
deleted file mode 100644
index 6822a04..0000000
--- a/src/com/android/tradefed/result/CodeCoverageReporter.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2012 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.tradefed.result;
-
-import com.android.ddmlib.IDevice;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.CodeCoverageTest;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil2;
-
-import org.apache.commons.compress.archivers.zip.ZipFile;
-import org.junit.Assert;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A {@link ITestInvocationListener} that will generate code coverage reports.
- * <p/>
- * Used in conjunction with {@link CodeCoverageTest}. This assumes that emmalib.jar
- * is in same filesystem location as ddmlib jar.
- */
-@OptionClass(alias = "code-coverage-reporter")
-public class CodeCoverageReporter implements ITestInvocationListener {
-    @Option(name = "coverage-metadata-file-path", description =
-            "The path of the Emma coverage meta data file used to generate the report.")
-    private String mCoverageMetaFilePath = null;
-
-    @Option(name = "coverage-output-path", description =
-            "The location where to store the html coverage reports.",
-            mandatory = true)
-    private String mReportRootPath = null;
-
-    @Option(name = "coverage-metadata-label", description =
-            "The label of the Emma coverage meta data zip file inside the IBuildInfo.")
-    private String mCoverageMetaZipFileName = "emma_meta.zip";
-
-    @Option(name = "log-retention-days", description =
-            "The number of days to keep generated coverage files")
-    private Integer mLogRetentionDays = null;
-
-    private static final int REPORT_GENERATION_TIMEOUT_MS = 3 * 60 * 1000;
-
-    public static final String XML_REPORT_NAME = "report.xml";
-
-    private IBuildInfo mBuildInfo;
-    private LogFileSaver mLogFileSaver;
-
-    private File mLocalTmpDir = null;
-    private List<File> mCoverageFilesList = new ArrayList<File>();
-    private File mCoverageMetaFile = null;
-    private File mXMLReportFile = null;
-    private File mReportOutputPath = null;
-
-    public void setMetaZipFilePath(String filePath) {
-        mCoverageMetaFilePath = filePath;
-    }
-
-    public void setReportRootPath(String rootPath) {
-        mReportRootPath = rootPath;
-    }
-
-    public void setMetaZipFileName(String filename) {
-        mCoverageMetaZipFileName = filename;
-    }
-
-    public void setLogRetentionDays(Integer logRetentionDays) {
-        mLogRetentionDays = logRetentionDays;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void testLog(String dataName, LogDataType dataType, InputStreamSource dataStream) {
-        if (LogDataType.COVERAGE.equals(dataType)) {
-            File coverageFile = saveLogAsFile(dataName, dataType, dataStream);
-            mCoverageFilesList.add(coverageFile);
-            CLog.d("Saved a new device coverage file saved at %s", coverageFile.getAbsolutePath());
-        }
-    }
-
-    private File saveLogAsFile(String dataName, LogDataType dataType,
-            InputStreamSource dataStream) {
-        try {
-            File logFile = mLogFileSaver.saveLogData(dataName, dataType,
-                    dataStream.createInputStream());
-            return logFile;
-        } catch (IOException e) {
-            CLog.e(e);
-        }
-        return null;
-    }
-
-    public File getXMLReportFile() {
-        return mXMLReportFile;
-    }
-
-    public File getReportOutputPath() {
-        return mReportOutputPath;
-    }
-
-    public File getHTMLReportFile() {
-        return new File(mReportOutputPath, "index.html");
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void invocationStarted(IInvocationContext context) {
-        // FIXME: do code coverage reporting for each different build info (for multi-device case)
-        mBuildInfo = context.getBuildInfos().get(0);
-
-        // Append build and branch information to output directory.
-        mReportOutputPath = generateReportLocation(mReportRootPath);
-        CLog.d("ReportOutputPath: %s", mReportOutputPath);
-
-        mXMLReportFile = new File(mReportOutputPath, XML_REPORT_NAME);
-        CLog.d("ReportOutputPath: %s", mXMLReportFile);
-
-        // We want to save all other files in the same directory as the report.
-        mLogFileSaver = new LogFileSaver(mReportOutputPath);
-
-        CLog.d("ReportOutputPath %s", mReportOutputPath.getAbsolutePath());
-        CLog.d("LogfileSaver file dir %s", mLogFileSaver.getFileDir().getAbsolutePath());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void invocationEnded(long elapsedTime) {
-        // Generate report
-        generateReport();
-    }
-
-    public void generateReport() {
-        CLog.d("Generating report for code coverage");
-        try {
-            fetchAppropriateMetaDataFile();
-
-            if (!mCoverageFilesList.isEmpty()) {
-                generateCoverageReport(mCoverageFilesList, mCoverageMetaFile);
-            } else {
-                CLog.w("No coverage files were generated by the test. " +
-                        "Perhaps test failed to run successfully.");
-            }
-        } finally {
-            // Cleanup residual files.
-            if (!mCoverageFilesList.isEmpty()) {
-                for (File coverageFile : mCoverageFilesList) {
-                    FileUtil.recursiveDelete(coverageFile);
-                }
-            }
-            if (mLocalTmpDir != null) {
-                FileUtil.recursiveDelete(mLocalTmpDir);
-
-            }
-        }
-    }
-
-    private void fetchAppropriateMetaDataFile() {
-        File coverageZipFile = mBuildInfo.getFile(mCoverageMetaZipFileName);
-        Assert.assertNotNull("Failed to get the coverage metadata zipfile from the build.",
-                coverageZipFile);
-        CLog.d("Coverage zip file: %s", coverageZipFile.getAbsolutePath());
-
-        try {
-            mLocalTmpDir = FileUtil.createTempDir("emma-meta");
-            ZipFile zipFile = new ZipFile(coverageZipFile);
-            ZipUtil2.extractZip(zipFile, mLocalTmpDir);
-            File coverageMetaFile;
-            if (mCoverageMetaFilePath == null) {
-                coverageMetaFile = FileUtil.findFile(mLocalTmpDir, "coverage.em");
-            } else {
-                coverageMetaFile = new File(mLocalTmpDir, mCoverageMetaFilePath);
-            }
-            if (coverageMetaFile.exists()) {
-                mCoverageMetaFile = coverageMetaFile;
-                CLog.d("Coverage meta data file %s", mCoverageMetaFile.getAbsolutePath());
-            }
-        } catch (IOException e) {
-            CLog.e(e);
-        }
-    }
-
-    private File generateReportLocation(String rootPath) {
-        String branchName = mBuildInfo.getBuildBranch();
-        String buildId = mBuildInfo.getBuildId();
-        String testTag = mBuildInfo.getTestTag();
-        File branchPath = new File(rootPath, branchName);
-        File buildIdPath = new File(branchPath, buildId);
-        File testTagPath = new File(buildIdPath, testTag);
-        FileUtil.mkdirsRWX(testTagPath);
-        if (mLogRetentionDays != null) {
-            RetentionFileSaver f = new RetentionFileSaver();
-            f.writeRetentionFile(testTagPath, mLogRetentionDays);
-        }
-        return testTagPath;
-    }
-
-    private void generateCoverageReport(List<File> coverageFileList, File metaFile) {
-        Assert.assertFalse("Could not find a valid coverage file.", coverageFileList.isEmpty());
-        Assert.assertNotNull("Could not find a valid meta data coverage file.", metaFile);
-        String emmaPath = findEmmaJarPath();
-        List<String> cmdList = new ArrayList<String>();
-        cmdList.addAll(Arrays.asList("java", "-cp", emmaPath, "emma", "report", "-r", "html",
-                "-r", "xml", "-in", metaFile.getAbsolutePath(), "-Dreport.html.out.encoding=UTF-8",
-                "-Dreport.html.out.file=" + mReportOutputPath.getAbsolutePath() + "/index.html",
-                "-Dreport.xml.out.file=" + mReportOutputPath.getAbsolutePath() + "/report.xml"));
-        // Now append all the coverage files collected.
-        for (File coverageFile : coverageFileList) {
-            cmdList.add("-in");
-            cmdList.add(coverageFile.getAbsolutePath());
-        }
-        String[] cmd = cmdList.toArray(new String[cmdList.size()]);
-        IRunUtil runUtil = RunUtil.getDefault();
-        CommandResult result = runUtil.runTimedCmd(REPORT_GENERATION_TIMEOUT_MS, cmd);
-        if (!result.getStatus().equals(CommandStatus.SUCCESS)) {
-            CLog.e("Failed to generate coverage report. stderr: %s",
-                    result.getStderr());
-        } else {
-            // Make the report world readable.
-            boolean setPerms = FileUtil.chmodRWXRecursively(mReportOutputPath);
-            if (!setPerms) {
-                CLog.w("Failed to set %s to be world accessible.",
-                        mReportOutputPath.getAbsolutePath());
-            }
-        }
-    }
-
-    /**
-     * Tries to find emma.jar in same location as ddmlib.jar.
-     *
-     * @return full path to emma jar file
-     * @throws AssertionError if could not find emma jar
-     */
-    String findEmmaJarPath() {
-        String ddmlibPath = IDevice.class.getProtectionDomain()
-                .getCodeSource()
-                .getLocation()
-                .getFile();
-        Assert.assertFalse("failed to find ddmlib path", ddmlibPath.isEmpty());
-        File parentFolder = new File(ddmlibPath);
-        File emmaJar = new File(parentFolder.getParent(), "emmalib.jar");
-        Assert.assertTrue(
-                String.format("Failed to find emma.jar in %s", emmaJar.getAbsolutePath()),
-                emmaJar.exists());
-        CLog.d("Found emma jar at %s", emmaJar.getAbsolutePath());
-        return emmaJar.getAbsolutePath();
-    }
-}
diff --git a/src/com/android/tradefed/testtype/InstrumentationTest.java b/src/com/android/tradefed/testtype/InstrumentationTest.java
index 788c2e8..fe51ce2 100644
--- a/src/com/android/tradefed/testtype/InstrumentationTest.java
+++ b/src/com/android/tradefed/testtype/InstrumentationTest.java
@@ -225,6 +225,14 @@
     )
     private boolean mShouldEnforceFormat = false;
 
+    @Option(
+        name = "hidden-api-checks",
+        description =
+                "If set to false, the '--no-hidden-api-checks' flag will be passed to the am "
+                        + "instrument command. Only works for P or later."
+    )
+    private boolean mHiddenApiChecks = true;
+
     private IAbi mAbi = null;
 
     private Collection<String> mInstallArgs = new ArrayList<>();
@@ -568,10 +576,19 @@
         RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
                 packageName, runnerName, device);
         String abiName = resolveAbiName();
+        String runOptions = "";
+        if (!mHiddenApiChecks) {
+            runOptions += "--no-hidden-api-checks ";
+        }
         if (abiName != null) {
             mInstallArgs.add(String.format("--abi %s", abiName));
-            runner.setRunOptions(String.format("--abi %s", abiName));
+            runOptions += String.format("--abi %s", abiName);
         }
+        // Set the run options if any.
+        if (!runOptions.isEmpty()) {
+            runner.setRunOptions(runOptions);
+        }
+
         runner.setEnforceTimeStamp(mShouldEnforceFormat);
         return runner;
     }
diff --git a/src/com/android/tradefed/testtype/JackCodeCoverageTest.java b/src/com/android/tradefed/testtype/JackCodeCoverageTest.java
deleted file mode 100644
index e3d3d93..0000000
--- a/src/com/android/tradefed/testtype/JackCodeCoverageTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2016 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.tradefed.testtype;
-
-import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.CSV;
-import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.HTML;
-import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.XML;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.ZipUtil2;
-
-import com.google.common.collect.Lists;
-
-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.PathMatcher;
-import java.security.CodeSource;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * An {@link IRemoteTest} which runs installed instrumentation test(s) and generates a code coverage
- * report. This test type supports collecting coverage information from classes that have already
- * been instrumented by the Jack compiler.
- */
-@OptionClass(alias = "jack-coverage")
-public class JackCodeCoverageTest extends CodeCoverageTestBase<JackCodeCoverageReportFormat> {
-
-    /** Location of the report generation tool. */
-    private File mCoverageReporter = null;
-
-    @Option(name = "metadata-zip-artifact",
-            description = "The name of the build artifact that contains the coverage metadata " +
-            "files. Defaults to emma_meta.zip")
-    private String mMetadataZipArtifact = "emma_meta.zip" ;
-
-    @Option(name = "metadata-files-filter",
-            description = "Glob pattern used to select the metadata files to use when " +
-            "generating the coverage report. May be repeated.")
-    private List<String> mMetadataFilesFilter = new ArrayList<>();
-
-    @Option(name = "report-timeout", isTimeVal = true,
-            description = "Maximum time to wait for coverage report generation to complete in ms")
-    private long mReportTimeout = 5 * 60 * 1000; // 5 Minutes
-
-    @Option(name = "report-format",
-            description = "Which output format(s) to use when generating the coverage report. " +
-            "May be repeated to output multiple formats. Defaults to HTML if unspecified.")
-    private List<JackCodeCoverageReportFormat> mReportFormat = new ArrayList<>();
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected List<JackCodeCoverageReportFormat> getReportFormat() {
-        return mReportFormat.isEmpty() ? Arrays.asList(HTML) : mReportFormat;
-    }
-
-    /**
-     * Returns the name of the build artifact that contains the coverage metadata.
-     */
-    protected String getMetadataZipArtifact() {
-        return mMetadataZipArtifact;
-    }
-
-    /**
-     * Returns the list of glob patterns used to select metadata files to use when generating the
-     * coverage report. Exposed for unit testing.
-     */
-    protected List<String> getMetadataFilesFilter() {
-        return mMetadataFilesFilter.isEmpty() ? Arrays.asList("glob:**.em") : mMetadataFilesFilter;
-    }
-
-    /** Returns the maximum time to wait for the coverage report to be generated. */
-    protected long getReportTimeout() {
-        return mReportTimeout;
-    }
-
-    /** Returns the location of the report generation tool. */
-    protected File getCoverageReporter() throws IOException {
-        if (mCoverageReporter == null) {
-            // The coverage reporter tool should already be on our class path. This code computes
-            // the location of the jar file containing the coverage tool's main class.
-            Class<?> mainClass = com.android.jack.tools.jacoco.Main.class;
-            CodeSource source = mainClass.getProtectionDomain().getCodeSource();
-            if (source == null) {
-                throw new IOException("Failed to find coverage reporter tool");
-            }
-            mCoverageReporter = new File(source.getLocation().getFile());
-        }
-        return mCoverageReporter;
-    }
-
-    private File mMetadataCache = null;
-
-    /**
-     * Returns the set of metadata files that should be used to generate the coverage report.
-     *
-     * @return The set of metadata files that match at least one of the metadata-files-filters.
-     */
-    protected Set<File> getMetadataFiles() throws IOException {
-        // Extract the metadata files if we haven't already
-        if (mMetadataCache == null) {
-            File metadataZip = getBuild().getFile(getMetadataZipArtifact());
-            mMetadataCache = ZipUtil2.extractZipToTemp(metadataZip, "metadata");
-        }
-
-        // Convert the filter strings to PathMatchers
-        FileSystem fs = FileSystems.getDefault();
-        Set<PathMatcher> filters = getMetadataFilesFilter().stream()
-                .map(f -> fs.getPathMatcher(f))
-                .collect(Collectors.toSet());
-
-        // Find metadata files that match the specified filters
-        return Files.walk(mMetadataCache.toPath())
-                .filter(p -> filters.stream().anyMatch(f -> f.matches(p)))
-                .map(p -> p.toFile())
-                .collect(Collectors.toSet());
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected File generateCoverageReport(Collection<File> executionFiles,
-            JackCodeCoverageReportFormat format) throws IOException {
-
-        // Construct a command line for running the report generation tool
-        File dest = FileUtil.createTempDir("coverage");
-        File coverageReporter = getCoverageReporter();
-        List<String> cmd = Lists.newArrayList("java", "-jar",
-                coverageReporter.getAbsolutePath());
-        for (File metadata : getMetadataFiles()) {
-            cmd.add("--metadata-file");
-            cmd.add(metadata.getAbsolutePath());
-        }
-        for (File coverageFile : executionFiles) {
-            cmd.add("--coverage-file");
-            cmd.add(coverageFile.getAbsolutePath());
-        }
-        cmd.add("--report-dir");
-        cmd.add(dest.getAbsolutePath());
-        cmd.add("--report-type");
-        cmd.add(format.getReporterArg());
-
-        // Run the command
-        CommandResult result = runTimedCmd(getReportTimeout(), cmd.toArray(new String[0]));
-        if (!CommandStatus.SUCCESS.equals(result.getStatus())) {
-            FileUtil.recursiveDelete(dest);
-            throw new IOException(String.format(
-                    "Failed to generate code coverage report: %s", result.getStderr()));
-        }
-
-        // CSV reports (and XML) get put in dest/report.csv. Return the actual report file.
-        if (CSV.equals(format) || XML.equals(format)) {
-            try {
-                // Make a copy of the file, so we can clean up the dest directory
-                String ext = format.getLogDataType().getFileExt();
-                return copyFile(new File(dest, String.format("report.%s", ext)));
-            } finally {
-                FileUtil.recursiveDelete(dest);
-            }
-        } else {
-            return dest;
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void cleanup() {
-        FileUtil.recursiveDelete(mMetadataCache);
-        mMetadataCache = null;
-    }
-
-    /** Returns a copy of the given {@code source} file. */
-    File copyFile(File source) throws IOException {
-        // Create a new file with the same prefix and extension as the source file
-        String filename = source.getPath();
-        int pos = filename.lastIndexOf(".");
-        File ret = FileUtil.createTempFile(filename.substring(0, pos), filename.substring(pos));
-
-        // Copy the contents of the source file to the new file and return it
-        FileUtil.copyFile(source, ret);
-        return ret;
-    }
-
-    /** Calls {@link RunUtil#runTimedCmd(long, String[])}. Exposed for unit testing. */
-    CommandResult runTimedCmd(long timeout, String[] command) {
-        return RunUtil.getDefault().runTimedCmd(timeout, command);
-    }
-}
diff --git a/src/com/android/tradefed/testtype/suite/ModuleDefinition.java b/src/com/android/tradefed/testtype/suite/ModuleDefinition.java
index b4faf32..174cdc9 100644
--- a/src/com/android/tradefed/testtype/suite/ModuleDefinition.java
+++ b/src/com/android/tradefed/testtype/suite/ModuleDefinition.java
@@ -257,9 +257,16 @@
             if (preparationException != null) {
                 // For reporting purpose we create a failure placeholder with the error stack
                 // similar to InitializationError of JUnit.
+                TestIdentifier testid =
+                        new TestIdentifier(
+                                preparationException.getClass().getCanonicalName(),
+                                "preparationError");
                 listener.testRunStarted(getId(), 1);
+                listener.testStarted(testid);
                 StringWriter sw = new StringWriter();
                 preparationException.printStackTrace(new PrintWriter(sw));
+                listener.testFailed(testid, sw.toString());
+                listener.testEnded(testid, Collections.emptyMap());
                 listener.testRunFailed(sw.toString());
                 Map<String, String> metrics = new HashMap<>();
                 metrics.put(TEST_TIME, "0");
diff --git a/src/com/android/tradefed/util/StreamUtil.java b/src/com/android/tradefed/util/StreamUtil.java
index eee61b4..a904fd6 100644
--- a/src/com/android/tradefed/util/StreamUtil.java
+++ b/src/com/android/tradefed/util/StreamUtil.java
@@ -33,11 +33,10 @@
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.Objects;
 import java.util.zip.GZIPOutputStream;
 import java.util.zip.ZipOutputStream;
 
-import javax.xml.bind.DatatypeConverter;
-
 /**
  * Utility class for managing input streams.
  */
@@ -309,7 +308,29 @@
             // Read through the stream to update digest.
         }
         input.close();
-        String md5 = DatatypeConverter.printHexBinary(md.digest()).toLowerCase();
+        String md5 = bytesToHexString(md.digest());
         return md5;
     }
+
+    private static final char[] HEX_CHARS = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    /**
+     * Converts a byte array into a String of hexadecimal characters.
+     *
+     * @param bytes an array of bytes
+     * @return hex string representation of bytes array
+     */
+    private static String bytesToHexString(byte[] bytes) {
+        Objects.requireNonNull(bytes);
+        StringBuilder sb = new StringBuilder(2 * bytes.length);
+        for (int i = 0; i < bytes.length; i++) {
+            int b = 0x0f & (bytes[i] >> 4);
+            sb.append(HEX_CHARS[b]);
+            b = 0x0f & bytes[i];
+            sb.append(HEX_CHARS[b]);
+        }
+        return sb.toString();
+    }
 }
diff --git a/tests/src/com/android/tradefed/UnitTests.java b/tests/src/com/android/tradefed/UnitTests.java
index 2d35fb7..8b82c6b 100644
--- a/tests/src/com/android/tradefed/UnitTests.java
+++ b/tests/src/com/android/tradefed/UnitTests.java
@@ -149,7 +149,6 @@
 import com.android.tradefed.testtype.InstrumentationFileTestTest;
 import com.android.tradefed.testtype.InstrumentationSerialTestTest;
 import com.android.tradefed.testtype.InstrumentationTestTest;
-import com.android.tradefed.testtype.JackCodeCoverageTestTest;
 import com.android.tradefed.testtype.JacocoCodeCoverageTestTest;
 import com.android.tradefed.testtype.NativeBenchmarkTestParserTest;
 import com.android.tradefed.testtype.NativeBenchmarkTestTest;
@@ -408,7 +407,6 @@
     InstrumentationSerialTestTest.class,
     InstrumentationFileTestTest.class,
     InstrumentationTestTest.class,
-    JackCodeCoverageTestTest.class,
     JacocoCodeCoverageTestTest.class,
     NativeBenchmarkTestParserTest.class,
     NativeBenchmarkTestTest.class,
diff --git a/tests/src/com/android/tradefed/testtype/JackCodeCoverageTestTest.java b/tests/src/com/android/tradefed/testtype/JackCodeCoverageTestTest.java
deleted file mode 100644
index 7972fc5..0000000
--- a/tests/src/com/android/tradefed/testtype/JackCodeCoverageTestTest.java
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-package com.android.tradefed.testtype;
-
-import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.CSV;
-import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.HTML;
-import static com.android.tradefed.testtype.JackCodeCoverageReportFormat.XML;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-
-import junit.framework.TestCase;
-
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-
-/** Unit tests for {@link JackCodeCoverageTest}. */
-public class JackCodeCoverageTestTest extends TestCase {
-
-    private static final File COVERAGE_FILE1 = new File("/some/example/coverage.ec");
-    private static final File COVERAGE_FILE2 = new File("/another/example/coverage.ec");
-    private static final File COVERAGE_FILE3 = new File("/different/extension/example.exec");
-
-    private static final File METADATA_FILE1 = new File("/some/example/coverage.em");
-    private static final File METADATA_FILE2 = new File("/another/example/coverage.em");
-    private static final File METADATA_FILE3 = new File("/different/extension/example.meta");
-
-    private static final String EMMA_METADATA_RESOURCE_PATH = "/testdata/emma_meta.zip";
-    private static final String EMMA_METADATA_ARTIFACT_NAME = "emma_meta.zip";
-    private static final String FOO_METADATA =
-            "/out/target/common/obj/JAVA_LIBRARIES/foo_intermediates/coverage.em";
-    private static final String BAR_METADATA =
-            "/out/target/common/obj/APPS/bar_intermediates/coverage.em";
-    private static final String BAZ_METADATA =
-            "/out/target/common/obj/APPS/baz_intermediates/coverage.em";
-
-    private static final CommandResult SUCCESS = new CommandResult(CommandStatus.SUCCESS);
-    private static final File FAKE_REPORT_TOOL = new File("/path/to/jack-jacoco-reporter.jar");
-
-    public void testGetCoverageReporter() throws IOException {
-        // Try to get the coverage reporter
-        JackCodeCoverageTest coverageTest = new JackCodeCoverageTest();
-        File coverageReporter = coverageTest.getCoverageReporter();
-
-        // Verify that we were able to find the coverage reporter tool and that the tool exists
-        assertNotNull(coverageReporter);
-        assertTrue(coverageReporter.exists());
-    }
-
-    public void testGetMetadataFiles() throws IOException {
-        // Prepare test data
-        File metadataZipFile = extractResource(EMMA_METADATA_RESOURCE_PATH);
-
-        // Set up mocks
-        IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class);
-        doReturn(metadataZipFile).when(mockBuild).getFile(EMMA_METADATA_ARTIFACT_NAME);
-        JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest());
-        doReturn(mockBuild).when(coverageTest).getBuild();
-        doReturn(EMMA_METADATA_ARTIFACT_NAME).when(coverageTest).getMetadataZipArtifact();
-
-        // Get the metadata files
-        Set<File> metadataFiles = null;
-        try {
-            metadataFiles = coverageTest.getMetadataFiles();
-        } finally {
-            // Cleanup
-            FileUtil.deleteFile(metadataZipFile);
-            coverageTest.cleanup();
-        }
-
-        // Verify that we got all of the metdata files
-        assertNotNull(metadataFiles);
-        assertEquals(3, metadataFiles.size());
-        Set<String> expectedFiles = Sets.newHashSet(FOO_METADATA, BAR_METADATA, BAZ_METADATA);
-        for (File metadata : metadataFiles) {
-            for (String expected : expectedFiles) {
-                if (metadata.getAbsolutePath().endsWith(expected)) {
-                    expectedFiles.remove(expected);
-                    break;
-                }
-            }
-        }
-        assertTrue(expectedFiles.isEmpty());
-    }
-
-    public void testGetMetadataFiles_withFilter() throws IOException {
-        // Prepare test data
-        File metadataZipFile = extractResource(EMMA_METADATA_RESOURCE_PATH);
-
-        // Set up mocks
-        IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class);
-        doReturn(metadataZipFile).when(mockBuild).getFile(EMMA_METADATA_ARTIFACT_NAME);
-        JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest());
-        doReturn(mockBuild).when(coverageTest).getBuild();
-        doReturn(EMMA_METADATA_ARTIFACT_NAME).when(coverageTest).getMetadataZipArtifact();
-        doReturn(Arrays.asList("glob:**/foo_intermediates/coverage.em")).when(coverageTest)
-                .getMetadataFilesFilter();
-
-        // Get the metadata files
-        Set<File> metadataFiles = null;
-        try {
-            metadataFiles = coverageTest.getMetadataFiles();
-        } finally {
-            // Cleanup
-            FileUtil.deleteFile(metadataZipFile);
-            coverageTest.cleanup();
-        }
-
-        // Verify that only the framework metadata file was returned
-        assertNotNull(metadataFiles);
-        assertEquals(1, metadataFiles.size());
-        File metadataFile = Iterables.getOnlyElement(metadataFiles);
-        assertTrue(metadataFile.getAbsolutePath().endsWith(FOO_METADATA));
-    }
-
-    private File extractResource(String resourcePath) throws IOException {
-        // Write the resource to a file and return it
-        File dest = FileUtil.createTempFile(Files.getNameWithoutExtension(resourcePath),
-                "." + Files.getFileExtension(resourcePath));
-        FileUtil.writeToFile(getClass().getResourceAsStream(resourcePath), dest);
-        return dest;
-    }
-
-    private void verifyCommandLine(List<String> commandLine, File reportTool,
-            Collection<File> coverageFiles, Collection<File> metadataFiles, String format) {
-
-        // Verify positional arguments
-        assertEquals("java", commandLine.get(0));
-        assertEquals("-jar", commandLine.get(1));
-        assertEquals(reportTool.getAbsolutePath(), commandLine.get(2));
-
-        // Verify the rest of the command line arguments
-        assertTrue(commandLine.contains("--report-dir"));
-        for (int i = 3; i < commandLine.size() - 1; i++) {
-            switch (commandLine.get(i)) {
-                case "--coverage-file":
-                    File coverageFile = new File(commandLine.get(++i));
-                    assertTrue(String.format("Unexpected coverage file: %s", coverageFile),
-                            coverageFiles.remove(coverageFile));
-                    break;
-                case "--metadata-file":
-                    File metadataFile = new File(commandLine.get(++i));
-                    assertTrue(String.format("Unexpected metadata file: %s", metadataFile),
-                            metadataFiles.remove(metadataFile));
-                    break;
-                case "--report-dir":
-                    i++;
-                    break;
-                case "--report-type":
-                    assertEquals(format, commandLine.get(++i));
-                    break;
-            }
-        }
-        assertTrue(coverageFiles.isEmpty());
-        assertTrue(metadataFiles.isEmpty());
-    }
-
-    public void testGenerateCoverageReport_html() throws IOException {
-        // Prepare some test data
-        Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3);
-        Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3);
-
-        // Set up mocks
-        JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest());
-        IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class);
-        doReturn(mockBuild).when(coverageTest).getBuild();
-        doReturn(metadataFiles).when(coverageTest).getMetadataFiles();
-        doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter();
-        doReturn(SUCCESS).when(coverageTest).runTimedCmd(anyLong(), any(String[].class));
-
-        File report = null;
-        try {
-            // Generate a coverage report
-            report = coverageTest.generateCoverageReport(coverageFiles, HTML);
-
-            // Verify that the command was called with the right arguments
-            ArgumentCaptor<String[]> cmdLineCaptor = ArgumentCaptor.forClass(String[].class);
-            Mockito.verify(coverageTest).runTimedCmd(anyLong(), cmdLineCaptor.capture());
-            verifyCommandLine(Arrays.asList(cmdLineCaptor.getValue()), FAKE_REPORT_TOOL,
-                    coverageFiles, metadataFiles, HTML.getReporterArg());
-        } finally {
-            FileUtil.recursiveDelete(report);
-            coverageTest.cleanup();
-        }
-    }
-
-    public void testGenerateCoverageReport_csv() throws IOException {
-        // Prepare some test data
-        Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3);
-        Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3);
-
-        // Set up mocks
-        JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest());
-        IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class);
-        doReturn(mockBuild).when(coverageTest).getBuild();
-        doReturn(metadataFiles).when(coverageTest).getMetadataFiles();
-        doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter();
-        doReturn(SUCCESS).when(coverageTest).runTimedCmd(anyLong(), any(String[].class));
-        doReturn(new File("/copy/of/report.csv")).when(coverageTest).copyFile(any(File.class));
-
-        // Generate a coverage report
-        coverageTest.generateCoverageReport(coverageFiles, CSV);
-
-        // Verify that the command was called with the right arguments
-        ArgumentCaptor<String[]> cmdLineCaptor = ArgumentCaptor.forClass(String[].class);
-        Mockito.verify(coverageTest).runTimedCmd(anyLong(), cmdLineCaptor.capture());
-        verifyCommandLine(Arrays.asList(cmdLineCaptor.getValue()), FAKE_REPORT_TOOL,
-                coverageFiles, metadataFiles, CSV.getReporterArg());
-    }
-
-    public void testGenerateCoverageReport_xml() throws IOException {
-        // Prepare some test data
-        Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3);
-        Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3);
-
-        // Set up mocks
-        JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest());
-        IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class);
-        doReturn(mockBuild).when(coverageTest).getBuild();
-        doReturn(metadataFiles).when(coverageTest).getMetadataFiles();
-        doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter();
-        doReturn(SUCCESS).when(coverageTest).runTimedCmd(anyLong(), any(String[].class));
-        doReturn(new File("/copy/of/report.xml")).when(coverageTest).copyFile(any(File.class));
-
-        // Generate a coverage report
-        coverageTest.generateCoverageReport(coverageFiles, XML);
-
-        // Verify that the command was called with the right arguments
-        ArgumentCaptor<String[]> cmdLineCaptor = ArgumentCaptor.forClass(String[].class);
-        Mockito.verify(coverageTest).runTimedCmd(anyLong(), cmdLineCaptor.capture());
-        verifyCommandLine(Arrays.asList(cmdLineCaptor.getValue()), FAKE_REPORT_TOOL,
-                coverageFiles, metadataFiles, XML.getReporterArg());
-    }
-
-    public void testGenerateCoverageReport_error() throws IOException {
-        // Prepare some test data
-        Set<File> coverageFiles = Sets.newHashSet(COVERAGE_FILE1, COVERAGE_FILE2, COVERAGE_FILE3);
-        Set<File> metadataFiles = Sets.newHashSet(METADATA_FILE1, METADATA_FILE2, METADATA_FILE3);
-        String stderr = "some error message";
-
-        // Set up mocks
-        CommandResult failed = new CommandResult(CommandStatus.FAILED);
-        failed.setStderr(stderr);
-
-        JackCodeCoverageTest coverageTest = Mockito.spy(new JackCodeCoverageTest());
-        IBuildInfo mockBuild = Mockito.mock(IBuildInfo.class);
-        doReturn(mockBuild).when(coverageTest).getBuild();
-        doReturn(metadataFiles).when(coverageTest).getMetadataFiles();
-        doReturn(FAKE_REPORT_TOOL).when(coverageTest).getCoverageReporter();
-        doReturn(failed).when(coverageTest).runTimedCmd(anyLong(), any(String[].class));
-
-        // Generate a coverage report
-        try {
-            coverageTest.generateCoverageReport(coverageFiles, HTML);
-            fail("IOException not thrown");
-        } catch (IOException e) {
-            assertTrue(e.getMessage().contains(stderr));
-        }
-    }
-}
diff --git a/tests/src/com/android/tradefed/testtype/suite/ModuleDefinitionTest.java b/tests/src/com/android/tradefed/testtype/suite/ModuleDefinitionTest.java
index 32a666e..8adad4f 100644
--- a/tests/src/com/android/tradefed/testtype/suite/ModuleDefinitionTest.java
+++ b/tests/src/com/android/tradefed/testtype/suite/ModuleDefinitionTest.java
@@ -212,6 +212,10 @@
         mMockCleaner.tearDown(EasyMock.eq(mMockDevice), EasyMock.eq(mMockBuildInfo),
                 EasyMock.isNull());
         mMockListener.testRunStarted(EasyMock.eq(MODULE_NAME), EasyMock.eq(1));
+        mMockListener.testStarted(
+                new TestIdentifier(TargetSetupError.class.getCanonicalName(), "preparationError"));
+        mMockListener.testFailed(EasyMock.anyObject(), EasyMock.contains(exceptionMessage));
+        mMockListener.testEnded(EasyMock.anyObject(), EasyMock.anyObject());
         mMockListener.testRunFailed(EasyMock.contains(exceptionMessage));
         mMockListener.testRunEnded(EasyMock.anyLong(), EasyMock.anyObject());
         replayMocks();
diff --git a/tests/test-apps/NativeTestSampleApp/src/Android.mk b/tests/test-apps/NativeTestSampleApp/src/Android.mk
index 1bb595c..6100eb5 100644
--- a/tests/test-apps/NativeTestSampleApp/src/Android.mk
+++ b/tests/test-apps/NativeTestSampleApp/src/Android.mk
@@ -20,6 +20,8 @@
 #All source files for the library
 LOCAL_SRC_FILES := TradeFedNativeTestSampleLib.cpp
 
+LOCAL_CFLAGS := -Wall -Werror
+
 LOCAL_C_INCLUDES := \
 	$(LOCAL_PATH)/../include
 
diff --git a/tests/test-apps/TradeFedNativeTestApp/Android.mk b/tests/test-apps/TradeFedNativeTestApp/Android.mk
index 7e8df0f..551b9e2 100644
--- a/tests/test-apps/TradeFedNativeTestApp/Android.mk
+++ b/tests/test-apps/TradeFedNativeTestApp/Android.mk
@@ -23,6 +23,8 @@
 # All source files will be bundled into one test module
 LOCAL_SRC_FILES := TradeFedNativeTestApp_test.cpp
 
+LOCAL_CFLAGS := -Wall -Werror
+
 # All gtests in all files should be compiled into one binary
 # The standard naming should conform to: <module_being_tested>tests
 # For example, for libjingle, use libjingletests
diff --git a/tradefed_win.bat b/tradefed_win.bat
index 1362740..4145821 100755
--- a/tradefed_win.bat
+++ b/tradefed_win.bat
@@ -22,14 +22,9 @@
 call:checkCommand java

 

 :: check java version

-set JAVA_VERSION=

 

-for /f "delims=" %%j in ('java -version 2^>^&1 ^| findstr /i """1.8"') do (

-    set JAVA_VERSION=8

-)

-

-if "%JAVA_VERSION%" == "" (

-    echo "Wrong java version. 1.8 is required."

+%JAVA% -version 2>&1 | findstr /R "version\ \"1*\.*[89].*\"$" || (

+    echo "Wrong java version. 1.8 or 9 is required."

     exit /B

 )