Search in sources :

Example 6 with BuildFailedException

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

the class ParallelBuilderTest method testCyclicActionGraph.

@Test
public void testCyclicActionGraph() throws Exception {
    // foo -> [action] -> bar
    // bar -> [action] -> baz
    // baz -> [action] -> foo
    Artifact foo = createDerivedArtifact("foo");
    Artifact bar = createDerivedArtifact("bar");
    Artifact baz = createDerivedArtifact("baz");
    try {
        registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(bar)));
        registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
        registerAction(new TestAction(TestAction.NO_EFFECT, asSet(baz), asSet(foo)));
        buildArtifacts(foo);
        fail("Builder failed to detect cyclic action graph");
    } catch (BuildFailedException e) {
        assertEquals(e.getMessage(), CYCLE_MSG);
    }
}
Also used : BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) Artifact(com.google.devtools.build.lib.actions.Artifact) TestAction(com.google.devtools.build.lib.actions.util.TestAction) Test(org.junit.Test)

Example 7 with BuildFailedException

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

the class ParallelBuilderTest method testSelfCyclicActionGraph.

@Test
public void testSelfCyclicActionGraph() throws Exception {
    // foo -> [action] -> foo
    Artifact foo = createDerivedArtifact("foo");
    try {
        registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(foo)));
        buildArtifacts(foo);
        fail("Builder failed to detect cyclic action graph");
    } catch (BuildFailedException e) {
        assertEquals(e.getMessage(), CYCLE_MSG);
    }
}
Also used : BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) Artifact(com.google.devtools.build.lib.actions.Artifact) TestAction(com.google.devtools.build.lib.actions.util.TestAction) Test(org.junit.Test)

Example 8 with BuildFailedException

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

the class TimestampBuilderTest method testBuildingNonexistentSourcefileFails.

@Test
public void testBuildingNonexistentSourcefileFails() throws Exception {
    reporter.removeHandler(failFastHandler);
    Artifact hello = createSourceArtifact("hello");
    try {
        buildArtifacts(cachingBuilder(), hello);
        fail("Expected input file to be missing");
    } catch (BuildFailedException e) {
        assertThat(e).hasMessage("missing input file '" + hello.getPath() + "'");
    }
}
Also used : BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) Artifact(com.google.devtools.build.lib.actions.Artifact) Test(org.junit.Test)

Example 9 with BuildFailedException

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

the class BuildTool method buildTargets.

/**
   * The crux of the build system. Builds the targets specified in the request using the specified
   * Executor.
   *
   * <p>Performs loading, analysis and execution for the specified set of targets, honoring the
   * configuration options in the BuildRequest. Returns normally iff successful, throws an exception
   * otherwise.
   *
   * <p>Callers must ensure that {@link #stopRequest} is called after this method, even if it
   * throws.
   *
   * <p>The caller is responsible for setting up and syncing the package cache.
   *
   * <p>During this function's execution, the actualTargets and successfulTargets
   * fields of the request object are set.
   *
   * @param request the build request that this build tool is servicing, which specifies various
   *        options; during this method's execution, the actualTargets and successfulTargets fields
   *        of the request object are populated
   * @param result the build result that is the mutable result of this build
   * @param validator target validator
   */
public void buildTargets(BuildRequest request, BuildResult result, TargetValidator validator) throws BuildFailedException, InterruptedException, ViewCreationFailedException, TargetParsingException, LoadingFailedException, AbruptExitException, InvalidConfigurationException, TestExecException {
    validateOptions(request);
    BuildOptions buildOptions = runtime.createBuildOptions(request);
    // Sync the package manager before sending the BuildStartingEvent in runLoadingPhase()
    env.setupPackageCache(request, DefaultsPackage.getDefaultsPackageContent(buildOptions));
    ExecutionTool executionTool = null;
    boolean catastrophe = false;
    try {
        env.getEventBus().post(new BuildStartingEvent(env, request));
        LOG.info("Build identifier: " + request.getId());
        executionTool = new ExecutionTool(env, request);
        if (needsExecutionPhase(request.getBuildOptions())) {
            // Initialize the execution tool early if we need it. This hides the latency of setting up
            // the execution backends.
            executionTool.init();
        }
        // Error out early if multi_cpus is set, but we're not in build or test command.
        if (!request.getMultiCpus().isEmpty()) {
            getReporter().handle(Event.warn("The --experimental_multi_cpu option is _very_ experimental and only intended for " + "internal testing at this time. If you do not work on the build tool, then you " + "should stop now!"));
            if (!"build".equals(request.getCommandName()) && !"test".equals(request.getCommandName())) {
                throw new InvalidConfigurationException("The experimental setting to select multiple CPUs is only supported for 'build' and " + "'test' right now!");
            }
        }
        // Exit if there are any pending exceptions from modules.
        env.throwPendingException();
        // Target pattern evaluation.
        LoadingResult loadingResult = evaluateTargetPatterns(request, validator);
        // Exit if there are any pending exceptions from modules.
        env.throwPendingException();
        // Configuration creation.
        BuildConfigurationCollection configurations = env.getSkyframeExecutor().createConfigurations(env.getReporter(), runtime.getConfigurationFactory(), buildOptions, request.getMultiCpus(), request.getViewOptions().keepGoing);
        env.throwPendingException();
        if (configurations.getTargetConfigurations().size() == 1) {
            // TODO(bazel-team): This is not optimal - we retain backwards compatibility in the case
            // where there's only a single configuration, but we don't send an event in the multi-config
            // case. Can we do better? [multi-config]
            env.getEventBus().post(new MakeEnvironmentEvent(configurations.getTargetConfigurations().get(0).getMakeEnvironment()));
        }
        LOG.info("Configurations created");
        if (request.getBuildOptions().performAnalysisPhase) {
            AnalysisResult analysisResult = runAnalysisPhase(request, loadingResult, configurations);
            result.setBuildConfigurationCollection(configurations);
            result.setActualTargets(analysisResult.getTargetsToBuild());
            result.setTestTargets(analysisResult.getTargetsToTest());
            LoadedPackageProvider bridge = new LoadedPackageProvider(env.getPackageManager(), env.getReporter());
            checkTargetEnvironmentRestrictions(analysisResult.getTargetsToBuild(), bridge);
            reportTargets(analysisResult);
            // Execution phase.
            if (needsExecutionPhase(request.getBuildOptions())) {
                executionTool.executeBuild(request.getId(), analysisResult, result, configurations, analysisResult.getPackageRoots(), request.getTopLevelArtifactContext());
            }
            String delayedErrorMsg = analysisResult.getError();
            if (delayedErrorMsg != null) {
                throw new BuildFailedException(delayedErrorMsg);
            }
        } else {
            getReporter().handle(Event.progress("Loading complete."));
            LOG.info("No analysis requested, so finished");
            String errorMessage = BuildView.createErrorMessage(loadingResult, null);
            if (errorMessage != null) {
                throw new BuildFailedException(errorMessage);
            }
        // Return.
        }
    } catch (RuntimeException e) {
        // Print an error message for unchecked runtime exceptions. This does not concern Error
        // subclasses such as OutOfMemoryError.
        request.getOutErr().printErrLn("Unhandled exception thrown during build; message: " + e.getMessage());
        catastrophe = true;
        throw e;
    } catch (Error e) {
        catastrophe = true;
        throw e;
    } catch (InvalidConfigurationException e) {
        // TODO(gregce): With "global configurations" we cannot tie a configuration creation failure
        // to a single target and have to halt the entire build. Once configurations are genuinely
        // created as part of the analysis phase they should report their error on the level of the
        // target(s) that triggered them.
        catastrophe = true;
        throw e;
    } finally {
        if (!catastrophe) {
            // Delete dirty nodes to ensure that they do not accumulate indefinitely.
            long versionWindow = request.getViewOptions().versionWindowForDirtyNodeGc;
            if (versionWindow != -1) {
                env.getSkyframeExecutor().deleteOldNodes(versionWindow);
            }
            if (executionTool != null) {
                executionTool.shutdown();
            }
            // The workspace status actions will not run with certain flags, or if an error
            // occurs early in the build. Tell a lie so that the event is not missing.
            // If multiple build_info events are sent, only the first is kept, so this does not harm
            // successful runs (which use the workspace status action).
            env.getEventBus().post(new BuildInfoEvent(env.getBlazeWorkspace().getWorkspaceStatusActionFactory().createDummyWorkspaceStatus()));
        }
    }
}
Also used : BuildStartingEvent(com.google.devtools.build.lib.buildtool.buildevent.BuildStartingEvent) MakeEnvironmentEvent(com.google.devtools.build.lib.analysis.MakeEnvironmentEvent) LoadedPackageProvider(com.google.devtools.build.lib.pkgcache.LoadedPackageProvider) AnalysisResult(com.google.devtools.build.lib.analysis.BuildView.AnalysisResult) InvalidConfigurationException(com.google.devtools.build.lib.analysis.config.InvalidConfigurationException) LoadingResult(com.google.devtools.build.lib.pkgcache.LoadingResult) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) BuildOptions(com.google.devtools.build.lib.analysis.config.BuildOptions) BuildInfoEvent(com.google.devtools.build.lib.analysis.BuildInfoEvent) BuildConfigurationCollection(com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection)

Example 10 with BuildFailedException

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

the class SkyframeBuilder method processResult.

/**
   * Process the Skyframe update, taking into account the keepGoing setting.
   *
   * <p>Returns optional {@link ExitCode} based on following conditions: 1. null, if result had no
   * errors. 2. Optional.absent(), if result had errors but none of the errors specified an exit
   * code. 3. Optional.of(e), if result had errors and one of them specified exit code 'e'. Throws
   * on fail-fast failures.
   */
@Nullable
private static Optional<ExitCode> processResult(ExtendedEventHandler eventHandler, EvaluationResult<?> result, boolean keepGoing, SkyframeExecutor skyframeExecutor) throws BuildFailedException, TestExecException {
    if (result.hasError()) {
        for (Map.Entry<SkyKey, ErrorInfo> entry : result.errorMap().entrySet()) {
            Iterable<CycleInfo> cycles = entry.getValue().getCycleInfo();
            skyframeExecutor.reportCycles(eventHandler, cycles, entry.getKey());
        }
        if (result.getCatastrophe() != null) {
            rethrow(result.getCatastrophe());
        }
        if (keepGoing) {
            // If build fails and keepGoing is true, an exit code is assigned using reported errors
            // in the following order:
            //   1. First infrastructure error with non-null exit code
            //   2. First non-infrastructure error with non-null exit code
            //   3. Null (later default to 1)
            ExitCode exitCode = null;
            for (Map.Entry<SkyKey, ErrorInfo> error : result.errorMap().entrySet()) {
                Throwable cause = error.getValue().getException();
                if (cause instanceof ActionExecutionException) {
                    ActionExecutionException actionExecutionCause = (ActionExecutionException) cause;
                    ExitCode code = actionExecutionCause.getExitCode();
                    // a lower 'reporting' priority.
                    if (ExitCodeComparator.INSTANCE.compare(code, exitCode) > 0) {
                        exitCode = code;
                    }
                }
            }
            return Optional.fromNullable(exitCode);
        }
        ErrorInfo errorInfo = Preconditions.checkNotNull(result.getError(), result);
        Exception exception = errorInfo.getException();
        if (exception == null) {
            Preconditions.checkState(!Iterables.isEmpty(errorInfo.getCycleInfo()), errorInfo);
            // cycles above.
            throw new BuildFailedException(null, /*hasCatastrophe=*/
            false);
        } else {
            rethrow(exception);
        }
    }
    return null;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) ErrorInfo(com.google.devtools.build.skyframe.ErrorInfo) ExitCode(com.google.devtools.build.lib.util.ExitCode) CycleInfo(com.google.devtools.build.skyframe.CycleInfo) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) Map(java.util.Map) BuildFileNotFoundException(com.google.devtools.build.lib.packages.BuildFileNotFoundException) AbruptExitException(com.google.devtools.build.lib.util.AbruptExitException) TestExecException(com.google.devtools.build.lib.actions.TestExecException) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) Nullable(javax.annotation.Nullable)

Aggregations

BuildFailedException (com.google.devtools.build.lib.actions.BuildFailedException)25 Artifact (com.google.devtools.build.lib.actions.Artifact)20 Test (org.junit.Test)17 TestAction (com.google.devtools.build.lib.actions.util.TestAction)12 IOException (java.io.IOException)8 ActionInputHelper.treeFileArtifact (com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact)7 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)7 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)7 ActionExecutionException (com.google.devtools.build.lib.actions.ActionExecutionException)6 ActionExecutionContext (com.google.devtools.build.lib.actions.ActionExecutionContext)5 StoredEventHandler (com.google.devtools.build.lib.events.StoredEventHandler)5 ImmutableList (com.google.common.collect.ImmutableList)4 TestExecException (com.google.devtools.build.lib.actions.TestExecException)4 SpawnActionTemplate (com.google.devtools.build.lib.analysis.actions.SpawnActionTemplate)4 List (java.util.List)4 Action (com.google.devtools.build.lib.actions.Action)3 DummyAction (com.google.devtools.build.lib.actions.util.TestAction.DummyAction)3 ActionTemplate (com.google.devtools.build.lib.analysis.actions.ActionTemplate)3 ExitCode (com.google.devtools.build.lib.util.ExitCode)3 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)3