Add starter tests for Android platforms.

These initialize an environment with multiple SDKs and NDKs and add asserts expecting `--platforms` to trigger expected versions.

The tests pass now as if --platforms is a no-op (which it currently is). As platforms semantics evolve and these tests break, we can uncomment the asserts that expect intended results.

PiperOrigin-RevId: 318279491
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/AndroidPlatformsTest.java b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidPlatformsTest.java
new file mode 100644
index 0000000..466d532
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/AndroidPlatformsTest.java
@@ -0,0 +1,166 @@
+// Copyright 2020 The Bazel Authors. All rights reserved.
+//
+// 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.google.devtools.build.lib.rules.android;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.packages.util.MockPlatformSupport;
+import com.google.devtools.build.lib.rules.cpp.CppLinkAction;
+import com.google.devtools.build.lib.testutil.TestConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests Android support for Blaze's platforms API
+ * (https://docs.bazel.build/versions/master/platforms-intro.html).
+ *
+ * <p>This only provides the first-level of testing: that <code>--platforms</code> settings directly
+ * impact toolchain selection in expected ways. Devs can lean on this test for quick interactive
+ * feedback on their changes.
+ *
+ * <p>More broadly, we also need to ensure a) all other Android tests continue to pass and b) CI
+ * continues working.
+ *
+ * <p>For a), we need to split any tests that set legacy flags (<code>--android_sdk</code>, <code>
+ * --android_cpu</code>, <code>--fat_apk_cpu</code>, <code>--android_crosstool_top</code>, etc.) to
+ * also run with the equivalent <code>--platforms</code> settings.
+ *
+ * <p>For b), we similarly need to split CI projects that build with legacy flags to run with
+ * equivalent platform settings.
+ */
+@RunWith(JUnit4.class)
+public class AndroidPlatformsTest extends AndroidBuildViewTestCase {
+  private static final ImmutableList<String> MOCK_SDK_VERSIONS = ImmutableList.of("foo", "bar");
+  private static final ImmutableList<String> MOCK_NDK_CPUS = ImmutableList.of("x86", "armeabi-v7a");
+
+  private static final String PLATFORM_TEMPLATE =
+      String.join(
+          "\n",
+          "platform(",
+          "    name = '%s',",
+          "    constraint_values = [",
+          "        '" + TestConstants.PLATFORM_PACKAGE_ROOT + "/java/constraints:java8',",
+          "    ])");
+
+  @Before
+  public void writeMockPlatforms() throws Exception {
+    MockPlatformSupport.setup(mockToolsConfig);
+    // This line is necessary so an ARM C++ toolchain is available for dependencies under an Android
+    // split transition. BazelMockAndroidSupport.setupNdk(mockToolsConfig) isn't sufficient for this
+    // because that sets up the NDK in a special package //android/crosstool that tests then have to
+    // manually trigger with --android_crosstool_top=//android/crosstool:everything. Since the point
+    // of this test is to test that --platforms sets the correct NDK toolchain, we don't want these
+    // tests to have to explicitly set --android_crosstool_top. Until --platforms correctly does
+    // that, NDKs default to the default C++ toolchain. That's what this line configures.
+    getAnalysisMock().ccSupport().setupCcToolchainConfigForCpu(mockToolsConfig, "armeabi-v7a");
+
+    for (String sdkVersion : MOCK_SDK_VERSIONS) {
+      scratch.appendFile("platforms/BUILD", String.format(PLATFORM_TEMPLATE, "sdk_" + sdkVersion));
+    }
+    for (String ndkCpu : MOCK_NDK_CPUS) {
+      scratch.appendFile("platforms/BUILD", String.format(PLATFORM_TEMPLATE, "ndk_" + ndkCpu));
+    }
+  }
+
+  @Before
+  public void writeMockSDKs() throws Exception {
+    for (String sdkVersion : MOCK_SDK_VERSIONS) {
+      scratch.appendFile(
+          "sdk/BUILD",
+          "android_sdk(",
+          String.format("    name = 'sdk_%s',", sdkVersion),
+          "    aapt = 'aapt',",
+          "    aapt2 = 'aapt2',",
+          "    adb = 'adb',",
+          "    aidl = 'aidl',",
+          "    android_jar = 'android.jar',",
+          String.format("    apksigner = 'apksigner_%s',", sdkVersion),
+          "    dx = 'dx',",
+          "    framework_aidl = 'framework_aidl',",
+          "    main_dex_classes = 'main_dex_classes',",
+          "    main_dex_list_creator = 'main_dex_list_creator',",
+          "    proguard = 'proguard',",
+          "    shrinked_android_jar = 'shrinked_android_jar',",
+          "    zipalign = 'zipalign',",
+          "    tags = ['__ANDROID_RULES_MIGRATION__'])");
+    }
+  }
+
+  @Test
+  public void chooseSdk() throws Exception {
+    scratch.file(
+        "java/a/BUILD",
+        "android_binary(",
+        "    name = 'a',",
+        "    srcs = ['A.java'],",
+        "    manifest = 'AndroidManifest.xml')");
+
+    useConfiguration("--platforms=//platforms:sdk_foo");
+    Artifact apkFoo =
+        getImplicitOutputArtifact(
+            getConfiguredTarget("//java/a:a"), AndroidRuleClasses.ANDROID_BINARY_APK);
+    // TODO(blaze-team): replace with the commented line below when platform-based resolution works.
+    assertThat(getGeneratingSpawnActionArgs(apkFoo).get(0)).endsWith("/ApkSignerBinary");
+    // assertThat(getGeneratingSpawnActionArgs(apkFoo).get(0)).isEqualTo("sdk/apksigner_foo");
+
+    useConfiguration("--platforms=//platforms:sdk_bar");
+    Artifact apkBar =
+        getImplicitOutputArtifact(
+            getConfiguredTarget("//java/a:a"), AndroidRuleClasses.ANDROID_BINARY_APK);
+    // TODO(blaze-team): replace with the commented line below when platform-based resolution works.
+    assertThat(getGeneratingSpawnActionArgs(apkBar).get(0)).endsWith("/ApkSignerBinary");
+    // assertThat(getGeneratingSpawnActionArgs(apkBar).get(0)).isEqualTo("sdk/apksigner_foo");
+  }
+
+  @Test
+  public void chooseNdk() throws Exception {
+    scratch.file(
+        "java/a/BUILD",
+        "cc_library(",
+        "    name = 'cclib',",
+        "    srcs  = ['cclib.cc'])",
+        "android_binary(",
+        "    name = 'a',",
+        "    srcs = ['A.java'],",
+        "    deps = [':cclib'],",
+        "    manifest = 'AndroidManifest.xml')");
+
+    // See BazelMockAndroidSupport for the NDK toolchain this should imply. This replaces
+    // "--fat_apk_cpu=x86", "--android_crosstool_top=//android/crosstool:everything".
+    useConfiguration("--platforms=//platforms:ndk_x86");
+    ConfiguredTarget x86Binary = getConfiguredTarget("//java/a:a");
+    CppLinkAction x86Link =
+        (CppLinkAction) getGeneratingAction(getPrerequisiteArtifacts(x86Binary, "deps").get(0));
+    // TODO(blaze-team): replace with the commented line below when platform-based resolution works.
+    assertThat(x86Link.getLinkCommandLine().getLinkerPathString()).isEqualTo("/usr/bin/mock-ar");
+    // assertThat(cppLinkAction.getLinkCommandLine().getLinkerPathString())
+    //    .isEqualTo("android/crosstool/x86/bin/i686-linux-android-ar");
+
+    // See BazelMockAndroidSupport for the NDK toolchain this should imply. This replaces
+    // "--fat_apk_cpu=armeabi-v7a", "--android_crosstool_top=//android/crosstool:everything".
+    useConfiguration("--platforms=//platforms:ndk_armeabi-v7a");
+    ConfiguredTarget armBinary = getConfiguredTarget("//java/a:a");
+    CppLinkAction armLink =
+        (CppLinkAction) getGeneratingAction(getPrerequisiteArtifacts(armBinary, "deps").get(0));
+    // TODO(blaze-team): replace with the commented line below when platform-based resolution works.
+    assertThat(armLink.getLinkCommandLine().getLinkerPathString()).isEqualTo("/usr/bin/mock-ar");
+    // assertThat(cppLinkAction.getLinkCommandLine().getLinkerPathString())
+    //    .isEqualTo("android/crosstool/arm/bin/arm-linux-androideabi-ar");
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/android/BUILD b/src/test/java/com/google/devtools/build/lib/rules/android/BUILD
index 5cb3f3f..ebae4b7 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/android/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/rules/android/BUILD
@@ -127,6 +127,23 @@
 )
 
 java_test(
+    name = "AndroidPlatformsTest",
+    srcs = ["AndroidPlatformsTest.java"],
+    deps = [
+        ":AndroidBuildViewTestCase",
+        "//src/main/java/com/google/devtools/build/lib/actions",
+        "//src/main/java/com/google/devtools/build/lib/analysis:configured_target",
+        "//src/main/java/com/google/devtools/build/lib/rules/android",
+        "//src/main/java/com/google/devtools/build/lib/rules/cpp",
+        "//src/test/java/com/google/devtools/build/lib/packages:testutil",
+        "//src/test/java/com/google/devtools/build/lib/testutil:TestConstants",
+        "//third_party:guava",
+        "//third_party:junit4",
+        "//third_party:truth",
+    ],
+)
+
+java_test(
     name = "ResourceFilterFactoryTest",
     srcs = ["ResourceFilterFactoryTest.java"],
     deps = [