Skip to content

Commit

Permalink
Add android test rules.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 378831366
  • Loading branch information
xunkai55 authored and tflite-support-robot committed Jun 11, 2021
1 parent 4369c81 commit 71c7de1
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 1 deletion.
10 changes: 9 additions & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -398,15 +398,23 @@ apple_support_dependencies()
load("@upb//bazel:repository_defs.bzl", "bazel_version_repository")
bazel_version_repository(name = "bazel_version")


python_configure(name = "local_config_python")

ATS_TAG = "androidx-test-1.3.0"
http_archive(
name = "android_test_support",
strip_prefix = "android-test-%s" % ATS_TAG,
urls = ["https://github.com/android/android-test/archive/%s.tar.gz" % ATS_TAG],
)
load("@android_test_support//:repo.bzl", "android_test_repositories")
android_test_repositories()

# Maven dependencies.

maven_install(
artifacts = [
"androidx.annotation:annotation:aar:1.1.0",
"androidx.annotation:annotation-experimental:1.1.0",
"androidx.test:core:jar:1.3.0",
"org.robolectric:robolectric:jar:4.4",
"com.google.truth:truth:jar:1.1",
Expand Down
6 changes: 6 additions & 0 deletions tensorflow_lite_support/opensource/opensource_only.files
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ tensorflow_lite_support/third_party/stblib.BUILD
tensorflow_lite_support/third_party/toolchains/java/BUILD
tensorflow_lite_support/third_party/utf.BUILD
tensorflow_lite_support/third_party/zlib.BUILD
tensorflow_lite_support/tools/build_rules/android_test/AndroidManifest_instrumentation_test_template.xml
tensorflow_lite_support/tools/build_rules/android_test/AndroidManifest_target_stub.xml
tensorflow_lite_support/tools/build_rules/android_test/android_library_instrumentation_tests.bzl
tensorflow_lite_support/tools/build_rules/android_test/android_multidevice_instrumentation_test.bzl
tensorflow_lite_support/tools/build_rules/android_test/generate_instrumentation_tests.bzl
tensorflow_lite_support/tools/build_rules/android_test/infer_java_package_name.bzl
tensorflow_lite_support/tools/build_rules/http_files.bzl
tensorflow_lite_support/tools/ci_build/build_all.sh
tensorflow_lite_support/tools/ci_build/common.sh
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="${applicationId}" >

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="28" />

<application/>

<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="${instrumentationTargetPackage}">
</instrumentation>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2018 The Android Open Source Project
~
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="${applicationId}" >

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="28" />

</manifest>
11 changes: 11 additions & 0 deletions tensorflow_lite_support/tools/build_rules/android_test/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package(
default_visibility = ["//tensorflow_lite_support:users"],
licenses = ["notice"], # Apache 2.0
)

exports_files(
[
"AndroidManifest_instrumentation_test_template.xml",
"AndroidManifest_target_stub.xml",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
"""A rule wrapper for an instrumentation test for an android library."""

load(
"//tensorflow_lite_support/tools/build_rules/android_test:generate_instrumentation_tests.bzl",
"generate_instrumentation_tests",
)
load(
"//tensorflow_lite_support/tools/build_rules/android_test:infer_java_package_name.bzl",
"infer_java_package_name",
)

def android_library_instrumentation_tests(
name,
srcs,
deps,
target_devices,
test_java_package = None,
library_args = {},
binary_args = {},
**kwargs):
"""A macro for an instrumentation test whose target under test is an android_library.
Will generate a 'self-instrumentating' test binary and other associated rules
The intent of this wrapper is to simplify the build API for creating instrumentation test rules
for simple cases, while still supporting build_cleaner for automatic dependency management.
This will generate:
- an unused stub android_binary under test, to placate bazel
- a test_lib android_library, containing all sources and dependencies
- a test_binary android_binary (soon to be android_application)
- the manifest to use for the test library.
- for each device combination:
- an android_instrumentation_test rule)
Args:
name: the name to use for the generated android_library rule. This is needed for build_cleaner to
manage dependencies
srcs: the test sources to generate rules for
deps: the build dependencies to use for the generated test binary
target_devices: array of device targets to execute on
test_java_package: Optional. A custom root package name to use for the tests. If unset
will be derived based on current path to a java source root
library_args: additional arguments to pass to generated android_library
binary_args: additional arguments to pass to generated android_binary
**kwargs: arguments to pass to generated android_instrumentation_test rules
"""
library_name = "%s_library" % name
test_java_package_name = test_java_package if test_java_package else infer_java_package_name()

native.android_binary(
name = "target_stub_binary",
manifest = "//tensorflow_lite_support/tools/build_rules/android_test:AndroidManifest_target_stub.xml",
# use the same package name as the test package, so it gets overridden
manifest_values = {"applicationId": test_java_package_name},
testonly = 1,
)

native.android_library(
name = library_name,
srcs = srcs,
testonly = 1,
deps = deps,
**library_args
)

generate_instrumentation_tests(
name = name,
srcs = srcs,
deps = [library_name],
target_devices = target_devices,
test_java_package_name = test_java_package_name,
test_android_package_name = test_java_package_name,
instrumentation_target_package = test_java_package_name,
instruments = ":target_stub_binary",
binary_args = binary_args,
**kwargs
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Utility for running single test on multiple emulator targets."""

def android_multidevice_instrumentation_test(name, target_devices, **kwargs):
"""Generates a android_instrumentation_test rule for each given device.
Args:
name: Name prefix to use for the rules. The name of the generated rules will follow:
name + target_device[-6:] eg name-15_x86
target_devices: array of device targets
**kwargs: arguments to pass to generated android_test rules
"""
for device in target_devices:
native.android_instrumentation_test(
name = name + "-" + device[-6:],
target_device = device,
**kwargs
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""Internal helper function for generating instrumentation tests ."""

load(
"//tensorflow_lite_support/tools/build_rules/android_test:android_multidevice_instrumentation_test.bzl",
"android_multidevice_instrumentation_test",
)

def generate_instrumentation_tests(
name,
srcs,
deps,
target_devices,
test_java_package_name,
test_android_package_name,
instrumentation_target_package,
instruments,
binary_args = {},
**kwargs):
"""A helper rule to generate instrumentation tests.
This will generate:
- a test_binary android_binary (soon to be android_application)
- the manifest to use for the test library.
- for each device combination:
- an android_instrumentation_test rule)
Args:
name: unique prefix to use for generated rules
srcs: the test sources to generate rules for
deps: the build dependencies to use for the generated test binary
target_devices: array of device targets to execute on
test_java_package_name: the root java package name for the tests.
test_android_package_name: the android package name to use for the android_binary test app. Typically this is the same as test_java_package_name
instrumentation_target_package: the android package name to specify as instrumentationTargetPackage in the test_app manifest
instruments: The android binary the tests instrument.
binary_args: Optional additional arguments to pass to generated android_binary
**kwargs: arguments to pass to generated android_instrumentation_test rules
"""

_manifest_values = {
"applicationId": test_android_package_name,
"instrumentationTargetPackage": instrumentation_target_package,
}
_manifest_values.update(binary_args.pop("manifest_values", {}))
native.android_binary(
name = "%s_binary" % name,
instruments = instruments,
manifest = "//tensorflow_lite_support/tools/build_rules/android_test:AndroidManifest_instrumentation_test_template.xml",
manifest_values = _manifest_values,
testonly = 1,
deps = deps + [
"@android_test_support//runner/android_junit_runner",
],
**binary_args
)
android_multidevice_instrumentation_test(
name = "%s_tests" % name,
target_devices = target_devices,
test_app = "%s_binary" % name,
**kwargs
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""A rule for inferring a java package name."""

_JAVA_ROOTS = [
"javatests/",
"javatest/",
"java/",
]

def infer_java_package_name():
"""Infer a java package name based on current path below 'javatests' or 'java'"""
return _infer_java_package_name_from_path(native.package_name())

def infer_java_package_name_from_label(label):
package_path = _get_path_from_label(label)
return _infer_java_package_name_from_path(package_path)

def _infer_java_package_name_from_path(package_path):
for root in _JAVA_ROOTS:
if root in package_path:
root_index = package_path.rindex(root) + len(root)
return package_path[root_index:].replace("/", ".")
fail("Could not find one of java roots %s in %s" % (_JAVA_ROOTS, package_path))

def _get_path_from_label(label_string):
label_string = label_string.split(":")[0]
if not label_string.startswith("//"):
label_string = "//%s%s" % (native.package_name(), label_string)
return label_string

0 comments on commit 71c7de1

Please sign in to comment.