Separate android integration tests that require an NDK.

RELNOTES: None
PiperOrigin-RevId: 165616290
diff --git a/src/test/shell/bazel/android/BUILD b/src/test/shell/bazel/android/BUILD
index c3277bb..fd02d82 100644
--- a/src/test/shell/bazel/android/BUILD
+++ b/src/test/shell/bazel/android/BUILD
@@ -4,25 +4,37 @@
     visibility = ["//src/test/shell/bazel:__pkg__"],
 )
 
+# These tests rely on the //external:android_{s,n}dk_for_testing filegroups.
+# These targets should point to filegroups containing the contents of
+# the Android SDK and NDK. They *must not* contain any BUILD files that
+# are generated by Android{S,N}dkRepositoryFunction, or else the
+# integration will attempt to overwrite those files and fail. Note that
+# this is incorrect because the filegroups should contain all of the
+# files needed, but since they contain files with names that are not
+# legal Bazel labels, there isn't really a better option.
+#
+# The definitions of these filegroups are in
+# tools/android/android_sdk_repository_template.bzl and
+# src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_ndk_build_file_template.txt
+
 sh_test(
     name = "android_integration_test",
     size = "large",
     srcs = ["android_integration_test.sh"],
     data = [
+        "//external:android_sdk_for_testing",
         "//src/test/shell/bazel:test-deps",
-        # These targets should point to filegroups containing the contents of
-        # the Android SDK and NDK. They *must not* contain any BUILD files that
-        # are generated by Android{S,N}dkRepositoryFunction, or else the
-        # integration will attempt to overwrite those files and fail. Note that
-        # this is incorrect because the filegroups should contain all of the
-        # files needed, but since they contain files with names that are not
-        # legal Bazel labels, there isn't really a better option.
-        #
-        # The definitions of these filegroups are in
-        # tools/android/android_sdk_repository_template.bzl and
-        # src/main/java/com/google/devtools/build/lib/bazel/rules/android/android_ndk_build_file_template.txt
+    ],
+)
+
+sh_test(
+    name = "android_ndk_integration_test",
+    size = "large",
+    srcs = ["android_ndk_integration_test.sh"],
+    data = [
         "//external:android_ndk_for_testing",
         "//external:android_sdk_for_testing",
+        "//src/test/shell/bazel:test-deps",
     ],
 )
 
@@ -31,7 +43,6 @@
     size = "large",
     srcs = ["desugarer_integration_test.sh"],
     data = [
-        # See comment in data attribute of :android_integration_test.
         "//external:android_sdk_for_testing",
         "//src/test/shell/bazel:test-deps",
     ],
diff --git a/src/test/shell/bazel/android/android_integration_test.sh b/src/test/shell/bazel/android/android_integration_test.sh
index 6d40bc0..d5d4446 100755
--- a/src/test/shell/bazel/android/android_integration_test.sh
+++ b/src/test/shell/bazel/android/android_integration_test.sh
@@ -16,10 +16,9 @@
 
 # For these tests to run do the following:
 #
-#   1. Install an Android SDK and NDK from https://developer.android.com
-#   2. Set the $ANDROID_HOME and $ANDROID_NDK_HOME environment variables
-#   3. Uncomment the two lines in WORKSPACE containing android_sdk_repository
-#      and android_ndk_repository
+#   1. Install an Android SDK from https://developer.android.com
+#   2. Set the $ANDROID_HOME environment variable
+#   3. Uncomment the line in WORKSPACE containing android_sdk_repository
 #
 # Note that if the environment is not set up as above android_integration_test
 # will silently be ignored and will be shown as passing.
@@ -37,57 +36,16 @@
     name = "lib",
     srcs = ["Lib.java"],
 )
-
 android_binary(
     name = "bin",
-    srcs = [
-        "MainActivity.java",
-        "Jni.java",
-    ],
-    legacy_native_support = 0,
+    srcs = ["MainActivity.java"],
     manifest = "AndroidManifest.xml",
-    deps = [
-        ":lib",
-        ":jni"
-    ],
+    deps = [":lib"],
 )
-
-cc_library(
-    name = "jni",
-    srcs = ["jni.cc"],
-    deps = [":jni_dep"],
-)
-
-cc_library(
-    name = "jni_dep",
-    srcs = ["jni_dep.cc"],
-    hdrs = ["jni_dep.h"],
-)
-
 EOF
 
   cat > java/bazel/AndroidManifest.xml <<EOF
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="bazel.android"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-sdk
-        android:minSdkVersion="21"
-        android:targetSdkVersion="21" />
-
-    <application
-        android:label="Bazel Test App" >
-        <activity
-            android:name="bazel.MainActivity"
-            android:label="Bazel" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
+  <manifest package="bazel.android" />
 EOF
 
   cat > java/bazel/Lib.java <<EOF
@@ -100,14 +58,6 @@
 }
 EOF
 
-  cat > java/bazel/Jni.java <<EOF
-package bazel;
-
-public class Jni {
-  public static native String hello();
-}
-
-EOF
   cat > java/bazel/MainActivity.java <<EOF
 package bazel;
 
@@ -121,71 +71,6 @@
   }
 }
 EOF
-
-  cat > java/bazel/jni_dep.h <<EOF
-#pragma once
-
-#include <jni.h>
-
-jstring NewStringLatin1(JNIEnv *env, const char *str);
-EOF
-
-  cat > java/bazel/jni_dep.cc <<EOF
-#include "java/bazel/jni_dep.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-jstring NewStringLatin1(JNIEnv *env, const char *str) {
-  int len = strlen(str);
-  jchar *str1;
-  str1 = reinterpret_cast<jchar *>(malloc(len * sizeof(jchar)));
-
-  for (int i = 0; i < len; i++) {
-    str1[i] = (unsigned char)str[i];
-  }
-  jstring result = env->NewString(str1, len);
-  free(str1);
-  return result;
-}
-EOF
-
-  cat > java/bazel/jni.cc <<EOF
-#include <jni.h>
-#include <string>
-
-#include "java/bazel/jni_dep.h"
-
-extern "C" JNIEXPORT jstring JNICALL
-Java_bazel_Jni_hello(JNIEnv *env, jclass clazz) {
-  std::string hello = "Hello";
-  std::string jni = "JNI";
-  return NewStringLatin1(env, (hello + " " + jni).c_str());
-}
-EOF
-}
-
-function check_num_sos() {
-  num_sos=$(unzip -Z1 bazel-bin/java/bazel/bin.apk '*.so' | wc -l | sed -e 's/[[:space:]]//g')
-  assert_equals "7" "$num_sos"
-}
-
-function check_soname() {
-  unzip -p bazel-bin/java/bazel/bin.apk lib/x86/libbin.so > libbin.so
-  # For an android_binary with name foo, readelf output format is
-  #  Tag        Type          Name/Value
-  # 0x00000010 (SONAME)       Library soname: [libfoo]
-  #
-  # If -Wl,soname= is not set, then SONAME will not appear in the output.
-  #
-  # readelf is a Linux utility and not available on Mac by default. The NDK
-  # includes readelf however the path is difference for Mac vs Linux, hence the
-  # star.
-  readelf="${TEST_SRCDIR}/androidndk/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/*/bin/arm-linux-androideabi-readelf"
-  soname=$($readelf -d libbin.so \
-    | grep SONAME \
-    | awk '{print substr($5,2,length($5)-2)}')
-  assert_equals "libbin" "$soname"
 }
 
 function test_sdk_library_deps() {
@@ -203,75 +88,6 @@
   bazel build --nobuild //java/a:a || fail "build failed"
 }
 
-function test_android_binary() {
-  create_new_workspace
-  setup_android_sdk_support
-  setup_android_ndk_support
-  create_android_binary
-
-  cpus="armeabi,armeabi-v7a,arm64-v8a,mips,mips64,x86,x86_64"
-
-  bazel build -s //java/bazel:bin --fat_apk_cpu="$cpus" || fail "build failed"
-  check_num_sos
-  check_soname
-}
-
-is_ndk_10() {
-  if [[ -r "${BAZEL_RUNFILES}/external/androidndk/ndk/source.properties" ]]; then
-    return 1
-  else
-    return 0
-  fi
-}
-
-function test_android_binary_clang() {
-  # clang3.8 is only available on NDK r11
-  if is_ndk_10; then
-    echo "Not running test_android_binary_clang because it requires NDK11 or later"
-    return
-  fi
-  create_new_workspace
-  setup_android_sdk_support
-  setup_android_ndk_support
-  create_android_binary
-
-  cpus="armeabi,armeabi-v7a,arm64-v8a,mips,mips64,x86,x86_64"
-
-  bazel build -s //java/bazel:bin \
-      --fat_apk_cpu="$cpus" \
-      --android_compiler=clang3.8 \
-      || fail "build failed"
-  check_num_sos
-  check_soname
-}
-
-# Regression test for https://github.com/bazelbuild/bazel/issues/2601.
-function test_clang_include_paths() {
-  if is_ndk_10; then
-    echo "Not running test_clang_include_paths because it requires NDK11 or later"
-    return
-  fi
-  create_new_workspace
-  setup_android_ndk_support
-  cat > BUILD <<EOF
-cc_binary(
-    name = "foo",
-    srcs = ["foo.cc"],
-    copts = ["-mfpu=neon"],
-)
-EOF
-  cat > foo.cc <<EOF
-#include <arm_neon.h>
-int main() { return 0; }
-EOF
-  bazel build //:foo \
-    --compiler=clang3.8 \
-    --cpu=armeabi-v7a \
-    --crosstool_top=//external:android/crosstool \
-    --host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
-    || fail "build failed"
-}
-
 # Regression test for https://github.com/bazelbuild/bazel/issues/1928.
 function test_empty_tree_artifact_action_inputs_mount_empty_directories() {
   create_new_workspace
@@ -332,20 +148,6 @@
     "path"
 }
 
-function test_android_ndk_repository_path_from_environment() {
-  create_new_workspace
-  setup_android_ndk_support
-  cat > WORKSPACE <<EOF
-android_ndk_repository(
-    name = "androidndk",
-    api_level = 25,
-)
-EOF
-  ANDROID_NDK_HOME=$ANDROID_NDK bazel build @androidndk//:files || fail \
-    "android_ndk_repository failed to build with \$ANDROID_NDK_HOME instead " \
-    "of path"
-}
-
 function test_android_sdk_repository_no_path_or_android_home() {
   create_new_workspace
   cat > WORKSPACE <<EOF
@@ -358,36 +160,18 @@
   expect_log "Either the path attribute of android_sdk_repository"
 }
 
-function test_android_ndk_repository_no_path_or_android_ndk_home() {
-  create_new_workspace
-  cat > WORKSPACE <<EOF
-android_ndk_repository(
-    name = "androidndk",
-    api_level = 25,
-)
-EOF
-  bazel build @androidndk//:files >& $TEST_log && fail "Should have failed"
-  expect_log "Either the path attribute of android_ndk_repository"
-}
-
 # Check that the build succeeds if an android_sdk is specified with --android_sdk
 function test_specifying_android_sdk_flag() {
   create_new_workspace
   setup_android_sdk_support
-  setup_android_ndk_support
   create_android_binary
   cat > WORKSPACE <<EOF
 android_sdk_repository(
     name = "a",
 )
-android_ndk_repository(
-    name = "androidndk",
-    api_level = 24,
-)
 EOF
-  ANDROID_HOME=$ANDROID_SDK ANDROID_NDK_HOME=$ANDROID_NDK bazel build \
-    --android_sdk=@a//:sdk-24 //java/bazel:bin || fail \
-    "build with --android_sdk failed"
+  ANDROID_HOME=$ANDROID_SDK bazel build --android_sdk=@a//:sdk-24 \
+    //java/bazel:bin || fail "build with --android_sdk failed"
 }
 
 # Regression test for https://github.com/bazelbuild/bazel/issues/2621.
@@ -402,15 +186,6 @@
   ANDROID_HOME=$ANDROID_SDK bazel build @androidsdk//:files || "Build failed"
 }
 
-# ndk r10 and earlier
-if [[ ! -r "${TEST_SRCDIR}/androidndk/ndk/RELEASE.TXT" ]]; then
-  # ndk r11 and later
-  if [[ ! -r "${TEST_SRCDIR}/androidndk/ndk/source.properties" ]]; then
-    echo "Not running Android tests due to lack of an Android NDK."
-    exit 0
-  fi
-fi
-
 if [[ ! -r "${TEST_SRCDIR}/androidsdk/tools/android" ]]; then
   echo "Not running Android tests due to lack of an Android SDK."
   exit 0
diff --git a/src/test/shell/bazel/android/android_ndk_integration_test.sh b/src/test/shell/bazel/android/android_ndk_integration_test.sh
new file mode 100755
index 0000000..d2c21b6
--- /dev/null
+++ b/src/test/shell/bazel/android/android_ndk_integration_test.sh
@@ -0,0 +1,301 @@
+#!/bin/bash
+#
+# Copyright 2017 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.
+
+# For these tests to run do the following:
+#
+#   1. Install an Android SDK and NDK from https://developer.android.com
+#   2. Set the $ANDROID_HOME and $ANDROID_NDK_HOME environment variables
+#   3. Uncomment the two lines in WORKSPACE containing android_sdk_repository
+#      and android_ndk_repository
+#
+# Note that if the environment is not set up as above
+# android_ndk_integration_test will silently be ignored and will be shown as
+# passing.
+
+# Load the test setup defined in the parent directory
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${CURRENT_DIR}/../../integration_test_setup.sh" \
+  || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+
+function create_android_binary() {
+  mkdir -p java/bazel
+  cat > java/bazel/BUILD <<EOF
+android_library(
+    name = "lib",
+    srcs = ["Lib.java"],
+)
+
+android_binary(
+    name = "bin",
+    srcs = [
+        "MainActivity.java",
+        "Jni.java",
+    ],
+    legacy_native_support = 0,
+    manifest = "AndroidManifest.xml",
+    deps = [
+        ":lib",
+        ":jni"
+    ],
+)
+
+cc_library(
+    name = "jni",
+    srcs = ["jni.cc"],
+    deps = [":jni_dep"],
+)
+
+cc_library(
+    name = "jni_dep",
+    srcs = ["jni_dep.cc"],
+    hdrs = ["jni_dep.h"],
+)
+
+EOF
+
+  cat > java/bazel/AndroidManifest.xml <<EOF
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="bazel.android"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="21"
+        android:targetSdkVersion="21" />
+
+    <application
+        android:label="Bazel Test App" >
+        <activity
+            android:name="bazel.MainActivity"
+            android:label="Bazel" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+EOF
+
+  cat > java/bazel/Lib.java <<EOF
+package bazel;
+
+public class Lib {
+  public static String message() {
+    return "Hello Lib";
+  }
+}
+EOF
+
+  cat > java/bazel/Jni.java <<EOF
+package bazel;
+
+public class Jni {
+  public static native String hello();
+}
+
+EOF
+  cat > java/bazel/MainActivity.java <<EOF
+package bazel;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+  @Override
+  public void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+  }
+}
+EOF
+
+  cat > java/bazel/jni_dep.h <<EOF
+#pragma once
+
+#include <jni.h>
+
+jstring NewStringLatin1(JNIEnv *env, const char *str);
+EOF
+
+  cat > java/bazel/jni_dep.cc <<EOF
+#include "java/bazel/jni_dep.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+jstring NewStringLatin1(JNIEnv *env, const char *str) {
+  int len = strlen(str);
+  jchar *str1;
+  str1 = reinterpret_cast<jchar *>(malloc(len * sizeof(jchar)));
+
+  for (int i = 0; i < len; i++) {
+    str1[i] = (unsigned char)str[i];
+  }
+  jstring result = env->NewString(str1, len);
+  free(str1);
+  return result;
+}
+EOF
+
+  cat > java/bazel/jni.cc <<EOF
+#include <jni.h>
+#include <string>
+
+#include "java/bazel/jni_dep.h"
+
+extern "C" JNIEXPORT jstring JNICALL
+Java_bazel_Jni_hello(JNIEnv *env, jclass clazz) {
+  std::string hello = "Hello";
+  std::string jni = "JNI";
+  return NewStringLatin1(env, (hello + " " + jni).c_str());
+}
+EOF
+}
+
+function check_num_sos() {
+  num_sos=$(unzip -Z1 bazel-bin/java/bazel/bin.apk '*.so' | wc -l | sed -e 's/[[:space:]]//g')
+  assert_equals "7" "$num_sos"
+}
+
+function check_soname() {
+  unzip -p bazel-bin/java/bazel/bin.apk lib/x86/libbin.so > libbin.so
+  # For an android_binary with name foo, readelf output format is
+  #  Tag        Type          Name/Value
+  # 0x00000010 (SONAME)       Library soname: [libfoo]
+  #
+  # If -Wl,soname= is not set, then SONAME will not appear in the output.
+  #
+  # readelf is a Linux utility and not available on Mac by default. The NDK
+  # includes readelf however the path is difference for Mac vs Linux, hence the
+  # star.
+  readelf="${TEST_SRCDIR}/androidndk/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/*/bin/arm-linux-androideabi-readelf"
+  soname=$($readelf -d libbin.so \
+    | grep SONAME \
+    | awk '{print substr($5,2,length($5)-2)}')
+  assert_equals "libbin" "$soname"
+}
+
+function test_android_binary() {
+  create_new_workspace
+  setup_android_sdk_support
+  setup_android_ndk_support
+  create_android_binary
+
+  cpus="armeabi,armeabi-v7a,arm64-v8a,mips,mips64,x86,x86_64"
+
+  bazel build -s //java/bazel:bin --fat_apk_cpu="$cpus" || fail "build failed"
+  check_num_sos
+  check_soname
+}
+
+is_ndk_10() {
+  if [[ -r "${BAZEL_RUNFILES}/external/androidndk/ndk/source.properties" ]]; then
+    return 1
+  else
+    return 0
+  fi
+}
+
+function test_android_binary_clang() {
+  # clang3.8 is only available on NDK r11
+  if is_ndk_10; then
+    echo "Not running test_android_binary_clang because it requires NDK11 or later"
+    return
+  fi
+  create_new_workspace
+  setup_android_sdk_support
+  setup_android_ndk_support
+  create_android_binary
+
+  cpus="armeabi,armeabi-v7a,arm64-v8a,mips,mips64,x86,x86_64"
+
+  bazel build -s //java/bazel:bin \
+      --fat_apk_cpu="$cpus" \
+      --android_compiler=clang3.8 \
+      || fail "build failed"
+  check_num_sos
+  check_soname
+}
+
+# Regression test for https://github.com/bazelbuild/bazel/issues/2601.
+function test_clang_include_paths() {
+  if is_ndk_10; then
+    echo "Not running test_clang_include_paths because it requires NDK11 or later"
+    return
+  fi
+  create_new_workspace
+  setup_android_ndk_support
+  cat > BUILD <<EOF
+cc_binary(
+    name = "foo",
+    srcs = ["foo.cc"],
+    copts = ["-mfpu=neon"],
+)
+EOF
+  cat > foo.cc <<EOF
+#include <arm_neon.h>
+int main() { return 0; }
+EOF
+  bazel build //:foo \
+    --compiler=clang3.8 \
+    --cpu=armeabi-v7a \
+    --crosstool_top=//external:android/crosstool \
+    --host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
+    || fail "build failed"
+}
+
+function test_android_ndk_repository_path_from_environment() {
+  create_new_workspace
+  setup_android_ndk_support
+  cat > WORKSPACE <<EOF
+android_ndk_repository(
+    name = "androidndk",
+    api_level = 25,
+)
+EOF
+  ANDROID_NDK_HOME=$ANDROID_NDK bazel build @androidndk//:files || fail \
+    "android_ndk_repository failed to build with \$ANDROID_NDK_HOME instead " \
+    "of path"
+}
+
+function test_android_ndk_repository_no_path_or_android_ndk_home() {
+  create_new_workspace
+  cat > WORKSPACE <<EOF
+android_ndk_repository(
+    name = "androidndk",
+    api_level = 25,
+)
+EOF
+  bazel build @androidndk//:files >& $TEST_log && fail "Should have failed"
+  expect_log "Either the path attribute of android_ndk_repository"
+}
+
+# ndk r10 and earlier
+if [[ ! -r "${TEST_SRCDIR}/androidndk/ndk/RELEASE.TXT" ]]; then
+  # ndk r11 and later
+  if [[ ! -r "${TEST_SRCDIR}/androidndk/ndk/source.properties" ]]; then
+    echo "Not running Android NDK tests due to lack of an Android NDK."
+    exit 0
+  fi
+fi
+
+if [[ ! -r "${TEST_SRCDIR}/androidsdk/tools/android" ]]; then
+  echo "Not running Android NDK tests due to lack of an Android SDK."
+  exit 0
+fi
+
+run_suite "Android NDK integration tests"