diff options
author | 2017-10-18 00:58:29 +0200 | |
---|---|---|
committer | 2017-10-18 10:28:27 +0200 | |
commit | 841880dc66bfd0702a08105835a445cb3dc271c9 (patch) | |
tree | 758c9178d16f161ed19313a7f0d082c19a4a6db5 | |
parent | 34a9fea78f201caed8ace5c714a0cf288cb97c65 (diff) |
Actions now have the option of returning an ActionResult, containing a (possibly empty) set of SpawnResults created during execution of the Action.
RELNOTES: None.
PiperOrigin-RevId: 172529328
35 files changed, 376 insertions, 220 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Action.java b/src/main/java/com/google/devtools/build/lib/actions/Action.java index 9faddfea0c..e87d79edcf 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Action.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Action.java @@ -89,32 +89,31 @@ public interface Action extends ActionExecutionMetadata, Describable { void prepare(Path execRoot) throws IOException; /** - * Executes this action; called by the Builder when all of this Action's - * inputs have been successfully created. (Behaviour is undefined if the - * prerequisites are not up to date.) This method <i>actually does the work - * of the Action, unconditionally</i>; in other words, it is invoked by the - * Builder only when dependency analysis has deemed it necessary.</p> + * Executes this action; called by the Builder when all of this Action's inputs have been + * successfully created. (Behaviour is undefined if the prerequisites are not up to date.) This + * method <i>actually does the work of the Action, unconditionally</i>; in other words, it is + * invoked by the Builder only when dependency analysis has deemed it necessary. * - * <p>The framework guarantees that the output directory for each file in - * <code>getOutputs()</code> has already been created, and will check to - * ensure that each of those files is indeed created.</p> + * <p>The framework guarantees that the output directory for each file in <code>getOutputs() + * </code> has already been created, and will check to ensure that each of those files is indeed + * created. * - * <p>Implementations of this method should try to honour the {@link - * java.lang.Thread#interrupted} contract: if an interrupt is delivered to - * the thread in which execution occurs, the action should detect this on a - * best-effort basis and terminate as quickly as possible by throwing an + * <p>Implementations of this method should try to honour the {@link java.lang.Thread#interrupted} + * contract: if an interrupt is delivered to the thread in which execution occurs, the action + * should detect this on a best-effort basis and terminate as quickly as possible by throwing an * ActionExecutionException. * - * <p>Action execution must be ThreadCompatible in order to be safely used - * with a concurrent Builder implementation such as ParallelBuilder. + * <p>Action execution must be ThreadCompatible in order to be safely used with a concurrent + * Builder implementation such as ParallelBuilder. * - * @param actionExecutionContext Services in the scope of the action, like the output and error - * streams to use for messages arising during action execution. - * @throws ActionExecutionException if execution fails for any reason. + * @param actionExecutionContext services in the scope of the action, like the output and error + * streams to use for messages arising during action execution + * @return returns an ActionResult containing action execution metadata + * @throws ActionExecutionException if execution fails for any reason * @throws InterruptedException */ @ConditionallyThreadCompatible - void execute(ActionExecutionContext actionExecutionContext) + ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException; /** diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionResult.java b/src/main/java/com/google/devtools/build/lib/actions/ActionResult.java new file mode 100644 index 0000000000..3ae8e02f92 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionResult.java @@ -0,0 +1,55 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.actions; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; +import java.util.Set; + +/** Holds the result(s) of an action's execution. */ +@AutoValue +public abstract class ActionResult { + + /** An empty ActionResult used by Actions that don't have any metadata to return. */ + public static final ActionResult EMPTY = ActionResult.create(ImmutableSet.of()); + + /** Returns the SpawnResults for the action. */ + public abstract Set<SpawnResult> spawnResults(); + + /** Returns a builder that can be used to construct a {@link ActionResult} object. */ + public static Builder builder() { + return new AutoValue_ActionResult.Builder(); + } + + /** Creates an ActionResult given a set of SpawnResults. */ + public static ActionResult create(Set<SpawnResult> spawnResults) { + if (spawnResults == null) { + return EMPTY; + } else { + return builder().setSpawnResults(spawnResults).build(); + } + } + + /** Builder for a {@link ActionResult} instance, which is immutable once built. */ + @AutoValue.Builder + public abstract static class Builder { + + /** Sets the SpawnResults for the action. */ + public abstract Builder setSpawnResults(Set<SpawnResult> spawnResults); + + /** Builds and returns an ActionResult object. */ + public abstract ActionResult build(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/FailAction.java b/src/main/java/com/google/devtools/build/lib/actions/FailAction.java index 8bebf4eb99..7f217409c8 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/FailAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/FailAction.java @@ -39,7 +39,7 @@ public final class FailAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { throw new ActionExecutionException(errorMessage, this, false); } diff --git a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java index 7474c7c13d..6713032058 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java @@ -51,8 +51,7 @@ public final class MiddlemanAction extends AbstractAction { } @Override - public final void execute( - ActionExecutionContext actionExecutionContext) { + public final ActionResult execute(ActionExecutionContext actionExecutionContext) { throw new IllegalStateException("MiddlemanAction should never be executed"); } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/PseudoAction.java b/src/main/java/com/google/devtools/build/lib/analysis/PseudoAction.java index d37770fd77..4c85dc0ada 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/PseudoAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/PseudoAction.java @@ -18,6 +18,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.CommandLineExpansionException; import com.google.devtools.build.lib.actions.extra.ExtraActionInfo; @@ -50,7 +51,7 @@ public class PseudoAction<InfoType extends MessageLite> extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { throw new ActionExecutionException( mnemonic + "ExtraAction should not be executed.", this, false); diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/AbstractFileWriteAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/AbstractFileWriteAction.java index 53a03d6308..3789e986b4 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/AbstractFileWriteAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/AbstractFileWriteAction.java @@ -20,6 +20,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.cmdline.Label; @@ -55,10 +56,13 @@ public abstract class AbstractFileWriteAction extends AbstractAction { } @Override - public final void execute(ActionExecutionContext actionExecutionContext) + public final ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { + ActionResult actionResult; try { - getStrategy(actionExecutionContext).exec(this, actionExecutionContext); + actionResult = + ActionResult.create( + getStrategy(actionExecutionContext).exec(this, actionExecutionContext)); } catch (ExecException e) { throw e.toActionExecutionException( "Writing file for rule '" + Label.print(getOwner().getLabel()) + "'", @@ -66,6 +70,7 @@ public abstract class AbstractFileWriteAction extends AbstractAction { this); } afterWrite(actionExecutionContext); + return actionResult; } /** diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutableSymlinkAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutableSymlinkAction.java index 4cdf2f1e12..74131b1295 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutableSymlinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutableSymlinkAction.java @@ -18,6 +18,7 @@ import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.vfs.Path; import java.io.IOException; @@ -33,7 +34,7 @@ public final class ExecutableSymlinkAction extends SymlinkAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { Path inputPath = getPrimaryInput().getPath(); try { @@ -56,7 +57,7 @@ public final class ExecutableSymlinkAction extends SymlinkAction { + "' due to I/O error: " + e.getMessage(), e, this, false); } - super.execute(actionExecutionContext); + return super.execute(actionExecutionContext); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactAction.java index 8efe29ffef..7f64be3f40 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactAction.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionMetadata; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Actions; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; @@ -34,6 +35,7 @@ import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.RunfilesSupplier; import com.google.devtools.build.lib.actions.Spawn; import com.google.devtools.build.lib.actions.SpawnActionContext; +import com.google.devtools.build.lib.actions.SpawnResult; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.util.Preconditions; @@ -43,6 +45,7 @@ import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Set; /** * An action that populates a TreeArtifact with the contents of an archive file. @@ -151,7 +154,7 @@ public final class PopulateTreeArtifactAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { Spawn spawn; @@ -167,7 +170,7 @@ public final class PopulateTreeArtifactAction extends AbstractAction { // If the spawn does not have any output, it means the archive file contains nothing. In this // case we just return without generating anything under the output TreeArtifact. if (spawn.getOutputFiles().isEmpty()) { - return; + return ActionResult.EMPTY; } // Check spawn output TreeFileArtifact conflicts. @@ -188,8 +191,9 @@ public final class PopulateTreeArtifactAction extends AbstractAction { } // Execute the spawn. + Set<SpawnResult> spawnResults; try { - getContext(actionExecutionContext).exec(spawn, actionExecutionContext); + spawnResults = getContext(actionExecutionContext).exec(spawn, actionExecutionContext); } catch (ExecException e) { throw e.toActionExecutionException( getMnemonic() + " action failed for target: " + getOwner().getLabel(), @@ -202,6 +206,7 @@ public final class PopulateTreeArtifactAction extends AbstractAction { actionExecutionContext.getMetadataHandler().addExpandedTreeOutput( (TreeFileArtifact) fileEntry); } + return ActionResult.create(spawnResults); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java index 688d2aaa94..cd19919d47 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java @@ -28,6 +28,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; import com.google.devtools.build.lib.actions.BaseSpawn; @@ -262,11 +263,10 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { try { - // TODO(b/62588075): internalExecute() now returns a set of SpawnResults, we could capture it. - internalExecute(actionExecutionContext); + return ActionResult.create(internalExecute(actionExecutionContext)); } catch (ExecException e) { String failMessage; if (isShellCommand()) { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkAction.java index df3b56f829..e9bbdf7e19 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkAction.java @@ -20,6 +20,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.util.Preconditions; @@ -107,7 +108,7 @@ public class SymlinkAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { Path srcPath; if (inputPath == null) { @@ -123,6 +124,7 @@ public class SymlinkAction extends AbstractAction { + "' to the '" + Iterables.getOnlyElement(getInputs()).prettyPrint() + "' due to I/O error: " + e.getMessage(), e, this, false); } + return ActionResult.EMPTY; } @Override diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkTreeAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkTreeAction.java index 25da294619..d510c28e86 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkTreeAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SymlinkTreeAction.java @@ -19,6 +19,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.util.Fingerprint; @@ -113,10 +114,11 @@ public final class SymlinkTreeAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { - actionExecutionContext - .getContext(SymlinkTreeActionContext.class) - .createSymlinks(this, actionExecutionContext, shellEnvironment, enableRunfiles); + return ActionResult.create( + actionExecutionContext + .getContext(SymlinkTreeActionContext.class) + .createSymlinks(this, actionExecutionContext, shellEnvironment, enableRunfiles)); } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/extra/ExtraAction.java b/src/main/java/com/google/devtools/build/lib/analysis/extra/ExtraAction.java index 8c4d14aa79..39b9f4c5bd 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/extra/ExtraAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/extra/ExtraAction.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionEnvironment; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.CompositeRunfilesSupplier; import com.google.devtools.build.lib.actions.RunfilesSupplier; @@ -147,17 +148,16 @@ public final class ExtraAction extends SpawnAction { /** * @InheritDoc * - * This method calls in to {@link AbstractAction#getInputFilesForExtraAction} and - * {@link Action#getExtraActionInfo} of the action being shadowed from the thread executing this + * <p>This method calls in to {@link AbstractAction#getInputFilesForExtraAction} and {@link + * Action#getExtraActionInfo} of the action being shadowed from the thread executing this * ExtraAction. It assumes these methods are safe to call from a different thread than the thread * responsible for the execution of the action being shadowed. */ @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { // PHASE 2: execution of extra_action. - - super.execute(actionExecutionContext); + ActionResult actionResult = super.execute(actionExecutionContext); // PHASE 3: create dummy output. // If the user didn't specify output, we need to create dummy output @@ -171,6 +171,8 @@ public final class ExtraAction extends SpawnAction { } } } + + return actionResult; } /** diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java index 49a56222e7..a3525e5501 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestRunnerAction.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.CommandLineExpansionException; import com.google.devtools.build.lib.actions.ExecException; @@ -656,11 +657,11 @@ public class TestRunnerAction extends AbstractAction implements NotifyOnActionCa } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { TestActionContext context = actionExecutionContext.getContext(TestActionContext.class); try { - context.exec(this, actionExecutionContext); + return ActionResult.create(context.exec(this, actionExecutionContext)); } catch (ExecException e) { throw e.toActionExecutionException(this); } finally { diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java index 16f882fd11..3bdb6d48ed 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java @@ -24,6 +24,7 @@ import com.google.common.eventbus.Subscribe; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactFactory; import com.google.devtools.build.lib.actions.ArtifactOwner; @@ -177,7 +178,7 @@ public class BazelWorkspaceStatusModule extends BlazeModule { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { try { Map<String, String> statusMap = parseWorkspaceStatus( @@ -231,6 +232,7 @@ public class BazelWorkspaceStatusModule extends BlazeModule { this, true); } + return ActionResult.EMPTY; } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java index 5d6c3689d4..3d93900fa6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionLookupValue; import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.ActionStatusMessage; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; @@ -37,6 +38,7 @@ import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.ExecutionInfoSpecifier; import com.google.devtools.build.lib.actions.ExecutionRequirements; import com.google.devtools.build.lib.actions.ResourceSet; +import com.google.devtools.build.lib.actions.SpawnResult; import com.google.devtools.build.lib.actions.extra.CppCompileInfo; import com.google.devtools.build.lib.actions.extra.EnvironmentVariable; import com.google.devtools.build.lib.actions.extra.ExtraActionInfo; @@ -1150,11 +1152,9 @@ public class CppCompileAction extends AbstractAction @Override @ThreadCompatible - public void execute( - ActionExecutionContext actionExecutionContext) - throws ActionExecutionException, InterruptedException { + public ActionResult execute(ActionExecutionContext actionExecutionContext) + throws ActionExecutionException, InterruptedException { setModuleFileFlags(); - CppCompileActionContext.Reply reply; ShowIncludesFilter showIncludesFilterForStdout = null; ShowIncludesFilter showIncludesFilterForStderr = null; @@ -1166,13 +1166,15 @@ public class CppCompileAction extends AbstractAction actionExecutionContext.getFileOutErr().setOutputFilter(showIncludesFilterForStdout); actionExecutionContext.getFileOutErr().setErrorFilter(showIncludesFilterForStderr); } + + Set<SpawnResult> spawnResults; try { CppCompileActionResult cppCompileActionResult = actionExecutionContext .getContext(actionContext) .execWithReply(this, actionExecutionContext); - // TODO(b/62588075) Save spawnResults from cppCompileActionResult and return them upwards. reply = cppCompileActionResult.contextReply(); + spawnResults = cppCompileActionResult.spawnResults(); } catch (ExecException e) { throw e.toActionExecutionException( "C++ compilation of rule '" + getOwner().getLabel() + "'", @@ -1213,6 +1215,7 @@ public class CppCompileAction extends AbstractAction actionExecutionContext.getArtifactExpander(), actionExecutionContext.getEventHandler()); } + return ActionResult.create(spawnResults); } @VisibleForTesting diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java index 806ecfc96a..63a8b6ce88 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.CommandAction; import com.google.devtools.build.lib.actions.CommandLineExpansionException; @@ -302,10 +303,11 @@ public final class CppLinkAction extends AbstractAction @Override @ThreadCompatible - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { if (fake) { executeFake(); + return ActionResult.EMPTY; } else { try { Spawn spawn = new SimpleSpawn( @@ -316,8 +318,10 @@ public final class CppLinkAction extends AbstractAction ImmutableList.copyOf(getMandatoryInputs()), getOutputs().asList(), estimateResourceConsumptionLocal()); - actionExecutionContext.getSpawnActionContext(getMnemonic()) - .exec(spawn, actionExecutionContext); + return ActionResult.create( + actionExecutionContext + .getSpawnActionContext(getMnemonic()) + .exec(spawn, actionExecutionContext)); } catch (ExecException e) { throw e.toActionExecutionException( "Linking of rule '" + getOwner().getLabel() + "'", diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkAction.java index ee8e92b2ef..c0da518642 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CreateIncSymlinkAction.java @@ -22,6 +22,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.util.Fingerprint; @@ -61,8 +62,8 @@ public final class CreateIncSymlinkAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) - throws ActionExecutionException { + public ActionResult execute(ActionExecutionContext actionExecutionContext) + throws ActionExecutionException { try { for (Map.Entry<Artifact, Artifact> entry : symlinks.entrySet()) { Path symlink = entry.getKey().getPath(); @@ -72,6 +73,7 @@ public final class CreateIncSymlinkAction extends AbstractAction { String message = "IO Error while creating symlink"; throw new ActionExecutionException(message, e, this, false); } + return ActionResult.EMPTY; } @VisibleForTesting diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtractInclusionAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtractInclusionAction.java index e66fae1f63..1bd76c280c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtractInclusionAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/ExtractInclusionAction.java @@ -19,6 +19,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; @@ -64,7 +65,7 @@ final class ExtractInclusionAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { IncludeScanningContext context = actionExecutionContext.getContext(IncludeScanningContext.class); @@ -76,5 +77,6 @@ final class ExtractInclusionAction extends AbstractAction { } catch (ExecException e) { throw e.toActionExecutionException(this); } + return ActionResult.EMPTY; } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java index dc36e72f69..7f00e3eb24 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java @@ -23,9 +23,11 @@ import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ExecException; import com.google.devtools.build.lib.actions.ResourceSet; +import com.google.devtools.build.lib.actions.SpawnResult; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible; @@ -37,6 +39,7 @@ import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import java.io.IOException; +import java.util.Set; import java.util.UUID; import java.util.logging.Logger; @@ -120,9 +123,10 @@ public class FakeCppCompileAction extends CppCompileAction { @Override @ThreadCompatible - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { setModuleFileFlags(); + Set<SpawnResult> spawnResults; // First, do a normal compilation, to generate the ".d" file. The generated object file is built // to a temporary location (tempOutputFile) and ignored afterwards. logger.info("Generating " + getDotdFile()); @@ -131,8 +135,8 @@ public class FakeCppCompileAction extends CppCompileAction { try { CppCompileActionResult cppCompileActionResult = context.execWithReply(this, actionExecutionContext); - // TODO(b/62588075) Save spawnResults from cppCompileActionResult and return them upwards. reply = cppCompileActionResult.contextReply(); + spawnResults = cppCompileActionResult.spawnResults(); } catch (ExecException e) { throw e.toActionExecutionException( "C++ compilation of rule '" + getOwner().getLabel() + "'", @@ -238,6 +242,7 @@ public class FakeCppCompileAction extends CppCompileAction { throw new ActionExecutionException("failed to create fake compile command for rule '" + getOwner().getLabel() + ": " + e.getMessage(), this, false); } + return ActionResult.create(spawnResults); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoStubAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoStubAction.java index be9624625b..26b0276488 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoStubAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoStubAction.java @@ -17,6 +17,7 @@ import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.vfs.Path; @@ -43,7 +44,8 @@ public final class FdoStubAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) { + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + return ActionResult.EMPTY; } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java index 98b3f2fa54..48b12a80ac 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/SolibSymlinkAction.java @@ -20,6 +20,7 @@ import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Actions; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Root; @@ -54,8 +55,8 @@ public final class SolibSymlinkAction extends AbstractAction { } @Override - public void execute( - ActionExecutionContext actionExecutionContext) throws ActionExecutionException { + public ActionResult execute(ActionExecutionContext actionExecutionContext) + throws ActionExecutionException { Path mangledPath = symlink.getPath(); try { mangledPath.createSymbolicLink(target); @@ -63,6 +64,7 @@ public final class SolibSymlinkAction extends AbstractAction { throw new ActionExecutionException("failed to create _solib symbolic link '" + symlink.prettyPrint() + "' to target '" + target + "'", e, this, false); } + return ActionResult.EMPTY; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompileAction.java index cabab193d3..0e179314a2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCompileAction.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactResolver; import com.google.devtools.build.lib.actions.CommandLineExpansionException; @@ -213,9 +214,9 @@ public class ObjcCompileAction extends SpawnAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { - super.execute(actionExecutionContext); + ActionResult actionResult = super.execute(actionExecutionContext); if (dotdPruningPlan == HeaderDiscovery.DotdPruningMode.USE) { IncludeScanningContext scanningContext = @@ -232,6 +233,8 @@ public class ObjcCompileAction extends SpawnAction { // haven't quite managed to get that right yet. updateActionInputs(getInputs()); } + + return actionResult; } @VisibleForTesting diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java index be0ba39ae3..81192024af 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java @@ -847,8 +847,9 @@ public final class SkyframeActionExecutor implements ActionExecutionContextFacto // instead. FileOutErr outErrBuffer = actionExecutionContext.getFileOutErr(); try { + // TODO(b/62588075): Now that execute() returns information about the execution, we could log + // the data to the invocations table. action.execute(actionExecutionContext); - // Action terminated fine, now report the output. // The .showOutput() method is not necessarily a quick check: in its // current implementation it uses regular expression matching. diff --git a/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java b/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java index 1458fdf690..1849284908 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/ExecutableSymlinkActionTest.java @@ -67,7 +67,8 @@ public class ExecutableSymlinkActionTest { Artifact input = new Artifact(inputFile, inputRoot); Artifact output = new Artifact(outputFile, outputRoot); ExecutableSymlinkAction action = new ExecutableSymlinkAction(NULL_ACTION_OWNER, input, output); - action.execute(createContext()); + ActionResult actionResult = action.execute(createContext()); + assertThat(actionResult.spawnResults()).isEmpty(); assertThat(outputFile.resolveSymbolicLinks()).isEqualTo(inputFile); } diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java index 9e7f9b796c..4a58eae2b3 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java @@ -34,6 +34,7 @@ import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionInputPrefetcher; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; @@ -266,8 +267,8 @@ public final class ActionsTestUtil { } @Override - public void execute(ActionExecutionContext actionExecutionContext) { - + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + return ActionResult.EMPTY; } @Override protected String computeKey() { diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java b/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java index f5c1a965a1..5f7a680537 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java +++ b/src/test/java/com/google/devtools/build/lib/actions/util/TestAction.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.util.Preconditions; @@ -90,7 +91,7 @@ public class TestAction extends AbstractAction { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { for (Artifact artifact : getInputs()) { // Do not check *.optional artifacts - artifacts with such extension are @@ -120,6 +121,8 @@ public class TestAction extends AbstractAction { } catch (IOException e) { throw new AssertionError(e); } + + return ActionResult.EMPTY; } @Override diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/FileWriteActionTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/FileWriteActionTestCase.java index d12b512c93..1d07a726f8 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/FileWriteActionTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/FileWriteActionTestCase.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionInputPrefetcher; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.analysis.util.ActionTester; @@ -73,7 +74,8 @@ public abstract class FileWriteActionTestCase extends BuildViewTestCase { } protected void checkCanWriteNonExecutableFile() throws Exception { - action.execute(context); + ActionResult actionResult = action.execute(context); + assertThat(actionResult.spawnResults()).isEmpty(); String content = new String(FileSystemUtils.readContentAsLatin1(output)); assertThat(content).isEqualTo("Hello World"); assertThat(output.isExecutable()).isFalse(); @@ -83,7 +85,8 @@ public abstract class FileWriteActionTestCase extends BuildViewTestCase { Artifact outputArtifact = getBinArtifactWithNoOwner("hello"); Path output = outputArtifact.getPath(); Action action = createAction(NULL_ACTION_OWNER, outputArtifact, "echo 'Hello World'", true); - action.execute(context); + ActionResult actionResult = action.execute(context); + assertThat(actionResult.spawnResults()).isEmpty(); String content = new String(FileSystemUtils.readContentAsLatin1(output)); assertThat(content).isEqualTo("echo 'Hello World'"); assertThat(output.isExecutable()).isTrue(); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java index dce0ce30d0..81ac13a42e 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java @@ -21,6 +21,7 @@ import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionInputPrefetcher; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; @@ -83,7 +84,8 @@ public class ParamFileWriteActionTest extends BuildViewTestCase { Action action = createParameterFileWriteAction( ImmutableList.<Artifact>of(), createNormalCommandLine()); ActionExecutionContext context = actionExecutionContext(); - action.execute(context); + ActionResult actionResult = action.execute(context); + assertThat(actionResult.spawnResults()).isEmpty(); String content = new String(FileSystemUtils.readContentAsLatin1(outputArtifact.getPath())); assertThat(content.trim()).isEqualTo("--flag1\n--flag2\n--flag3\nvalue1\nvalue2"); } @@ -94,7 +96,8 @@ public class ParamFileWriteActionTest extends BuildViewTestCase { ImmutableList.of(treeArtifact), createTreeArtifactExpansionCommandLine()); ActionExecutionContext context = actionExecutionContext(); - action.execute(context); + ActionResult actionResult = action.execute(context); + assertThat(actionResult.spawnResults()).isEmpty(); String content = new String(FileSystemUtils.readContentAsLatin1(outputArtifact.getPath())); assertThat(content.trim()) .isEqualTo( diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java index f12f380e5c..1fb182a22a 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputPrefetcher; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; @@ -166,7 +167,9 @@ public class PopulateTreeArtifactActionTest extends BuildViewTestCase { ArrayList<Artifact> treefileArtifacts = new ArrayList<Artifact>(); PopulateTreeArtifactAction action = createPopulateTreeArtifactAction(); ActionExecutionContext executionContext = actionExecutionContext(treefileArtifacts); - action.execute(executionContext); + ActionResult actionResult = action.execute(executionContext); + + assertThat(actionResult.spawnResults()).isEmpty(); assertThat(Artifact.toExecPaths(treefileArtifacts)).containsExactly( "test/archive_member/archive_members/1.class", @@ -216,8 +219,9 @@ public class PopulateTreeArtifactActionTest extends BuildViewTestCase { ArrayList<Artifact> treeFileArtifacts = new ArrayList<Artifact>(); ActionExecutionContext executionContext = actionExecutionContext(treeFileArtifacts); - action.execute(executionContext); + ActionResult actionResult = action.execute(executionContext); + assertThat(actionResult.spawnResults()).isEmpty(); assertThat(treeFileArtifacts).isEmpty(); } @@ -231,7 +235,9 @@ public class PopulateTreeArtifactActionTest extends BuildViewTestCase { ArrayList<Artifact> treeFileArtifacts = new ArrayList<Artifact>(); ActionExecutionContext executionContext = actionExecutionContext(treeFileArtifacts); - action.execute(executionContext); + ActionResult actionResult = action.execute(executionContext); + + assertThat(actionResult.spawnResults()).isEmpty(); // We check whether the parent directory structures of output TreeFileArtifacts exist even // though the spawn is not executed (the SpawnActionContext is mocked out). diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SymlinkActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SymlinkActionTest.java index e0ae5308af..532615bf8e 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SymlinkActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SymlinkActionTest.java @@ -19,6 +19,7 @@ import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.NULL_AC import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionInputPrefetcher; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; @@ -73,8 +74,17 @@ public class SymlinkActionTest extends BuildViewTestCase { @Test public void testSymlink() throws Exception { Executor executor = new TestExecutorBuilder(directories, null).build(); - action.execute(new ActionExecutionContext(executor, null, ActionInputPrefetcher.NONE, null, - null, ImmutableMap.<String, String>of(), null)); + ActionResult actionResult = + action.execute( + new ActionExecutionContext( + executor, + null, + ActionInputPrefetcher.NONE, + null, + null, + ImmutableMap.<String, String>of(), + null)); + assertThat(actionResult.spawnResults()).isEmpty(); assertThat(output.isSymbolicLink()).isTrue(); assertThat(output.resolveSymbolicLinks()).isEqualTo(input); assertThat(action.getPrimaryInput()).isEqualTo(inputArtifact); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java index f065cfda79..b36f9243bf 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionOwner; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactFactory; import com.google.devtools.build.lib.actions.ArtifactOwner; @@ -209,7 +210,7 @@ public final class AnalysisTestUtil { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { try { FileSystemUtils.writeContent(stableStatus.getPath(), new byte[] {}); @@ -217,6 +218,7 @@ public final class AnalysisTestUtil { } catch (IOException e) { throw new ActionExecutionException(e, this, true); } + return ActionResult.EMPTY; } @Override diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java index 808b55f7d4..e271d90237 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ParallelBuilderTest.java @@ -29,6 +29,7 @@ import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionExecutedEvent; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.BuildFailedException; import com.google.devtools.build.lib.actions.cache.ActionCache; @@ -679,30 +680,33 @@ public class ParallelBuilderTest extends TimestampBuilderTestCase { ? ImmutableList.of(artifacts[0]) : Artifact.NO_ARTIFACTS; final int iCopy = ii; - registerAction(new TestAction(new Callable<Void>() { - @Override - public Void call() throws Exception { - Thread.sleep(100); // 100ms - completedTasks.getAndIncrement(); - throw new IOException("task failed"); - } - }, - inputs, ImmutableList.of(out)) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) - throws ActionExecutionException { - if (catastrophe && iCopy == 0) { - try { - Thread.sleep(300); // 300ms - } catch (InterruptedException e) { - throw new RuntimeException(e); + registerAction( + new TestAction( + new Callable<Void>() { + @Override + public Void call() throws Exception { + Thread.sleep(100); // 100ms + completedTasks.getAndIncrement(); + throw new IOException("task failed"); + } + }, + inputs, + ImmutableList.of(out)) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) + throws ActionExecutionException { + if (catastrophe && iCopy == 0) { + try { + Thread.sleep(300); // 300ms + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + completedTasks.getAndIncrement(); + throw new ActionExecutionException("This is a catastrophe", this, true); + } + return super.execute(actionExecutionContext); } - completedTasks.getAndIncrement(); - throw new ActionExecutionException("This is a catastrophe", this, true); - } - super.execute(actionExecutionContext); - } - }); + }); artifacts[ii] = out; } diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java index c6ac94a0db..6af5623ac7 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeAwareActionTest.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.actions.AbstractAction; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Executor; import com.google.devtools.build.lib.actions.util.ActionsTestUtil; @@ -175,7 +176,7 @@ public class SkyframeAwareActionTest extends TimestampBuilderTestCase { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { executionCounter.incrementAndGet(); @@ -197,6 +198,7 @@ public class SkyframeAwareActionTest extends TimestampBuilderTestCase { } catch (IOException e) { throw new ActionExecutionException(e, this, false); } + return ActionResult.EMPTY; } @Override @@ -756,9 +758,10 @@ public class SkyframeAwareActionTest extends TimestampBuilderTestCase { registerAction( new SingleOutputAction(null, genFile1) { @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { writeOutput(null, "gen1"); + return ActionResult.EMPTY; } }); @@ -770,9 +773,10 @@ public class SkyframeAwareActionTest extends TimestampBuilderTestCase { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException { writeOutput(readInput(), "gen2"); + return ActionResult.EMPTY; } }); diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java index 3ecc85b596..de8a0beedc 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java @@ -36,6 +36,7 @@ import com.google.devtools.build.lib.actions.ActionInputPrefetcher; import com.google.devtools.build.lib.actions.ActionLogBufferPathGenerator; import com.google.devtools.build.lib.actions.ActionLookupData; import com.google.devtools.build.lib.actions.ActionLookupValue; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.BuildFailedException; import com.google.devtools.build.lib.actions.Executor; @@ -410,9 +411,9 @@ public abstract class TimestampBuilderTestCase extends FoundationTestCase { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { - super.execute(actionExecutionContext); + ActionResult actionResult = super.execute(actionExecutionContext); try { FileSystemUtils.copyFile( Iterables.getOnlyElement(getInputs()).getPath(), @@ -420,6 +421,7 @@ public abstract class TimestampBuilderTestCase extends FoundationTestCase { } catch (IOException e) { throw new IllegalStateException(e); } + return actionResult; } } diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java index a6057bce64..fac36eb3d6 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java @@ -34,6 +34,7 @@ import com.google.devtools.build.lib.actions.ActionExecutionException; import com.google.devtools.build.lib.actions.ActionInput; import com.google.devtools.build.lib.actions.ActionInputFileCache; import com.google.devtools.build.lib.actions.ActionInputHelper; +import com.google.devtools.build.lib.actions.ActionResult; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; import com.google.devtools.build.lib.actions.Artifact.SpecialArtifactType; @@ -148,23 +149,25 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { registerAction(actionOne); final Artifact normalOutput = createDerivedArtifact("normal/out"); - Action testAction = new TestAction( - TestAction.NO_EFFECT, ImmutableList.of(outOne), ImmutableList.of(normalOutput)) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) { - try { - // Check the file cache for input TreeFileArtifacts. - ActionInputFileCache fileCache = actionExecutionContext.getActionInputFileCache(); - assertThat(fileCache.getMetadata(outOneFileOne).isFile()).isTrue(); - assertThat(fileCache.getMetadata(outOneFileTwo).isFile()).isTrue(); - - // Touch the action output. - touchFile(normalOutput); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + Action testAction = + new TestAction( + TestAction.NO_EFFECT, ImmutableList.of(outOne), ImmutableList.of(normalOutput)) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + try { + // Check the file cache for input TreeFileArtifacts. + ActionInputFileCache fileCache = actionExecutionContext.getActionInputFileCache(); + assertThat(fileCache.getMetadata(outOneFileOne).isFile()).isTrue(); + assertThat(fileCache.getMetadata(outOneFileTwo).isFile()).isTrue(); + + // Touch the action output. + touchFile(normalOutput); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(testAction); buildArtifact(normalOutput); @@ -470,21 +473,23 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { public void testOutputsAreReadOnlyAndExecutable() throws Exception { final Artifact out = createTreeArtifact("output"); - TreeArtifactTestAction action = new TreeArtifactTestAction(out) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) { - try { - writeFile(out.getPath().getChild("one"), "one"); - writeFile(out.getPath().getChild("two"), "two"); - writeFile(out.getPath().getChild("three").getChild("four"), "three/four"); - registerOutput(actionExecutionContext, "one"); - registerOutput(actionExecutionContext, "two"); - registerOutput(actionExecutionContext, "three/four"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + TreeArtifactTestAction action = + new TreeArtifactTestAction(out) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + try { + writeFile(out.getPath().getChild("one"), "one"); + writeFile(out.getPath().getChild("two"), "two"); + writeFile(out.getPath().getChild("three").getChild("four"), "three/four"); + registerOutput(actionExecutionContext, "one"); + registerOutput(actionExecutionContext, "two"); + registerOutput(actionExecutionContext, "three/four"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(action); @@ -501,20 +506,21 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { public void testValidRelativeSymlinkAccepted() throws Exception { final Artifact out = createTreeArtifact("output"); - TreeArtifactTestAction action = new TreeArtifactTestAction(out) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) { - try { - writeFile(out.getPath().getChild("one"), "one"); - writeFile(out.getPath().getChild("two"), "two"); - FileSystemUtils.ensureSymbolicLink( - out.getPath().getChild("links").getChild("link"), - "../one"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + TreeArtifactTestAction action = + new TreeArtifactTestAction(out) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + try { + writeFile(out.getPath().getChild("one"), "one"); + writeFile(out.getPath().getChild("two"), "two"); + FileSystemUtils.ensureSymbolicLink( + out.getPath().getChild("links").getChild("link"), "../one"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(action); @@ -530,20 +536,21 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { final Artifact out = createTreeArtifact("output"); - TreeArtifactTestAction action = new TreeArtifactTestAction(out) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) { - try { - writeFile(out.getPath().getChild("one"), "one"); - writeFile(out.getPath().getChild("two"), "two"); - FileSystemUtils.ensureSymbolicLink( - out.getPath().getChild("links").getChild("link"), - "../invalid"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + TreeArtifactTestAction action = + new TreeArtifactTestAction(out) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + try { + writeFile(out.getPath().getChild("one"), "one"); + writeFile(out.getPath().getChild("two"), "two"); + FileSystemUtils.ensureSymbolicLink( + out.getPath().getChild("links").getChild("link"), "../invalid"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(action); @@ -569,20 +576,21 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { final Artifact out = createTreeArtifact("output"); - TreeArtifactTestAction action = new TreeArtifactTestAction(out) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) { - try { - writeFile(out.getPath().getChild("one"), "one"); - writeFile(out.getPath().getChild("two"), "two"); - FileSystemUtils.ensureSymbolicLink( - out.getPath().getChild("links").getChild("link"), - "/random/pointer"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + TreeArtifactTestAction action = + new TreeArtifactTestAction(out) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + try { + writeFile(out.getPath().getChild("one"), "one"); + writeFile(out.getPath().getChild("two"), "two"); + FileSystemUtils.ensureSymbolicLink( + out.getPath().getChild("links").getChild("link"), "/random/pointer"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(action); @@ -607,7 +615,7 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { TreeArtifactTestAction action = new TreeArtifactTestAction(out) { @Override - public void execute(ActionExecutionContext actionExecutionContext) { + public ActionResult execute(ActionExecutionContext actionExecutionContext) { try { writeFile(out.getPath().getChild("one"), "one"); writeFile(out.getPath().getChild("two"), "two"); @@ -616,6 +624,7 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { } catch (Exception e) { throw new RuntimeException(e); } + return ActionResult.EMPTY; } }; @@ -633,20 +642,21 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { final Artifact out = createTreeArtifact("output"); - TreeArtifactTestAction action = new TreeArtifactTestAction(out) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) { - try { - writeFile(out.getPath().getChild("one"), "one"); - writeFile(out.getPath().getChild("two"), "two"); - FileSystemUtils.ensureSymbolicLink( - out.getPath().getChild("links").getChild("link"), - "../../output/random/pointer"); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + TreeArtifactTestAction action = + new TreeArtifactTestAction(out) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) { + try { + writeFile(out.getPath().getChild("one"), "one"); + writeFile(out.getPath().getChild("two"), "two"); + FileSystemUtils.ensureSymbolicLink( + out.getPath().getChild("links").getChild("link"), "../../output/random/pointer"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(action); @@ -673,27 +683,33 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { // TODO(bazel-team): write real tests for injectDigest, here and elsewhere. @Test public void testDigestInjection() throws Exception { - TreeArtifactTestAction action = new TreeArtifactTestAction(outOne) { - @Override - public void execute(ActionExecutionContext actionExecutionContext) - throws ActionExecutionException { - try { - writeFile(outOneFileOne, "one"); - writeFile(outOneFileTwo, "two"); - - MetadataHandler md = actionExecutionContext.getMetadataHandler(); - FileStatus stat = outOneFileOne.getPath().stat(Symlinks.NOFOLLOW); - md.injectDigest(outOneFileOne, - stat, Hashing.md5().hashString("one", Charset.forName("UTF-8")).asBytes()); - - stat = outOneFileTwo.getPath().stat(Symlinks.NOFOLLOW); - md.injectDigest(outOneFileTwo, - stat, Hashing.md5().hashString("two", Charset.forName("UTF-8")).asBytes()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; + TreeArtifactTestAction action = + new TreeArtifactTestAction(outOne) { + @Override + public ActionResult execute(ActionExecutionContext actionExecutionContext) + throws ActionExecutionException { + try { + writeFile(outOneFileOne, "one"); + writeFile(outOneFileTwo, "two"); + + MetadataHandler md = actionExecutionContext.getMetadataHandler(); + FileStatus stat = outOneFileOne.getPath().stat(Symlinks.NOFOLLOW); + md.injectDigest( + outOneFileOne, + stat, + Hashing.md5().hashString("one", Charset.forName("UTF-8")).asBytes()); + + stat = outOneFileTwo.getPath().stat(Symlinks.NOFOLLOW); + md.injectDigest( + outOneFileTwo, + stat, + Hashing.md5().hashString("two", Charset.forName("UTF-8")).asBytes()); + } catch (Exception e) { + throw new RuntimeException(e); + } + return ActionResult.EMPTY; + } + }; registerAction(action); buildArtifact(action.getSoleOutput()); @@ -980,7 +996,7 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { } @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { if (getInputs().iterator().hasNext()) { // Sanity check--verify all inputs exist. @@ -1010,6 +1026,7 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { throw new ActionExecutionException("TestAction failed due to exception", e, this, false); } + return ActionResult.EMPTY; } void executeTestBehavior(ActionExecutionContext c) throws ActionExecutionException { @@ -1229,8 +1246,10 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { /** Do nothing */ @Override - public void execute(ActionExecutionContext actionExecutionContext) - throws ActionExecutionException {} + public ActionResult execute(ActionExecutionContext actionExecutionContext) + throws ActionExecutionException { + return ActionResult.EMPTY; + } } /** No-op action that throws when executed */ @@ -1241,7 +1260,7 @@ public class TreeArtifactBuildTest extends TimestampBuilderTestCase { /** Throws */ @Override - public void execute(ActionExecutionContext actionExecutionContext) + public ActionResult execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException { throw new ActionExecutionException("Throwing dummy action", this, true); } |