blob: f93c53ae5fb3ea5ac6e080b9fc1518e8c4029e37 [file] [log] [blame]
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +00001// 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.
14package com.google.devtools.build.lib.skyframe;
15
16import static com.google.devtools.build.lib.actions.util.ActionCacheTestHelper.AMNESIAC_CACHE;
17
tomlua155b532017-11-08 20:12:47 +010018import com.google.common.base.Preconditions;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000019import com.google.common.base.Predicate;
20import com.google.common.base.Predicates;
janakr93e3eea2017-03-30 22:09:37 +000021import com.google.common.base.Suppliers;
Lukacs Berkid3262d12015-10-30 14:33:51 +000022import com.google.common.collect.ImmutableList;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000023import com.google.common.collect.ImmutableMap;
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +000024import com.google.common.collect.ImmutableSet;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000025import com.google.common.collect.Iterables;
26import com.google.common.collect.Range;
27import com.google.common.collect.Sets;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000028import com.google.devtools.build.lib.actions.Action;
Rumou Duan33bab462016-04-25 17:55:12 +000029import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000030import com.google.devtools.build.lib.actions.ActionCacheChecker;
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +000031import com.google.devtools.build.lib.actions.ActionExecutionContext;
32import com.google.devtools.build.lib.actions.ActionExecutionException;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000033import com.google.devtools.build.lib.actions.ActionExecutionStatusReporter;
ulfjack7599a4d2017-07-21 13:58:33 +020034import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
tomlu3d1a1942017-11-29 14:01:21 -080035import com.google.devtools.build.lib.actions.ActionKeyContext;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000036import com.google.devtools.build.lib.actions.ActionLogBufferPathGenerator;
janakr93e3eea2017-03-30 22:09:37 +000037import com.google.devtools.build.lib.actions.ActionLookupData;
38import com.google.devtools.build.lib.actions.ActionLookupValue;
ruperts841880d2017-10-18 00:58:29 +020039import com.google.devtools.build.lib.actions.ActionResult;
janakr0175ce32018-02-26 15:54:57 -080040import com.google.devtools.build.lib.actions.Actions;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000041import com.google.devtools.build.lib.actions.Artifact;
janakr45b308a2018-06-08 12:51:58 -070042import com.google.devtools.build.lib.actions.ArtifactOwner;
tomlu1cdcdf92018-01-16 11:07:51 -080043import com.google.devtools.build.lib.actions.ArtifactRoot;
cparsonse2d200f2018-03-06 16:15:11 -080044import com.google.devtools.build.lib.actions.BasicActionLookupValue;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000045import com.google.devtools.build.lib.actions.BuildFailedException;
46import com.google.devtools.build.lib.actions.Executor;
shahan602cc852018-06-06 20:09:57 -070047import com.google.devtools.build.lib.actions.FileStateValue;
48import com.google.devtools.build.lib.actions.FileValue;
shahan499503b2018-06-07 18:57:07 -070049import com.google.devtools.build.lib.actions.MetadataProvider;
janakr0175ce32018-02-26 15:54:57 -080050import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000051import com.google.devtools.build.lib.actions.ResourceManager;
52import com.google.devtools.build.lib.actions.ResourceSet;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000053import com.google.devtools.build.lib.actions.TestExecException;
54import com.google.devtools.build.lib.actions.cache.ActionCache;
jmmv9573a0d2017-09-26 11:59:22 -040055import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics;
56import com.google.devtools.build.lib.actions.cache.Protos.ActionCacheStatistics.MissReason;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000057import com.google.devtools.build.lib.actions.util.DummyExecutor;
58import com.google.devtools.build.lib.actions.util.TestAction;
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +000059import com.google.devtools.build.lib.analysis.BlazeDirectories;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000060import com.google.devtools.build.lib.analysis.ConfiguredTarget;
janakr3b63a4e2017-09-14 09:55:40 +020061import com.google.devtools.build.lib.analysis.ServerDirectories;
Googlerbfd4e242016-07-15 22:23:37 +000062import com.google.devtools.build.lib.analysis.TopLevelArtifactContext;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000063import com.google.devtools.build.lib.buildtool.SkyframeBuilder;
philwo3bcb9f62017-09-06 12:52:21 +020064import com.google.devtools.build.lib.clock.BlazeClock;
65import com.google.devtools.build.lib.clock.Clock;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000066import com.google.devtools.build.lib.events.Reporter;
67import com.google.devtools.build.lib.events.StoredEventHandler;
Rumou Duana1c75342016-10-12 22:39:19 +000068import com.google.devtools.build.lib.exec.SingleBuildFileCache;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000069import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
tomlu6ed4fd52018-04-03 10:01:10 -070070import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
Nathan Harmatad4f75942016-10-18 08:55:17 +000071import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
John Cater5e9ce942016-10-12 17:23:30 +000072import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy;
Janak Ramakrishnan3bf4fd02017-03-21 19:01:13 +000073import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ActionCompletedReceiver;
74import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ProgressSupplier;
shahan569e1692018-02-20 16:06:00 -080075import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
Florian Weikertcca703a2015-12-07 09:56:38 +000076import com.google.devtools.build.lib.testutil.FoundationTestCase;
Luis Fernando Pino Duquebe102182016-05-23 14:03:55 +000077import com.google.devtools.build.lib.testutil.TestConstants;
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +000078import com.google.devtools.build.lib.testutil.TestRuleClassProvider;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000079import com.google.devtools.build.lib.testutil.TestUtils;
80import com.google.devtools.build.lib.util.AbruptExitException;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000081import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor;
82import com.google.devtools.build.lib.vfs.FileSystem;
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +000083import com.google.devtools.build.lib.vfs.FileSystemUtils;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000084import com.google.devtools.build.lib.vfs.Path;
85import com.google.devtools.build.lib.vfs.PathFragment;
tomluee6a6862018-01-17 14:36:26 -080086import com.google.devtools.build.lib.vfs.Root;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000087import com.google.devtools.build.skyframe.CycleInfo;
88import com.google.devtools.build.skyframe.ErrorInfo;
89import com.google.devtools.build.skyframe.EvaluationProgressReceiver;
90import com.google.devtools.build.skyframe.EvaluationResult;
91import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator;
92import com.google.devtools.build.skyframe.RecordingDifferencer;
janakr1cde8722017-10-10 03:22:21 +020093import com.google.devtools.build.skyframe.SequencedRecordingDifferencer;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000094import com.google.devtools.build.skyframe.SequentialBuildDriver;
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +000095import com.google.devtools.build.skyframe.SkyFunction;
Rumou Duan73876202016-06-06 18:52:08 +000096import com.google.devtools.build.skyframe.SkyFunctionException;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +000097import com.google.devtools.build.skyframe.SkyFunctionName;
98import com.google.devtools.build.skyframe.SkyKey;
99import com.google.devtools.build.skyframe.SkyValue;
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +0000100import java.io.IOException;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000101import java.io.PrintStream;
102import java.util.ArrayList;
103import java.util.Collection;
104import java.util.Collections;
105import java.util.HashMap;
106import java.util.HashSet;
107import java.util.List;
108import java.util.Map;
109import java.util.Set;
110import java.util.UUID;
111import java.util.concurrent.atomic.AtomicReference;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000112import javax.annotation.Nullable;
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000113import org.junit.Before;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000114
115/**
116 * The common code that's shared between various builder tests.
117 */
Florian Weikertcca703a2015-12-07 09:56:38 +0000118public abstract class TimestampBuilderTestCase extends FoundationTestCase {
shahan1fe23122018-02-28 09:18:36 -0800119 @AutoCodec
janakr573807d2018-01-11 14:02:35 -0800120 protected static final ActionLookupValue.ActionLookupKey ACTION_LOOKUP_KEY =
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000121 new SingletonActionLookupKey();
shahan1fe23122018-02-28 09:18:36 -0800122
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000123 protected static final Predicate<Action> ALWAYS_EXECUTE_FILTER = Predicates.alwaysTrue();
124 protected static final String CYCLE_MSG = "Yarrrr, there be a cycle up in here";
125
126 protected Clock clock = BlazeClock.instance();
127 protected TimestampGranularityMonitor tsgm;
janakr1cde8722017-10-10 03:22:21 +0200128 protected RecordingDifferencer differencer = new SequencedRecordingDifferencer();
Rumou Duan73876202016-06-06 18:52:08 +0000129 private Set<ActionAnalysisMetadata> actions;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000130
tomlu3d1a1942017-11-29 14:01:21 -0800131 protected final ActionKeyContext actionKeyContext = new ActionKeyContext();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000132
Florian Weikert92b22362015-12-03 10:17:18 +0000133 @Before
134 public final void initialize() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000135 inMemoryCache = new InMemoryActionCache();
136 tsgm = new TimestampGranularityMonitor(clock);
137 ResourceManager.instance().setAvailableResources(ResourceSet.createWithRamCpuIo(100, 1, 1));
138 actions = new HashSet<>();
janakr93e3eea2017-03-30 22:09:37 +0000139 actionTemplateExpansionFunction =
tomlu3d1a1942017-11-29 14:01:21 -0800140 new ActionTemplateExpansionFunction(actionKeyContext, Suppliers.ofInstance(false));
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000141 }
142
143 protected void clearActions() {
144 actions.clear();
145 }
146
Rumou Duan73876202016-06-06 18:52:08 +0000147 protected <T extends ActionAnalysisMetadata> T registerAction(T action) {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000148 actions.add(action);
149 return action;
150 }
151
Ulf Adams94f63302016-04-29 15:04:13 +0000152 protected Builder createBuilder(ActionCache actionCache) throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000153 return createBuilder(actionCache, 1, /*keepGoing=*/ false);
154 }
155
156 /**
157 * Create a ParallelBuilder with a DatabaseDependencyChecker using the
158 * specified ActionCache.
159 */
160 protected Builder createBuilder(
Ulf Adams94f63302016-04-29 15:04:13 +0000161 ActionCache actionCache, final int threadCount, final boolean keepGoing) throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000162 return createBuilder(actionCache, threadCount, keepGoing, null);
163 }
164
165 protected Builder createBuilder(
166 final ActionCache actionCache,
167 final int threadCount,
168 final boolean keepGoing,
Ulf Adams94f63302016-04-29 15:04:13 +0000169 @Nullable EvaluationProgressReceiver evaluationProgressReceiver) throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000170 AtomicReference<PathPackageLocator> pkgLocator =
John Catere0d1d0e2017-11-28 20:47:41 -0800171 new AtomicReference<>(
172 new PathPackageLocator(
173 outputBase,
tomluee6a6862018-01-17 14:36:26 -0800174 ImmutableList.of(Root.fromPath(rootDirectory)),
John Catere0d1d0e2017-11-28 20:47:41 -0800175 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY));
Ulf Adamsc73051c62016-03-23 09:18:13 +0000176 AtomicReference<TimestampGranularityMonitor> tsgmRef = new AtomicReference<>(tsgm);
janakr3b63a4e2017-09-14 09:55:40 +0200177 BlazeDirectories directories =
178 new BlazeDirectories(
Klaus Aehligc2499c42018-02-27 05:47:21 -0800179 new ServerDirectories(rootDirectory, outputBase, outputBase),
janakr3b63a4e2017-09-14 09:55:40 +0200180 rootDirectory,
cushon849df362018-05-14 01:51:45 -0700181 /* defaultSystemJavabase= */ null,
janakr3b63a4e2017-09-14 09:55:40 +0200182 TestConstants.PRODUCT_NAME);
nharmata3fb7d342018-02-23 11:37:51 -0800183 ExternalFilesHelper externalFilesHelper = ExternalFilesHelper.createForTesting(
Nathan Harmatad4f75942016-10-18 08:55:17 +0000184 pkgLocator,
185 ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS,
186 directories);
janakr1cde8722017-10-10 03:22:21 +0200187 differencer = new SequencedRecordingDifferencer();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000188
189 ActionExecutionStatusReporter statusReporter =
190 ActionExecutionStatusReporter.create(new StoredEventHandler());
191 final SkyframeActionExecutor skyframeActionExecutor =
shahanb1dd4e32018-05-09 08:23:31 -0700192 new SkyframeActionExecutor(
193 actionKeyContext,
194 new AtomicReference<>(statusReporter),
shahan0015d182018-05-15 15:09:46 -0700195 /*sourceRootSupplier=*/ () -> ImmutableList.of(),
shahanb1dd4e32018-05-09 08:23:31 -0700196 /*usesActionFileSystem=*/ () -> false);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000197
Ulf Adams94f63302016-04-29 15:04:13 +0000198 Path actionOutputBase = scratch.dir("/usr/local/google/_blaze_jrluser/FAKEMD5/action_out/");
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000199 skyframeActionExecutor.setActionLogBufferPathGenerator(
200 new ActionLogBufferPathGenerator(actionOutputBase));
201
shahan499503b2018-06-07 18:57:07 -0700202 MetadataProvider cache =
203 new SingleBuildFileCache(rootDirectory.getPathString(), scratch.getFileSystem());
ulfjack7599a4d2017-07-21 13:58:33 +0200204 skyframeActionExecutor.configure(cache, ActionInputPrefetcher.NONE);
Rumou Duana1c75342016-10-12 22:39:19 +0000205
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000206 final InMemoryMemoizingEvaluator evaluator =
207 new InMemoryMemoizingEvaluator(
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +0000208 ImmutableMap.<SkyFunctionName, SkyFunction>builder()
shahan602cc852018-06-06 20:09:57 -0700209 .put(FileStateValue.FILE_STATE, new FileStateFunction(tsgmRef, externalFilesHelper))
210 .put(FileValue.FILE, new FileFunction(pkgLocator))
janakr45b308a2018-06-08 12:51:58 -0700211 .put(Artifact.ARTIFACT, new ArtifactFunction())
Damien Martin-Guillerezbc8b5e02016-02-05 22:09:09 +0000212 .put(
213 SkyFunctions.ACTION_EXECUTION,
Ulf Adamsc73051c62016-03-23 09:18:13 +0000214 new ActionExecutionFunction(skyframeActionExecutor, tsgmRef))
Damien Martin-Guillerezbc8b5e02016-02-05 22:09:09 +0000215 .put(
216 SkyFunctions.PACKAGE,
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +0000217 new PackageFunction(null, null, null, null, null, null, null))
John Cater5e9ce942016-10-12 17:23:30 +0000218 .put(
219 SkyFunctions.PACKAGE_LOOKUP,
John Cater0c0735a2016-11-11 01:52:02 +0000220 new PackageLookupFunction(
221 null,
222 CrossRepositoryLabelViolationStrategy.ERROR,
John Catere0d1d0e2017-11-28 20:47:41 -0800223 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY))
Damien Martin-Guillerezbc8b5e02016-02-05 22:09:09 +0000224 .put(
225 SkyFunctions.WORKSPACE_AST,
Damien Martin-Guillerez4ecfe512016-01-22 11:03:23 +0000226 new WorkspaceASTFunction(TestRuleClassProvider.getRuleClassProvider()))
Damien Martin-Guillerezbc8b5e02016-02-05 22:09:09 +0000227 .put(
228 SkyFunctions.WORKSPACE_FILE,
229 new WorkspaceFileFunction(
230 TestRuleClassProvider.getRuleClassProvider(),
John Catere0d1d0e2017-11-28 20:47:41 -0800231 TestConstants.PACKAGE_FACTORY_BUILDER_FACTORY_FOR_TESTING
carmid6a98282018-03-13 19:19:16 -0700232 .builder(directories)
nharmatae57e9a32018-04-02 15:10:24 -0700233 .build(TestRuleClassProvider.getRuleClassProvider()),
Kristina Chodorow5a2936f2016-04-22 17:02:19 +0000234 directories))
Damien Martin-Guillerezbc8b5e02016-02-05 22:09:09 +0000235 .put(SkyFunctions.EXTERNAL_PACKAGE, new ExternalPackageFunction())
John Cater5e9ce942016-10-12 17:23:30 +0000236 .put(
237 SkyFunctions.ACTION_TEMPLATE_EXPANSION,
238 new DelegatingActionTemplateExpansionFunction())
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +0000239 .build(),
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000240 differencer,
241 evaluationProgressReceiver);
242 final SequentialBuildDriver driver = new SequentialBuildDriver(evaluator);
243 PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID());
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +0000244 PrecomputedValue.ACTION_ENV.set(differencer, ImmutableMap.<String, String>of());
Kristina Chodorowf9fdc8d2015-12-08 12:49:31 +0000245 PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get());
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000246
247 return new Builder() {
janakr0175ce32018-02-26 15:54:57 -0800248 private void setGeneratingActions() throws ActionConflictException {
janakr573807d2018-01-11 14:02:35 -0800249 if (evaluator.getExistingValue(ACTION_LOOKUP_KEY) == null) {
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000250 differencer.inject(
janakr93e3eea2017-03-30 22:09:37 +0000251 ImmutableMap.of(
janakr573807d2018-01-11 14:02:35 -0800252 ACTION_LOOKUP_KEY,
cparsonse2d200f2018-03-06 16:15:11 -0800253 new BasicActionLookupValue(
janakr0175ce32018-02-26 15:54:57 -0800254 Actions.filterSharedActionsAndThrowActionConflict(
255 actionKeyContext, ImmutableList.copyOf(actions)),
256 false)));
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000257 }
258 }
259
260 @Override
261 public void buildArtifacts(
262 Reporter reporter,
263 Set<Artifact> artifacts,
264 Set<ConfiguredTarget> parallelTests,
265 Set<ConfiguredTarget> exclusiveTests,
gregce45ae0962017-07-22 00:11:13 +0200266 Set<ConfiguredTarget> targetsToBuild,
267 Set<ConfiguredTarget> targetsToSkip,
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000268 Collection<AspectValue> aspects,
269 Executor executor,
cpeyser8e9b28f2018-06-04 08:05:13 -0700270 Set<ConfiguredTargetKey> builtTargets,
tomlu6ed4fd52018-04-03 10:01:10 -0700271 Set<AspectKey> builtAspects,
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000272 boolean explain,
Googlerbfd4e242016-07-15 22:23:37 +0000273 Range<Long> lastExecutionTimeRange,
274 TopLevelArtifactContext topLevelArtifactContext)
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000275 throws BuildFailedException, AbruptExitException, InterruptedException,
276 TestExecException {
277 skyframeActionExecutor.prepareForExecution(
278 reporter,
279 executor,
janakrc8dce992017-09-25 21:48:27 +0200280 keepGoing,
281 /*explain=*/ false,
tomlu3d1a1942017-11-29 14:01:21 -0800282 new ActionCacheChecker(
283 actionCache, null, actionKeyContext, ALWAYS_EXECUTE_FILTER, null),
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000284 null);
Janak Ramakrishnan3bf4fd02017-03-21 19:01:13 +0000285 skyframeActionExecutor.setActionExecutionProgressReportingObjects(
286 EMPTY_PROGRESS_SUPPLIER, EMPTY_COMPLETION_RECEIVER);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000287
288 List<SkyKey> keys = new ArrayList<>();
289 for (Artifact artifact : artifacts) {
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000290 keys.add(ArtifactSkyKey.key(artifact, true));
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000291 }
292
janakr0175ce32018-02-26 15:54:57 -0800293 try {
294 setGeneratingActions();
295 } catch (ActionConflictException e) {
296 throw new IllegalStateException(e);
297 }
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000298 EvaluationResult<SkyValue> result = driver.evaluate(keys, keepGoing, threadCount, reporter);
299
300 if (result.hasError()) {
301 boolean hasCycles = false;
302 for (Map.Entry<SkyKey, ErrorInfo> entry : result.errorMap().entrySet()) {
303 Iterable<CycleInfo> cycles = entry.getValue().getCycleInfo();
304 hasCycles |= !Iterables.isEmpty(cycles);
305 }
306 if (hasCycles) {
307 throw new BuildFailedException(CYCLE_MSG);
308 } else if (result.errorMap().isEmpty() || keepGoing) {
309 throw new BuildFailedException();
310 } else {
311 SkyframeBuilder.rethrow(Preconditions.checkNotNull(result.getError().getException()));
312 }
313 }
314 }
315 };
316 }
317
318 /** A non-persistent cache. */
319 protected InMemoryActionCache inMemoryCache;
320
Rumou Duan73876202016-06-06 18:52:08 +0000321 protected SkyFunction actionTemplateExpansionFunction;
322
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000323 /** A class that records an event. */
324 protected static class Button implements Runnable {
325 protected boolean pressed = false;
326
327 @Override
328 public void run() {
329 pressed = true;
330 }
331 }
332
333 /** A class that counts occurrences of an event. */
334 static class Counter implements Runnable {
335 int count = 0;
336
337 @Override
338 public void run() {
339 count++;
340 }
341 }
342
Rumou Duana1c75342016-10-12 22:39:19 +0000343 protected Artifact createSourceArtifact(String name) {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000344 return createSourceArtifact(scratch.getFileSystem(), name);
345 }
346
janakr45b308a2018-06-08 12:51:58 -0700347 private static Artifact createSourceArtifact(FileSystem fs, String name) {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000348 Path root = fs.getPath(TestUtils.tmpDir());
janakr45b308a2018-06-08 12:51:58 -0700349 return new Artifact.SourceArtifact(
350 ArtifactRoot.asSourceRoot(Root.fromPath(root)),
351 PathFragment.create(name),
352 ArtifactOwner.NullArtifactOwner.INSTANCE);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000353 }
354
355 protected Artifact createDerivedArtifact(String name) {
356 return createDerivedArtifact(scratch.getFileSystem(), name);
357 }
358
359 Artifact createDerivedArtifact(FileSystem fs, String name) {
360 Path execRoot = fs.getPath(TestUtils.tmpDir());
nharmatab4060b62017-04-04 17:11:39 +0000361 PathFragment execPath = PathFragment.create("out").getRelative(name);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000362 return new Artifact(
tomlu1cdcdf92018-01-16 11:07:51 -0800363 ArtifactRoot.asDerivedRoot(execRoot, execRoot.getRelative("out")),
janakr573807d2018-01-11 14:02:35 -0800364 execPath,
365 ACTION_LOOKUP_KEY);
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000366 }
367
368 /**
369 * Creates and returns a new "amnesiac" builder based on the amnesiac cache.
370 */
Ulf Adams94f63302016-04-29 15:04:13 +0000371 protected Builder amnesiacBuilder() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000372 return createBuilder(AMNESIAC_CACHE);
373 }
374
375 /**
376 * Creates and returns a new caching builder based on the inMemoryCache.
377 */
Ulf Adams94f63302016-04-29 15:04:13 +0000378 protected Builder cachingBuilder() throws Exception {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000379 return createBuilder(inMemoryCache);
380 }
381
382 /**
383 * Creates a TestAction from 'inputs' to 'outputs', and a new button, such
384 * that executing the action causes the button to be pressed. The button is
385 * returned.
386 */
387 protected Button createActionButton(Collection<Artifact> inputs, Collection<Artifact> outputs) {
388 Button button = new Button();
389 registerAction(new TestAction(button, inputs, outputs));
390 return button;
391 }
392
393 /**
394 * Creates a TestAction from 'inputs' to 'outputs', and a new counter, such
395 * that executing the action causes the counter to be incremented. The
396 * counter is returned.
397 */
398 protected Counter createActionCounter(Collection<Artifact> inputs, Collection<Artifact> outputs) {
399 Counter counter = new Counter();
400 registerAction(new TestAction(counter, inputs, outputs));
401 return counter;
402 }
403
404 protected static Set<Artifact> emptySet = Collections.emptySet();
405
406 protected void buildArtifacts(Builder builder, Artifact... artifacts)
407 throws BuildFailedException, AbruptExitException, InterruptedException, TestExecException {
tomluf903eb52017-10-27 12:12:11 -0400408 buildArtifacts(builder, new DummyExecutor(fileSystem, rootDirectory), artifacts);
Rumou Duana1c75342016-10-12 22:39:19 +0000409 }
410
411 protected void buildArtifacts(Builder builder, Executor executor, Artifact... artifacts)
412 throws BuildFailedException, AbruptExitException, InterruptedException, TestExecException {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000413
414 tsgm.setCommandStartTime();
415 Set<Artifact> artifactsToBuild = Sets.newHashSet(artifacts);
cpeyser8e9b28f2018-06-04 08:05:13 -0700416 Set<ConfiguredTargetKey> builtTargets = new HashSet<>();
tomlu6ed4fd52018-04-03 10:01:10 -0700417 Set<AspectKey> builtAspects = new HashSet<>();
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000418 try {
419 builder.buildArtifacts(
420 reporter,
421 artifactsToBuild,
422 null,
423 null,
424 null,
425 null,
gregce45ae0962017-07-22 00:11:13 +0200426 null,
Rumou Duana1c75342016-10-12 22:39:19 +0000427 executor,
tomlu6ed4fd52018-04-03 10:01:10 -0700428 builtTargets,
429 builtAspects,
430 false /*explain*/,
Googlerbfd4e242016-07-15 22:23:37 +0000431 null,
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000432 null);
433 } finally {
434 tsgm.waitForTimestampGranularity(reporter.getOutErr());
435 }
436 }
437
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +0000438 /** {@link TestAction} that copies its single input to its single output. */
439 protected static class CopyingAction extends TestAction {
440 CopyingAction(Runnable effect, Artifact input, Artifact output) {
441 super(effect, ImmutableSet.of(input), ImmutableSet.of(output));
442 }
443
444 @Override
ruperts841880d2017-10-18 00:58:29 +0200445 public ActionResult execute(ActionExecutionContext actionExecutionContext)
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +0000446 throws ActionExecutionException {
ruperts841880d2017-10-18 00:58:29 +0200447 ActionResult actionResult = super.execute(actionExecutionContext);
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +0000448 try {
449 FileSystemUtils.copyFile(
450 Iterables.getOnlyElement(getInputs()).getPath(),
451 Iterables.getOnlyElement(getOutputs()).getPath());
452 } catch (IOException e) {
453 throw new IllegalStateException(e);
454 }
ruperts841880d2017-10-18 00:58:29 +0200455 return actionResult;
Janak Ramakrishnan08b0f7f2016-07-13 17:00:59 +0000456 }
457 }
458
ruperts5afd9ee2017-09-28 19:47:49 -0400459 /** In-memory {@link ActionCache} backed by a HashMap */
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000460 protected static class InMemoryActionCache implements ActionCache {
461
462 private final Map<String, Entry> actionCache = new HashMap<>();
463
464 @Override
465 public synchronized void put(String key, ActionCache.Entry entry) {
466 actionCache.put(key, entry);
467 }
468
469 @Override
470 public synchronized Entry get(String key) {
471 return actionCache.get(key);
472 }
473
474 @Override
475 public synchronized void remove(String key) {
476 actionCache.remove(key);
477 }
478
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000479 public synchronized void reset() {
480 actionCache.clear();
481 }
482
483 @Override
484 public long save() {
485 // safe to ignore
486 return 0;
487 }
488
489 @Override
Yun Penge44da5a2017-06-16 21:34:09 +0200490 public void clear() {
491 // safe to ignore
492 }
493
494 @Override
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000495 public void dump(PrintStream out) {
496 out.println("In-memory action cache has " + actionCache.size() + " records");
497 }
jmmv9573a0d2017-09-26 11:59:22 -0400498
499 @Override
500 public void accountHit() {
501 // Not needed for these tests.
502 }
503
504 @Override
505 public void accountMiss(MissReason reason) {
506 // Not needed for these tests.
507 }
508
509 @Override
510 public void mergeIntoActionCacheStatistics(ActionCacheStatistics.Builder builder) {
511 // Not needed for these tests.
512 }
513
514 @Override
515 public void resetStatistics() {
516 // Not needed for these tests.
517 }
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000518 }
519
shahan569e1692018-02-20 16:06:00 -0800520 static class SingletonActionLookupKey extends ActionLookupValue.ActionLookupKey {
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000521 @Override
janakr573807d2018-01-11 14:02:35 -0800522 public SkyFunctionName functionName() {
523 return SkyFunctions.CONFIGURED_TARGET;
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000524 }
525 }
Rumou Duan73876202016-06-06 18:52:08 +0000526
527 private class DelegatingActionTemplateExpansionFunction implements SkyFunction {
528 @Override
529 public SkyValue compute(SkyKey skyKey, Environment env)
530 throws SkyFunctionException, InterruptedException {
531 return actionTemplateExpansionFunction.compute(skyKey, env);
532 }
533
534 @Override
535 public String extractTag(SkyKey skyKey) {
536 return actionTemplateExpansionFunction.extractTag(skyKey);
John Cater5e9ce942016-10-12 17:23:30 +0000537 }
Rumou Duan73876202016-06-06 18:52:08 +0000538 }
Janak Ramakrishnan3bf4fd02017-03-21 19:01:13 +0000539
540 private static final ProgressSupplier EMPTY_PROGRESS_SUPPLIER =
541 new ProgressSupplier() {
542 @Override
543 public String getProgressString() {
544 return "";
545 }
546 };
547
548 private static final ActionCompletedReceiver EMPTY_COMPLETION_RECEIVER =
549 new ActionCompletedReceiver() {
550 @Override
janakr93e3eea2017-03-30 22:09:37 +0000551 public void actionCompleted(ActionLookupData actionLookupData) {}
552
553 @Override
554 public void noteActionEvaluationStarted(ActionLookupData actionLookupData, Action action) {}
Janak Ramakrishnan3bf4fd02017-03-21 19:01:13 +0000555 };
Han-Wen Nienhuys81b90832015-10-26 16:57:27 +0000556}