Skip to content

Commit

Permalink
Properly report loading errors during configuration creation.
Browse files Browse the repository at this point in the history
This only applies to interleaved loading and analysis - the production code
is fine.

Add tests for the RedirectChaser, the fdoOptimize code path, the XcodeConfig,
and the Jvm loader. Unfortunately, the configuration factory we internally
create by default contains a mock Jvm loader implementation. Since that is one
Yak too many right now, I'm adding a temporary method to the AnalysisMock.

I added the tests to BuildViewTest for now; technically, they ought to go
into the language-specific test cases, but that would require more refactoring
as those don't currently run with interleaved loading and analysis.

--
MOS_MIGRATED_REVID=114221476
  • Loading branch information
ulfjack authored and dslomov committed Feb 10, 2016
1 parent bf3dc4c commit 3e34a11
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.AbstractAttributeMapper;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
Expand Down Expand Up @@ -100,8 +101,10 @@ public static Label followRedirects(ConfigurationEnvironment env, Label label, S
}
}
} catch (NoSuchPackageException e) {
env.getEventHandler().handle(Event.error(e.getMessage()));
throw new InvalidConfigurationException(e.getMessage(), e);
} catch (NoSuchTargetException e) {
// TODO(ulfjack): Consider throwing an exception here instead of returning silently.
return label;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
*/
public interface ConfigurationEnvironment {

/**
* Returns an event handler to report errors to. Note that reporting an error does not cause the
* computation to abort - you also need to throw an exception.
*/
EventHandler getEventHandler();

/**
* Returns a target for the given label, loading it if necessary, and throwing an exception if it
* does not exist.
Expand Down Expand Up @@ -73,6 +79,11 @@ public TargetProviderEnvironment(PackageProvider packageProvider,
this(packageProvider, eventHandler, null);
}

@Override
public EventHandler getEventHandler() {
return packageProvider.getEventHandler();
}

@Override
public Target getTarget(final Label label)
throws NoSuchPackageException, NoSuchTargetException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
Expand All @@ -28,6 +29,8 @@
* A variant of PackageProvider which is used during a creation of BuildConfiguration.Fragments.
*/
public interface PackageProviderForConfigurations {
EventHandler getEventHandler();

/**
* Adds dependency to fileName if needed. Used only in skyframe, for creating correct dependencies
* for {@link com.google.devtools.build.lib.skyframe.ConfigurationCollectionValue}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib:cmdline",
"//src/main/java/com/google/devtools/build/lib:common",
"//src/main/java/com/google/devtools/build/lib:concurrent",
"//src/main/java/com/google/devtools/build/lib:events",
"//src/main/java/com/google/devtools/build/lib:packages-internal",
"//src/main/java/com/google/devtools/build/lib:preconditions",
"//src/main/java/com/google/devtools/build/lib:shell",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
Expand Down Expand Up @@ -206,6 +207,7 @@ private static Rule getRuleForLabel(Label label, String type, ConfigurationEnvir
description, label, type));
}
} catch (NoSuchPackageException | NoSuchTargetException exception) {
env.getEventHandler().handle(Event.error(exception.getMessage()));
throw new InvalidConfigurationException(exception);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.InputFile;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
Expand Down Expand Up @@ -156,6 +157,7 @@ protected CppConfigurationParameters createParameters(
"The --fdo_optimize parameter you specified resolves to a file that does not exist");
}
} catch (NoSuchPackageException | NoSuchTargetException | LabelSyntaxException e) {
env.getEventHandler().handle(Event.error(e.getMessage()));
throw new InvalidConfigurationException(e);
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
Expand Down Expand Up @@ -157,10 +158,9 @@ private Jvm createDefault(ConfigurationEnvironment lookup, String javaHome, Stri
}
throw new InvalidConfigurationException("No JVM target found under " + javaHome
+ " that would work for " + cpu);
} catch (NoSuchPackageException e) {
} catch (NoSuchPackageException | NoSuchTargetException e) {
lookup.getEventHandler().handle(Event.error(e.getMessage()));
throw new InvalidConfigurationException(e.getMessage(), e);
} catch (NoSuchTargetException e) {
throw new InvalidConfigurationException("No such target: " + e.getMessage(), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.devtools.build.lib.analysis.config.PackageProviderForConfigurations;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
Expand Down Expand Up @@ -105,6 +106,11 @@ private final class ConfigurationBuilderEnvironment implements ConfigurationEnvi
this.packageProvider = packageProvider;
}

@Override
public EventHandler getEventHandler() {
return packageProvider.getEventHandler();
}

@Override
public Target getTarget(Label label) throws NoSuchPackageException, NoSuchTargetException {
return packageProvider.getTarget(label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Package;
Expand Down Expand Up @@ -49,6 +50,11 @@ public SkyframePackageLoaderWithValueEnvironment(SkyFunction.Environment env,
this.ruleClassProvider = ruleClassProvider;
}

@Override
public EventHandler getEventHandler() {
return env.getListener();
}

private Package getPackage(final PackageIdentifier pkgIdentifier)
throws NoSuchPackageException {
SkyKey key = PackageValue.key(pkgIdentifier);
Expand All @@ -60,8 +66,7 @@ private Package getPackage(final PackageIdentifier pkgIdentifier)
}

@Override
public Target getTarget(Label label) throws NoSuchPackageException,
NoSuchTargetException {
public Target getTarget(Label label) throws NoSuchPackageException, NoSuchTargetException {
Package pkg = getPackage(label.getPackageIdentifier());
return pkg == null ? null : pkg.getTarget(label.getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import com.google.devtools.build.lib.actions.FailAction;
import com.google.devtools.build.lib.analysis.BuildView.AnalysisResult;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.analysis.util.AnalysisMock;
import com.google.devtools.build.lib.analysis.util.AnalysisTestCase.Flag;
import com.google.devtools.build.lib.analysis.util.BuildViewTestBase;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.Aspect;
Expand All @@ -47,6 +49,7 @@
import com.google.devtools.build.lib.skyframe.SkyFunctions;
import com.google.devtools.build.lib.skyframe.TargetPatternValue.TargetPatternKey;
import com.google.devtools.build.lib.testutil.Suite;
import com.google.devtools.build.lib.testutil.TestConstants;
import com.google.devtools.build.lib.testutil.TestSpec;
import com.google.devtools.build.lib.testutil.TestUtils;
import com.google.devtools.build.lib.util.Pair;
Expand Down Expand Up @@ -1032,6 +1035,77 @@ public void testMissingLabelInConfiguration() throws Exception {
"no such target '//nobuild:bar': target 'bar' not declared in package 'nobuild'", 1);
}

@Test
public void testBadLabelInConfiguration() throws Exception {
useConfiguration("--crosstool_top=//third_party/crosstool/v2");
reporter.removeHandler(failFastHandler);
try {
update(defaultFlags().with(Flag.KEEP_GOING));
fail();
} catch (LoadingFailedException | InvalidConfigurationException e) {
assertContainsEvent(
"no such package 'third_party/crosstool/v2': BUILD file not found on package path");
}
}

@Test
public void testMissingFdoOptimize() throws Exception {
// The fdo_optimize flag uses a different code path, because it also accepts paths.
useConfiguration("--fdo_optimize=//does/not/exist");
reporter.removeHandler(failFastHandler);
try {
update(defaultFlags().with(Flag.KEEP_GOING));
fail();
} catch (LoadingFailedException | InvalidConfigurationException e) {
assertContainsEvent(
"no such package 'does/not/exist': BUILD file not found on package path");
}
}

@Test
public void testMissingJavabase() throws Exception {
// The javabase flag uses yet another code path with its own redirection logic on top of the
// redirect chaser.
scratch.file("jdk/BUILD",
"filegroup(name = 'jdk', srcs = [",
" '//does/not/exist:a-piii', '//does/not/exist:b-k8', '//does/not/exist:c-default'])");
scratch.file("does/not/exist/BUILD");
useConfigurationFactory(AnalysisMock.get().createFullConfigurationFactory());
useConfiguration("--javabase=//jdk");
reporter.removeHandler(failFastHandler);
try {
update(defaultFlags().with(Flag.KEEP_GOING));
fail();
} catch (LoadingFailedException | InvalidConfigurationException e) {
if (TestConstants.THIS_IS_BAZEL) {
// TODO(ulfjack): Bazel ignores the --cpu setting and just uses "default" instead. This
// means all cross-platform Java builds are broken for checked-in JDKs.
assertContainsEvent(
"no such target '//does/not/exist:c-default': target 'c-default' not declared in");
} else {
assertContainsEvent(
"no such target '//does/not/exist:b-k8': target 'b-k8' not declared in package");
}
}
}

@Test
public void testMissingXcodeVersion() throws Exception {
// The xcode_version flag uses yet another code path on top of the redirect chaser.
// Note that the redirect chaser throws if it can't find a package, but doesn't throw if it
// can't find a label in a package - that's why we use an empty package here.
scratch.file("xcode/BUILD");
useConfiguration("--xcode_version=1.2", "--xcode_version_config=//xcode:does_not_exist");
reporter.removeHandler(failFastHandler);
try {
update(defaultFlags().with(Flag.KEEP_GOING));
fail();
} catch (LoadingFailedException | InvalidConfigurationException e) {
assertContainsEvent(
"no such target '//xcode:does_not_exist': target 'does_not_exist' not declared");
}
}

/** Runs the same test with the reduced loading phase. */
@TestSpec(size = Suite.SMALL_TESTS)
@RunWith(JUnit4.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ public ConfigurationFactory createConfigurationFactory() {
new AndroidConfiguration.Loader());
}

@Override
public ConfigurationFactory createFullConfigurationFactory() {
return createConfigurationFactory();
}

@Override
public ConfigurationCollectionFactory createConfigurationCollectionFactory() {
return new BazelConfigurationCollection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ public static AnalysisMock get() {

public abstract ConfigurationFactory createConfigurationFactory();

/**
* Creates a configuration factory that doesn't contain any mock parts.
*/
public abstract ConfigurationFactory createFullConfigurationFactory();

public abstract ConfigurationCollectionFactory createConfigurationCollectionFactory();

public abstract Collection<String> getOptionOverrides();
Expand Down Expand Up @@ -110,6 +115,11 @@ public ConfigurationFactory createConfigurationFactory() {
return delegate.createConfigurationFactory();
}

@Override
public ConfigurationFactory createFullConfigurationFactory() {
return delegate.createFullConfigurationFactory();
}

@Override
public ConfigurationCollectionFactory createConfigurationCollectionFactory() {
return delegate.createConfigurationCollectionFactory();
Expand Down

0 comments on commit 3e34a11

Please sign in to comment.