diff options
author | Ulf Adams <ulfjack@google.com> | 2016-02-01 20:27:13 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2016-02-02 14:57:36 +0000 |
commit | 4ecd05ed16ce58f755e0aa711461c165056c1aeb (patch) | |
tree | c0851619e335d986495ba2275fac51c9eabf64c1 /src | |
parent | d5ef2b4956619c44c9d17ac097857508e4d53b40 (diff) |
Move tests from SkyframeLoadingAndAnalysisTest to LoadingPhaseRunnerTest.
This exposes an issue with the new Skyframe-based implementation, which is
fixed here as well.
--
MOS_MIGRATED_REVID=113556169
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java | 12 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java | 51 |
2 files changed, 62 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index bfc7fb3453..f60b333036 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -1760,9 +1760,19 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { ImmutableList.of(key), keepGoing, /*numThreads=*/10, eventHandler); if (evalResult.hasError()) { ErrorInfo errorInfo = evalResult.getError(key); - if (errorInfo != null && errorInfo.getException() != null) { + if (!Iterables.isEmpty(errorInfo.getCycleInfo())) { + String errorMessage = "cycles detected during target parsing"; + getCyclesReporter().reportCycles(errorInfo.getCycleInfo(), key, eventHandler); + throw new TargetParsingException(errorMessage); + } + if (errorInfo.getException() != null) { Exception e = errorInfo.getException(); Throwables.propagateIfInstanceOf(e, TargetParsingException.class); + if (!keepGoing) { + // This is the same code as in SkyframeTargetPatternEvaluator; we allow any exception + // and turn it into a TargetParsingException here. + throw new TargetParsingException(e.getMessage()); + } throw new IllegalStateException("Unexpected Exception type from TargetPatternPhaseValue " + "for '" + targetPatterns + "'' with root causes: " + Iterables.toString(errorInfo.getRootCauses()), e); diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java index 74d27fc629..f933199b2f 100644 --- a/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java +++ b/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import com.google.common.base.Functions; import com.google.common.base.Joiner; @@ -34,6 +35,7 @@ import com.google.devtools.build.lib.analysis.BuildView; import com.google.devtools.build.lib.analysis.util.AnalysisMock; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.cmdline.TargetParsingException; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.EventKind; import com.google.devtools.build.lib.events.StoredEventHandler; @@ -448,6 +450,55 @@ public class LoadingPhaseRunnerTest { .containsExactly("//foo:a.y", "//foo:b.y"); } + /** Regression test: handle symlink cycles gracefully. */ + @Test + public void testCycleReporting_SymlinkCycleDuringTargetParsing() throws Exception { + tester.addFile("hello/BUILD", "cc_library(name = 'a', srcs = glob(['*.cc']))"); + Path buildFilePath = tester.getWorkspace().getRelative("hello/BUILD"); + Path dirPath = buildFilePath.getParentDirectory(); + Path fooFilePath = dirPath.getRelative("foo.cc"); + Path barFilePath = dirPath.getRelative("bar.cc"); + Path bazFilePath = dirPath.getRelative("baz.cc"); + fooFilePath.createSymbolicLink(barFilePath); + barFilePath.createSymbolicLink(bazFilePath); + bazFilePath.createSymbolicLink(fooFilePath); + assertCircularSymlinksDuringTargetParsing("//hello:a"); + } + + @Test + public void testRecursivePatternWithCircularSymlink() throws Exception { + tester.getWorkspace().getChild("broken").createDirectory(); + + // Create a circular symlink. + tester.getWorkspace().getRelative(new PathFragment("broken/BUILD")) + .createSymbolicLink(new PathFragment("BUILD")); + + assertCircularSymlinksDuringTargetParsing("//broken/..."); + } + + @Test + public void testRecursivePatternWithTwoCircularSymlinks() throws Exception { + tester.getWorkspace().getChild("broken").createDirectory(); + + // Create a circular symlink. + tester.getWorkspace().getRelative(new PathFragment("broken/BUILD")) + .createSymbolicLink(new PathFragment("x")); + tester.getWorkspace().getRelative(new PathFragment("broken/x")) + .createSymbolicLink(new PathFragment("BUILD")); + + assertCircularSymlinksDuringTargetParsing("//broken/..."); + } + + private void assertCircularSymlinksDuringTargetParsing(String targetPattern) throws Exception { + try { + tester.load(targetPattern); + fail(); + } catch (TargetParsingException e) { + // Expected. + tester.assertContainsError("circular symlinks detected"); + } + } + private LoadingResult assertNoErrors(LoadingResult loadingResult) { assertFalse(loadingResult.hasTargetPatternError()); assertFalse(loadingResult.hasLoadingError()); |