use of com.google.devtools.build.lib.actions.util.TestAction in project bazel by bazelbuild.
the class TreeArtifactBuildTest method testInputTreeArtifactPerActionFileCache.
@Test
public void testInputTreeArtifactPerActionFileCache() throws Exception {
TouchingTestAction actionOne = new TouchingTestAction(outOneFileOne, outOneFileTwo);
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.getDigest(outOneFileOne)).isNotNull();
assertThat(fileCache.getDigest(outOneFileTwo)).isNotNull();
// Touch the action output.
touchFile(normalOutput);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
registerAction(testAction);
buildArtifact(normalOutput);
}
use of com.google.devtools.build.lib.actions.util.TestAction in project bazel by bazelbuild.
the class ParallelBuilderTest method testWaitsForSubprocesses.
// Regression test for bug fixed in CL 3548332: builder was not waiting for
// all its subprocesses to terminate.
@Test
public void testWaitsForSubprocesses() throws Exception {
final Semaphore semaphore = new Semaphore(1);
final boolean[] finished = { false };
// t=0: semaphore acquired
semaphore.acquireUninterruptibly();
// This arrangement ensures that the "bar" action tries to run for about
// 100ms after the "foo" action has completed (failed).
// [action] -> foo
Artifact foo = createDerivedArtifact("foo");
Callable<Void> makeFoo = new Callable<Void>() {
@Override
public Void call() throws IOException {
// t=2: semaphore re-acquired
semaphore.acquireUninterruptibly();
throw new IOException("foo action failed");
}
};
registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
// [action] -> bar
Artifact bar = createDerivedArtifact("bar");
Runnable makeBar = new Runnable() {
@Override
public void run() {
// t=1: semaphore released
semaphore.release();
try {
// 100ms
Thread.sleep(100);
} catch (InterruptedException e) {
// This might happen (though not necessarily). The
// ParallelBuilder interrupts all its workers at the first sign
// of trouble.
}
finished[0] = true;
}
};
registerAction(new TestAction(makeBar, emptySet, asSet(bar)));
// Don't fail fast when we encounter the error
reporter.removeHandler(failFastHandler);
try {
buildArtifacts(foo, bar);
fail();
} catch (BuildFailedException e) {
assertThat(e.getMessage()).contains("TestAction failed due to exception: foo action failed");
assertContainsEvent("TestAction failed due to exception: foo action failed");
}
assertTrue("bar action not finished, yet buildArtifacts has completed.", finished[0]);
}
use of com.google.devtools.build.lib.actions.util.TestAction in project bazel by bazelbuild.
the class ParallelBuilderTest method runsInParallelWithBuilder.
/**
* Test that independent actions are run in parallel threads
* that are scheduled concurrently.
*/
public void runsInParallelWithBuilder(Builder builder) throws Exception {
// We create two actions, each of which waits (spinning) until the
// other action has started. If the two actions are not run
// in parallel, the test will deadlock and time out.
// This specifies how many iterations to run before timing out.
// This should be large enough to ensure that that there is at
// least one context switch, otherwise the test may spuriously fail.
final long maxIterations = 100000000;
// This specifies how often to print out progress messages.
// Uncomment this for debugging.
//final long PRINT_FREQUENCY = maxIterations / 10;
runningFooAction = false;
runningBarAction = false;
// [action] -> foo
Artifact foo = createDerivedArtifact("foo");
Runnable makeFoo = new Runnable() {
@Override
public void run() {
runningFooAction = true;
for (long i = 0; i < maxIterations; i++) {
Thread.yield();
if (runningBarAction) {
return;
}
// Uncomment this for debugging.
//if (i % PRINT_FREQUENCY == 0) {
// String msg = "ParallelBuilderTest: foo: waiting for bar";
// System.out.println(bar);
//}
}
fail("ParallelBuilderTest: foo: waiting for bar: timed out");
}
};
registerAction(new TestAction(makeFoo, Artifact.NO_ARTIFACTS, ImmutableList.of(foo)));
// [action] -> bar
Artifact bar = createDerivedArtifact("bar");
Runnable makeBar = new Runnable() {
@Override
public void run() {
runningBarAction = true;
for (long i = 0; i < maxIterations; i++) {
Thread.yield();
if (runningFooAction) {
return;
}
// Uncomment this for debugging.
//if (i % PRINT_FREQUENCY == 0) {
// String msg = "ParallelBuilderTest: bar: waiting for foo";
// System.out.println(msg);
//}
}
fail("ParallelBuilderTest: bar: waiting for foo: timed out");
}
};
registerAction(new TestAction(makeBar, Artifact.NO_ARTIFACTS, ImmutableList.of(bar)));
buildArtifacts(builder, foo, bar);
}
use of com.google.devtools.build.lib.actions.util.TestAction in project bazel by bazelbuild.
the class ParallelBuilderTest method testProgressReporting.
@Test
public void testProgressReporting() throws Exception {
// Build three artifacts in 3 separate actions (baz depends on bar and bar
// depends on foo. Make sure progress is reported at the beginning of all
// three actions.
List<Artifact> sourceFiles = new ArrayList<>();
for (int i = 0; i < 10; i++) {
sourceFiles.add(createInputFile("file" + i));
}
Artifact foo = createDerivedArtifact("foo");
Artifact bar = createDerivedArtifact("bar");
Artifact baz = createDerivedArtifact("baz");
bar.getPath().delete();
baz.getPath().delete();
final List<String> messages = new ArrayList<>();
EventHandler handler = new EventHandler() {
@Override
public void handle(Event event) {
EventKind k = event.getKind();
if (k == EventKind.START || k == EventKind.FINISH) {
// Remove the tmpDir as this is user specific and the assert would
// fail below.
messages.add(event.getMessage().replaceFirst(TestUtils.tmpDir(), "") + " " + event.getKind());
}
}
};
reporter.addHandler(handler);
reporter.addHandler(new PrintingEventHandler(EventKind.ALL_EVENTS));
registerAction(new TestAction(TestAction.NO_EFFECT, sourceFiles, asSet(foo)));
registerAction(new TestAction(TestAction.NO_EFFECT, asSet(foo), asSet(bar)));
registerAction(new TestAction(TestAction.NO_EFFECT, asSet(bar), asSet(baz)));
buildArtifacts(baz);
// Check that the percentages increase non-linearly, because foo has 10 input files
List<String> expectedMessages = Lists.newArrayList("Test foo START", "Test foo FINISH", "Test bar START", "Test bar FINISH", "Test baz START", "Test baz FINISH");
assertThat(messages).containsAllIn(expectedMessages);
// Now do an incremental rebuild of bar and baz,
// and check the incremental progress percentages.
messages.clear();
bar.getPath().delete();
baz.getPath().delete();
// This uses a new builder instance so that we refetch timestamps from
// (in-memory) file system, rather than using cached entries.
buildArtifacts(baz);
expectedMessages = Lists.newArrayList("Test bar START", "Test bar FINISH", "Test baz START", "Test baz FINISH");
assertThat(messages).containsAllIn(expectedMessages);
}
use of com.google.devtools.build.lib.actions.util.TestAction in project bazel by bazelbuild.
the class ParallelBuilderTest method testDuplicatedInput.
@Test
public void testDuplicatedInput() throws Exception {
// <null> -> [action] -> foo
// (foo, foo) -> [action] -> bar
Artifact foo = createDerivedArtifact("foo");
Artifact bar = createDerivedArtifact("bar");
registerAction(new TestAction(TestAction.NO_EFFECT, ParallelBuilderTest.<Artifact>asSet(), asSet(foo)));
registerAction(new TestAction(TestAction.NO_EFFECT, Lists.<Artifact>newArrayList(foo, foo), asSet(bar)));
buildArtifacts(bar);
}
Aggregations