/* * Copyright 2014-present Facebook, Inc. * * 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.facebook.buck.android; import com.facebook.buck.cxx.CxxPlatform; import com.facebook.buck.jvm.java.CalculateAbiFromClasses; import com.facebook.buck.jvm.java.DefaultJavaLibrary; import com.facebook.buck.jvm.java.HasJavaAbi; import com.facebook.buck.jvm.java.JavaBuckConfig; import com.facebook.buck.jvm.java.JavaLibrary; import com.facebook.buck.jvm.java.JavaOptions; import com.facebook.buck.jvm.java.JavaTest; import com.facebook.buck.jvm.java.JavaTestDescription; import com.facebook.buck.jvm.java.JavacFactory; import com.facebook.buck.jvm.java.JavacOptions; import com.facebook.buck.jvm.java.JavacOptionsFactory; import com.facebook.buck.jvm.java.TestType; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.parser.NoSuchBuildTargetException; import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.BuildRuleParams; import com.facebook.buck.rules.BuildRuleResolver; import com.facebook.buck.rules.CellPathResolver; import com.facebook.buck.rules.Description; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.SourcePathRuleFinder; import com.facebook.buck.rules.TargetGraph; import com.facebook.buck.util.DependencyMode; import com.facebook.buck.util.immutables.BuckStyleImmutable; import com.google.common.base.Preconditions; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSortedSet; import java.util.Optional; import org.immutables.value.Value; public class RobolectricTestDescription implements Description<RobolectricTestDescriptionArg> { private final JavaBuckConfig javaBuckConfig; private final JavaOptions javaOptions; private final JavacOptions templateOptions; private final Optional<Long> defaultTestRuleTimeoutMs; private final CxxPlatform cxxPlatform; public RobolectricTestDescription( JavaBuckConfig javaBuckConfig, JavaOptions javaOptions, JavacOptions templateOptions, Optional<Long> defaultTestRuleTimeoutMs, CxxPlatform cxxPlatform) { this.javaBuckConfig = javaBuckConfig; this.javaOptions = javaOptions; this.templateOptions = templateOptions; this.defaultTestRuleTimeoutMs = defaultTestRuleTimeoutMs; this.cxxPlatform = cxxPlatform; } @Override public Class<RobolectricTestDescriptionArg> getConstructorArgType() { return RobolectricTestDescriptionArg.class; } @Override public BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, CellPathResolver cellRoots, RobolectricTestDescriptionArg args) throws NoSuchBuildTargetException { SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver); if (HasJavaAbi.isClassAbiTarget(params.getBuildTarget())) { Preconditions.checkArgument( !params .getBuildTarget() .getFlavors() .contains(AndroidLibraryGraphEnhancer.DUMMY_R_DOT_JAVA_FLAVOR)); BuildTarget testTarget = HasJavaAbi.getLibraryTarget(params.getBuildTarget()); BuildRule testRule = resolver.requireRule(testTarget); return CalculateAbiFromClasses.of( params.getBuildTarget(), ruleFinder, params, Preconditions.checkNotNull(testRule.getSourcePathToOutput())); } JavacOptions javacOptions = JavacOptionsFactory.create(templateOptions, params, resolver, args); AndroidLibraryGraphEnhancer graphEnhancer = new AndroidLibraryGraphEnhancer( params.getBuildTarget(), params.copyReplacingExtraDeps( Suppliers.ofInstance(resolver.getAllRules(args.getExportedDeps()))), JavacFactory.create(ruleFinder, javaBuckConfig, args), javacOptions, DependencyMode.TRANSITIVE, args.isForceFinalResourceIds(), /* resourceUnionPackage */ Optional.empty(), /* rName */ Optional.empty(), args.isUseOldStyleableFormat()); ImmutableList<String> vmArgs = args.getVmArgs(); Optional<DummyRDotJava> dummyRDotJava = graphEnhancer.getBuildableForAndroidResources(resolver, /* createBuildableIfEmpty */ true); if (dummyRDotJava.isPresent()) { ImmutableSortedSet<BuildRule> newDeclaredDeps = ImmutableSortedSet.<BuildRule>naturalOrder() .addAll(params.getDeclaredDeps().get()) .add(dummyRDotJava.get()) .build(); params = params.copyReplacingDeclaredAndExtraDeps( Suppliers.ofInstance(newDeclaredDeps), params.getExtraDeps()); } JavaTestDescription.CxxLibraryEnhancement cxxLibraryEnhancement = new JavaTestDescription.CxxLibraryEnhancement( params, args.getUseCxxLibraries(), args.getCxxLibraryWhitelist(), resolver, ruleFinder, cxxPlatform); params = cxxLibraryEnhancement.updatedParams; BuildRuleParams testsLibraryParams = params.withAppendedFlavor(JavaTest.COMPILED_TESTS_LIBRARY_FLAVOR); JavaLibrary testsLibrary = resolver.addToIndex( DefaultJavaLibrary.builder(testsLibraryParams, resolver, javaBuckConfig) .setArgs(args) .setJavacOptions(javacOptions) .setJavacOptionsAmender(new BootClasspathAppender()) .setGeneratedSourceFolder(javacOptions.getGeneratedSourceFolderName()) .setTrackClassUsage(javacOptions.trackClassUsage()) .build()); return new RobolectricTest( params.copyReplacingDeclaredAndExtraDeps( Suppliers.ofInstance(ImmutableSortedSet.of(testsLibrary)), Suppliers.ofInstance(ImmutableSortedSet.of())), ruleFinder, testsLibrary, args.getLabels(), args.getContacts(), TestType.JUNIT, javaOptions, vmArgs, cxxLibraryEnhancement.nativeLibsEnvironment, dummyRDotJava, args.getTestRuleTimeoutMs().map(Optional::of).orElse(defaultTestRuleTimeoutMs), args.getTestCaseTimeoutMs(), args.getEnv(), args.getRunTestSeparately(), args.getForkMode(), args.getStdOutLogLevel(), args.getStdErrLogLevel(), args.getRobolectricRuntimeDependency(), args.getRobolectricManifest()); } @BuckStyleImmutable @Value.Immutable interface AbstractRobolectricTestDescriptionArg extends JavaTestDescription.CoreArg { Optional<String> getRobolectricRuntimeDependency(); Optional<SourcePath> getRobolectricManifest(); @Value.Default default boolean isUseOldStyleableFormat() { return false; } @Value.Default default boolean isForceFinalResourceIds() { return true; } } }