[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
)