diff options
author | shreyax <shreyax@google.com> | 2018-02-23 07:46:54 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-02-23 07:48:26 -0800 |
commit | 246f0aa048aeb3f456c89565e1e3021957b6cef4 (patch) | |
tree | fbc8d8d8d81df14587a377b3b9b897382c88c1d9 /src/test | |
parent | f0c7c4650d874d31a4ef97df191a743445c0463d (diff) |
Automated rollback of commit 7fe59b98eefc96a6310f0b0221d4e0f18e2a9000.
*** Reason for rollback ***
Fixed bug due to TransitiveTargetFunction requesting multiple Package dependencies when computing its aspect deps by only applying the optimization to TransitiveTraversalFunction.
*** Original change description ***
Automated rollback of commit cce164aed44aba1de244f0d764cd33a5cc6980b2.
PiperOrigin-RevId: 186766812
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunctionTest.java | 109 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java | 28 |
2 files changed, 137 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunctionTest.java new file mode 100644 index 0000000000..80a07e0b8b --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalFunctionTest.java @@ -0,0 +1,109 @@ +// Copyright 2018 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.skyframe; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.packages.NoSuchPackageException; +import com.google.devtools.build.lib.packages.NoSuchTargetException; +import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.skyframe.TransitiveBaseTraversalFunction.TargetAndErrorIfAnyImpl; +import com.google.devtools.build.lib.util.GroupedList; +import com.google.devtools.build.lib.util.GroupedList.GroupedListHelper; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyKey; +import java.util.concurrent.atomic.AtomicBoolean; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mockito; + +/** Test for {@link TransitiveTraversalFunction}. */ +@RunWith(JUnit4.class) +public class TransitiveTraversalFunctionTest extends BuildViewTestCase { + + @Test + public void noRepeatedLabelVisitationForTransitiveTraversalFunction() throws Exception { + // Create a basic package with a target //foo:foo. + Label label = Label.parseAbsolute("//foo:foo"); + Package pkg = + scratchPackage( + "workspace", + label.getPackageIdentifier(), + "sh_library(name = '" + label.getName() + "')"); + TargetAndErrorIfAnyImpl targetAndErrorIfAny = + new TargetAndErrorIfAnyImpl( + /*packageLoadedSuccessfully=*/ true, + /*errorLoadingTarget=*/ null, + pkg.getTarget(label.getName())); + TransitiveTraversalFunction function = + new TransitiveTraversalFunction() { + @Override + LoadTargetResults loadTarget(Environment env, Label label) { + return targetAndErrorIfAny; + } + }; + // Create the GroupedList saying we had already requested two targets the last time we called + // #compute. + GroupedListHelper<SkyKey> helper = new GroupedListHelper<>(); + SkyKey fakeDep1 = function.getKey(Label.parseAbsolute("//foo:bar")); + SkyKey fakeDep2 = function.getKey(Label.parseAbsolute("//foo:baz")); + helper.add(TargetMarkerValue.key(label)); + helper.add(PackageValue.key(label.getPackageIdentifier())); + helper.startGroup(); + // Note that these targets don't actually exist in the package we created initially. It doesn't + // matter for the purpose of this test, the original package was just to create some objects + // that we needed. + helper.add(fakeDep1); + helper.add(fakeDep2); + helper.endGroup(); + GroupedList<SkyKey> groupedList = new GroupedList<>(); + groupedList.append(helper); + AtomicBoolean wasOptimizationUsed = new AtomicBoolean(false); + SkyFunction.Environment mockEnv = Mockito.mock(SkyFunction.Environment.class); + when(mockEnv.getTemporaryDirectDeps()).thenReturn(groupedList); + when(mockEnv.getValuesOrThrow( + groupedList.get(2), NoSuchPackageException.class, NoSuchTargetException.class)) + .thenAnswer( + (invocationOnMock) -> { + wasOptimizationUsed.set(true); + // It doesn't matter what this map is, we'll return false in the valuesMissing() call. + return ImmutableMap.of(); + }); + when(mockEnv.valuesMissing()).thenReturn(true); + + // Run the compute function and check that we returned null. + assertThat(function.compute(function.getKey(label), mockEnv)).isNull(); + + // Verify that the mock was called with the arguments we expected. + assertThat(wasOptimizationUsed.get()).isTrue(); + } + + private Package scratchPackage(String workspaceName, PackageIdentifier packageId, String... lines) + throws Exception { + Path buildFile = scratch.file("" + packageId.getSourceRoot() + "/BUILD", lines); + Package.Builder externalPkg = + Package.newExternalPackageBuilder( + Package.Builder.DefaultHelper.INSTANCE, buildFile.getRelative("WORKSPACE"), "TESTING"); + externalPkg.setWorkspaceName(workspaceName); + return pkgFactory.createPackageForTesting( + packageId, externalPkg.build(), buildFile, packageIdentifier -> buildFile, reporter); + } +} diff --git a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java index 0b1ed3561e..b1518fc3b9 100644 --- a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java +++ b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java @@ -53,6 +53,7 @@ import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -214,6 +215,33 @@ public class MemoizingEvaluatorTest { } @Test + public void testEnvProvidesTemporaryDirectDeps() throws Exception { + AtomicInteger counter = new AtomicInteger(); + List<SkyKey> deps = Collections.synchronizedList(new ArrayList<>()); + SkyKey topKey = toSkyKey("top"); + SkyKey bottomKey = toSkyKey("bottom"); + SkyValue bottomValue = new StringValue("bottom"); + tester + .getOrCreate(topKey) + .setBuilder( + new NoExtractorFunction() { + @Override + public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { + if (counter.getAndIncrement() > 0) { + deps.addAll(env.getTemporaryDirectDeps().get(0)); + } else { + assertThat(env.getTemporaryDirectDeps().listSize()).isEqualTo(0); + } + return env.getValue(bottomKey); + } + }); + tester.getOrCreate(bottomKey).setConstantValue(bottomValue); + EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/ true, "top"); + assertThat(result.get(topKey)).isEqualTo(bottomValue); + assertThat(deps).containsExactly(bottomKey); + } + + @Test public void cachedErrorShutsDownThreadpool() throws Exception { // When a node throws an error on the first build, SkyKey cachedErrorKey = GraphTester.skyKey("error"); |