blob: 514001771dbadd9812e20c383441518973467682 [file] [log] [blame]
/*
* Copyright 2012-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 static org.junit.Assert.assertEquals;
import com.facebook.buck.cpp.PrebuiltNativeLibraryBuildRule;
import com.facebook.buck.java.DefaultJavaLibraryRule;
import com.facebook.buck.java.KeystoreRule;
import com.facebook.buck.java.PrebuiltJarRule;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.model.BuildTargetPattern;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.DependencyGraph;
import com.facebook.buck.rules.FakeAbstractBuildRuleBuilderParams;
import com.facebook.buck.testutil.RuleMap;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
public class AndroidTransitiveDependencyGraphTest {
/**
* This is a regression test to ensure that an additional 1 second startup cost is not
* re-introduced to fb4a.
*/
@Test
public void testFindTransitiveDependencies() {
BuildRuleResolver ruleResolver = new BuildRuleResolver();
// Create an AndroidBinaryRule that transitively depends on two prebuilt JARs. One of the two
// prebuilt JARs will be listed in the AndroidBinaryRule's no_dx list.
PrebuiltJarRule guavaRule = ruleResolver.buildAndAddToIndex(
PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//third_party/guava:guava"))
.setBinaryJar("third_party/guava/guava-10.0.1.jar")
.addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
PrebuiltJarRule jsr305Rule = ruleResolver.buildAndAddToIndex(
PrebuiltJarRule.newPrebuiltJarRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//third_party/jsr-305:jsr-305"))
.setBinaryJar("third_party/jsr-305/jsr305.jar")
.addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
NdkLibraryRule ndkLibraryRule = ruleResolver.buildAndAddToIndex(
NdkLibraryRule.newNdkLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//java/com/facebook/native_library:library"))
.addSrc("Android.mk")
.setIsAsset(false)
.addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
PrebuiltNativeLibraryBuildRule prebuiltNativeLibraryBuildRule = ruleResolver.buildAndAddToIndex(
PrebuiltNativeLibraryBuildRule.newPrebuiltNativeLibrary(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//java/com/facebook/prebuilt_native_library:library"))
.setNativeLibsDirectory("/java/com/facebook/prebuilt_native_library/libs")
.setIsAsset(true)
.addVisibilityPattern(BuildTargetPattern.MATCH_ALL));
DefaultJavaLibraryRule libraryRule = ruleResolver.buildAndAddToIndex(
DefaultJavaLibraryRule.newJavaLibraryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//java/src/com/facebook:example"))
.addDep(guavaRule.getBuildTarget())
.addDep(jsr305Rule.getBuildTarget())
.addDep(prebuiltNativeLibraryBuildRule.getBuildTarget())
.addDep(ndkLibraryRule.getBuildTarget()));
AndroidResourceRule manifestRule = ruleResolver.buildAndAddToIndex(
AndroidResourceRule.newAndroidResourceRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//java/src/com/facebook:res"))
.setManifestFile("java/src/com/facebook/module/AndroidManifest.xml")
.setAssetsDirectory("assets/"));
BuildTarget keystoreTarget = BuildTargetFactory.newInstance("//keystore:debug");
ruleResolver.buildAndAddToIndex(
KeystoreRule.newKeystoreBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(keystoreTarget)
.setStore("keystore/debug.keystore")
.setProperties("keystore/debug.keystore.properties"));
AndroidBinaryRule binaryRule = ruleResolver.buildAndAddToIndex(
AndroidBinaryRule.newAndroidBinaryRuleBuilder(new FakeAbstractBuildRuleBuilderParams())
.setBuildTarget(BuildTargetFactory.newInstance("//java/src/com/facebook:app"))
.addDep(libraryRule.getBuildTarget())
.addDep(manifestRule.getBuildTarget())
.addBuildRuleToExcludeFromDex(BuildTargetFactory.newInstance("//third_party/guava:guava"))
.setManifest("java/src/com/facebook/AndroidManifest.xml")
.setTarget("Google Inc.:Google APIs:16")
.setKeystore(keystoreTarget));
// Verify that the correct transitive dependencies are found.
DependencyGraph graph = RuleMap.createGraphFromBuildRules(ruleResolver);
AndroidTransitiveDependencies transitiveDeps = binaryRule.findTransitiveDependencies(graph);
AndroidDexTransitiveDependencies dexTransitiveDeps =
binaryRule.findDexTransitiveDependencies(graph);
assertEquals(
"Because guava was passed to no_dx, it should not be in the classpathEntriesToDex list",
ImmutableSet.of("third_party/jsr-305/jsr305.jar"),
dexTransitiveDeps.classpathEntriesToDex);
assertEquals(
"Because guava was passed to no_dx, it should not be treated as a third-party JAR whose " +
"resources need to be extracted and repacked in the APK. If this is done, then code in " +
"the guava-10.0.1.dex.1.jar in the APK's assets/ folder may try to load the resource " +
"from the APK as a ZipFileEntry rather than as a resource within guava-10.0.1.dex.1.jar. " +
"Loading a resource in this way could take substantially longer. Specifically, this was " +
"observed to take over one second longer to load the resource in fb4a. Because the " +
"resource was loaded on startup, this introduced a substantial regression in the startup " +
"time for the fb4a app.",
ImmutableSet.of("third_party/jsr-305/jsr305.jar"),
dexTransitiveDeps.pathsToThirdPartyJars);
assertEquals(
"Because assets directory was passed an AndroidResourceRule it should be added to the " +
"transitive dependencies",
ImmutableSet.of("assets/"),
transitiveDeps.assetsDirectories);
assertEquals(
"Because manifest file was passed an AndroidResourceRule it should be added to the " +
"transitive dependencies",
ImmutableSet.of("java/src/com/facebook/module/AndroidManifest.xml"),
transitiveDeps.manifestFiles);
assertEquals(
"Because a native library was declared as a dependency, it should be added to the " +
"transitive dependencies.",
ImmutableSet.of(ndkLibraryRule.getPathToOutputFile()),
transitiveDeps.nativeLibsZips);
assertEquals(
"Because a prebuilt native library was declared as a dependency (and asset), it should " +
"be added to the transitive dependecies.",
ImmutableSet.of(prebuiltNativeLibraryBuildRule.getPathToOutputFile()),
transitiveDeps.nativeLibAssetsZips);
}
}