blob: ba449e41ccc6ec461c643af368bbfa48a81c4fa7 [file] [log] [blame]
// Copyright 2022 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.runtime.commands;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
import com.google.devtools.build.lib.buildtool.util.BuildIntegrationTestCase;
import com.google.devtools.build.lib.runtime.BlazeCommandDispatcher;
import com.google.devtools.build.lib.runtime.BlazeCommandResult;
import com.google.devtools.build.lib.runtime.BlazeRuntime;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.util.io.RecordingOutErr;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Tests for {@link DumpCommand}. */
@RunWith(JUnit4.class)
public final class DumpCommandTest extends BuildIntegrationTestCase {
private BlazeCommandDispatcher dispatcher;
private RecordingOutErr recordingOutErr;
@Before
public void createDispatcher() {
BlazeRuntime runtime = getRuntime();
runtime.getCommandMap().put("dump", new DumpCommand());
dispatcher = new BlazeCommandDispatcher(runtime);
}
@Before
public void createRecording() throws Exception {
recordingOutErr = new RecordingOutErr();
}
private BlazeCommandResult dump(String... args) throws InterruptedException {
List<String> params = Lists.newArrayList("dump");
Collections.addAll(params, args);
return dispatcher.exec(params, "test", recordingOutErr);
}
@Test
public void multiOptionSmoke() throws Exception {
write("foo/BUILD", "genrule(name = 'foo', outs = ['out'], cmd = 'touch $@')");
addOptions("--nobuild");
buildTarget("//foo:foo");
assertThat(dump("--rule_classes", "--rules", "--skyframe", "summary").isSuccess()).isTrue();
assertThat(recordingOutErr.outAsLatin1()).contains("filegroup");
assertThat(recordingOutErr.outAsLatin1()).contains("RULE");
assertThat(recordingOutErr.outAsLatin1()).contains("Node count");
}
@Test
public void interruptedOnRuleTypes() throws Exception {
write(
"foo/BUILD",
"genrule(name = 'bar', outs = ['bar.out'], cmd = 'touch $@')",
"genrule(name = 'bad', outs = ['bad.out'], srcs = [':bar'], cmd = '$BAD_VARIABLE')",
"genrule(name = 'foo', outs = ['foo.out'], srcs = [':bad'], cmd = 'touch $@')");
addOptions("--nobuild");
// The analysis failure enqueues nodes for invalidation/deletion, which get triggered during the
// getPackage() Skyframe evaluations during the rule-type dump. The interrupt then kicks in.
assertThrows(ViewCreationFailedException.class, () -> buildTarget("//foo:foo"));
Thread.currentThread().interrupt();
BlazeCommandResult result = dump("--rule_classes", "--rules", "--skyframe", "summary");
assertThat(result.getExitCode()).isEqualTo(ExitCode.INTERRUPTED);
assertThat(recordingOutErr.errAsLatin1()).contains("Interrupted");
// Dump output that happened before the interrupt is still there: this is sensitive to the order
// DumpCommand processes its options in.
assertThat(recordingOutErr.outAsLatin1()).contains("filegroup");
// There is no rule type output.
assertThat(recordingOutErr.outAsLatin1()).doesNotContain("RULE");
// Later dump output does not happen.
assertThat(recordingOutErr.outAsLatin1()).doesNotContain("Node count");
}
}