in src/com/facebook/buck/android/RobolectricTestDescription.java [149:463]
public BuildRule createBuildRule(
BuildRuleCreationContextWithTargetGraph context,
BuildTarget buildTarget,
BuildRuleParams params,
RobolectricTestDescriptionArg args) {
ActionGraphBuilder graphBuilder = context.getActionGraphBuilder();
ProjectFilesystem projectFilesystem = context.getProjectFilesystem();
if (JavaAbis.isClassAbiTarget(buildTarget)) {
Preconditions.checkArgument(
!buildTarget.getFlavors().contains(AndroidLibraryGraphEnhancer.DUMMY_R_DOT_JAVA_FLAVOR));
BuildTarget testTarget = JavaAbis.getLibraryTarget(buildTarget);
BuildRule testRule = graphBuilder.requireRule(testTarget);
return CalculateClassAbi.of(
buildTarget,
graphBuilder,
projectFilesystem,
Objects.requireNonNull(testRule.getSourcePathToOutput()));
}
JavacOptions javacOptions =
JavacOptionsFactory.create(
defaultJavacOptions.getUnchecked(buildTarget.getTargetConfiguration()),
buildTarget,
graphBuilder,
args);
AndroidLibraryGraphEnhancer graphEnhancer =
new AndroidLibraryGraphEnhancer(
buildTarget,
projectFilesystem,
ImmutableSortedSet.copyOf(
Iterables.concat(
params.getBuildDeps(), graphBuilder.getAllRules(args.getExportedDeps()))),
javacFactory.create(graphBuilder, args, buildTarget.getTargetConfiguration()),
javacOptions,
DependencyMode.TRANSITIVE,
args.isForceFinalResourceIds(),
args.getResourceUnionPackage(),
/* rName */ Optional.empty(),
args.isUseOldStyleableFormat(),
/* skipNonUnionRDotJava */ false);
StringWithMacrosConverter macrosConverter =
StringWithMacrosConverter.of(
buildTarget,
context.getCellPathResolver().getCellNameResolver(),
graphBuilder,
JavaTestDescription.MACRO_EXPANDERS);
ImmutableList<Arg> vmArgs =
ImmutableList.copyOf(Lists.transform(args.getVmArgs(), macrosConverter::convert));
Optional<DummyRDotJava> dummyRDotJava =
graphEnhancer.getBuildableForAndroidResources(
graphBuilder, /* createBuildableIfEmpty */ true);
RobolectricTestDescriptionArg testLibraryArgs = args;
AndroidPlatformTarget androidPlatformTarget =
toolchainProvider.getByName(
AndroidPlatformTarget.DEFAULT_NAME,
buildTarget.getTargetConfiguration(),
AndroidPlatformTarget.class);
Optional<UnitTestOptions> unitTestOptions = Optional.empty();
if (dummyRDotJava.isPresent()) {
DummyRDotJava actualDummyRDotJava = dummyRDotJava.get();
ImmutableSortedSet<BuildRule> newDeclaredDeps =
ImmutableSortedSet.<BuildRule>naturalOrder()
.addAll(params.getDeclaredDeps().get())
.add(actualDummyRDotJava)
.build();
if (!args.isUseBinaryResources()) {
params = params.withDeclaredDeps(newDeclaredDeps);
testLibraryArgs =
testLibraryArgs.withDeps(
Iterables.concat(
args.getDeps(),
Collections.singletonList(actualDummyRDotJava.getBuildTarget())));
} else {
Optional<SourcePath> maybeRoboManifest = args.getRobolectricManifest();
Preconditions.checkArgument(
maybeRoboManifest.isPresent(),
"You must specify a manifest to use binary resources mode.");
SourcePath robolectricManifest = maybeRoboManifest.get();
FilteredResourcesProvider resourcesProvider =
new IdentityResourcesProvider(
actualDummyRDotJava.getAndroidResourceDeps().stream()
.map(HasAndroidResourceDeps::getRes)
.collect(ImmutableList.toImmutableList()));
ToolProvider aapt2ToolProvider = androidPlatformTarget.getAapt2ToolProvider();
ImmutableList<Aapt2Compile> compileables =
AndroidBinaryResourcesGraphEnhancer.createAapt2CompileablesForResourceProvider(
projectFilesystem,
graphBuilder,
aapt2ToolProvider,
resourcesProvider,
buildTarget,
true,
false);
BuildTarget aapt2LinkBuildTarget =
buildTarget.withAppendedFlavors(InternalFlavor.of("aapt2_link"));
Aapt2Link aapt2Link =
new Aapt2Link(
aapt2LinkBuildTarget,
projectFilesystem,
graphBuilder,
compileables,
robolectricManifest,
ManifestEntries.builder().build(),
0,
ImmutableList.of(),
false,
false,
false,
false,
false,
false,
aapt2ToolProvider.resolve(
graphBuilder, aapt2LinkBuildTarget.getTargetConfiguration()),
ImmutableList.of(),
androidPlatformTarget.getAndroidJar(),
false,
ImmutableSet.of(),
ImmutableSet.of());
graphBuilder.addToIndex(aapt2Link);
AaptOutputInfo aaptOutputInfo = aapt2Link.getAaptOutputInfo();
unitTestOptions =
Optional.of(
new UnitTestOptions(
buildTarget.withAppendedFlavors(InternalFlavor.of("unit_test_options")),
projectFilesystem,
graphBuilder,
ImmutableMap.of(
"android_resource_apk",
graphBuilder
.getSourcePathResolver()
.getAbsolutePath(aaptOutputInfo.getPrimaryResourcesApkPath())
.toString())));
graphBuilder.addToIndex(unitTestOptions.get());
GenerateRDotJava generateRDotJava =
new GenerateRDotJava(
buildTarget.withAppendedFlavors(InternalFlavor.of("generate_rdot_java")),
projectFilesystem,
graphBuilder,
EnumSet.noneOf(RDotTxtEntry.RType.class),
Optional.empty(),
ImmutableList.of(aaptOutputInfo.getPathToRDotTxt()),
args.getResourceUnionPackage(),
actualDummyRDotJava.getAndroidResourceDeps().stream()
.map(HasAndroidResourceDeps::getBuildTarget)
.map(graphBuilder::requireRule)
.collect(ImmutableSortedSet.toImmutableSortedSet(Comparator.naturalOrder())),
ImmutableList.of(resourcesProvider));
graphBuilder.addToIndex(generateRDotJava);
params =
params.copyAppendingExtraDeps(
ImmutableSortedSet.of(generateRDotJava, unitTestOptions.get()));
ImmutableSortedSet<SourcePath> updatedSrcs =
ImmutableSortedSet.<SourcePath>naturalOrder()
.addAll(testLibraryArgs.getSrcs())
.add(generateRDotJava.getSourcePathToRZip())
.build();
testLibraryArgs = testLibraryArgs.withSrcs(updatedSrcs);
}
}
JavaTestDescription.CxxLibraryEnhancement cxxLibraryEnhancement =
new JavaTestDescription.CxxLibraryEnhancement(
buildTarget,
projectFilesystem,
params,
args.getUseCxxLibraries(),
args.getCxxLibraryWhitelist(),
graphBuilder,
getCxxPlatform(args, buildTarget.getTargetConfiguration())
.resolve(graphBuilder, buildTarget.getTargetConfiguration()));
params = cxxLibraryEnhancement.updatedParams;
BuildTarget testLibraryBuildTarget =
buildTarget.withAppendedFlavors(JavaTest.COMPILED_TESTS_LIBRARY_FLAVOR);
JavaLibrary testsLibrary =
graphBuilder.addToIndex(
DefaultJavaLibrary.rulesBuilder(
testLibraryBuildTarget,
projectFilesystem,
context.getToolchainProvider(),
params,
graphBuilder,
compilerFactory.getCompiler(
args.getLanguage().orElse(AndroidLibraryDescription.JvmLanguage.JAVA),
javacFactory,
buildTarget.getTargetConfiguration()),
javaBuckConfig,
testLibraryArgs)
.setJavacOptions(javacOptions)
.build()
.buildLibrary());
params = params.copyAppendingExtraDeps(ImmutableSortedSet.of(testsLibrary));
Optional<BuildTarget> runner = args.getRunner();
Optional<TestRunnerSpec> runnerSpecs = args.getSpecs();
if (runnerSpecs.isPresent()) {
JavaTestRunner testRunner;
if (runner.isPresent()) {
BuildRule runnerRule = graphBuilder.requireRule(runner.get());
if (!(runnerRule instanceof JavaTestRunner)) {
throw new HumanReadableException(
"Robolectric tests should have a java_test_runner as the runner for test protocol");
}
testRunner = (JavaTestRunner) runnerRule;
} else {
throw new HumanReadableException(
"Robolectric test should have a java_test_runner as the runner for test protocol");
}
params = params.copyAppendingExtraDeps(testRunner.getCompiledTestsLibrary());
// Construct the build rule to build the binary JAR.
ImmutableSet<JavaLibrary> transitiveClasspathDeps =
JavaLibraryClasspathProvider.getClasspathDeps(params.getBuildDeps());
ImmutableSet<SourcePath> transitiveClasspaths =
JavaLibraryClasspathProvider.getClasspathsFromLibraries(transitiveClasspathDeps);
JavaBinary javaBinary =
new JavaBinary(
buildTarget.withFlavors(InternalFlavor.of("bin")),
projectFilesystem,
params.copyAppendingExtraDeps(transitiveClasspathDeps),
javaOptionsForTests
.apply(buildTarget.getTargetConfiguration())
.getJavaRuntimeLauncher(graphBuilder, buildTarget.getTargetConfiguration()),
testRunner.getMainClass(),
args.getManifestFile().orElse(null),
true,
false,
null,
ImmutableSet.of(),
transitiveClasspathDeps,
transitiveClasspaths,
javaBuckConfig.shouldCacheBinaries(),
javaBuckConfig.getDuplicatesLogLevel());
graphBuilder.addToIndex(javaBinary);
return new RobolectricTestX(
buildTarget,
projectFilesystem,
params.copyAppendingExtraDeps(javaBinary),
javaBinary,
testsLibrary,
args.getLabels(),
args.getContacts(),
TestRunnerSpecCoercer.coerce(args.getSpecs().get(), macrosConverter),
vmArgs,
dummyRDotJava,
args.getUnbundledResourcesRoot(),
args.getRobolectricRuntimeDependency(),
javaBuckConfig
.getDelegate()
.getBooleanValue("test", "pass_robolectric_directories_in_file", false));
} else if (runner.isPresent()) {
throw new HumanReadableException("Should not have runner set when no specs are set");
}
return new RobolectricTest(
buildTarget,
projectFilesystem,
params,
androidPlatformTarget,
testsLibrary,
args.getLabels(),
args.getContacts(),
TestType.JUNIT,
javacOptions.getLanguageLevelOptions().getTargetLevel(),
vmArgs,
cxxLibraryEnhancement.nativeLibsEnvironment,
args.isUseBinaryResources() ? Optional.empty() : dummyRDotJava,
unitTestOptions,
args.getTestRuleTimeoutMs()
.map(Optional::of)
.orElse(
javaBuckConfig
.getDelegate()
.getView(TestBuckConfig.class)
.getDefaultTestRuleTimeoutMs()),
args.getTestCaseTimeoutMs(),
ImmutableMap.copyOf(Maps.transformValues(args.getEnv(), macrosConverter::convert)),
args.getRunTestSeparately(),
args.getForkMode(),
args.getStdOutLogLevel(),
args.getStdErrLogLevel(),
args.getUnbundledResourcesRoot(),
args.getRobolectricRuntimeDependency(),
args.getRobolectricManifest(),
javaBuckConfig
.getDelegate()
.getBooleanValue("test", "pass_robolectric_directories_in_file", false),
javaOptionsForTests
.apply(buildTarget.getTargetConfiguration())
.getJavaRuntimeLauncher(graphBuilder, buildTarget.getTargetConfiguration()));
}