Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 1 | // Copyright 2015 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. |
| 14 | package com.google.devtools.build.lib.skyframe; |
Janak Ramakrishnan | a5578af | 2017-03-21 17:28:39 +0000 | [diff] [blame] | 15 | |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 16 | import static com.google.common.truth.Truth.assertThat; |
lberki | 812e6fe | 2019-07-25 07:50:55 -0700 | [diff] [blame] | 17 | import static com.google.devtools.build.lib.actions.FileArtifactValue.createForTesting; |
michajlo | 660d17f | 2020-03-27 09:01:57 -0700 | [diff] [blame] | 18 | import static org.junit.Assert.assertThrows; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 19 | |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 20 | import com.google.common.base.Preconditions; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 21 | import com.google.common.collect.ImmutableList; |
| 22 | import com.google.common.collect.ImmutableMap; |
| 23 | import com.google.common.collect.ImmutableSet; |
| 24 | import com.google.common.collect.Iterables; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 25 | import com.google.devtools.build.lib.actions.Action; |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 26 | import com.google.devtools.build.lib.actions.ActionLookupData; |
| 27 | import com.google.devtools.build.lib.actions.ActionLookupValue; |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 28 | import com.google.devtools.build.lib.actions.ActionTemplate; |
janakr | 0175ce3 | 2018-02-26 15:54:57 -0800 | [diff] [blame] | 29 | import com.google.devtools.build.lib.actions.Actions; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 30 | import com.google.devtools.build.lib.actions.Artifact; |
Googler | 72d648a | 2020-05-21 11:56:40 -0700 | [diff] [blame] | 31 | import com.google.devtools.build.lib.actions.Artifact.DerivedArtifact; |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 32 | import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; |
| 33 | import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; |
| 34 | import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; |
tomlu | 1cdcdf9 | 2018-01-16 11:07:51 -0800 | [diff] [blame] | 35 | import com.google.devtools.build.lib.actions.ArtifactRoot; |
Googler | f0b0c39 | 2021-01-27 17:56:52 -0800 | [diff] [blame] | 36 | import com.google.devtools.build.lib.actions.ArtifactRoot.RootType; |
cparsons | e2d200f | 2018-03-06 16:15:11 -0800 | [diff] [blame] | 37 | import com.google.devtools.build.lib.actions.BasicActionLookupValue; |
shahan | 602cc85 | 2018-06-06 20:09:57 -0700 | [diff] [blame] | 38 | import com.google.devtools.build.lib.actions.FileArtifactValue; |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 39 | import com.google.devtools.build.lib.actions.FilesetOutputSymlink; |
jhorvitz | 3daedc3 | 2020-07-22 18:33:55 -0700 | [diff] [blame] | 40 | import com.google.devtools.build.lib.actions.MiddlemanType; |
janakr | 0175ce3 | 2018-02-26 15:54:57 -0800 | [diff] [blame] | 41 | import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 42 | import com.google.devtools.build.lib.actions.util.ActionsTestUtil; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 43 | import com.google.devtools.build.lib.actions.util.TestAction.DummyAction; |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 44 | import com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate; |
ulfjack | 1e1a775 | 2019-12-10 21:17:58 -0800 | [diff] [blame] | 45 | import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; |
| 46 | import com.google.devtools.build.lib.collect.nestedset.Order; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 47 | import com.google.devtools.build.lib.events.NullEventHandler; |
janakr | 8b2f14f | 2021-04-02 11:17:58 -0700 | [diff] [blame] | 48 | import com.google.devtools.build.lib.skyframe.ArtifactFunction.SourceArtifactException; |
janakr | 40f2f0e | 2020-06-08 17:03:06 -0700 | [diff] [blame] | 49 | import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationDepsUtils; |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 50 | import com.google.devtools.build.lib.skyframe.serialization.testutils.SerializationTester; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 51 | import com.google.devtools.build.lib.util.Pair; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 52 | import com.google.devtools.build.lib.vfs.FileStatus; |
lberki | f225af1 | 2019-08-01 04:21:58 -0700 | [diff] [blame] | 53 | import com.google.devtools.build.lib.vfs.FileStatusWithDigestAdapter; |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 54 | import com.google.devtools.build.lib.vfs.FileSystem; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 55 | import com.google.devtools.build.lib.vfs.Path; |
| 56 | import com.google.devtools.build.lib.vfs.PathFragment; |
tomlu | ee6a686 | 2018-01-17 14:36:26 -0800 | [diff] [blame] | 57 | import com.google.devtools.build.lib.vfs.Root; |
lberki | f225af1 | 2019-08-01 04:21:58 -0700 | [diff] [blame] | 58 | import com.google.devtools.build.lib.vfs.Symlinks; |
Googler | 1002867 | 2018-10-25 12:14:34 -0700 | [diff] [blame] | 59 | import com.google.devtools.build.skyframe.EvaluationContext; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 60 | import com.google.devtools.build.skyframe.EvaluationResult; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 61 | import com.google.devtools.build.skyframe.SkyFunction; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 62 | import com.google.devtools.build.skyframe.SkyKey; |
| 63 | import com.google.devtools.build.skyframe.SkyValue; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 64 | import java.io.IOException; |
buchgr | d4d3d50 | 2018-08-02 06:47:19 -0700 | [diff] [blame] | 65 | import java.util.ArrayList; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 66 | import java.util.Arrays; |
| 67 | import java.util.HashMap; |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 68 | import java.util.HashSet; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 69 | import java.util.Map; |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 70 | import java.util.Set; |
Janak Ramakrishnan | ad77f97 | 2016-07-29 20:58:42 +0000 | [diff] [blame] | 71 | import org.junit.Before; |
| 72 | import org.junit.Test; |
| 73 | import org.junit.runner.RunWith; |
| 74 | import org.junit.runners.JUnit4; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 75 | |
| 76 | /** |
| 77 | * Tests for {@link ArtifactFunction}. |
| 78 | */ |
| 79 | // Doesn't actually need any particular Skyframe, but is only relevant to Skyframe full mode. |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 80 | @RunWith(JUnit4.class) |
Michael Thvedt | 8d5a7bb | 2016-02-09 03:06:34 +0000 | [diff] [blame] | 81 | public class ArtifactFunctionTest extends ArtifactFunctionTestCase { |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 82 | |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 83 | private final Set<Artifact> omittedOutputs = new HashSet<>(); |
| 84 | |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 85 | @Before |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 86 | public final void setUp() { |
| 87 | delegateActionExecutionFunction = new SimpleActionExecutionFunction(omittedOutputs); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | private void assertFileArtifactValueMatches(boolean expectDigest) throws Throwable { |
| 91 | Artifact output = createDerivedArtifact("output"); |
| 92 | Path path = output.getPath(); |
| 93 | file(path, "contents"); |
olaola | bfd1d33 | 2017-06-19 16:55:24 -0400 | [diff] [blame] | 94 | assertValueMatches(path.stat(), expectDigest ? path.getDigest() : null, evaluateFAN(output)); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 95 | } |
| 96 | |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 97 | @Test |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 98 | public void testBasicArtifact() throws Throwable { |
| 99 | fastDigest = false; |
| 100 | assertFileArtifactValueMatches(/*expectDigest=*/ true); |
| 101 | } |
| 102 | |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 103 | @Test |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 104 | public void testBasicArtifactWithXattr() throws Throwable { |
| 105 | fastDigest = true; |
| 106 | assertFileArtifactValueMatches(/*expectDigest=*/ true); |
| 107 | } |
| 108 | |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 109 | @Test |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 110 | public void testMissingNonMandatoryArtifact() throws Throwable { |
| 111 | Artifact input = createSourceArtifact("input1"); |
lberki | 36df7ed | 2019-06-27 06:32:03 -0700 | [diff] [blame] | 112 | assertThat(evaluateArtifactValue(input)).isNotNull(); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 113 | } |
| 114 | |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 115 | @Test |
Michajlo Matijkiw | 528957e | 2016-01-19 21:17:45 +0000 | [diff] [blame] | 116 | public void testUnreadableInputWithFsWithAvailableDigest() throws Throwable { |
Googler | e764d56 | 2019-10-16 10:56:33 -0700 | [diff] [blame] | 117 | final byte[] expectedDigest = {1, 2, 3, 4}; |
Michajlo Matijkiw | 528957e | 2016-01-19 21:17:45 +0000 | [diff] [blame] | 118 | setupRoot( |
| 119 | new CustomInMemoryFs() { |
| 120 | @Override |
ajurkowski | 8883c61 | 2021-03-08 08:12:37 -0800 | [diff] [blame] | 121 | public byte[] getDigest(PathFragment path) throws IOException { |
ccalvarin | dd9f60e | 2018-07-23 18:16:18 -0700 | [diff] [blame] | 122 | return path.getBaseName().equals("unreadable") ? expectedDigest : super.getDigest(path); |
Michajlo Matijkiw | 528957e | 2016-01-19 21:17:45 +0000 | [diff] [blame] | 123 | } |
| 124 | }); |
| 125 | |
| 126 | Artifact input = createSourceArtifact("unreadable"); |
| 127 | Path inputPath = input.getPath(); |
| 128 | file(inputPath, "dummynotused"); |
| 129 | inputPath.chmod(0); |
| 130 | |
lberki | 36df7ed | 2019-06-27 06:32:03 -0700 | [diff] [blame] | 131 | FileArtifactValue value = (FileArtifactValue) evaluateArtifactValue(input); |
Michajlo Matijkiw | 528957e | 2016-01-19 21:17:45 +0000 | [diff] [blame] | 132 | |
| 133 | FileStatus stat = inputPath.stat(); |
| 134 | assertThat(value.getSize()).isEqualTo(stat.getSize()); |
| 135 | assertThat(value.getDigest()).isEqualTo(expectedDigest); |
| 136 | } |
| 137 | |
| 138 | @Test |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 139 | public void testMiddlemanArtifact() throws Throwable { |
Janak Ramakrishnan | a5578af | 2017-03-21 17:28:39 +0000 | [diff] [blame] | 140 | Artifact output = createMiddlemanArtifact("output"); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 141 | Artifact input1 = createSourceArtifact("input1"); |
| 142 | Artifact input2 = createDerivedArtifact("input2"); |
Benjamin Peterson | 63748e4 | 2018-06-03 22:11:16 -0700 | [diff] [blame] | 143 | SpecialArtifact tree = createDerivedTreeArtifactWithAction("treeArtifact"); |
buchgr | d4d3d50 | 2018-08-02 06:47:19 -0700 | [diff] [blame] | 144 | TreeFileArtifact treeFile1 = createFakeTreeFileArtifact(tree, "child1", "hello1"); |
| 145 | TreeFileArtifact treeFile2 = createFakeTreeFileArtifact(tree, "child2", "hello2"); |
| 146 | file(treeFile1.getPath(), "src1"); |
| 147 | file(treeFile2.getPath(), "src2"); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 148 | Action action = |
| 149 | new DummyAction( |
ulfjack | 1e1a775 | 2019-12-10 21:17:58 -0800 | [diff] [blame] | 150 | NestedSetBuilder.create(Order.STABLE_ORDER, input1, input2, tree), |
| 151 | output, |
leba | 40f2e72 | 2021-06-30 02:46:15 -0700 | [diff] [blame] | 152 | MiddlemanType.RUNFILES_MIDDLEMAN); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 153 | actions.add(action); |
| 154 | file(input2.getPath(), "contents"); |
| 155 | file(input1.getPath(), "source contents"); |
janakr | 8541f6d | 2019-06-11 14:40:21 -0700 | [diff] [blame] | 156 | evaluate( |
| 157 | Iterables.toArray( |
lberki | 36df7ed | 2019-06-27 06:32:03 -0700 | [diff] [blame] | 158 | Artifact.keys(ImmutableSet.of(input2, input1, input2, tree)), SkyKey.class)); |
Janak Ramakrishnan | ad77f97 | 2016-07-29 20:58:42 +0000 | [diff] [blame] | 159 | SkyValue value = evaluateArtifactValue(output); |
buchgr | d4d3d50 | 2018-08-02 06:47:19 -0700 | [diff] [blame] | 160 | ArrayList<Pair<Artifact, ?>> inputs = new ArrayList<>(); |
leba | 40f2e72 | 2021-06-30 02:46:15 -0700 | [diff] [blame] | 161 | inputs.addAll(((RunfilesArtifactValue) value).getFileArtifacts()); |
| 162 | inputs.addAll(((RunfilesArtifactValue) value).getTreeArtifacts()); |
buchgr | d4d3d50 | 2018-08-02 06:47:19 -0700 | [diff] [blame] | 163 | assertThat(inputs) |
Benjamin Peterson | 63748e4 | 2018-06-03 22:11:16 -0700 | [diff] [blame] | 164 | .containsExactly( |
lberki | 812e6fe | 2019-07-25 07:50:55 -0700 | [diff] [blame] | 165 | Pair.of(input1, createForTesting(input1)), |
| 166 | Pair.of(input2, createForTesting(input2)), |
buchgr | d4d3d50 | 2018-08-02 06:47:19 -0700 | [diff] [blame] | 167 | Pair.of(tree, ((TreeArtifactValue) evaluateArtifactValue(tree)))); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 168 | } |
| 169 | |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 170 | /** |
janakr | 8b2f14f | 2021-04-02 11:17:58 -0700 | [diff] [blame] | 171 | * Tests that ArtifactFunction rethrows a transitive {@link IOException} as an {@link |
| 172 | * SourceArtifactException}. |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 173 | */ |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 174 | @Test |
jmmv | bfbd95f | 2020-08-31 13:12:38 -0700 | [diff] [blame] | 175 | public void testIOException_endToEnd() throws Throwable { |
janakr | 8b2f14f | 2021-04-02 11:17:58 -0700 | [diff] [blame] | 176 | IOException exception = new IOException("beep"); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 177 | setupRoot( |
| 178 | new CustomInMemoryFs() { |
| 179 | @Override |
ajurkowski | 8883c61 | 2021-03-08 08:12:37 -0800 | [diff] [blame] | 180 | public FileStatus statIfFound(PathFragment path, boolean followSymlinks) |
| 181 | throws IOException { |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 182 | if (path.getBaseName().equals("bad")) { |
| 183 | throw exception; |
| 184 | } |
felly | a205ed8 | 2018-09-10 11:52:34 -0700 | [diff] [blame] | 185 | return super.statIfFound(path, followSymlinks); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 186 | } |
| 187 | }); |
janakr | 8b2f14f | 2021-04-02 11:17:58 -0700 | [diff] [blame] | 188 | Artifact sourceArtifact = createSourceArtifact("bad"); |
| 189 | SourceArtifactException e = |
| 190 | assertThrows(SourceArtifactException.class, () -> evaluateArtifactValue(sourceArtifact)); |
| 191 | assertThat(e) |
| 192 | .hasMessageThat() |
| 193 | .isEqualTo("error reading file '" + sourceArtifact.getExecPathString() + "': beep"); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 194 | } |
| 195 | |
Han-Wen Nienhuys | 3b2eae3 | 2015-10-28 16:35:08 +0000 | [diff] [blame] | 196 | @Test |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 197 | public void testActionTreeArtifactOutput() throws Throwable { |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 198 | SpecialArtifact artifact = createDerivedTreeArtifactWithAction("treeArtifact"); |
janakr | efb3f15 | 2019-06-05 17:42:34 -0700 | [diff] [blame] | 199 | TreeFileArtifact treeFileArtifact1 = createFakeTreeFileArtifact(artifact, "child1", "hello1"); |
| 200 | TreeFileArtifact treeFileArtifact2 = createFakeTreeFileArtifact(artifact, "child2", "hello2"); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 201 | |
| 202 | TreeArtifactValue value = (TreeArtifactValue) evaluateArtifactValue(artifact); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 203 | assertThat(value.getChildValues()).containsKey(treeFileArtifact1); |
| 204 | assertThat(value.getChildValues()).containsKey(treeFileArtifact2); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 205 | assertThat(value.getChildValues().get(treeFileArtifact1).getDigest()).isNotNull(); |
| 206 | assertThat(value.getChildValues().get(treeFileArtifact2).getDigest()).isNotNull(); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 207 | } |
| 208 | |
| 209 | @Test |
| 210 | public void testSpawnActionTemplate() throws Throwable { |
| 211 | // artifact1 is a tree artifact generated by normal action. |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 212 | SpecialArtifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1"); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 213 | createFakeTreeFileArtifact(artifact1, "child1", "hello1"); |
| 214 | createFakeTreeFileArtifact(artifact1, "child2", "hello2"); |
| 215 | |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 216 | // artifact2 is a tree artifact generated by action template. |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 217 | SpecialArtifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2"); |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 218 | SpawnActionTemplate actionTemplate = |
| 219 | ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2); |
| 220 | actions.add(actionTemplate); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 221 | TreeFileArtifact treeFileArtifact1 = |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 222 | createFakeExpansionTreeFileArtifact(actionTemplate, "child1", "hello1"); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 223 | TreeFileArtifact treeFileArtifact2 = |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 224 | createFakeExpansionTreeFileArtifact(actionTemplate, "child2", "hello2"); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 225 | |
| 226 | TreeArtifactValue value = (TreeArtifactValue) evaluateArtifactValue(artifact2); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 227 | assertThat(value.getChildValues()).containsKey(treeFileArtifact1); |
| 228 | assertThat(value.getChildValues()).containsKey(treeFileArtifact2); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 229 | assertThat(value.getChildValues().get(treeFileArtifact1).getDigest()).isNotNull(); |
| 230 | assertThat(value.getChildValues().get(treeFileArtifact2).getDigest()).isNotNull(); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | @Test |
| 234 | public void testConsecutiveSpawnActionTemplates() throws Throwable { |
| 235 | // artifact1 is a tree artifact generated by normal action. |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 236 | SpecialArtifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1"); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 237 | createFakeTreeFileArtifact(artifact1, "child1", "hello1"); |
| 238 | createFakeTreeFileArtifact(artifact1, "child2", "hello2"); |
| 239 | |
| 240 | // artifact2 is a tree artifact generated by action template. |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 241 | SpecialArtifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2"); |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 242 | SpawnActionTemplate template2 = |
| 243 | ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2); |
| 244 | actions.add(template2); |
| 245 | createFakeExpansionTreeFileArtifact(template2, "child1", "hello1"); |
| 246 | createFakeExpansionTreeFileArtifact(template2, "child2", "hello2"); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 247 | |
| 248 | // artifact3 is a tree artifact generated by action template. |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 249 | SpecialArtifact artifact3 = createDerivedTreeArtifactOnly("treeArtifact3"); |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 250 | SpawnActionTemplate template3 = |
| 251 | ActionsTestUtil.createDummySpawnActionTemplate(artifact2, artifact3); |
| 252 | actions.add(template3); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 253 | TreeFileArtifact treeFileArtifact1 = |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 254 | createFakeExpansionTreeFileArtifact(template3, "child1", "hello1"); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 255 | TreeFileArtifact treeFileArtifact2 = |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 256 | createFakeExpansionTreeFileArtifact(template3, "child2", "hello2"); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 257 | |
| 258 | TreeArtifactValue value = (TreeArtifactValue) evaluateArtifactValue(artifact3); |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 259 | assertThat(value.getChildValues()).containsKey(treeFileArtifact1); |
| 260 | assertThat(value.getChildValues()).containsKey(treeFileArtifact2); |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 261 | assertThat(value.getChildValues().get(treeFileArtifact1).getDigest()).isNotNull(); |
| 262 | assertThat(value.getChildValues().get(treeFileArtifact2).getDigest()).isNotNull(); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 263 | } |
| 264 | |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 265 | @Test |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 266 | public void actionTemplateExpansionOutputsOmitted() throws Throwable { |
| 267 | // artifact1 is a tree artifact generated by normal action. |
| 268 | SpecialArtifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1"); |
| 269 | createFakeTreeFileArtifact(artifact1, "child1", "hello1"); |
| 270 | createFakeTreeFileArtifact(artifact1, "child2", "hello2"); |
| 271 | |
| 272 | // artifact2 is a tree artifact generated by action template. |
| 273 | SpecialArtifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2"); |
| 274 | SpawnActionTemplate actionTemplate = |
| 275 | ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2); |
| 276 | actions.add(actionTemplate); |
| 277 | TreeFileArtifact treeFileArtifact1 = |
| 278 | createFakeExpansionTreeFileArtifact(actionTemplate, "child1", "hello1"); |
| 279 | TreeFileArtifact treeFileArtifact2 = |
| 280 | createFakeExpansionTreeFileArtifact(actionTemplate, "child2", "hello2"); |
| 281 | |
| 282 | omittedOutputs.add(treeFileArtifact1); |
| 283 | omittedOutputs.add(treeFileArtifact2); |
| 284 | |
| 285 | SkyValue value = evaluateArtifactValue(artifact2); |
Googler | 61a9f57 | 2020-06-02 10:28:24 -0700 | [diff] [blame] | 286 | assertThat(value).isEqualTo(TreeArtifactValue.OMITTED_TREE_MARKER); |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 287 | } |
| 288 | |
| 289 | @Test |
| 290 | public void cannotOmitSomeButNotAllActionTemplateExpansionOutputs() throws Throwable { |
| 291 | // artifact1 is a tree artifact generated by normal action. |
| 292 | SpecialArtifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1"); |
| 293 | createFakeTreeFileArtifact(artifact1, "child1", "hello1"); |
| 294 | createFakeTreeFileArtifact(artifact1, "child2", "hello2"); |
| 295 | |
| 296 | // artifact2 is a tree artifact generated by action template. |
| 297 | SpecialArtifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2"); |
| 298 | SpawnActionTemplate actionTemplate = |
| 299 | ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2); |
| 300 | actions.add(actionTemplate); |
| 301 | TreeFileArtifact treeFileArtifact1 = |
| 302 | createFakeExpansionTreeFileArtifact(actionTemplate, "child1", "hello1"); |
| 303 | TreeFileArtifact treeFileArtifact2 = |
| 304 | createFakeExpansionTreeFileArtifact(actionTemplate, "child2", "hello2"); |
| 305 | |
| 306 | omittedOutputs.add(treeFileArtifact1); |
| 307 | |
| 308 | Exception e = assertThrows(RuntimeException.class, () -> evaluateArtifactValue(artifact2)); |
| 309 | assertThat(e).hasCauseThat().isInstanceOf(IllegalStateException.class); |
| 310 | assertThat(e) |
| 311 | .hasCauseThat() |
| 312 | .hasMessageThat() |
| 313 | .matches( |
| 314 | "Action template expansion has some but not all outputs omitted, present outputs: .*" |
| 315 | + treeFileArtifact2.getParentRelativePath() |
| 316 | + ".*"); |
| 317 | } |
| 318 | |
| 319 | @Test |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 320 | public void actionExecutionValueSerialization() throws Exception { |
janakr | efb3f15 | 2019-06-05 17:42:34 -0700 | [diff] [blame] | 321 | ActionLookupData dummyData = ActionLookupData.create(ALL_OWNER, 0); |
Googler | 72d648a | 2020-05-21 11:56:40 -0700 | [diff] [blame] | 322 | DerivedArtifact artifact1 = createDerivedArtifact("one"); |
lberki | f7eee1e | 2019-07-31 05:49:10 -0700 | [diff] [blame] | 323 | FileArtifactValue metadata1 = |
| 324 | ActionMetadataHandler.fileArtifactValueFromArtifact(artifact1, null, null); |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 325 | SpecialArtifact treeArtifact = createDerivedTreeArtifactOnly("tree"); |
janakr | efb3f15 | 2019-06-05 17:42:34 -0700 | [diff] [blame] | 326 | treeArtifact.setGeneratingActionKey(dummyData); |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 327 | TreeFileArtifact treeFileArtifact = TreeFileArtifact.createTreeOutput(treeArtifact, "subpath"); |
janakr | efb3f15 | 2019-06-05 17:42:34 -0700 | [diff] [blame] | 328 | Path path = treeFileArtifact.getPath(); |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 329 | path.getParentDirectory().createDirectoryAndParents(); |
janakr | efb3f15 | 2019-06-05 17:42:34 -0700 | [diff] [blame] | 330 | writeFile(path, "contents"); |
jhorvitz | ed7ec3b | 2020-07-24 15:08:03 -0700 | [diff] [blame] | 331 | TreeArtifactValue tree = |
| 332 | TreeArtifactValue.newBuilder(treeArtifact) |
| 333 | .putChild(treeFileArtifact, FileArtifactValue.createForTesting(treeFileArtifact)) |
| 334 | .build(); |
Googler | 72d648a | 2020-05-21 11:56:40 -0700 | [diff] [blame] | 335 | DerivedArtifact artifact3 = createDerivedArtifact("three"); |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 336 | FilesetOutputSymlink filesetOutputSymlink = |
| 337 | FilesetOutputSymlink.createForTesting( |
| 338 | PathFragment.EMPTY_FRAGMENT, PathFragment.EMPTY_FRAGMENT, PathFragment.EMPTY_FRAGMENT); |
| 339 | ActionExecutionValue actionExecutionValue = |
| 340 | ActionExecutionValue.create( |
lberki | c35878a | 2019-08-01 02:28:54 -0700 | [diff] [blame] | 341 | ImmutableMap.of(artifact1, metadata1, artifact3, FileArtifactValue.DEFAULT_MIDDLEMAN), |
jhorvitz | ed7ec3b | 2020-07-24 15:08:03 -0700 | [diff] [blame] | 342 | ImmutableMap.of(treeArtifact, tree), |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 343 | ImmutableList.of(filesetOutputSymlink), |
| 344 | null, |
| 345 | true); |
Googler | ce6ad29 | 2019-12-20 10:29:21 -0800 | [diff] [blame] | 346 | new SerializationTester(actionExecutionValue) |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 347 | .addDependency(FileSystem.class, root.getFileSystem()) |
nharmata | f93c72c | 2020-03-13 14:22:10 -0700 | [diff] [blame] | 348 | .addDependency( |
| 349 | Root.RootCodecDependencies.class, |
| 350 | new Root.RootCodecDependencies(Root.absoluteRoot(root.getFileSystem()))) |
janakr | 40f2f0e | 2020-06-08 17:03:06 -0700 | [diff] [blame] | 351 | .addDependencies(SerializationDepsUtils.SERIALIZATION_DEPS_FOR_TEST) |
janakr | e82933c | 2019-01-02 14:41:50 -0800 | [diff] [blame] | 352 | .runTests(); |
| 353 | } |
| 354 | |
ajurkowski | e298291 | 2020-04-09 10:32:08 -0700 | [diff] [blame] | 355 | private static void file(Path path, String contents) throws Exception { |
jhorvitz | ed7ec3b | 2020-07-24 15:08:03 -0700 | [diff] [blame] | 356 | path.getParentDirectory().createDirectoryAndParents(); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 357 | writeFile(path, contents); |
| 358 | } |
| 359 | |
| 360 | private Artifact createSourceArtifact(String path) { |
janakr | aea0560 | 2019-05-22 15:41:29 -0700 | [diff] [blame] | 361 | return ActionsTestUtil.createArtifactWithExecPath( |
| 362 | ArtifactRoot.asSourceRoot(Root.fromPath(root)), PathFragment.create(path)); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 363 | } |
| 364 | |
Googler | 72d648a | 2020-05-21 11:56:40 -0700 | [diff] [blame] | 365 | private DerivedArtifact createDerivedArtifact(String path) { |
nharmata | b4060b6 | 2017-04-04 17:11:39 +0000 | [diff] [blame] | 366 | PathFragment execPath = PathFragment.create("out").getRelative(path); |
Googler | 72d648a | 2020-05-21 11:56:40 -0700 | [diff] [blame] | 367 | DerivedArtifact output = |
jhorvitz | cab340f | 2021-09-27 09:16:23 -0700 | [diff] [blame^] | 368 | DerivedArtifact.create( |
Googler | f0b0c39 | 2021-01-27 17:56:52 -0800 | [diff] [blame] | 369 | ArtifactRoot.asDerivedRoot(root, RootType.Output, "out"), execPath, ALL_OWNER); |
ulfjack | 1e1a775 | 2019-12-10 21:17:58 -0800 | [diff] [blame] | 370 | actions.add(new DummyAction(NestedSetBuilder.emptySet(Order.STABLE_ORDER), output)); |
janakr | 8541f6d | 2019-06-11 14:40:21 -0700 | [diff] [blame] | 371 | output.setGeneratingActionKey(ActionLookupData.create(ALL_OWNER, actions.size() - 1)); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 372 | return output; |
| 373 | } |
| 374 | |
Janak Ramakrishnan | a5578af | 2017-03-21 17:28:39 +0000 | [diff] [blame] | 375 | private Artifact createMiddlemanArtifact(String path) { |
tomlu | 1cdcdf9 | 2018-01-16 11:07:51 -0800 | [diff] [blame] | 376 | ArtifactRoot middlemanRoot = |
Googler | f0b0c39 | 2021-01-27 17:56:52 -0800 | [diff] [blame] | 377 | ArtifactRoot.asDerivedRoot(middlemanPath, RootType.Middleman, PathFragment.create("out")); |
jhorvitz | cab340f | 2021-09-27 09:16:23 -0700 | [diff] [blame^] | 378 | return DerivedArtifact.create( |
janakr | 3290e22 | 2019-05-29 16:34:22 -0700 | [diff] [blame] | 379 | middlemanRoot, middlemanRoot.getExecPath().getRelative(path), ALL_OWNER); |
Janak Ramakrishnan | a5578af | 2017-03-21 17:28:39 +0000 | [diff] [blame] | 380 | } |
| 381 | |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 382 | private SpecialArtifact createDerivedTreeArtifactWithAction(String path) { |
| 383 | SpecialArtifact treeArtifact = createDerivedTreeArtifactOnly(path); |
ulfjack | 1e1a775 | 2019-12-10 21:17:58 -0800 | [diff] [blame] | 384 | actions.add(new DummyAction(NestedSetBuilder.emptySet(Order.STABLE_ORDER), treeArtifact)); |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 385 | treeArtifact.setGeneratingActionKey(ActionLookupData.create(ALL_OWNER, actions.size() - 1)); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 386 | return treeArtifact; |
| 387 | } |
| 388 | |
cpeyser | ac09f0a | 2018-02-05 09:33:15 -0800 | [diff] [blame] | 389 | private SpecialArtifact createDerivedTreeArtifactOnly(String path) { |
nharmata | b4060b6 | 2017-04-04 17:11:39 +0000 | [diff] [blame] | 390 | PathFragment execPath = PathFragment.create("out").getRelative(path); |
jhorvitz | cab340f | 2021-09-27 09:16:23 -0700 | [diff] [blame^] | 391 | return SpecialArtifact.create( |
Googler | f0b0c39 | 2021-01-27 17:56:52 -0800 | [diff] [blame] | 392 | ArtifactRoot.asDerivedRoot(root, RootType.Output, "out"), |
Googler | 147c287 | 2021-01-21 08:47:48 -0800 | [diff] [blame] | 393 | execPath, |
| 394 | ALL_OWNER, |
| 395 | SpecialArtifactType.TREE); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 396 | } |
| 397 | |
ajurkowski | e298291 | 2020-04-09 10:32:08 -0700 | [diff] [blame] | 398 | private static TreeFileArtifact createFakeTreeFileArtifact( |
| 399 | SpecialArtifact treeArtifact, String parentRelativePath, String content) throws Exception { |
janakr | 45b308a | 2018-06-08 12:51:58 -0700 | [diff] [blame] | 400 | TreeFileArtifact treeFileArtifact = |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 401 | TreeFileArtifact.createTreeOutput(treeArtifact, parentRelativePath); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 402 | Path path = treeFileArtifact.getPath(); |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 403 | path.getParentDirectory().createDirectoryAndParents(); |
| 404 | writeFile(path, content); |
| 405 | return treeFileArtifact; |
| 406 | } |
| 407 | |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 408 | private TreeFileArtifact createFakeExpansionTreeFileArtifact( |
| 409 | ActionTemplate<?> actionTemplate, String parentRelativePath, String content) |
| 410 | throws Exception { |
| 411 | int actionIndex = Iterables.indexOf(actions, actionTemplate::equals); |
| 412 | Preconditions.checkState(actionIndex >= 0, "%s not registered", actionTemplate); |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 413 | TreeFileArtifact treeFileArtifact = |
| 414 | TreeFileArtifact.createTemplateExpansionOutput( |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 415 | actionTemplate.getOutputTreeArtifact(), |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 416 | parentRelativePath, |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 417 | ActionTemplateExpansionValue.key(ALL_OWNER, actionIndex)); |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 418 | Path path = treeFileArtifact.getPath(); |
| 419 | path.getParentDirectory().createDirectoryAndParents(); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 420 | writeFile(path, content); |
| 421 | return treeFileArtifact; |
| 422 | } |
| 423 | |
ajurkowski | e298291 | 2020-04-09 10:32:08 -0700 | [diff] [blame] | 424 | private static void assertValueMatches(FileStatus file, byte[] digest, FileArtifactValue value) |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 425 | throws IOException { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 426 | assertThat(value.getSize()).isEqualTo(file.getSize()); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 427 | if (digest == null) { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 428 | assertThat(value.getDigest()).isNull(); |
| 429 | assertThat(value.getModifiedTime()).isEqualTo(file.getLastModifiedTime()); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 430 | } else { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 431 | assertThat(value.getDigest()).isEqualTo(digest); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 432 | } |
| 433 | } |
| 434 | |
| 435 | private FileArtifactValue evaluateFAN(Artifact artifact) throws Throwable { |
| 436 | return ((FileArtifactValue) evaluateArtifactValue(artifact)); |
| 437 | } |
| 438 | |
Janak Ramakrishnan | ad77f97 | 2016-07-29 20:58:42 +0000 | [diff] [blame] | 439 | private SkyValue evaluateArtifactValue(Artifact artifact) throws Throwable { |
lberki | 36df7ed | 2019-06-27 06:32:03 -0700 | [diff] [blame] | 440 | SkyKey key = Artifact.key(artifact); |
Janak Ramakrishnan | ad77f97 | 2016-07-29 20:58:42 +0000 | [diff] [blame] | 441 | EvaluationResult<SkyValue> result = evaluate(ImmutableList.of(key).toArray(new SkyKey[0])); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 442 | if (result.hasError()) { |
| 443 | throw result.getError().getException(); |
| 444 | } |
janakr | 8541f6d | 2019-06-11 14:40:21 -0700 | [diff] [blame] | 445 | SkyValue value = result.get(key); |
| 446 | if (value instanceof ActionExecutionValue) { |
Googler | aed4160 | 2020-06-02 12:22:53 -0700 | [diff] [blame] | 447 | return ((ActionExecutionValue) value).getExistingFileArtifactValue(artifact); |
janakr | 8541f6d | 2019-06-11 14:40:21 -0700 | [diff] [blame] | 448 | } |
| 449 | return value; |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 450 | } |
| 451 | |
janakr | 0175ce3 | 2018-02-26 15:54:57 -0800 | [diff] [blame] | 452 | private void setGeneratingActions() throws InterruptedException, ActionConflictException { |
janakr | 573807d | 2018-01-11 14:02:35 -0800 | [diff] [blame] | 453 | if (evaluator.getExistingValue(ALL_OWNER) == null) { |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 454 | differencer.inject( |
| 455 | ImmutableMap.of( |
janakr | 573807d | 2018-01-11 14:02:35 -0800 | [diff] [blame] | 456 | ALL_OWNER, |
cparsons | e2d200f | 2018-03-06 16:15:11 -0800 | [diff] [blame] | 457 | new BasicActionLookupValue( |
janakr | efb3f15 | 2019-06-05 17:42:34 -0700 | [diff] [blame] | 458 | Actions.assignOwnersAndFilterSharedActionsAndThrowActionConflict( |
| 459 | actionKeyContext, |
| 460 | ImmutableList.copyOf(actions), |
| 461 | ALL_OWNER, |
Googler | ce6ad29 | 2019-12-20 10:29:21 -0800 | [diff] [blame] | 462 | /*outputFiles=*/ null)))); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 463 | } |
| 464 | } |
| 465 | |
| 466 | private <E extends SkyValue> EvaluationResult<E> evaluate(SkyKey... keys) |
janakr | 0175ce3 | 2018-02-26 15:54:57 -0800 | [diff] [blame] | 467 | throws InterruptedException, ActionConflictException { |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 468 | setGeneratingActions(); |
Googler | 1002867 | 2018-10-25 12:14:34 -0700 | [diff] [blame] | 469 | EvaluationContext evaluationContext = |
| 470 | EvaluationContext.newBuilder() |
| 471 | .setKeepGoing(false) |
| 472 | .setNumThreads(SkyframeExecutor.DEFAULT_THREAD_COUNT) |
michajlo | 7a485be | 2020-07-30 11:08:46 -0700 | [diff] [blame] | 473 | .setEventHandler(NullEventHandler.INSTANCE) |
Googler | 1002867 | 2018-10-25 12:14:34 -0700 | [diff] [blame] | 474 | .build(); |
| 475 | return driver.evaluate(Arrays.asList(keys), evaluationContext); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 476 | } |
| 477 | |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 478 | /** |
| 479 | * Value builder for actions that just stats and stores the output file (which must either be |
| 480 | * orphaned or exist). |
| 481 | */ |
| 482 | private static final class SimpleActionExecutionFunction implements SkyFunction { |
| 483 | private final Set<Artifact> omittedOutputs; |
| 484 | |
| 485 | SimpleActionExecutionFunction(Set<Artifact> omittedOutputs) { |
| 486 | this.omittedOutputs = omittedOutputs; |
| 487 | } |
| 488 | |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 489 | @Override |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 490 | public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { |
lberki | f7eee1e | 2019-07-31 05:49:10 -0700 | [diff] [blame] | 491 | Map<Artifact, FileArtifactValue> artifactData = new HashMap<>(); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 492 | Map<Artifact, TreeArtifactValue> treeArtifactData = new HashMap<>(); |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 493 | ActionLookupData actionLookupData = (ActionLookupData) skyKey.argument(); |
| 494 | ActionLookupValue actionLookupValue = |
janakr | baf52ae | 2018-02-14 09:03:18 -0800 | [diff] [blame] | 495 | (ActionLookupValue) env.getValue(actionLookupData.getActionLookupKey()); |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 496 | Action action = actionLookupValue.getAction(actionLookupData.getActionIndex()); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 497 | Artifact output = Iterables.getOnlyElement(action.getOutputs()); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 498 | |
| 499 | try { |
Googler | 3b2967d | 2020-05-18 14:54:46 -0700 | [diff] [blame] | 500 | if (omittedOutputs.contains(output)) { |
| 501 | Preconditions.checkState(!output.isTreeArtifact(), "Cannot omit %s", output); |
| 502 | artifactData.put(output, FileArtifactValue.OMITTED_FILE_MARKER); |
| 503 | } else if (output.isTreeArtifact()) { |
jhorvitz | ed7ec3b | 2020-07-24 15:08:03 -0700 | [diff] [blame] | 504 | SpecialArtifact parent = (SpecialArtifact) output; |
Googler | 1d8d138 | 2020-05-18 12:10:49 -0700 | [diff] [blame] | 505 | TreeFileArtifact treeFileArtifact1 = |
| 506 | TreeFileArtifact.createTreeOutput((SpecialArtifact) output, "child1"); |
| 507 | TreeFileArtifact treeFileArtifact2 = |
| 508 | TreeFileArtifact.createTreeOutput((SpecialArtifact) output, "child2"); |
jhorvitz | ed7ec3b | 2020-07-24 15:08:03 -0700 | [diff] [blame] | 509 | TreeArtifactValue tree = |
| 510 | TreeArtifactValue.newBuilder(parent) |
| 511 | .putChild( |
| 512 | treeFileArtifact1, FileArtifactValue.createForTesting(treeFileArtifact1)) |
| 513 | .putChild( |
| 514 | treeFileArtifact2, FileArtifactValue.createForTesting(treeFileArtifact2)) |
| 515 | .build(); |
| 516 | treeArtifactData.put(output, tree); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 517 | } else if (action.getActionType() == MiddlemanType.NORMAL) { |
lberki | f225af1 | 2019-08-01 04:21:58 -0700 | [diff] [blame] | 518 | Path path = output.getPath(); |
| 519 | FileArtifactValue noDigest = |
| 520 | ActionMetadataHandler.fileArtifactValueFromArtifact( |
| 521 | output, |
| 522 | FileStatusWithDigestAdapter.adapt(path.statIfFound(Symlinks.NOFOLLOW)), |
| 523 | null); |
| 524 | FileArtifactValue withDigest = |
| 525 | FileArtifactValue.createFromInjectedDigest( |
| 526 | noDigest, path.getDigest(), !output.isConstantMetadata()); |
| 527 | artifactData.put(output, withDigest); |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 528 | } else { |
lberki | c35878a | 2019-08-01 02:28:54 -0700 | [diff] [blame] | 529 | artifactData.put(output, FileArtifactValue.DEFAULT_MIDDLEMAN); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 530 | } |
Rumou Duan | 7387620 | 2016-06-06 18:52:08 +0000 | [diff] [blame] | 531 | } catch (IOException e) { |
| 532 | throw new IllegalStateException(e); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 533 | } |
janakr | b9d8d58 | 2018-06-13 21:57:19 -0700 | [diff] [blame] | 534 | return ActionExecutionValue.create( |
| 535 | artifactData, |
| 536 | treeArtifactData, |
janakr | b9d8d58 | 2018-06-13 21:57:19 -0700 | [diff] [blame] | 537 | /*outputSymlinks=*/ null, |
shahan | ef6f4cf | 2018-06-26 11:24:59 -0700 | [diff] [blame] | 538 | /*discoveredModules=*/ null, |
janakr | 9f496f3 | 2018-10-24 15:08:09 -0700 | [diff] [blame] | 539 | /*actionDependsOnBuildId=*/ false); |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 540 | } |
| 541 | |
| 542 | @Override |
| 543 | public String extractTag(SkyKey skyKey) { |
| 544 | return null; |
| 545 | } |
| 546 | } |
Han-Wen Nienhuys | 81b9083 | 2015-10-26 16:57:27 +0000 | [diff] [blame] | 547 | } |