aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar ulfjack <ulfjack@google.com>2017-06-06 08:33:40 -0400
committerGravatar John Cater <jcater@google.com>2017-06-06 09:51:12 -0400
commitf3753580583ab025eceaaf2b76e61b7b99be2e39 (patch)
tree5fa1c5e6fce2029ff71f5713f8783f469ceae5ff /src/main/java/com/google
parent24e3d7a387f9e15733b01fe09e2cb03f18f8c271 (diff)
Move the instrumentation filter computation to BuildTool
Previously, it was in CoverageCommand, which led to all sorts of special casing and workarounds, because it required options editing, error handling during options editing, as well as early package path setup. It also caused us to duplicate target pattern evaluation for the coverage command. A semantic change is that the TestCommand can now also trigger the heuristic instrumentation filter computation, if collect_code_coverage is enabled; we might consider also enabling this for the BuildCommand, which can also have collect_code_coverage enabled (e.g., when a user wants to build a non-test binary with coverage instrumentation). Also remove a bunch of unnecessary AbruptExitException declarations. RELNOTES: bazel test now also computes a default instrumentation filter if --collect_code_coverage is enabled PiperOrigin-RevId: 158129953
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/buildtool/InstrumentationFilterSupport.java150
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BlazeCommand.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/commands/CoverageCommand.java183
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/commands/TestCommand.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/mobileinstall/MobileInstallCommand.java4
7 files changed, 190 insertions, 194 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java
index 2384e31c9a..efbd6ec202 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequest.java
@@ -415,8 +415,9 @@ public class BuildRequest implements OptionsClassProvider {
private long startTimeMillis = 0; // milliseconds since UNIX epoch.
- private boolean runningInEmacs = false;
- private boolean runTests = false;
+ private boolean needsInstrumentationFilter;
+ private boolean runningInEmacs;
+ private boolean runTests;
private static final ImmutableList<Class<? extends OptionsBase>> MANDATORY_OPTIONS =
ImmutableList.of(
@@ -576,6 +577,14 @@ public class BuildRequest implements OptionsClassProvider {
return startTimeMillis;
}
+ public void setNeedsInstrumentationFilter(boolean needInstrumentationFilter) {
+ this.needsInstrumentationFilter = needInstrumentationFilter;
+ }
+
+ public boolean needsInstrumentationFilter() {
+ return needsInstrumentationFilter;
+ }
+
/**
* Validates the options for this BuildRequest.
*
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index 6692a9e5ae..dd5b81d58b 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -70,6 +70,8 @@ import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.util.Preconditions;
+import com.google.devtools.build.lib.util.RegexFilter;
+import com.google.devtools.common.options.OptionsParsingException;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -168,6 +170,22 @@ public final class BuildTool {
executionTool.init();
}
+ // Compute the heuristic instrumentation filter if needed.
+ if (request.needsInstrumentationFilter()) {
+ String instrumentationFilter =
+ InstrumentationFilterSupport.computeInstrumentationFilter(
+ env.getReporter(), loadingResult.getTestsToRun());
+ try {
+ // We're modifying the buildOptions in place, which is not ideal, but we also don't want
+ // to pay the price for making a copy. Maybe reconsider later if this turns out to be a
+ // problem (and the performance loss may not be a big deal).
+ buildOptions.get(BuildConfiguration.Options.class).instrumentationFilter =
+ new RegexFilter.RegexFilterConverter().convert(instrumentationFilter);
+ } catch (OptionsParsingException e) {
+ throw new InvalidConfigurationException(e);
+ }
+ }
+
// Exit if there are any pending exceptions from modules.
env.throwPendingException();
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/InstrumentationFilterSupport.java b/src/main/java/com/google/devtools/build/lib/buildtool/InstrumentationFilterSupport.java
new file mode 100644
index 0000000000..5781e0272b
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/InstrumentationFilterSupport.java
@@ -0,0 +1,150 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// 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.google.devtools.build.lib.buildtool;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.packages.AttributeMap;
+import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.packages.TargetUtils;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * Helper class to heuristically compute an instrumentation filter from a list of tests to run.
+ */
+public final class InstrumentationFilterSupport {
+ public static final String INSTRUMENTATION_FILTER_FLAG = "instrumentation_filter";
+
+ /**
+ * Method implements a heuristic used to set default value of the
+ * --instrumentation_filter option. Following algorithm is used:
+ * 1) Identify all test targets on the command line.
+ * 2) Expand all test suites into the individual test targets
+ * 3) Calculate list of package names containing all test targets above.
+ * 4) Replace all "javatests/" substrings in package names with "java/".
+ * 5) If two packages reside in the same directory, use filter based on
+ * the parent directory name instead. Doing so significantly simplifies
+ * instrumentation filter in majority of real-life scenarios (in
+ * particular when dealing with my/package/... wildcards).
+ * 6) Set --instrumentation_filter default value to instrument everything
+ * in those packages.
+ */
+ @VisibleForTesting
+ public static String computeInstrumentationFilter(
+ EventHandler eventHandler, Collection<Target> testTargets) {
+ SortedSet<String> packageFilters = Sets.newTreeSet();
+ collectInstrumentedPackages(testTargets, packageFilters);
+ optimizeFilterSet(packageFilters);
+
+ String instrumentationFilter = "//" + Joiner.on(",//").join(packageFilters);
+ if (!packageFilters.isEmpty()) {
+ eventHandler.handle(
+ Event.info("Using default value for --instrumentation_filter: \""
+ + instrumentationFilter + "\"."));
+ eventHandler.handle(Event.info("Override the above default with --"
+ + INSTRUMENTATION_FILTER_FLAG));
+ }
+ return instrumentationFilter;
+ }
+
+ private static void collectInstrumentedPackages(
+ Collection<Target> targets, Set<String> packageFilters) {
+ for (Target target : targets) {
+ // Add package-based filters for every test target.
+ String prefix = getInstrumentedPrefix(target.getLabel().getPackageName());
+ if (!prefix.isEmpty()) {
+ packageFilters.add(prefix);
+ }
+ if (TargetUtils.isTestSuiteRule(target)) {
+ AttributeMap attributes = NonconfigurableAttributeMapper.of((Rule) target);
+ // We don't need to handle $implicit_tests attribute since we already added
+ // test_suite package to the set.
+ for (Label label : attributes.get("tests", BuildType.LABEL_LIST)) {
+ // Add package-based filters for all tests in the test suite.
+ packageFilters.add(getInstrumentedPrefix(label.getPackageName()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns prefix string that should be instrumented for a given package. Input string should
+ * be formatted like the output of Label.getPackageName().
+ * Generally, package name will be used as such string with two modifications.
+ * - "javatests/ directories will be substituted with "java/", since we do
+ * not want to instrument java test code. "java/" directories in "test/" will
+ * be replaced by the same in "main/".
+ * - "/internal", "/public", and "tests/" package suffix will be dropped, since usually we would
+ * want to instrument code in the parent package as well
+ */
+ @VisibleForTesting
+ public static String getInstrumentedPrefix(String packageName) {
+ if (packageName.endsWith("/internal")) {
+ packageName = packageName.substring(0, packageName.length() - "/internal".length());
+ } else if (packageName.endsWith("/public")) {
+ packageName = packageName.substring(0, packageName.length() - "/public".length());
+ } else if (packageName.endsWith("/tests")) {
+ packageName = packageName.substring(0, packageName.length() - "/tests".length());
+ }
+ return packageName
+ .replaceFirst("(?<=^|/)javatests/", "java/")
+ .replaceFirst("(?<=^|/)test/java/", "main/java/");
+ }
+
+ private static void optimizeFilterSet(SortedSet<String> packageFilters) {
+ Iterator<String> iterator = packageFilters.iterator();
+ if (iterator.hasNext()) {
+ // Find common parent filters to reduce number of filter expressions. In practice this
+ // still produces nicely constrained instrumentation filter while making final
+ // filter value much more user-friendly - especially in case of /my/package/... wildcards.
+ Set<String> parentFilters = Sets.newTreeSet();
+ String filterString = iterator.next();
+ PathFragment parent = PathFragment.create(filterString).getParentDirectory();
+ while (iterator.hasNext()) {
+ String current = iterator.next();
+ if (parent != null && parent.getPathString().length() > 0
+ && !current.startsWith(filterString) && current.startsWith(parent.getPathString())) {
+ parentFilters.add(parent.getPathString());
+ } else {
+ filterString = current;
+ parent = PathFragment.create(filterString).getParentDirectory();
+ }
+ }
+ packageFilters.addAll(parentFilters);
+
+ // Optimize away nested filters.
+ iterator = packageFilters.iterator();
+ String prev = iterator.next();
+ while (iterator.hasNext()) {
+ String current = iterator.next();
+ if (current.startsWith(prev)) {
+ iterator.remove();
+ } else {
+ prev = current;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommand.java
index 6be7ae1afe..c1f3fd094e 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommand.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.runtime;
-import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsProvider;
@@ -52,8 +51,6 @@ public interface BlazeCommand {
*
* @param env the command environment of the currently running command
* @param optionsParser the options parser for the current command
- *
- * @throws AbruptExitException if something went wrong
*/
- void editOptions(CommandEnvironment env, OptionsParser optionsParser) throws AbruptExitException;
+ void editOptions(CommandEnvironment env, OptionsParser optionsParser);
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/CoverageCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/CoverageCommand.java
index 833e01145d..aa9e703fd4 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/CoverageCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/CoverageCommand.java
@@ -13,35 +13,13 @@
// limitations under the License.
package com.google.devtools.build.lib.runtime.commands;
-import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.cmdline.TargetParsingException;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.packages.AttributeMap;
-import com.google.devtools.build.lib.packages.BuildType;
-import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
-import com.google.devtools.build.lib.packages.Rule;
-import com.google.devtools.build.lib.packages.Target;
-import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.TestTimeout;
-import com.google.devtools.build.lib.pkgcache.FilteringPolicies;
-import com.google.devtools.build.lib.pkgcache.TargetPatternEvaluator;
-import com.google.devtools.build.lib.runtime.BlazeRuntime;
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
-import com.google.devtools.build.lib.util.AbruptExitException;
-import com.google.devtools.build.lib.util.ExitCode;
-import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.common.options.OptionPriority;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.OptionsParsingException;
-import com.google.devtools.common.options.OptionsProvider;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.SortedSet;
/**
* Handles the 'coverage' command on the Bazel command line.
@@ -136,16 +114,13 @@ import java.util.SortedSet;
help = "resource:coverage.txt",
allowResidue = true)
public class CoverageCommand extends TestCommand {
- private boolean wasInterrupted = false;
-
@Override
protected String commandName() {
return "coverage";
}
@Override
- public void editOptions(CommandEnvironment env, OptionsParser optionsParser)
- throws AbruptExitException {
+ public void editOptions(CommandEnvironment env, OptionsParser optionsParser) {
super.editOptions(env, optionsParser);
try {
optionsParser.parse(OptionPriority.SOFTWARE_REQUIREMENT,
@@ -154,165 +129,9 @@ public class CoverageCommand extends TestCommand {
optionsParser.parse(OptionPriority.COMPUTED_DEFAULT,
"Options suggested for the coverage command",
ImmutableList.of(TestTimeout.COVERAGE_CMD_TIMEOUT));
- if (!optionsParser.containsExplicitOption("instrumentation_filter")) {
- setDefaultInstrumentationFilter(env, optionsParser);
- }
} catch (OptionsParsingException e) {
// Should never happen.
throw new IllegalStateException("Unexpected exception", e);
}
}
-
- @Override
- public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
- if (wasInterrupted) {
- wasInterrupted = false;
- env.getReporter().handle(Event.error("Interrupted"));
- return ExitCode.INTERRUPTED;
- }
-
- return super.exec(env, options);
- }
-
- /**
- * Method implements a heuristic used to set default value of the
- * --instrumentation_filter option. Following algorithm is used:
- * 1) Identify all test targets on the command line.
- * 2) Expand all test suites into the individual test targets
- * 3) Calculate list of package names containing all test targets above.
- * 4) Replace all "javatests/" substrings in package names with "java/".
- * 5) If two packages reside in the same directory, use filter based on
- * the parent directory name instead. Doing so significantly simplifies
- * instrumentation filter in majority of real-life scenarios (in
- * particular when dealing with my/package/... wildcards).
- * 6) Set --instrumentation_filter default value to instrument everything
- * in those packages.
- */
- private void setDefaultInstrumentationFilter(CommandEnvironment env,
- OptionsParser optionsProvider)
- throws OptionsParsingException, AbruptExitException {
- try {
- BlazeRuntime runtime = env.getRuntime();
- // Initialize package cache, since it is used by the TargetPatternEvaluator.
- // TODO(bazel-team): Don't allow commands to setup the package cache more than once per build.
- // We'll have to move it earlier in the process to allow this. Possibly: Move it to
- // the command dispatcher and allow commands to annotate "need-packages".
- env.setupPackageCache(optionsProvider, runtime.getDefaultsPackageContent(optionsProvider));
-
- // Collect all possible test targets. We don't really care whether there will be parsing
- // errors here - they will be reported during actual build.
- TargetPatternEvaluator targetPatternEvaluator = env.newTargetPatternEvaluator();
- Set<Target> testTargets =
- targetPatternEvaluator.parseTargetPatternList(
- env.getReporter(),
- optionsProvider.getResidue(),
- FilteringPolicies.FILTER_TESTS,
- /*keep_going=*/true).getTargets();
-
- SortedSet<String> packageFilters = Sets.newTreeSet();
- collectInstrumentedPackages(env, testTargets, packageFilters);
- optimizeFilterSet(packageFilters);
-
- String instrumentationFilter = "//" + Joiner.on(",//").join(packageFilters);
- final String instrumentationFilterOptionName = "instrumentation_filter";
- if (!packageFilters.isEmpty()) {
- env.getReporter().handle(
- Event.info("Using default value for --instrumentation_filter: \""
- + instrumentationFilter + "\"."));
-
- env.getReporter().handle(Event.info("Override the above default with --"
- + instrumentationFilterOptionName));
- optionsProvider.parse(OptionPriority.COMPUTED_DEFAULT,
- "Instrumentation filter heuristic",
- ImmutableList.of("--" + instrumentationFilterOptionName
- + "=" + instrumentationFilter));
- }
- } catch (TargetParsingException e) {
- // We can't compute heuristic - just use default filter.
- } catch (InterruptedException e) {
- // We cannot quit now because AbstractCommand does not have the
- // infrastructure to do that. Just set a flag and return from exec() as
- // early as possible. We can do this because there is always an exec()
- // after an editOptions().
- wasInterrupted = true;
- }
- }
-
- private void collectInstrumentedPackages(CommandEnvironment env,
- Collection<Target> targets, Set<String> packageFilters) throws InterruptedException {
- for (Target target : targets) {
- // Add package-based filters for every test target.
- String prefix = getInstrumentedPrefix(target.getLabel().getPackageName());
- if (!prefix.isEmpty()) {
- packageFilters.add(prefix);
- }
- if (TargetUtils.isTestSuiteRule(target)) {
- AttributeMap attributes = NonconfigurableAttributeMapper.of((Rule) target);
- // We don't need to handle $implicit_tests attribute since we already added
- // test_suite package to the set.
- for (Label label : attributes.get("tests", BuildType.LABEL_LIST)) {
- // Add package-based filters for all tests in the test suite.
- packageFilters.add(getInstrumentedPrefix(label.getPackageName()));
- }
- }
- }
- }
-
- /**
- * Returns prefix string that should be instrumented for a given package. Input string should
- * be formatted like the output of Label.getPackageName().
- * Generally, package name will be used as such string with two modifications.
- * - "javatests/ directories will be substituted with "java/", since we do
- * not want to instrument java test code. "java/" directories in "test/" will
- * be replaced by the same in "main/".
- * - "/internal", "/public", and "tests/" package suffix will be dropped, since usually we would
- * want to instrument code in the parent package as well
- */
- public static String getInstrumentedPrefix(String packageName) {
- if (packageName.endsWith("/internal")) {
- packageName = packageName.substring(0, packageName.length() - "/internal".length());
- } else if (packageName.endsWith("/public")) {
- packageName = packageName.substring(0, packageName.length() - "/public".length());
- } else if (packageName.endsWith("/tests")) {
- packageName = packageName.substring(0, packageName.length() - "/tests".length());
- }
- return packageName
- .replaceFirst("(?<=^|/)javatests/", "java/")
- .replaceFirst("(?<=^|/)test/java/", "main/java/");
- }
-
- private static void optimizeFilterSet(SortedSet<String> packageFilters) {
- Iterator<String> iterator = packageFilters.iterator();
- if (iterator.hasNext()) {
- // Find common parent filters to reduce number of filter expressions. In practice this
- // still produces nicely constrained instrumentation filter while making final
- // filter value much more user-friendly - especially in case of /my/package/... wildcards.
- Set<String> parentFilters = Sets.newTreeSet();
- String filterString = iterator.next();
- PathFragment parent = PathFragment.create(filterString).getParentDirectory();
- while (iterator.hasNext()) {
- String current = iterator.next();
- if (parent != null && parent.getPathString().length() > 0
- && !current.startsWith(filterString) && current.startsWith(parent.getPathString())) {
- parentFilters.add(parent.getPathString());
- } else {
- filterString = current;
- parent = PathFragment.create(filterString).getParentDirectory();
- }
- }
- packageFilters.addAll(parentFilters);
-
- // Optimize away nested filters.
- iterator = packageFilters.iterator();
- String prev = iterator.next();
- while (iterator.hasNext()) {
- String current = iterator.next();
- if (current.startsWith(prev)) {
- iterator.remove();
- } else {
- prev = current;
- }
- }
- }
- }
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/TestCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/TestCommand.java
index c1403703d4..1900517604 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/TestCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/TestCommand.java
@@ -16,9 +16,11 @@ package com.google.devtools.build.lib.runtime.commands;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.buildtool.BuildRequest;
import com.google.devtools.build.lib.buildtool.BuildResult;
import com.google.devtools.build.lib.buildtool.BuildTool;
+import com.google.devtools.build.lib.buildtool.InstrumentationFilterSupport;
import com.google.devtools.build.lib.buildtool.buildevent.TestingCompleteEvent;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.exec.ExecutionOptions;
@@ -34,7 +36,6 @@ import com.google.devtools.build.lib.runtime.TerminalTestResultNotifier;
import com.google.devtools.build.lib.runtime.TerminalTestResultNotifier.TestSummaryOptions;
import com.google.devtools.build.lib.runtime.TestResultAnalyzer;
import com.google.devtools.build.lib.runtime.TestResultNotifier;
-import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.util.io.AnsiTerminalPrinter;
import com.google.devtools.common.options.OptionPriority;
@@ -65,8 +66,7 @@ public class TestCommand implements BlazeCommand {
}
@Override
- public void editOptions(CommandEnvironment env, OptionsParser optionsParser)
- throws AbruptExitException {
+ public void editOptions(CommandEnvironment env, OptionsParser optionsParser) {
TestOutputFormat testOutput = optionsParser.getOptions(ExecutionOptions.class).testOutput;
try {
@@ -112,6 +112,11 @@ public class TestCommand implements BlazeCommand {
runtime.getStartupOptionsProvider(), targets,
env.getReporter().getOutErr(), env.getCommandId(), env.getCommandStartTime());
request.setRunTests();
+ if (options.getOptions(BuildConfiguration.Options.class).collectCodeCoverage
+ && !options.containsExplicitOption(
+ InstrumentationFilterSupport.INSTRUMENTATION_FILTER_FLAG)) {
+ request.setNeedsInstrumentationFilter(true);
+ }
BuildResult buildResult = new BuildTool(env).processRequest(request, null);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/mobileinstall/MobileInstallCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/mobileinstall/MobileInstallCommand.java
index 82791a126d..f4cd3a39fc 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/mobileinstall/MobileInstallCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/mobileinstall/MobileInstallCommand.java
@@ -27,7 +27,6 @@ import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.runtime.commands.BuildCommand;
import com.google.devtools.build.lib.runtime.commands.ProjectFileSupport;
-import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionPriority;
@@ -111,8 +110,7 @@ public class MobileInstallCommand implements BlazeCommand {
}
@Override
- public void editOptions(CommandEnvironment env, OptionsParser optionsParser)
- throws AbruptExitException {
+ public void editOptions(CommandEnvironment env, OptionsParser optionsParser) {
try {
if (optionsParser.getOptions(Options.class).v2) {
optionsParser.parse(