Search in sources :

Example 16 with ActionExecutionContext

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

the class TreeArtifactBuildTest method testAbsoluteSymlinkAccepted.

@Test
public void testAbsoluteSymlinkAccepted() throws Exception {
    scratch.overwriteFile("/random/pointer");
    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);
            }
        }
    };
    registerAction(action);
    buildArtifact(action.getSoleOutput());
}
Also used : ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) ActionInputHelper.treeFileArtifact(com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) IOException(java.io.IOException) Test(org.junit.Test)

Example 17 with ActionExecutionContext

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

the class TreeArtifactBuildTest method testInvalidOutputRegistrations.

@Test
public void testInvalidOutputRegistrations() throws Exception {
    // Failure expected
    StoredEventHandler storingEventHandler = new StoredEventHandler();
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(storingEventHandler);
    TreeArtifactTestAction failureOne = new TreeArtifactTestAction(Runnables.doNothing(), outOneFileOne, outOneFileTwo) {

        @Override
        public void executeTestBehavior(ActionExecutionContext actionExecutionContext) {
            try {
                writeFile(outOneFileOne, "one");
                writeFile(outOneFileTwo, "two");
                // In this test case, we only register one output. This will fail.
                registerOutput(actionExecutionContext, "one");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    };
    registerAction(failureOne);
    try {
        buildArtifact(outOne);
        // Should have thrown
        fail();
    } catch (BuildFailedException e) {
        //not all outputs were created
        List<Event> errors = ImmutableList.copyOf(Iterables.filter(storingEventHandler.getEvents(), IS_ERROR_EVENT));
        assertThat(errors).hasSize(2);
        assertThat(errors.get(0).getMessage()).contains("not present on disk");
        assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
    }
    TreeArtifactTestAction failureTwo = new TreeArtifactTestAction(Runnables.doNothing(), outTwoFileOne, outTwoFileTwo) {

        @Override
        public void executeTestBehavior(ActionExecutionContext actionExecutionContext) {
            try {
                writeFile(outTwoFileOne, "one");
                writeFile(outTwoFileTwo, "two");
                // In this test case, register too many outputs. This will fail.
                registerOutput(actionExecutionContext, "one");
                registerOutput(actionExecutionContext, "two");
                registerOutput(actionExecutionContext, "three");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    };
    registerAction(failureTwo);
    storingEventHandler.clear();
    try {
        buildArtifact(outTwo);
        // Should have thrown
        fail();
    } catch (BuildFailedException e) {
        List<Event> errors = ImmutableList.copyOf(Iterables.filter(storingEventHandler.getEvents(), IS_ERROR_EVENT));
        assertThat(errors).hasSize(2);
        assertThat(errors.get(0).getMessage()).contains("not present on disk");
        assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
    }
}
Also used : StoredEventHandler(com.google.devtools.build.lib.events.StoredEventHandler) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) IOException(java.io.IOException) Test(org.junit.Test)

Example 18 with ActionExecutionContext

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

the class TreeArtifactBuildTest method testValidRelativeSymlinkAccepted.

@Test
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);
            }
        }
    };
    registerAction(action);
    buildArtifact(action.getSoleOutput());
}
Also used : ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) ActionInputHelper.treeFileArtifact(com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) IOException(java.io.IOException) Test(org.junit.Test)

Example 19 with ActionExecutionContext

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

the class TreeArtifactBuildTest method testAbsoluteSymlinkBadTargetRejected.

@Test
public void testAbsoluteSymlinkBadTargetRejected() throws Exception {
    // Failure expected
    StoredEventHandler storingEventHandler = new StoredEventHandler();
    reporter.removeHandler(failFastHandler);
    reporter.addHandler(storingEventHandler);
    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);
            }
        }
    };
    registerAction(action);
    try {
        buildArtifact(action.getSoleOutput());
        // Should have thrown
        fail();
    } catch (BuildFailedException e) {
        List<Event> errors = ImmutableList.copyOf(Iterables.filter(storingEventHandler.getEvents(), IS_ERROR_EVENT));
        assertThat(errors).hasSize(2);
        assertThat(errors.get(0).getMessage()).contains("Failed to resolve relative path links/link");
        assertThat(errors.get(1).getMessage()).contains("not all outputs were created or valid");
    }
}
Also used : StoredEventHandler(com.google.devtools.build.lib.events.StoredEventHandler) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) ActionInputHelper.treeFileArtifact(com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) IOException(java.io.IOException) Test(org.junit.Test)

Example 20 with ActionExecutionContext

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

the class SkyframeAwareActionTest method testRaceConditionBetweenInputAcquisitionAndSkyframeDeps.

/**
   * Regression test to avoid a potential race condition in {@link ActionExecutionFunction}.
   *
   * <p>The test ensures that when ActionExecutionFunction executes a Skyframe-aware action
   * (implementor of {@link SkyframeAwareAction}), ActionExecutionFunction first requests the inputs
   * of the action and ensures they are built before requesting any of its Skyframe dependencies.
   *
   * <p>This strict ordering is very important to avoid the race condition, which could arise if the
   * compute method were too eager to request all dependencies: request input files but even if some
   * are missing, request also the skyframe-dependencies. The race is described in this method's
   * body.
   */
@Test
public void testRaceConditionBetweenInputAcquisitionAndSkyframeDeps() throws Exception {
    // Sequence of events on threads A and B, showing SkyFunctions and requested SkyKeys, leading
    // to an InconsistentFilesystemException:
    //
    // _______________[Thread A]_________________|_______________[Thread B]_________________
    // ActionExecutionFunction(gen2_action:      | idle
    //   genfiles/gen1 -> genfiles/foo/bar/gen2) |
    // ARTIFACT:genfiles/gen1                    |
    // MOCK_VALUE:dummy_argument                 |
    // env.valuesMissing():yes ==> return        |
    //                                           |
    // ArtifactFunction(genfiles/gen1)           | MockFunction()
    // CONFIGURED_TARGET://foo:gen1              | FILE:genfiles/foo
    // ACTION_EXECUTION:gen1_action              | env.valuesMissing():yes ==> return
    // env.valuesMissing():yes ==> return        |
    //                                           | FileFunction(genfiles/foo)
    // ActionExecutionFunction(gen1_action)      | FILE:genfiles
    // ARTIFACT:genfiles/gen0                    | env.valuesMissing():yes ==> return
    // env.valuesMissing():yes ==> return        |
    //                                           | FileFunction(genfiles)
    // ArtifactFunction(genfiles/gen0)           | FILE_STATE:genfiles
    // CONFIGURED_TARGET://foo:gen0              | env.valuesMissing():yes ==> return
    // ACTION_EXECUTION:gen0_action              |
    // env.valuesMissing():yes ==> return        | FileStateFunction(genfiles)
    //                                           | stat genfiles
    // ActionExecutionFunction(gen0_action)      | return FileStateValue:non-existent
    // create output directory: genfiles         |
    // working                                   | FileFunction(genfiles/foo)
    //                                           | FILE:genfiles
    //                                           | FILE_STATE:genfiles/foo
    //                                           | env.valuesMissing():yes ==> return
    //                                           |
    //                                           | FileStateFunction(genfiles/foo)
    //                                           | stat genfiles/foo
    //                                           | return FileStateValue:non-existent
    //                                           |
    // done, created genfiles/gen0               | FileFunction(genfiles/foo)
    // return ActionExecutionValue(gen0_action)  | FILE:genfiles
    //                                           | FILE_STATE:genfiles/foo
    // ArtifactFunction(genfiles/gen0)           | return FileValue(genfiles/foo:non-existent)
    // CONFIGURED_TARGET://foo:gen0              |
    // ACTION_EXECUTION:gen0_action              | MockFunction()
    // return ArtifactSkyKey(genfiles/gen0)      | FILE:genfiles/foo
    //                                           | FILE:genfiles/foo/bar/gen1
    // ActionExecutionFunction(gen1_action)      | env.valuesMissing():yes ==> return
    // ARTIFACT:genfiles/gen0                    |
    // create output directory: genfiles/foo/bar | FileFunction(genfiles/foo/bar/gen1)
    // done, created genfiles/foo/bar/gen1       | FILE:genfiles/foo/bar
    // return ActionExecutionValue(gen1_action)  | env.valuesMissing():yes ==> return
    //                                           |
    // idle                                      | FileFunction(genfiles/foo/bar)
    //                                           | FILE:genfiles/foo
    //                                           | FILE_STATE:genfiles/foo/bar
    //                                           | env.valuesMissing():yes ==> return
    //                                           |
    //                                           | FileStateFunction(genfiles/foo/bar)
    //                                           | stat genfiles/foo/bar
    //                                           | return FileStateValue:directory
    //                                           |
    //                                           | FileFunction(genfiles/foo/bar)
    //                                           | FILE:genfiles/foo
    //                                           | FILE_STATE:genfiles/foo/bar
    //                                           | throw InconsistentFilesystemException:
    //                                           |     genfiles/foo doesn't exist but
    //                                           |     genfiles/foo/bar does!
    Artifact genFile1 = createDerivedArtifact("foo/bar/gen1.txt");
    Artifact genFile2 = createDerivedArtifact("gen2.txt");
    registerAction(new SingleOutputAction(null, genFile1) {

        @Override
        public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException {
            writeOutput(null, "gen1");
        }
    });
    registerAction(new SingleOutputSkyframeAwareAction(genFile1, genFile2) {

        @Override
        public void establishSkyframeDependencies(Environment env) throws ExceptionBase {
            assertThat(env.valuesMissing()).isFalse();
        }

        @Override
        public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException {
            writeOutput(readInput(), "gen2");
        }
    });
    builder.buildArtifacts(reporter, ImmutableSet.of(genFile2), null, null, null, null, executor, null, false, null, null);
}
Also used : ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) Environment(com.google.devtools.build.skyframe.SkyFunction.Environment) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) Artifact(com.google.devtools.build.lib.actions.Artifact) Test(org.junit.Test)

Aggregations

ActionExecutionContext (com.google.devtools.build.lib.actions.ActionExecutionContext)24 Test (org.junit.Test)19 Artifact (com.google.devtools.build.lib.actions.Artifact)17 ActionExecutionException (com.google.devtools.build.lib.actions.ActionExecutionException)13 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)13 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)13 IOException (java.io.IOException)12 BuildFailedException (com.google.devtools.build.lib.actions.BuildFailedException)10 Action (com.google.devtools.build.lib.actions.Action)7 ActionInputHelper.treeFileArtifact (com.google.devtools.build.lib.actions.ActionInputHelper.treeFileArtifact)7 ImmutableList (com.google.common.collect.ImmutableList)4 StoredEventHandler (com.google.devtools.build.lib.events.StoredEventHandler)4 TestExecutorBuilder (com.google.devtools.build.lib.exec.util.TestExecutorBuilder)4 List (java.util.List)4 Executor (com.google.devtools.build.lib.actions.Executor)3 FileOutErr (com.google.devtools.build.lib.util.io.FileOutErr)3 ArrayList (java.util.ArrayList)3 TestAction (com.google.devtools.build.lib.actions.util.TestAction)2 Collection (java.util.Collection)2 Before (org.junit.Before)2