| /* |
| * 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 static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import com.facebook.buck.util.HumanReadableException; |
| |
| import com.google.common.base.Optional; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.io.Files; |
| |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.rules.TemporaryFolder; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Path; |
| import java.nio.file.Paths; |
| import java.util.Set; |
| import java.util.regex.Matcher; |
| |
| public class AndroidPlatformTargetTest { |
| @Rule public TemporaryFolder tempDir = new TemporaryFolder(); |
| @Rule public TemporaryFolder projectRoot = new TemporaryFolder(); |
| |
| @Test |
| public void testCreateFromDefaultDirectoryStructure() { |
| String name = "Example Inc.:Google APIs:16"; |
| Path androidSdkDir = Paths.get("/home/android"); |
| String platformDirectoryPath = "platforms/android-16"; |
| Set<Path> additionalJarPaths = ImmutableSet.of(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| |
| AndroidPlatformTarget androidPlatformTarget = AndroidPlatformTarget |
| .createFromDefaultDirectoryStructure( |
| name, |
| androidDirectoryResolver, |
| platformDirectoryPath, |
| additionalJarPaths, |
| /* aaptOverride */ Optional.<Path>absent()); |
| assertEquals(name, androidPlatformTarget.getName()); |
| assertEquals(ImmutableList.of(Paths.get("/home/android/platforms/android-16/android.jar")), |
| androidPlatformTarget.getBootclasspathEntries()); |
| assertEquals(Paths.get("/home/android/platforms/android-16/android.jar"), |
| androidPlatformTarget.getAndroidJar()); |
| assertEquals(Paths.get("/home/android/platforms/android-16/framework.aidl"), |
| androidPlatformTarget.getAndroidFrameworkIdlFile()); |
| assertEquals(Paths.get("/home/android/tools/proguard/lib/proguard.jar"), |
| androidPlatformTarget.getProguardJar()); |
| assertEquals(Paths.get("/home/android/tools/proguard/proguard-android.txt"), |
| androidPlatformTarget.getProguardConfig()); |
| assertEquals(Paths.get("/home/android/tools/proguard/proguard-android-optimize.txt"), |
| androidPlatformTarget.getOptimizedProguardConfig()); |
| assertEquals(androidSdkDir.resolve("platform-tools/aapt").toAbsolutePath(), |
| androidPlatformTarget.getAaptExecutable()); |
| assertEquals(androidSdkDir.resolve("platform-tools/aidl"), |
| androidPlatformTarget.getAidlExecutable()); |
| assertEquals(androidSdkDir.resolve("platform-tools/dx"), |
| androidPlatformTarget.getDxExecutable()); |
| } |
| |
| @Test |
| public void testInstalledNewerBuildToolsViaOldUpgradePath() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| Path pathToAndroidSdkDir = androidSdkDir.toPath(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| File buildToolsDir = new File(androidSdkDir, "build-tools"); |
| buildToolsDir.mkdir(); |
| File buildToolsDirFromOldUpgradePath = new File(buildToolsDir, "17.0.0"); |
| buildToolsDirFromOldUpgradePath.mkdir(); |
| File addOnsLibsDir = new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs"); |
| addOnsLibsDir.mkdirs(); |
| Files.touch(new File(addOnsLibsDir, "effects.jar")); |
| Files.touch(new File(addOnsLibsDir, "maps.jar")); |
| Files.touch(new File(addOnsLibsDir, "usb.jar")); |
| |
| String platformId = "Google Inc.:Google APIs:17"; |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption = |
| AndroidPlatformTarget.getTargetForId( |
| platformId, |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| |
| assertTrue(androidPlatformTargetOption.isPresent()); |
| AndroidPlatformTarget androidPlatformTarget = androidPlatformTargetOption.get(); |
| assertEquals(platformId, androidPlatformTarget.getName()); |
| assertEquals( |
| ImmutableList.of( |
| pathToAndroidSdkDir.resolve("platforms/android-17/android.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/effects.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/maps.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/usb.jar")), |
| androidPlatformTarget.getBootclasspathEntries()); |
| assertEquals(pathToAndroidSdkDir.resolve("platforms/android-17/android.jar"), |
| androidPlatformTarget.getAndroidJar()); |
| assertEquals(pathToAndroidSdkDir.resolve("build-tools/17.0.0/aapt"), |
| androidPlatformTarget.getAaptExecutable()); |
| assertEquals(pathToAndroidSdkDir.resolve("platform-tools/adb"), |
| androidPlatformTarget.getAdbExecutable()); |
| assertEquals(pathToAndroidSdkDir.resolve("build-tools/17.0.0/aidl"), |
| androidPlatformTarget.getAidlExecutable()); |
| assertEquals(pathToAndroidSdkDir.resolve("build-tools/17.0.0/dx"), |
| androidPlatformTarget.getDxExecutable()); |
| } |
| |
| @Test |
| public void testInstalledNewerBuildToolsViaFreshDownload() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| Path pathToAndroidSdkDir = androidSdkDir.toPath(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| File buildToolsDir = new File(androidSdkDir, "build-tools"); |
| buildToolsDir.mkdir(); |
| File buildToolsDirFromFreshDownload = new File(buildToolsDir, "android-4.2.2"); |
| buildToolsDirFromFreshDownload.mkdir(); |
| File addOnsLibsDir = new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs"); |
| addOnsLibsDir.mkdirs(); |
| Files.touch(new File(addOnsLibsDir, "effects.jar")); |
| Files.touch(new File(addOnsLibsDir, "maps.jar")); |
| Files.touch(new File(addOnsLibsDir, "usb.jar")); |
| |
| String platformId = "Google Inc.:Google APIs:17"; |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption = |
| AndroidPlatformTarget.getTargetForId( |
| platformId, |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| |
| assertTrue(androidPlatformTargetOption.isPresent()); |
| AndroidPlatformTarget androidPlatformTarget = androidPlatformTargetOption.get(); |
| assertEquals(platformId, androidPlatformTarget.getName()); |
| assertEquals( |
| ImmutableList.of( |
| pathToAndroidSdkDir.resolve("platforms/android-17/android.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/effects.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/maps.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/usb.jar")), |
| androidPlatformTarget.getBootclasspathEntries()); |
| assertEquals(pathToAndroidSdkDir.resolve("platforms/android-17/android.jar"), |
| androidPlatformTarget.getAndroidJar()); |
| assertEquals(pathToAndroidSdkDir.resolve("build-tools/android-4.2.2/aapt"), |
| androidPlatformTarget.getAaptExecutable()); |
| assertEquals(pathToAndroidSdkDir.resolve("platform-tools/adb"), |
| androidPlatformTarget.getAdbExecutable()); |
| assertEquals(pathToAndroidSdkDir.resolve("build-tools/android-4.2.2/aidl"), |
| androidPlatformTarget.getAidlExecutable()); |
| assertEquals(pathToAndroidSdkDir.resolve("build-tools/android-4.2.2/dx"), |
| androidPlatformTarget.getDxExecutable()); |
| } |
| |
| @Test |
| public void testChoosesCorrectBuildToolsDirectory() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| File buildToolsDir = new File(androidSdkDir, "build-tools"); |
| buildToolsDir.mkdir(); |
| File addOnsLibsDir = new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs"); |
| addOnsLibsDir.mkdirs(); |
| Files.touch(new File(addOnsLibsDir, "effects.jar")); |
| Files.touch(new File(addOnsLibsDir, "maps.jar")); |
| Files.touch(new File(addOnsLibsDir, "usb.jar")); |
| |
| // Here is a number of subfolders in the build tools directory. |
| new File(buildToolsDir, "android-4.2.2").mkdir(); |
| new File(buildToolsDir, "android-4.1").mkdir(); |
| new File(buildToolsDir, "android-4.0.0").mkdir(); |
| new File(buildToolsDir, "17.0.0").mkdir(); |
| new File(buildToolsDir, "16.0.0").mkdir(); |
| |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption = |
| AndroidPlatformTarget.getTargetForId( |
| "Google Inc.:Google APIs:17", |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| assertTrue(androidPlatformTargetOption.isPresent()); |
| |
| assertEquals( |
| "17.0.0 should be used as the build directory", |
| new File(androidSdkDir, "build-tools/17.0.0/aapt").toPath().toAbsolutePath(), |
| androidPlatformTargetOption.get().getAaptExecutable()); |
| } |
| |
| @Test |
| public void testLooksForAdditionalAddonsDirectories() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| File buildToolsDir = new File(androidSdkDir, "build-tools"); |
| buildToolsDir.mkdir(); |
| new File(buildToolsDir, "android-4.2.2").mkdir(); |
| |
| File addOnsLibsDir1 = new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs"); |
| addOnsLibsDir1.mkdirs(); |
| File addOnsLibsDir2 = new File(androidSdkDir, "add-ons/addon-google_apis-google-17-2/libs"); |
| addOnsLibsDir2.mkdirs(); |
| Files.touch(new File(addOnsLibsDir2, "effects.jar")); |
| |
| // '-11' to test that the sorting works correctly. |
| File addOnsLibsDir3 = new File(androidSdkDir, "add-ons/addon-google_apis-google-17-11/libs"); |
| addOnsLibsDir3.mkdirs(); |
| Files.touch(new File(addOnsLibsDir3, "ignored.jar")); |
| |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption = |
| AndroidPlatformTarget.getTargetForId( |
| "Google Inc.:Google APIs:17", |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| assertTrue(androidPlatformTargetOption.isPresent()); |
| |
| // Verify that addOnsLibsDir2 was picked up since addOnsLibsDir1 is empty. |
| assertTrue(androidPlatformTargetOption.get().getBootclasspathEntries().contains( |
| addOnsLibsDir2.toPath().resolve("effects.jar").toAbsolutePath())); |
| assertFalse(androidPlatformTargetOption.get().getBootclasspathEntries().contains( |
| addOnsLibsDir3.toPath().resolve("ignored.jar").toAbsolutePath())); |
| } |
| |
| @Test |
| public void testThrowsExceptionWhenAddOnsDirectoryIsMissing() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| String platformId = "Google Inc.:Google APIs:17"; |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| try { |
| AndroidPlatformTarget.getTargetForId( |
| platformId, |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| fail("Should have thrown HumanReadableException"); |
| } catch (HumanReadableException e) { |
| assertEquals( |
| String.format( |
| "Google APIs not found in %s.\n" + |
| "Please run '%s/tools/android sdk' and select both 'SDK Platform' and " + |
| "'Google APIs' under Android (API 17)", |
| new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs").getAbsolutePath(), |
| androidSdkDir.getPath()), |
| e.getMessage()); |
| } |
| } |
| |
| @Test |
| public void testLooksForGoogleLibsOnlyWhenGoogleApiTarget() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| Path pathToAndroidSdkDir = androidSdkDir.toPath(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| File buildToolsDir = new File(androidSdkDir, "build-tools"); |
| buildToolsDir.mkdir(); |
| new File(buildToolsDir, "android-4.2.2").mkdir(); |
| |
| File addOnsLibsDir = new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs"); |
| addOnsLibsDir.mkdirs(); |
| Files.touch(new File(addOnsLibsDir, "effects.jar")); |
| Files.touch(new File(addOnsLibsDir, "maps.jar")); |
| Files.touch(new File(addOnsLibsDir, "usb.jar")); |
| |
| // This one should include the Google jars |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption1 = |
| AndroidPlatformTarget.getTargetForId( |
| "Google Inc.:Google APIs:17", |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| assertTrue(androidPlatformTargetOption1.isPresent()); |
| assertEquals( |
| ImmutableList.of( |
| pathToAndroidSdkDir.resolve("platforms/android-17/android.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/effects.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/maps.jar"), |
| pathToAndroidSdkDir.resolve("add-ons/addon-google_apis-google-17/libs/usb.jar")), |
| androidPlatformTargetOption1.get().getBootclasspathEntries()); |
| |
| // This one should only include android.jar |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption2 = |
| AndroidPlatformTarget.getTargetForId( |
| "android-17", |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| assertTrue(androidPlatformTargetOption2.isPresent()); |
| assertEquals( |
| ImmutableList.of( |
| pathToAndroidSdkDir.resolve("platforms/android-17/android.jar")), |
| androidPlatformTargetOption2.get().getBootclasspathEntries()); |
| } |
| |
| @Test |
| public void testPlatformTargetFindsCorrectZipAlign() throws IOException { |
| File androidSdkDir = tempDir.newFolder(); |
| Path pathToAndroidSdkDir = androidSdkDir.toPath(); |
| AndroidDirectoryResolver androidDirectoryResolver = |
| new FakeAndroidDirectoryResolver( |
| Optional.of(androidSdkDir.toPath()), |
| /* androidNdkDir */ Optional.<Path>absent(), |
| /* ndkVersion */ Optional.<String>absent()); |
| File buildToolsDir = new File(androidSdkDir, "build-tools"); |
| buildToolsDir.mkdir(); |
| File buildToolsDirFromOldUpgradePath = new File(buildToolsDir, "17.0.0"); |
| buildToolsDirFromOldUpgradePath.mkdir(); |
| Files.touch(new File(buildToolsDirFromOldUpgradePath, "zipalign")); |
| File addOnsLibsDir = new File(androidSdkDir, "add-ons/addon-google_apis-google-17/libs"); |
| addOnsLibsDir.mkdirs(); |
| Files.touch(new File(addOnsLibsDir, "effects.jar")); |
| |
| String platformId = "Google Inc.:Google APIs:17"; |
| Optional<AndroidPlatformTarget> androidPlatformTargetOption = |
| AndroidPlatformTarget.getTargetForId( |
| platformId, |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| |
| assertTrue(androidPlatformTargetOption.isPresent()); |
| AndroidPlatformTarget androidPlatformTarget = androidPlatformTargetOption.get(); |
| assertEquals(platformId, androidPlatformTarget.getName()); |
| assertEquals( |
| pathToAndroidSdkDir.resolve("build-tools/17.0.0/zipalign"), |
| androidPlatformTarget.getZipalignExecutable()); |
| |
| File toolsDir = new File(androidSdkDir, "tools"); |
| toolsDir.mkdirs(); |
| Files.touch(new File(toolsDir, "zipalign")); |
| androidPlatformTargetOption = |
| AndroidPlatformTarget.getTargetForId( |
| platformId, |
| androidDirectoryResolver, |
| /* aaptOverride */ Optional.<Path>absent()); |
| assertTrue(androidPlatformTargetOption.isPresent()); |
| androidPlatformTarget = androidPlatformTargetOption.get(); |
| assertEquals(platformId, androidPlatformTarget.getName()); |
| assertEquals( |
| pathToAndroidSdkDir.resolve("tools/zipalign"), |
| androidPlatformTarget.getZipalignExecutable()); |
| } |
| |
| @Test |
| public void testPlatformTargetPattern() { |
| testPlatformTargetRegex("Google Inc.:Google APIs:8", true, "8"); |
| testPlatformTargetRegex("Google Inc.:Google APIs:17", true, "17"); |
| testPlatformTargetRegex("android-8", true, "8"); |
| testPlatformTargetRegex("android-17", true, "17"); |
| testPlatformTargetRegex("Google Inc.:Google APIs:", false, ""); |
| testPlatformTargetRegex("Google Inc.:Google APIs:blah", false, ""); |
| testPlatformTargetRegex("android-", false, ""); |
| testPlatformTargetRegex("android-blah", false, ""); |
| } |
| |
| private void testPlatformTargetRegex(String input, boolean matches, String id) { |
| Matcher matcher = AndroidPlatformTarget.PLATFORM_TARGET_PATTERN.matcher(input); |
| assertEquals(matches, matcher.matches()); |
| if (matches) { |
| assertEquals(id, matcher.group(1)); |
| } |
| } |
| } |