blob: f8a2d675f86dd92763acac36a0c4bf8562e3036a [file] [log] [blame]
Ulf Adamsc0a84442017-03-21 10:08:03 +00001// Copyright 2017 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package com.google.devtools.build.lib.exec;
15
16import static com.google.common.truth.Truth.assertThat;
fellyf6408d62019-07-16 12:51:14 -070017import static com.google.devtools.build.lib.actions.FilesetManifest.RelativeSymlinkBehavior.ERROR;
18import static com.google.devtools.build.lib.actions.FilesetManifest.RelativeSymlinkBehavior.IGNORE;
19import static com.google.devtools.build.lib.actions.FilesetManifest.RelativeSymlinkBehavior.RESOLVE;
michajlo660d17f2020-03-27 09:01:57 -070020import static org.junit.Assert.assertThrows;
Ulf Adamsc0a84442017-03-21 10:08:03 +000021import static org.junit.Assert.fail;
22
ulfjack1973be42018-05-30 03:25:35 -070023import com.google.common.collect.ImmutableList;
24import com.google.common.collect.ImmutableMap;
Ulf Adamsc0a84442017-03-21 10:08:03 +000025import com.google.devtools.build.lib.actions.ActionInput;
Ulf Adamsc0a84442017-03-21 10:08:03 +000026import com.google.devtools.build.lib.actions.ActionInputHelper;
27import com.google.devtools.build.lib.actions.Artifact;
buchgrd4d3d502018-08-02 06:47:19 -070028import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
29import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
30import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType;
31import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
tomlu1cdcdf92018-01-16 11:07:51 -080032import com.google.devtools.build.lib.actions.ArtifactRoot;
Ulf Adamsc0a84442017-03-21 10:08:03 +000033import com.google.devtools.build.lib.actions.EmptyRunfilesSupplier;
shahan602cc852018-06-06 20:09:57 -070034import com.google.devtools.build.lib.actions.FileArtifactValue;
ulfjack1973be42018-05-30 03:25:35 -070035import com.google.devtools.build.lib.actions.FilesetOutputSymlink;
Ulf Adamsc0a84442017-03-21 10:08:03 +000036import com.google.devtools.build.lib.actions.RunfilesSupplier;
buchgrd4d3d502018-08-02 06:47:19 -070037import com.google.devtools.build.lib.actions.Spawn;
janakraea05602019-05-22 15:41:29 -070038import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
Ulf Adamsc0a84442017-03-21 10:08:03 +000039import com.google.devtools.build.lib.analysis.Runfiles;
40import com.google.devtools.build.lib.analysis.RunfilesSupplierImpl;
ulfjack3903c922017-07-06 04:30:34 -040041import com.google.devtools.build.lib.exec.util.FakeActionInputFileCache;
buchgrd4d3d502018-08-02 06:47:19 -070042import com.google.devtools.build.lib.exec.util.SpawnBuilder;
janakr97c0bd12020-09-08 13:19:03 -070043import com.google.devtools.build.lib.vfs.DigestHashFunction;
Ulf Adamsc0a84442017-03-21 10:08:03 +000044import com.google.devtools.build.lib.vfs.FileSystem;
45import com.google.devtools.build.lib.vfs.FileSystemUtils;
46import com.google.devtools.build.lib.vfs.Path;
47import com.google.devtools.build.lib.vfs.PathFragment;
tomluee6a6862018-01-17 14:36:26 -080048import com.google.devtools.build.lib.vfs.Root;
Ulf Adamsc0a84442017-03-21 10:08:03 +000049import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
50import java.io.IOException;
buchgrd4d3d502018-08-02 06:47:19 -070051import java.util.Arrays;
52import java.util.Collection;
ulfjack1973be42018-05-30 03:25:35 -070053import java.util.HashMap;
Ulf Adamsc0a84442017-03-21 10:08:03 +000054import java.util.Map;
Ulf Adamsc0a84442017-03-21 10:08:03 +000055import org.junit.Test;
56import org.junit.runner.RunWith;
57import org.junit.runners.JUnit4;
Ulf Adamsc0a84442017-03-21 10:08:03 +000058
buchgrd4d3d502018-08-02 06:47:19 -070059/** Tests for {@link SpawnInputExpander}. */
Ulf Adamsc0a84442017-03-21 10:08:03 +000060@RunWith(JUnit4.class)
61public class SpawnInputExpanderTest {
ulfjack3903c922017-07-06 04:30:34 -040062 private static final byte[] FAKE_DIGEST = new byte[] {1, 2, 3, 4};
63
buchgrd4d3d502018-08-02 06:47:19 -070064 private static final ArtifactExpander NO_ARTIFACT_EXPANDER =
65 (a, b) -> fail("expected no interactions");
66
janakr97c0bd12020-09-08 13:19:03 -070067 private final FileSystem fs = new InMemoryFileSystem(DigestHashFunction.SHA256);
Googler12498fd2018-10-10 10:47:00 -070068 private final Path execRoot = fs.getPath("/root");
janakr448f1cf2020-03-30 09:12:44 -070069 private final ArtifactRoot rootDir = ArtifactRoot.asDerivedRoot(execRoot, "out");
Ulf Adamsc0a84442017-03-21 10:08:03 +000070
Googler12498fd2018-10-10 10:47:00 -070071 private SpawnInputExpander expander = new SpawnInputExpander(execRoot, /*strict=*/ true);
72 private Map<PathFragment, ActionInput> inputMappings = new HashMap<>();
Ulf Adamsc0a84442017-03-21 10:08:03 +000073
74 @Test
75 public void testEmptyRunfiles() throws Exception {
76 RunfilesSupplier supplier = EmptyRunfilesSupplier.INSTANCE;
buchgrd4d3d502018-08-02 06:47:19 -070077 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
twerthc4dfb912020-07-20 10:32:42 -070078 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER);
Ulf Adamsc0a84442017-03-21 10:08:03 +000079 assertThat(inputMappings).isEmpty();
80 }
81
82 @Test
83 public void testRunfilesSingleFile() throws Exception {
84 Artifact artifact =
janakraea05602019-05-22 15:41:29 -070085 ActionsTestUtil.createArtifact(
86 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
87 fs.getPath("/root/dir/file"));
Ulf Adamsc0a84442017-03-21 10:08:03 +000088 Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
nharmatab4060b62017-04-04 17:11:39 +000089 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
ulfjack3903c922017-07-06 04:30:34 -040090 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
janakr39969b12019-03-03 16:25:48 -080091 mockCache.put(
92 artifact,
lberki812e6fe2019-07-25 07:50:55 -070093 FileArtifactValue.createForNormalFile(
janakr39969b12019-03-03 16:25:48 -080094 FAKE_DIGEST, /*proxy=*/ null, 0L, /*isShareable=*/ true));
Ulf Adamsc0a84442017-03-21 10:08:03 +000095
twerthc4dfb912020-07-20 10:32:42 -070096 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER);
Ulf Adamsc0a84442017-03-21 10:08:03 +000097 assertThat(inputMappings).hasSize(1);
98 assertThat(inputMappings)
nharmatab4060b62017-04-04 17:11:39 +000099 .containsEntry(PathFragment.create("runfiles/workspace/dir/file"), artifact);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000100 }
101
102 @Test
felly99ad9b92019-06-12 20:33:57 -0700103 public void testRunfilesWithFileset() throws Exception {
104 Artifact artifact = createFilesetArtifact("foo/biz/fs_out");
105 Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
106 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
107 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
108 mockCache.put(
109 artifact,
lberki812e6fe2019-07-25 07:50:55 -0700110 FileArtifactValue.createForNormalFile(
felly99ad9b92019-06-12 20:33:57 -0700111 FAKE_DIGEST, /*proxy=*/ null, 0L, /*isShareable=*/ true));
112
113 ArtifactExpander filesetExpander =
114 new ArtifactExpander() {
115 @Override
116 public void expand(Artifact artifact, Collection<? super Artifact> output) {
117 throw new IllegalStateException("Unexpected tree expansion");
118 }
119
120 @Override
121 public ImmutableList<FilesetOutputSymlink> getFileset(Artifact artifact) {
122 return ImmutableList.of(
123 FilesetOutputSymlink.createForTesting(
124 PathFragment.create("zizz"),
125 PathFragment.create("/foo/fake_exec/xyz/zizz"),
126 PathFragment.create("/foo/fake_exec/")));
127 }
128 };
129
twerthc4dfb912020-07-20 10:32:42 -0700130 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, filesetExpander);
felly99ad9b92019-06-12 20:33:57 -0700131 assertThat(inputMappings).hasSize(1);
132 assertThat(inputMappings)
133 .containsEntry(
134 PathFragment.create("runfiles/workspace/foo/biz/fs_out/zizz"),
135 ActionInputHelper.fromPath("/root/xyz/zizz"));
136 }
137
138 @Test
buchgrd4d3d502018-08-02 06:47:19 -0700139 public void testRunfilesDirectoryStrict() {
Ulf Adamsc0a84442017-03-21 10:08:03 +0000140 Artifact artifact =
janakraea05602019-05-22 15:41:29 -0700141 ActionsTestUtil.createArtifact(
142 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
143 fs.getPath("/root/dir/file"));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000144 Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
nharmatab4060b62017-04-04 17:11:39 +0000145 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
ulfjack3903c922017-07-06 04:30:34 -0400146 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
lberki812e6fe2019-07-25 07:50:55 -0700147 mockCache.put(artifact, FileArtifactValue.createForDirectoryWithMtime(-1));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000148
jcaterfb5ed302019-04-29 13:30:34 -0700149 IOException expected =
150 assertThrows(
151 IOException.class,
152 () ->
153 expander.addRunfilesToInputs(
twerthc4dfb912020-07-20 10:32:42 -0700154 inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER));
jcaterfb5ed302019-04-29 13:30:34 -0700155 assertThat(expected).hasMessageThat().isEqualTo("Not a file: dir/file");
Ulf Adamsc0a84442017-03-21 10:08:03 +0000156 }
157
158 @Test
159 public void testRunfilesDirectoryNonStrict() throws Exception {
160 Artifact artifact =
janakraea05602019-05-22 15:41:29 -0700161 ActionsTestUtil.createArtifact(
162 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
163 fs.getPath("/root/dir/file"));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000164 Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(artifact).build();
nharmatab4060b62017-04-04 17:11:39 +0000165 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
ulfjack3903c922017-07-06 04:30:34 -0400166 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
lberki812e6fe2019-07-25 07:50:55 -0700167 mockCache.put(artifact, FileArtifactValue.createForDirectoryWithMtime(-1));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000168
tomlu1a19b622018-01-11 15:17:28 -0800169 expander = new SpawnInputExpander(execRoot, /*strict=*/ false);
twerthc4dfb912020-07-20 10:32:42 -0700170 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000171 assertThat(inputMappings).hasSize(1);
172 assertThat(inputMappings)
nharmatab4060b62017-04-04 17:11:39 +0000173 .containsEntry(PathFragment.create("runfiles/workspace/dir/file"), artifact);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000174 }
175
176 @Test
177 public void testRunfilesTwoFiles() throws Exception {
178 Artifact artifact1 =
janakraea05602019-05-22 15:41:29 -0700179 ActionsTestUtil.createArtifact(
180 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
181 fs.getPath("/root/dir/file"));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000182 Artifact artifact2 =
janakraea05602019-05-22 15:41:29 -0700183 ActionsTestUtil.createArtifact(
184 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
185 fs.getPath("/root/dir/baz"));
buchgrd4d3d502018-08-02 06:47:19 -0700186 Runfiles runfiles =
187 new Runfiles.Builder("workspace").addArtifact(artifact1).addArtifact(artifact2).build();
nharmatab4060b62017-04-04 17:11:39 +0000188 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
ulfjack3903c922017-07-06 04:30:34 -0400189 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
janakr39969b12019-03-03 16:25:48 -0800190 mockCache.put(
191 artifact1,
lberki812e6fe2019-07-25 07:50:55 -0700192 FileArtifactValue.createForNormalFile(
janakr39969b12019-03-03 16:25:48 -0800193 FAKE_DIGEST, /*proxy=*/ null, 1L, /*isShareable=*/ true));
194 mockCache.put(
195 artifact2,
lberki812e6fe2019-07-25 07:50:55 -0700196 FileArtifactValue.createForNormalFile(
janakr39969b12019-03-03 16:25:48 -0800197 FAKE_DIGEST, /*proxy=*/ null, 12L, /*isShareable=*/ true));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000198
twerthc4dfb912020-07-20 10:32:42 -0700199 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000200 assertThat(inputMappings).hasSize(2);
201 assertThat(inputMappings)
nharmatab4060b62017-04-04 17:11:39 +0000202 .containsEntry(PathFragment.create("runfiles/workspace/dir/file"), artifact1);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000203 assertThat(inputMappings)
nharmatab4060b62017-04-04 17:11:39 +0000204 .containsEntry(PathFragment.create("runfiles/workspace/dir/baz"), artifact2);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000205 }
206
207 @Test
208 public void testRunfilesSymlink() throws Exception {
209 Artifact artifact =
janakraea05602019-05-22 15:41:29 -0700210 ActionsTestUtil.createArtifact(
211 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
212 fs.getPath("/root/dir/file"));
buchgrd4d3d502018-08-02 06:47:19 -0700213 Runfiles runfiles =
214 new Runfiles.Builder("workspace")
215 .addSymlink(PathFragment.create("symlink"), artifact)
216 .build();
nharmatab4060b62017-04-04 17:11:39 +0000217 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
ulfjack3903c922017-07-06 04:30:34 -0400218 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
janakr39969b12019-03-03 16:25:48 -0800219 mockCache.put(
220 artifact,
lberki812e6fe2019-07-25 07:50:55 -0700221 FileArtifactValue.createForNormalFile(
janakr39969b12019-03-03 16:25:48 -0800222 FAKE_DIGEST, /*proxy=*/ null, 1L, /*isShareable=*/ true));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000223
twerthc4dfb912020-07-20 10:32:42 -0700224 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000225 assertThat(inputMappings).hasSize(1);
226 assertThat(inputMappings)
nharmatab4060b62017-04-04 17:11:39 +0000227 .containsEntry(PathFragment.create("runfiles/workspace/symlink"), artifact);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000228 }
229
230 @Test
231 public void testRunfilesRootSymlink() throws Exception {
232 Artifact artifact =
janakraea05602019-05-22 15:41:29 -0700233 ActionsTestUtil.createArtifact(
234 ArtifactRoot.asSourceRoot(Root.fromPath(fs.getPath("/root"))),
235 fs.getPath("/root/dir/file"));
buchgrd4d3d502018-08-02 06:47:19 -0700236 Runfiles runfiles =
237 new Runfiles.Builder("workspace")
238 .addRootSymlink(PathFragment.create("symlink"), artifact)
239 .build();
nharmatab4060b62017-04-04 17:11:39 +0000240 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
ulfjack3903c922017-07-06 04:30:34 -0400241 FakeActionInputFileCache mockCache = new FakeActionInputFileCache();
janakr39969b12019-03-03 16:25:48 -0800242 mockCache.put(
243 artifact,
lberki812e6fe2019-07-25 07:50:55 -0700244 FileArtifactValue.createForNormalFile(
janakr39969b12019-03-03 16:25:48 -0800245 FAKE_DIGEST, /*proxy=*/ null, 1L, /*isShareable=*/ true));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000246
twerthc4dfb912020-07-20 10:32:42 -0700247 expander.addRunfilesToInputs(inputMappings, supplier, mockCache, NO_ARTIFACT_EXPANDER);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000248 assertThat(inputMappings).hasSize(2);
nharmatab4060b62017-04-04 17:11:39 +0000249 assertThat(inputMappings).containsEntry(PathFragment.create("runfiles/symlink"), artifact);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000250 // If there's no other entry, Runfiles adds an empty file in the workspace to make sure the
251 // directory gets created.
252 assertThat(inputMappings)
253 .containsEntry(
aiuto0f626a42021-01-08 10:51:30 -0800254 PathFragment.create("runfiles/workspace/.runfile"), SpawnInputExpander.EMPTY_FILE);
Ulf Adamsc0a84442017-03-21 10:08:03 +0000255 }
256
257 @Test
buchgrd4d3d502018-08-02 06:47:19 -0700258 public void testRunfilesWithTreeArtifacts() throws Exception {
259 SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
260 assertThat(treeArtifact.isTreeArtifact()).isTrue();
Googler1d8d1382020-05-18 12:10:49 -0700261 TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
262 TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
buchgrd4d3d502018-08-02 06:47:19 -0700263 FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
264 FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");
265
266 Runfiles runfiles = new Runfiles.Builder("workspace").addArtifact(treeArtifact).build();
267 ArtifactExpander artifactExpander =
268 (Artifact artifact, Collection<? super Artifact> output) -> {
269 if (artifact.equals(treeArtifact)) {
270 output.addAll(Arrays.asList(file1, file2));
271 }
272 };
273 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
274 FakeActionInputFileCache fakeCache = new FakeActionInputFileCache();
lberki812e6fe2019-07-25 07:50:55 -0700275 fakeCache.put(file1, FileArtifactValue.createForTesting(file1));
276 fakeCache.put(file2, FileArtifactValue.createForTesting(file2));
buchgrd4d3d502018-08-02 06:47:19 -0700277
twerthc4dfb912020-07-20 10:32:42 -0700278 expander.addRunfilesToInputs(inputMappings, supplier, fakeCache, artifactExpander);
buchgrd4d3d502018-08-02 06:47:19 -0700279 assertThat(inputMappings).hasSize(2);
280 assertThat(inputMappings)
281 .containsEntry(PathFragment.create("runfiles/workspace/treeArtifact/file1"), file1);
282 assertThat(inputMappings)
283 .containsEntry(PathFragment.create("runfiles/workspace/treeArtifact/file2"), file2);
284 }
285
286 @Test
287 public void testRunfilesWithTreeArtifactsInSymlinks() throws Exception {
288 SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
289 assertThat(treeArtifact.isTreeArtifact()).isTrue();
Googler1d8d1382020-05-18 12:10:49 -0700290 TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
291 TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
buchgrd4d3d502018-08-02 06:47:19 -0700292 FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
293 FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");
294 Runfiles runfiles =
295 new Runfiles.Builder("workspace")
296 .addSymlink(PathFragment.create("symlink"), treeArtifact)
297 .build();
298
299 ArtifactExpander artifactExpander =
300 (Artifact artifact, Collection<? super Artifact> output) -> {
301 if (artifact.equals(treeArtifact)) {
302 output.addAll(Arrays.asList(file1, file2));
303 }
304 };
305 RunfilesSupplier supplier = new RunfilesSupplierImpl(PathFragment.create("runfiles"), runfiles);
306 FakeActionInputFileCache fakeCache = new FakeActionInputFileCache();
lberki812e6fe2019-07-25 07:50:55 -0700307 fakeCache.put(file1, FileArtifactValue.createForTesting(file1));
308 fakeCache.put(file2, FileArtifactValue.createForTesting(file2));
buchgrd4d3d502018-08-02 06:47:19 -0700309
twerthc4dfb912020-07-20 10:32:42 -0700310 expander.addRunfilesToInputs(inputMappings, supplier, fakeCache, artifactExpander);
buchgrd4d3d502018-08-02 06:47:19 -0700311 assertThat(inputMappings).hasSize(2);
312 assertThat(inputMappings)
313 .containsEntry(PathFragment.create("runfiles/workspace/symlink/file1"), file1);
314 assertThat(inputMappings)
315 .containsEntry(PathFragment.create("runfiles/workspace/symlink/file2"), file2);
316 }
317
318 @Test
319 public void testTreeArtifactsInInputs() throws Exception {
320 SpecialArtifact treeArtifact = createTreeArtifact("treeArtifact");
321 assertThat(treeArtifact.isTreeArtifact()).isTrue();
Googler1d8d1382020-05-18 12:10:49 -0700322 TreeFileArtifact file1 = TreeFileArtifact.createTreeOutput(treeArtifact, "file1");
323 TreeFileArtifact file2 = TreeFileArtifact.createTreeOutput(treeArtifact, "file2");
buchgrd4d3d502018-08-02 06:47:19 -0700324 FileSystemUtils.writeContentAsLatin1(file1.getPath(), "foo");
325 FileSystemUtils.writeContentAsLatin1(file2.getPath(), "bar");
326
327 ArtifactExpander artifactExpander =
328 (Artifact artifact, Collection<? super Artifact> output) -> {
329 if (artifact.equals(treeArtifact)) {
330 output.addAll(Arrays.asList(file1, file2));
331 }
332 };
333 FakeActionInputFileCache fakeCache = new FakeActionInputFileCache();
lberki812e6fe2019-07-25 07:50:55 -0700334 fakeCache.put(file1, FileArtifactValue.createForTesting(file1));
335 fakeCache.put(file2, FileArtifactValue.createForTesting(file2));
buchgrd4d3d502018-08-02 06:47:19 -0700336
337 Spawn spawn = new SpawnBuilder("/bin/echo", "Hello World").withInput(treeArtifact).build();
twerthc4dfb912020-07-20 10:32:42 -0700338 inputMappings = expander.getInputMapping(spawn, artifactExpander, fakeCache);
buchgrd4d3d502018-08-02 06:47:19 -0700339 assertThat(inputMappings).hasSize(2);
janakraea05602019-05-22 15:41:29 -0700340 assertThat(inputMappings).containsEntry(PathFragment.create("out/treeArtifact/file1"), file1);
341 assertThat(inputMappings).containsEntry(PathFragment.create("out/treeArtifact/file2"), file2);
buchgrd4d3d502018-08-02 06:47:19 -0700342 }
343
344 private SpecialArtifact createTreeArtifact(String relPath) throws IOException {
Googler1d8d1382020-05-18 12:10:49 -0700345 SpecialArtifact treeArtifact = createSpecialArtifact(relPath, SpecialArtifactType.TREE);
346 treeArtifact.setGeneratingActionKey(ActionsTestUtil.NULL_ACTION_LOOKUP_DATA);
347 return treeArtifact;
felly99ad9b92019-06-12 20:33:57 -0700348 }
349
350 private SpecialArtifact createFilesetArtifact(String relPath) throws IOException {
351 return createSpecialArtifact(relPath, SpecialArtifactType.FILESET);
352 }
353
354 private SpecialArtifact createSpecialArtifact(String relPath, SpecialArtifactType type)
355 throws IOException {
janakr448f1cf2020-03-30 09:12:44 -0700356 String outputSegment = "out";
357 Path outputDir = execRoot.getRelative(outputSegment);
janakraea05602019-05-22 15:41:29 -0700358 Path outputPath = outputDir.getRelative(relPath);
buchgrd4d3d502018-08-02 06:47:19 -0700359 outputPath.createDirectoryAndParents();
janakr448f1cf2020-03-30 09:12:44 -0700360 ArtifactRoot derivedRoot = ArtifactRoot.asDerivedRoot(execRoot, outputSegment);
buchgrd4d3d502018-08-02 06:47:19 -0700361 return new SpecialArtifact(
362 derivedRoot,
363 derivedRoot.getExecPath().getRelative(derivedRoot.getRoot().relativize(outputPath)),
janakrefb3f152019-06-05 17:42:34 -0700364 ActionsTestUtil.NULL_ARTIFACT_OWNER,
felly99ad9b92019-06-12 20:33:57 -0700365 type);
buchgrd4d3d502018-08-02 06:47:19 -0700366 }
367
368 @Test
Ulf Adamsc0a84442017-03-21 10:08:03 +0000369 public void testEmptyManifest() throws Exception {
Googler12498fd2018-10-10 10:47:00 -0700370 Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
371 ImmutableMap.of(createFileset("out"), ImmutableList.of());
Ulf Adamsc0a84442017-03-21 10:08:03 +0000372
Googler12498fd2018-10-10 10:47:00 -0700373 expander.addFilesetManifests(filesetMappings, inputMappings);
374
Ulf Adamsc0a84442017-03-21 10:08:03 +0000375 assertThat(inputMappings).isEmpty();
376 }
377
378 @Test
379 public void testManifestWithSingleFile() throws Exception {
Googler12498fd2018-10-10 10:47:00 -0700380 Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
381 ImmutableMap.of(
382 createFileset("out"), ImmutableList.of(filesetSymlink("foo/bar", "/dir/file")));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000383
Googler12498fd2018-10-10 10:47:00 -0700384 expander.addFilesetManifests(filesetMappings, inputMappings);
385
Ulf Adamsc0a84442017-03-21 10:08:03 +0000386 assertThat(inputMappings)
Googler12498fd2018-10-10 10:47:00 -0700387 .containsExactly(
388 PathFragment.create("out/foo/bar"), ActionInputHelper.fromPath("/dir/file"));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000389 }
390
391 @Test
392 public void testManifestWithTwoFiles() throws Exception {
Googler12498fd2018-10-10 10:47:00 -0700393 Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
394 ImmutableMap.of(
395 createFileset("out"),
396 ImmutableList.of(
397 filesetSymlink("foo/bar", "/dir/file"), filesetSymlink("foo/baz", "/dir/file")));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000398
Googler12498fd2018-10-10 10:47:00 -0700399 expander.addFilesetManifests(filesetMappings, inputMappings);
400
Ulf Adamsc0a84442017-03-21 10:08:03 +0000401 assertThat(inputMappings)
Googler12498fd2018-10-10 10:47:00 -0700402 .containsExactly(
403 PathFragment.create("out/foo/bar"), ActionInputHelper.fromPath("/dir/file"),
404 PathFragment.create("out/foo/baz"), ActionInputHelper.fromPath("/dir/file"));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000405 }
406
407 @Test
408 public void testManifestWithDirectory() throws Exception {
Googler12498fd2018-10-10 10:47:00 -0700409 Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetMappings =
410 ImmutableMap.of(createFileset("out"), ImmutableList.of(filesetSymlink("foo/bar", "/some")));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000411
Googler12498fd2018-10-10 10:47:00 -0700412 expander.addFilesetManifests(filesetMappings, inputMappings);
413
Ulf Adamsc0a84442017-03-21 10:08:03 +0000414 assertThat(inputMappings)
Googler12498fd2018-10-10 10:47:00 -0700415 .containsExactly(PathFragment.create("out/foo/bar"), ActionInputHelper.fromPath("/some"));
Ulf Adamsc0a84442017-03-21 10:08:03 +0000416 }
ulfjack1973be42018-05-30 03:25:35 -0700417
Googler18b08442018-10-04 09:55:06 -0700418 private static FilesetOutputSymlink filesetSymlink(String from, String to) {
kush4b120e72018-07-11 16:21:27 -0700419 return FilesetOutputSymlink.createForTesting(
Googler18b08442018-10-04 09:55:06 -0700420 PathFragment.create(from), PathFragment.create(to), PathFragment.create("/root"));
ulfjack1973be42018-05-30 03:25:35 -0700421 }
422
tomlu73eccc22018-09-06 08:02:37 -0700423 private ImmutableMap<Artifact, ImmutableList<FilesetOutputSymlink>> simpleFilesetManifest() {
ulfjack1973be42018-05-30 03:25:35 -0700424 return ImmutableMap.of(
tomlu73eccc22018-09-06 08:02:37 -0700425 createFileset("out"),
ulfjack1973be42018-05-30 03:25:35 -0700426 ImmutableList.of(
Googler18b08442018-10-04 09:55:06 -0700427 filesetSymlink("workspace/bar", "foo"), filesetSymlink("workspace/foo", "/root/bar")));
ulfjack1973be42018-05-30 03:25:35 -0700428 }
429
tomlu73eccc22018-09-06 08:02:37 -0700430 private SpecialArtifact createFileset(String execPath) {
431 return new SpecialArtifact(
432 rootDir,
433 PathFragment.create(execPath),
janakrefb3f152019-06-05 17:42:34 -0700434 ActionsTestUtil.NULL_ARTIFACT_OWNER,
tomlu73eccc22018-09-06 08:02:37 -0700435 SpecialArtifactType.FILESET);
436 }
437
ulfjack1973be42018-05-30 03:25:35 -0700438 @Test
439 public void testManifestWithErrorOnRelativeSymlink() throws Exception {
440 expander = new SpawnInputExpander(execRoot, /*strict=*/ true, ERROR);
jcaterfb5ed302019-04-29 13:30:34 -0700441 IOException e =
442 assertThrows(
443 IOException.class,
444 () -> expander.addFilesetManifests(simpleFilesetManifest(), inputMappings));
445 assertThat(e).hasMessageThat().contains("runfiles target is not absolute: foo");
ulfjack1973be42018-05-30 03:25:35 -0700446 }
447
448 @Test
449 public void testManifestWithIgnoredRelativeSymlink() throws Exception {
450 expander = new SpawnInputExpander(execRoot, /*strict=*/ true, IGNORE);
Googler12498fd2018-10-10 10:47:00 -0700451 expander.addFilesetManifests(simpleFilesetManifest(), inputMappings);
452 assertThat(inputMappings)
ulfjack1973be42018-05-30 03:25:35 -0700453 .containsExactly(
Googler18b08442018-10-04 09:55:06 -0700454 PathFragment.create("out/workspace/foo"), ActionInputHelper.fromPath("/root/bar"));
ulfjack1973be42018-05-30 03:25:35 -0700455 }
456
457 @Test
458 public void testManifestWithResolvedRelativeSymlink() throws Exception {
459 expander = new SpawnInputExpander(execRoot, /*strict=*/ true, RESOLVE);
Googler12498fd2018-10-10 10:47:00 -0700460 expander.addFilesetManifests(simpleFilesetManifest(), inputMappings);
461 assertThat(inputMappings)
ulfjack1973be42018-05-30 03:25:35 -0700462 .containsExactly(
Googler18b08442018-10-04 09:55:06 -0700463 PathFragment.create("out/workspace/bar"), ActionInputHelper.fromPath("/root/bar"),
464 PathFragment.create("out/workspace/foo"), ActionInputHelper.fromPath("/root/bar"));
ulfjack1973be42018-05-30 03:25:35 -0700465 }
Ulf Adamsc0a84442017-03-21 10:08:03 +0000466}