Search in sources :

Example 1 with MissingInputFileException

use of com.google.devtools.build.lib.actions.MissingInputFileException in project bazel by bazelbuild.

the class ArtifactFunction method compute.

@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws ArtifactFunctionException, InterruptedException {
    OwnedArtifact ownedArtifact = (OwnedArtifact) skyKey.argument();
    Artifact artifact = ownedArtifact.getArtifact();
    if (artifact.isSourceArtifact()) {
        try {
            return createSourceValue(artifact, ownedArtifact.isMandatory(), env);
        } catch (MissingInputFileException e) {
            // is potentially used to report root causes.
            throw new ArtifactFunctionException(e, Transience.TRANSIENT);
        }
    }
    ActionAnalysisMetadata actionMetadata = extractActionFromArtifact(artifact, env);
    if (actionMetadata == null) {
        return null;
    }
    // actions, execute those actions in parallel and then aggregate the action execution results.
    if (artifact.isTreeArtifact() && actionMetadata instanceof ActionTemplate) {
        // Create the directory structures for the output TreeArtifact first.
        try {
            FileSystemUtils.createDirectoryAndParents(artifact.getPath());
        } catch (IOException e) {
            env.getListener().handle(Event.error(String.format("Failed to create output directory for TreeArtifact %s: %s", artifact, e.getMessage())));
            throw new ArtifactFunctionException(e, Transience.TRANSIENT);
        }
        return createTreeArtifactValueFromActionTemplate((ActionTemplate) actionMetadata, artifact, env);
    } else {
        Preconditions.checkState(actionMetadata instanceof Action, "%s is not a proper Action object and therefore cannot be executed", actionMetadata);
        Action action = (Action) actionMetadata;
        ActionExecutionValue actionValue = (ActionExecutionValue) env.getValue(ActionExecutionValue.key(action));
        if (actionValue == null) {
            return null;
        }
        if (artifact.isTreeArtifact()) {
            // TreeArtifactValue.
            return Preconditions.checkNotNull(actionValue.getTreeArtifactValue(artifact), artifact);
        } else if (isAggregatingValue(action)) {
            return createAggregatingValue(artifact, action, actionValue.getArtifactValue(artifact), env);
        } else {
            return createSimpleFileArtifactValue(artifact, action, actionValue, env);
        }
    }
}
Also used : Action(com.google.devtools.build.lib.actions.Action) ActionAnalysisMetadata(com.google.devtools.build.lib.actions.ActionAnalysisMetadata) IOException(java.io.IOException) ActionTemplate(com.google.devtools.build.lib.analysis.actions.ActionTemplate) OwnedArtifact(com.google.devtools.build.lib.skyframe.ArtifactSkyKey.OwnedArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) OwnedArtifact(com.google.devtools.build.lib.skyframe.ArtifactSkyKey.OwnedArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException)

Example 2 with MissingInputFileException

use of com.google.devtools.build.lib.actions.MissingInputFileException in project bazel by bazelbuild.

the class ActionExecutionFunction method checkInputs.

/**
   * Declare dependency on all known inputs of action. Throws exception if any are known to be
   * missing. Some inputs may not yet be in the graph, in which case the builder should abort.
   */
private Pair<Map<Artifact, FileArtifactValue>, Map<Artifact, Collection<Artifact>>> checkInputs(Environment env, Action action, Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps) throws ActionExecutionException {
    int missingCount = 0;
    int actionFailures = 0;
    boolean catastrophe = false;
    // Only populate input data if we have the input values, otherwise they'll just go unused.
    // We still want to loop through the inputs to collect missing deps errors. During the
    // evaluator "error bubbling", we may get one last chance at reporting errors even though
    // some deps are still missing.
    boolean populateInputData = !env.valuesMissing();
    NestedSetBuilder<Cause> rootCauses = NestedSetBuilder.stableOrder();
    Map<Artifact, FileArtifactValue> inputArtifactData = new HashMap<>(populateInputData ? inputDeps.size() : 0);
    Map<Artifact, Collection<Artifact>> expandedArtifacts = new HashMap<>(populateInputData ? 128 : 0);
    ActionExecutionException firstActionExecutionException = null;
    for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
        Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
        try {
            SkyValue value = depsEntry.getValue().get();
            if (populateInputData) {
                if (value instanceof AggregatingArtifactValue) {
                    AggregatingArtifactValue aggregatingValue = (AggregatingArtifactValue) value;
                    for (Pair<Artifact, FileArtifactValue> entry : aggregatingValue.getInputs()) {
                        inputArtifactData.put(entry.first, entry.second);
                    }
                    // We have to cache the "digest" of the aggregating value itself,
                    // because the action cache checker may want it.
                    inputArtifactData.put(input, aggregatingValue.getSelfData());
                    ImmutableList.Builder<Artifact> expansionBuilder = ImmutableList.builder();
                    for (Pair<Artifact, FileArtifactValue> pair : aggregatingValue.getInputs()) {
                        expansionBuilder.add(pair.first);
                    }
                    expandedArtifacts.put(input, expansionBuilder.build());
                } else if (value instanceof TreeArtifactValue) {
                    TreeArtifactValue treeValue = (TreeArtifactValue) value;
                    expandedArtifacts.put(input, ImmutableSet.<Artifact>copyOf(treeValue.getChildren()));
                    inputArtifactData.putAll(treeValue.getChildValues());
                    // Again, we cache the "digest" of the value for cache checking.
                    inputArtifactData.put(input, treeValue.getSelfData());
                } else {
                    Preconditions.checkState(value instanceof FileArtifactValue, depsEntry);
                    inputArtifactData.put(input, (FileArtifactValue) value);
                }
            }
        } catch (MissingInputFileException e) {
            missingCount++;
            if (input.getOwner() != null) {
                rootCauses.add(new LabelCause(input.getOwner()));
            }
        } catch (ActionExecutionException e) {
            actionFailures++;
            if (firstActionExecutionException == null) {
                firstActionExecutionException = e;
            }
            catastrophe = catastrophe || e.isCatastrophe();
            rootCauses.addTransitive(e.getRootCauses());
        }
    }
    // We need to rethrow first exception because it can contain useful error message
    if (firstActionExecutionException != null) {
        if (missingCount == 0 && actionFailures == 1) {
            // having to copy the root causes to the upwards transitive closure.
            throw firstActionExecutionException;
        }
        throw new ActionExecutionException(firstActionExecutionException.getMessage(), firstActionExecutionException.getCause(), action, rootCauses.build(), catastrophe, firstActionExecutionException.getExitCode());
    }
    if (missingCount > 0) {
        for (Cause missingInput : rootCauses.build()) {
            env.getListener().handle(Event.error(action.getOwner().getLocation(), String.format("%s: missing input file '%s'", action.getOwner().getLabel(), missingInput.getLabel())));
        }
        throw new ActionExecutionException(missingCount + " input file(s) do not exist", action, rootCauses.build(), /*catastrophe=*/
        false);
    }
    return Pair.of(inputArtifactData, expandedArtifacts);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) ValueOrException2(com.google.devtools.build.skyframe.ValueOrException2) Artifact(com.google.devtools.build.lib.actions.Artifact) SkyValue(com.google.devtools.build.skyframe.SkyValue) Cause(com.google.devtools.build.lib.causes.Cause) LabelCause(com.google.devtools.build.lib.causes.LabelCause) LabelCause(com.google.devtools.build.lib.causes.LabelCause) Collection(java.util.Collection) AlreadyReportedActionExecutionException(com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException)

Example 3 with MissingInputFileException

use of com.google.devtools.build.lib.actions.MissingInputFileException in project bazel by bazelbuild.

the class TreeArtifactMetadataTest method testIOExceptionEndToEnd.

/**
   * Tests that ArtifactFunction rethrows transitive {@link IOException}s as
   * {@link MissingInputFileException}s.
   */
@Test
public void testIOExceptionEndToEnd() throws Throwable {
    final IOException exception = new IOException("boop");
    setupRoot(new CustomInMemoryFs() {

        @Override
        public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
            if (path.getBaseName().equals("one")) {
                throw exception;
            }
            return super.stat(path, followSymlinks);
        }
    });
    try {
        Artifact artifact = createTreeArtifact("outOne");
        TreeArtifactValue value = evaluateTreeArtifact(artifact, ImmutableList.of(new PathFragment("one")));
        fail("MissingInputFileException expected, got " + value);
    } catch (Exception e) {
        assertThat(Throwables.getRootCause(e).getMessage()).contains(exception.getMessage());
    }
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) FileStatus(com.google.devtools.build.lib.vfs.FileStatus) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) IOException(java.io.IOException) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException) SkyFunctionException(com.google.devtools.build.skyframe.SkyFunctionException) IOException(java.io.IOException) Test(org.junit.Test)

Example 4 with MissingInputFileException

use of com.google.devtools.build.lib.actions.MissingInputFileException in project bazel by bazelbuild.

the class SkyframeBuilder method rethrow.

/** Figure out why an action's execution failed and rethrow the right kind of exception. */
@VisibleForTesting
public static void rethrow(Throwable cause) throws BuildFailedException, TestExecException {
    Throwable innerCause = cause.getCause();
    if (innerCause instanceof TestExecException) {
        throw (TestExecException) innerCause;
    }
    if (cause instanceof ActionExecutionException) {
        ActionExecutionException actionExecutionCause = (ActionExecutionException) cause;
        // Sometimes ActionExecutionExceptions are caused by Actions with no owner.
        String message = (actionExecutionCause.getLocation() != null) ? (actionExecutionCause.getLocation().print() + " " + cause.getMessage()) : cause.getMessage();
        throw new BuildFailedException(message, actionExecutionCause.isCatastrophe(), actionExecutionCause.getAction(), actionExecutionCause.getRootCauses(), /*errorAlreadyShown=*/
        !actionExecutionCause.showError(), actionExecutionCause.getExitCode());
    } else if (cause instanceof MissingInputFileException) {
        throw new BuildFailedException(cause.getMessage());
    } else if (cause instanceof BuildFileNotFoundException) {
        // Sadly, this can happen because we may load new packages during input discovery. Any
        // failures reading those packages shouldn't terminate the build, but in Skyframe they do.
        LoggingUtil.logToRemote(Level.WARNING, "undesirable loading exception", cause);
        throw new BuildFailedException(cause.getMessage());
    } else if (cause instanceof RuntimeException) {
        throw (RuntimeException) cause;
    } else if (cause instanceof Error) {
        throw (Error) cause;
    } else {
        // expectations in this method.
        throw new IllegalArgumentException("action terminated with " + "unexpected exception: " + cause.getMessage(), cause);
    }
}
Also used : BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) BuildFileNotFoundException(com.google.devtools.build.lib.packages.BuildFileNotFoundException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) TestExecException(com.google.devtools.build.lib.actions.TestExecException) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 5 with MissingInputFileException

use of com.google.devtools.build.lib.actions.MissingInputFileException in project bazel by bazelbuild.

the class CompletionFunction method compute.

@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws CompletionFunctionException, InterruptedException {
    TValue value = completor.getValueFromSkyKey(skyKey, env);
    TopLevelArtifactContext topLevelContext = completor.getTopLevelArtifactContext(skyKey);
    if (env.valuesMissing()) {
        return null;
    }
    Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps = env.getValuesOrThrow(ArtifactSkyKey.mandatoryKeys(completor.getAllArtifactsToBuild(value, topLevelContext).getAllArtifacts()), MissingInputFileException.class, ActionExecutionException.class);
    int missingCount = 0;
    ActionExecutionException firstActionExecutionException = null;
    MissingInputFileException missingInputException = null;
    NestedSetBuilder<Cause> rootCausesBuilder = NestedSetBuilder.stableOrder();
    for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
        Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
        try {
            depsEntry.getValue().get();
        } catch (MissingInputFileException e) {
            missingCount++;
            final Label inputOwner = input.getOwner();
            if (inputOwner != null) {
                Cause cause = new LabelCause(inputOwner);
                rootCausesBuilder.add(cause);
                env.getListener().handle(completor.getRootCauseError(value, cause));
            }
        } catch (ActionExecutionException e) {
            rootCausesBuilder.addTransitive(e.getRootCauses());
            if (firstActionExecutionException == null) {
                firstActionExecutionException = e;
            }
        }
    }
    if (missingCount > 0) {
        missingInputException = completor.getMissingFilesException(value, missingCount);
    }
    NestedSet<Cause> rootCauses = rootCausesBuilder.build();
    if (!rootCauses.isEmpty()) {
        eventBusRef.get().post(completor.createFailed(value, rootCauses));
        if (firstActionExecutionException != null) {
            throw new CompletionFunctionException(firstActionExecutionException);
        } else {
            throw new CompletionFunctionException(missingInputException);
        }
    }
    return env.valuesMissing() ? null : completor.createResult(value);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Label(com.google.devtools.build.lib.cmdline.Label) ValueOrException2(com.google.devtools.build.skyframe.ValueOrException2) Artifact(com.google.devtools.build.lib.actions.Artifact) Cause(com.google.devtools.build.lib.causes.Cause) LabelCause(com.google.devtools.build.lib.causes.LabelCause) LabelCause(com.google.devtools.build.lib.causes.LabelCause) TopLevelArtifactContext(com.google.devtools.build.lib.analysis.TopLevelArtifactContext) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) Map(java.util.Map) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException) Nullable(javax.annotation.Nullable)

Aggregations

MissingInputFileException (com.google.devtools.build.lib.actions.MissingInputFileException)8 Artifact (com.google.devtools.build.lib.actions.Artifact)5 ActionExecutionException (com.google.devtools.build.lib.actions.ActionExecutionException)3 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)3 IOException (java.io.IOException)3 Test (org.junit.Test)3 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)2 Cause (com.google.devtools.build.lib.causes.Cause)2 LabelCause (com.google.devtools.build.lib.causes.LabelCause)2 FileStatus (com.google.devtools.build.lib.vfs.FileStatus)2 Path (com.google.devtools.build.lib.vfs.Path)2 SkyKey (com.google.devtools.build.skyframe.SkyKey)2 ValueOrException2 (com.google.devtools.build.skyframe.ValueOrException2)2 Map (java.util.Map)2 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 ImmutableList (com.google.common.collect.ImmutableList)1 Action (com.google.devtools.build.lib.actions.Action)1 ActionAnalysisMetadata (com.google.devtools.build.lib.actions.ActionAnalysisMetadata)1 AlreadyReportedActionExecutionException (com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException)1 BuildFailedException (com.google.devtools.build.lib.actions.BuildFailedException)1