aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java b/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
new file mode 100644
index 0000000000..71cf9c4b5d
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/actions/ArtifactFactoryTest.java
@@ -0,0 +1,246 @@
+// Copyright 2015 Google Inc. 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.actions;
+
+
+import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.NULL_ACTION_OWNER;
+import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.NULL_ARTIFACT_OWNER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
+import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
+import com.google.devtools.build.lib.packages.PackageIdentifier;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.lib.vfs.util.FsApparatus;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Tests {@link ArtifactFactory}. Also see {@link ArtifactTest} for a test
+ * of individual artifacts.
+ */
+@RunWith(JUnit4.class)
+public class ArtifactFactoryTest {
+
+ private FsApparatus scratch = FsApparatus.newInMemory();
+
+ private Path execRoot;
+ private Root clientRoot;
+ private Root clientRoRoot;
+ private Root outRoot;
+
+ private PathFragment fooPath;
+ private PackageIdentifier fooPackage;
+ private PathFragment fooRelative;
+
+ private PathFragment barPath;
+ private PackageIdentifier barPackage;
+ private PathFragment barRelative;
+
+ private ArtifactFactory artifactFactory;
+
+ @Before
+ public void setUp() throws Exception {
+ execRoot = scratch.dir("/output/workspace");
+ clientRoot = Root.asSourceRoot(scratch.dir("/client/workspace"));
+ clientRoRoot = Root.asSourceRoot(scratch.dir("/client/RO/workspace"));
+ outRoot = Root.asDerivedRoot(execRoot, execRoot.getRelative("out-root/x/bin"));
+
+ fooPath = new PathFragment("foo");
+ fooPackage = PackageIdentifier.createInDefaultRepo(fooPath);
+ fooRelative = fooPath.getRelative("foosource.txt");
+
+ barPath = new PathFragment("foo/bar");
+ barPackage = PackageIdentifier.createInDefaultRepo(barPath);
+ barRelative = barPath.getRelative("barsource.txt");
+
+ artifactFactory = new ArtifactFactory(execRoot);
+ setupRoots();
+ }
+
+ private void setupRoots() {
+ Map<PackageIdentifier, Root> packageRootMap = new HashMap<>();
+ packageRootMap.put(fooPackage, clientRoot);
+ packageRootMap.put(barPackage, clientRoRoot);
+ artifactFactory.setPackageRoots(packageRootMap);
+ artifactFactory.setDerivedArtifactRoots(ImmutableList.of(outRoot));
+ }
+
+ @Test
+ public void testGetSourceArtifactYieldsSameArtifact() throws Exception {
+ assertSame(artifactFactory.getSourceArtifact(fooRelative, clientRoot),
+ artifactFactory.getSourceArtifact(fooRelative, clientRoot));
+ }
+
+ @Test
+ public void testGetSourceArtifactUnnormalized() throws Exception {
+ assertSame(artifactFactory.getSourceArtifact(fooRelative, clientRoot),
+ artifactFactory.getSourceArtifact(new PathFragment("foo/./foosource.txt"),
+ clientRoot));
+ }
+
+ @Test
+ public void testResolveArtifact_noDerived_simpleSource() throws Exception {
+ assertSame(artifactFactory.getSourceArtifact(fooRelative, clientRoot),
+ artifactFactory.resolveSourceArtifact(fooRelative));
+ assertSame(artifactFactory.getSourceArtifact(barRelative, clientRoRoot),
+ artifactFactory.resolveSourceArtifact(barRelative));
+ }
+
+ @Test
+ public void testResolveArtifact_noDerived_derivedRoot() throws Exception {
+ assertNull(artifactFactory.resolveSourceArtifact(
+ outRoot.getPath().getRelative(fooRelative).relativeTo(execRoot)));
+ assertNull(artifactFactory.resolveSourceArtifact(
+ outRoot.getPath().getRelative(barRelative).relativeTo(execRoot)));
+ }
+
+ @Test
+ public void testResolveArtifact_noDerived_simpleSource_other() throws Exception {
+ Artifact actual = artifactFactory.resolveSourceArtifact(fooRelative);
+ assertSame(artifactFactory.getSourceArtifact(fooRelative, clientRoot), actual);
+ actual = artifactFactory.resolveSourceArtifact(barRelative);
+ assertSame(artifactFactory.getSourceArtifact(barRelative, clientRoRoot), actual);
+ }
+
+ @Test
+ public void testClearResetsFactory() {
+ Artifact fooArtifact = artifactFactory.getSourceArtifact(fooRelative, clientRoot);
+ artifactFactory.clear();
+ setupRoots();
+ assertNotSame(fooArtifact, artifactFactory.getSourceArtifact(fooRelative, clientRoot));
+ }
+
+ @Test
+ public void testFindDerivedRoot() throws Exception {
+ assertSame(outRoot,
+ artifactFactory.findDerivedRoot(outRoot.getPath().getRelative(fooRelative)));
+ assertSame(outRoot,
+ artifactFactory.findDerivedRoot(outRoot.getPath().getRelative(barRelative)));
+ }
+
+ @Test
+ public void testSetGeneratingActionIdempotenceNewActionGraph() throws Exception {
+ Artifact a = artifactFactory.getDerivedArtifact(fooRelative, outRoot, NULL_ARTIFACT_OWNER);
+ Artifact b = artifactFactory.getDerivedArtifact(barRelative, outRoot, NULL_ARTIFACT_OWNER);
+ MutableActionGraph actionGraph = new MapBasedActionGraph();
+ Action originalAction = new ActionsTestUtil.NullAction(NULL_ACTION_OWNER, a);
+ actionGraph.registerAction(originalAction);
+
+ // Creating a second Action referring to the Artifact should create a conflict.
+ try {
+ Action action = new ActionsTestUtil.NullAction(NULL_ACTION_OWNER, a, b);
+ actionGraph.registerAction(action);
+ fail();
+ } catch (ActionConflictException e) {
+ assertSame(a, e.getArtifact());
+ assertSame(originalAction, actionGraph.getGeneratingAction(a));
+ }
+ }
+
+ @Test
+ public void testGetDerivedArtifact() throws Exception {
+ PathFragment toolPath = new PathFragment("_bin/tool");
+ Artifact artifact = artifactFactory.getDerivedArtifact(toolPath);
+ assertEquals(toolPath, artifact.getExecPath());
+ assertEquals(Root.asDerivedRoot(execRoot), artifact.getRoot());
+ assertEquals(execRoot.getRelative(toolPath), artifact.getPath());
+ assertNull(artifact.getOwner());
+ }
+
+ @Test
+ public void testGetDerivedArtifactFailsForAbsolutePath() throws Exception {
+ try {
+ artifactFactory.getDerivedArtifact(new PathFragment("/_bin/b"));
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected exception
+ }
+ }
+
+ private static class MockPackageRootResolver implements PackageRootResolver {
+ private Map<PathFragment, Root> packageRoots = Maps.newHashMap();
+
+ public void setPackageRoots(Map<PackageIdentifier, Root> packageRoots) {
+ for (Entry<PackageIdentifier, Root> packageRoot : packageRoots.entrySet()) {
+ this.packageRoots.put(packageRoot.getKey().getPackageFragment(), packageRoot.getValue());
+ }
+ }
+
+ @Override
+ public Map<PathFragment, Root> findPackageRoots(Iterable<PathFragment> execPaths) {
+ Map<PathFragment, Root> result = new HashMap<>();
+ for (PathFragment execPath : execPaths) {
+ for (PathFragment dir = execPath.getParentDirectory(); dir != null;
+ dir = dir.getParentDirectory()) {
+ if (packageRoots.get(dir) != null) {
+ result.put(execPath, packageRoots.get(dir));
+ }
+ }
+ if (result.get(execPath) == null) {
+ result.put(execPath, null);
+ }
+ }
+ return result;
+ }
+ }
+
+ @Test
+ public void testArtifactDeserializationWithoutReusedArtifacts() throws Exception {
+ PathFragment derivedPath = outRoot.getExecPath().getRelative("fruit/banana");
+ artifactFactory.clear();
+ artifactFactory.setDerivedArtifactRoots(ImmutableList.of(outRoot));
+ MockPackageRootResolver rootResolver = new MockPackageRootResolver();
+ rootResolver.setPackageRoots(
+ ImmutableMap.of(PackageIdentifier.createInDefaultRepo(""), clientRoot));
+ Artifact artifact1 = artifactFactory.deserializeArtifact(derivedPath, rootResolver);
+ Artifact artifact2 = artifactFactory.deserializeArtifact(derivedPath, rootResolver);
+ assertEquals(artifact1, artifact2);
+ assertNull(artifact1.getOwner());
+ assertNull(artifact2.getOwner());
+ assertEquals(derivedPath, artifact1.getExecPath());
+ assertEquals(derivedPath, artifact2.getExecPath());
+
+ // Source artifacts are always reused
+ PathFragment sourcePath = clientRoot.getExecPath().getRelative("fruit/mango");
+ artifact1 = artifactFactory.deserializeArtifact(sourcePath, rootResolver);
+ artifact2 = artifactFactory.deserializeArtifact(sourcePath, rootResolver);
+ assertSame(artifact1, artifact2);
+ assertEquals(sourcePath, artifact1.getExecPath());
+ }
+
+ @Test
+ public void testDeserializationWithInvalidPath() throws Exception {
+ artifactFactory.clear();
+ PathFragment randomPath = new PathFragment("maracuja/lemon/kiwi");
+ Artifact artifact = artifactFactory.deserializeArtifact(randomPath,
+ new MockPackageRootResolver());
+ assertNull(artifact);
+ }
+}