in src/com/facebook/buck/cli/TestCommand.java [460:701]
public ExitCode runWithoutHelp(CommandRunnerParams params) throws Exception {
assertArguments(params);
LOG.debug("Running with arguments %s", getArguments());
ListeningProcessExecutor processExecutor = new ListeningProcessExecutor();
try (CommandThreadManager pool =
new CommandThreadManager("Test", getConcurrencyLimit(params.getBuckConfig()));
BuildPrehook prehook = getPrehook(processExecutor, params)) {
prehook.startPrehookScript();
BuildEvent.Started started = BuildEvent.started(getArguments());
params.getBuckEventBus().post(started);
// The first step is to parse all of the build files. This will populate the parser and find
// all of the test rules.
TargetGraphCreationResult targetGraphCreationResult;
ParserConfig parserConfig = params.getBuckConfig().getView(ParserConfig.class);
ParsingContext parsingContext =
createParsingContext(params.getCells().getRootCell(), pool.getListeningExecutorService())
.withApplyDefaultFlavorsMode(parserConfig.getDefaultFlavorsMode())
.withSpeculativeParsing(SpeculativeParsing.ENABLED);
ImmutableSet<BuildTarget> explicitBuildTargets = ImmutableSet.of();
try {
// If the user asked to run all of the tests, parse all of the build files looking for any
// test rules.
if (isRunAllTests()) {
targetGraphCreationResult =
params
.getParser()
.buildTargetGraphWithoutTopLevelConfigurationTargets(
parsingContext,
ImmutableList.of(
TargetNodePredicateSpec.of(
BuildFileSpec.fromRecursivePath(
CellRelativePath.of(
params.getCells().getRootCell().getCanonicalName(),
ForwardRelativePath.of(""))),
true)),
params.getTargetConfiguration());
targetGraphCreationResult = targetGraphCreationResult.withBuildTargets(ImmutableSet.of());
// Otherwise, the user specified specific test targets to build and run, so build a graph
// around these.
} else {
LOG.debug("Parsing graph for arguments %s", getArguments());
targetGraphCreationResult =
params
.getParser()
.buildTargetGraphWithoutTopLevelConfigurationTargets(
parsingContext,
parseArgumentsAsTargetNodeSpecs(
params.getCells().getRootCell(),
params.getClientWorkingDir(),
getArguments(),
params.getBuckConfig()),
params.getTargetConfiguration());
explicitBuildTargets = targetGraphCreationResult.getBuildTargets();
LOG.debug("Got explicit build targets %s", explicitBuildTargets);
ImmutableSet.Builder<BuildTarget> testTargetsBuilder = ImmutableSet.builder();
for (TargetNode<?> node :
targetGraphCreationResult
.getTargetGraph()
.getAll(targetGraphCreationResult.getBuildTargets())) {
ImmutableSortedSet<BuildTarget> nodeTests = TargetNodes.getTestTargetsForNode(node);
if (!nodeTests.isEmpty()) {
LOG.debug("Got tests for target %s: %s", node.getBuildTarget(), nodeTests);
testTargetsBuilder.addAll(nodeTests);
}
}
ImmutableSet<BuildTarget> testTargets = testTargetsBuilder.build();
if (!testTargets.isEmpty()) {
LOG.debug("Got related test targets %s, building new target graph...", testTargets);
ImmutableSet<BuildTarget> allTargets =
MoreSets.union(targetGraphCreationResult.getBuildTargets(), testTargets);
targetGraphCreationResult =
params.getParser().buildTargetGraph(parsingContext, allTargets);
LOG.debug("Finished building new target graph with tests.");
}
}
if (params.getBuckConfig().getView(BuildBuckConfig.class).getBuildVersions()) {
targetGraphCreationResult = toVersionedTargetGraph(params, targetGraphCreationResult);
}
} catch (BuildFileParseException | VersionException e) {
params
.getBuckEventBus()
.post(ConsoleEvent.severe(MoreExceptions.getHumanReadableOrLocalizedMessage(e)));
return ExitCode.PARSE_ERROR;
}
ActionGraphAndBuilder actionGraphAndBuilder =
params.getActionGraphProvider().getActionGraph(targetGraphCreationResult);
// Look up all of the test rules in the action graph.
Iterable<TestRule> testRules =
Iterables.filter(actionGraphAndBuilder.getActionGraph().getNodes(), TestRule.class);
// Unless the user requests that we build filtered tests, filter them out here, before
// the build.
if (!isBuildFiltered(params.getBuckConfig())) {
testRules = filterTestRules(params.getBuckConfig(), explicitBuildTargets, testRules);
}
ImmutableSet<BuildRule> rulesToMaterializeForAnalysis = ImmutableSet.of();
if (isCodeCoverageEnabled) {
// Ensure that the libraries that we want to inspect after the build are built/fetched.
// This requires that the rules under test are materialized as well as any generated srcs
// that they use
BuildRuleResolver ruleResolver = actionGraphAndBuilder.getActionGraphBuilder();
ImmutableSet<JavaLibrary> rulesUnderTest = TestRunning.getRulesUnderTest(testRules);
rulesToMaterializeForAnalysis =
RichStream.from(rulesUnderTest)
.flatMap(
lib -> RichStream.from(ruleResolver.filterBuildRuleInputs(lib.getJavaSrcs())))
.concat(RichStream.from(rulesUnderTest))
.collect(ImmutableSet.toImmutableSet());
}
CachingBuildEngineBuckConfig cachingBuildEngineBuckConfig =
params.getBuckConfig().getView(CachingBuildEngineBuckConfig.class);
try (RuleKeyCacheScope<RuleKey> ruleKeyCacheScope =
getDefaultRuleKeyCacheScope(
params,
new RuleKeyCacheRecycler.SettingsAffectingCache(
params.getBuckConfig().getView(BuildBuckConfig.class).getKeySeed(),
actionGraphAndBuilder.getActionGraph()))) {
boolean remoteExecutionAutoEnabled =
params
.getBuckConfig()
.getView(RemoteExecutionConfig.class)
.isRemoteExecutionAutoEnabled(
params.getBuildEnvironmentDescription().getUser(), getArguments());
LocalCachingBuildEngineDelegate localCachingBuildEngineDelegate =
new LocalCachingBuildEngineDelegate(params.getFileHashCache());
try (CachingBuildEngine cachingBuildEngine =
new CachingBuildEngine(
localCachingBuildEngineDelegate,
ModernBuildRuleBuilderFactory.getBuildStrategy(
params.getBuckConfig().getView(ModernBuildRuleConfig.class),
params.getBuckConfig().getView(RemoteExecutionConfig.class),
actionGraphAndBuilder.getActionGraphBuilder(),
params.getCells().getRootCell(),
params.getCells().getRootCell().getCellPathResolver(),
localCachingBuildEngineDelegate.getFileHashCache(),
params.getBuckEventBus(),
params.getMetadataProvider(),
remoteExecutionAutoEnabled,
isRemoteExecutionForceDisabled()),
pool.getWeightedListeningExecutorService(),
getBuildEngineMode().orElse(cachingBuildEngineBuckConfig.getBuildEngineMode()),
cachingBuildEngineBuckConfig.getBuildDepFiles(),
cachingBuildEngineBuckConfig.getBuildMaxDepFileCacheEntries(),
cachingBuildEngineBuckConfig.getBuildArtifactCacheSizeLimit(),
actionGraphAndBuilder.getActionGraphBuilder(),
actionGraphAndBuilder.getBuildEngineActionToBuildRuleResolver(),
params.getTargetConfigurationSerializer(),
params.getBuildInfoStoreManager(),
cachingBuildEngineBuckConfig.getResourceAwareSchedulingInfo(),
cachingBuildEngineBuckConfig.getConsoleLogBuildRuleFailuresInline(),
RuleKeyFactories.of(
params.getRuleKeyConfiguration(),
localCachingBuildEngineDelegate.getFileHashCache(),
actionGraphAndBuilder.getActionGraphBuilder(),
params
.getBuckConfig()
.getView(BuildBuckConfig.class)
.getBuildInputRuleKeyFileSizeLimit(),
ruleKeyCacheScope.getCache()));
Build build =
new Build(
actionGraphAndBuilder.getActionGraphBuilder(),
params.getCells().getRootCell(),
cachingBuildEngine,
params.getArtifactCacheFactory().newInstance(),
params
.getBuckConfig()
.getView(JavaBuckConfig.class)
.createDefaultJavaPackageFinder(),
params.getClock(),
getExecutionContext(),
isKeepGoing())) {
// Build all of the test rules and runtime deps.
Iterable<BuildTarget> targets =
RichStream.from(testRules)
.filter(HasRuntimeDeps.class::isInstance)
.map(HasRuntimeDeps.class::cast)
.flatMap(
rule -> rule.getRuntimeDeps(actionGraphAndBuilder.getActionGraphBuilder()))
.concat(RichStream.from(testRules).map(TestRule::getBuildTarget))
.concat(
RichStream.from(rulesToMaterializeForAnalysis).map(BuildRule::getBuildTarget))
.toImmutableList();
ExitCode exitCode =
build.executeAndPrintFailuresToEventBus(
targets,
params.getBuckEventBus(),
params.getConsole(),
getPathToBuildReport(params.getBuckConfig()));
params.getBuckEventBus().post(BuildEvent.finished(started, exitCode));
if (exitCode != ExitCode.SUCCESS) {
return exitCode;
}
// If the user requests that we build tests that we filter out, then we perform
// the filtering here, after we've done the build but before we run the tests.
if (isBuildFiltered(params.getBuckConfig())) {
testRules = filterTestRules(params.getBuckConfig(), explicitBuildTargets, testRules);
}
BuildContext buildContext =
BuildContext.of(
actionGraphAndBuilder.getActionGraphBuilder().getSourcePathResolver(),
params.getCells().getRootCell().getRoot().getPath(),
params.getJavaPackageFinder(),
params.getBuckEventBus(),
params
.getBuckConfig()
.getView(BuildBuckConfig.class)
.getShouldDeleteTemporaries());
// Once all of the rules are built, then run the tests.
Optional<ImmutableList<String>> externalTestRunner =
params.getBuckConfig().getView(TestBuckConfig.class).getExternalTestRunner();
if (externalTestRunner.isPresent()) {
return runTestsExternal(
params, build, externalTestRunner.get(), testRules, buildContext);
}
return runTestsInternal(
params,
actionGraphAndBuilder.getActionGraphBuilder(),
cachingBuildEngine,
build,
buildContext,
testRules);
}
}
}
}