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