aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Dagostino <kevindagostino@google.com>2022-12-05 06:45:43 +0000
committerKevin Dagostino <kevindagostino@google.com>2022-12-12 19:27:28 +0000
commited21a6c9816e695b3c8c4426d2eba4c061effd7b (patch)
tree04b08bcf6f43ebd68964824951dd19bc2ae49602
parentd9d14c64cfb745d6ffe57415cb655e488617f69c (diff)
downloadbazel-ed21a6c9816e695b3c8c4426d2eba4c061effd7b.tar.gz
Support running Tradefed tests with Bazel
Replace the placeholder shell script with a working version that invokes Tradefed. Generate result-reporter.xml config. Generate test config from template if one is not specified. Test: b test //build/bazel/rules/tradefed/... Change-Id: I7f479492d4d3f4457465cda7c39ef3b0e074550f
-rw-r--r--rules/tradefed/test/BUILD.bazel10
-rw-r--r--rules/tradefed/tradefed.bzl157
-rw-r--r--rules/tradefed/tradefed.sh.tpl63
-rw-r--r--rules/tradefed/tradefed_test.bzl33
4 files changed, 181 insertions, 82 deletions
diff --git a/rules/tradefed/test/BUILD.bazel b/rules/tradefed/test/BUILD.bazel
index 477735d5..a8460468 100644
--- a/rules/tradefed/test/BUILD.bazel
+++ b/rules/tradefed/test/BUILD.bazel
@@ -1,7 +1,5 @@
-filegroup(
- name = "example_configs",
- srcs = glob(
- ["*.xml"],
- ),
- visibility = ["//build/bazel/rules/tradefed:__subpackages__"],
+package(default_visibility = ["//build/bazel/rules/tradefed:__subpackages__"])
+
+exports_files(
+ glob(["*.xml"]),
)
diff --git a/rules/tradefed/tradefed.bzl b/rules/tradefed/tradefed.bzl
index a2f40fce..c8c1e3df 100644
--- a/rules/tradefed/tradefed.bzl
+++ b/rules/tradefed/tradefed.bzl
@@ -14,93 +14,128 @@ See the License for the specific language governing permissions and
limitations under the License.
"""
-# Types where generating a tradefed config is supported.
-# These map to the template specified in _config_templates
-_config_templates = {
- "cc": "//build/make/core:native_test_config_template.xml",
- "cc-host": "//build/make/core:native_host_test_config_template.xml",
-}
-
TRADEFED_TEST_ATTRIBUTES = {
"test": attr.label(
providers = [[CcInfo]],
doc = "Test target to run in tradefed.",
),
+ "host": attr.bool(
+ default = False,
+ doc = "Is a host (deviceless) test",
+ ),
"_tradefed_test_sh_template": attr.label(
default = ":tradefed.sh.tpl",
allow_single_file = True,
doc = "Template script to launch tradefed.",
),
- "host": attr.bool(
- default = False,
- doc = "Is a host (deviceless) test",
+ "_tradefed_dependencies": attr.label_list(
+ default = [
+ "//prebuilts/runtime:prebuilt-runtime-adb",
+ "//tools/tradefederation/prebuilts/filegroups/tradefed:bp2build_all_srcs",
+ "//tools/tradefederation/prebuilts/filegroups/suite:compatibility-host-util-prebuilt",
+ "//tools/tradefederation/prebuilts/filegroups/suite:compatibility-tradefed-prebuilt",
+ "//tools/asuite/atest:atest-tradefed",
+ "//tools/asuite/atest/bazel/reporter:bazel-result-reporter",
+ ],
+ doc = "Files needed on the PATH to run tradefed",
),
- # Tradefed config specific attributes.
- "tradefed_configs": attr.label_list(
- allow_files = True,
- doc = "Tradefed configs.",
+ # Test config and if test config generation attributes.
+ "test_config": attr.label(
+ allow_single_file = True,
+ doc = "Test/Tradefed config.",
),
- "_config_templates": attr.label_list(
- default = _config_templates.values(),
- allow_files = True,
- doc = "List of templates to generate a tradefed config based on a provider type.",
+ "template_test_config": attr.label(
+ allow_single_file = True,
+ doc = "Template to generate test config.",
),
- "extra_configs": attr.string(
- doc = "Extra configs to extend into generated tf config.",
+ "template_configs": attr.string_list(
+ doc = "Extra tradefed config options to extend into generated test config.",
),
- "test_install_base": attr.string(
+ "template_install_base": attr.string(
default = "/data/local/tmp",
doc = "Directory to install tests onto the device for generated config",
),
}
-# Generate tradefed config from template.
-def _create_tradefed_test_configs(ctx):
- # Check for existing tradefed configs; and symlink
- if len(ctx.files.tradefed_configs) > 0:
- configs = []
- for f in ctx.files.tradefed_configs:
- out = ctx.actions.declare_file(f.basename + ".tradefed.config")
- ctx.actions.symlink(
- output = out,
- target_file = f,
- )
- configs.append(out)
- return configs
-
- # No existing configs -- generate from template.
- out = ctx.actions.declare_file(ctx.attr.name + ".tradefed.config")
+# Get test config if specified or generate test config from template.
+def _get_or_generate_test_config(ctx):
+ # Validate input
+ c = ctx.file.test_config
+ c_template = ctx.file.template_test_config
+ if c and c_template:
+ fail("Both test_config and test_config_template were provided, please use only 1 of them")
+ if not c and not c_template:
+ fail("Either test_config or test_config_template should be provided")
+
+ # Check for existing tradefed configs and if found add a symlink.
+ if c:
+ out = ctx.actions.declare_file(c.basename + ".test.config")
+ ctx.actions.symlink(
+ output = out,
+ target_file = c,
+ )
+ return out
+
+ # No existing config specified - generate from template.
+ out = ctx.actions.declare_file(ctx.attr.name + ".test.config")
+
+ # Join extra configs together and add xml spacing indent.
+ extra_configs = "\n ".join(ctx.attr.template_configs)
module_name = ctx.attr.test.label.name
- # Choose template based on test target provider and host attribute.
- key = ""
- template_file = None
- if CcInfo in ctx.attr.test:
- key = "cc"
- if ctx.attr.host:
- key += "-host"
- for t in ctx.attr._config_templates:
- if str(t.label) == "@" + _config_templates[key]:
- template_file = t.files.to_list()[0]
- if not template_file:
- fail("Unsupported target for tradefed config generation: " + str(ctx.attr.test))
-
ctx.actions.expand_template(
- template = template_file,
+ template = c_template,
output = out,
substitutions = {
"{MODULE}": module_name,
- "{EXTRA_CONFIGS}": ctx.attr.extra_configs,
- "{TEST_INSTALL_BASE}": ctx.attr.test_install_base,
+ "{EXTRA_CONFIGS}": extra_configs,
+ "{TEST_INSTALL_BASE}": ctx.attr.template_install_base,
},
)
- return [out]
+ return out
+
+# Generate tradefed result reporter config.
+def _create_result_reporter_config(ctx):
+ result_reporters_config_file = ctx.actions.declare_file("result-reporters.xml")
+ config_lines = [
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>",
+ "<configuration>",
+ ]
+
+ result_reporters = [
+ "com.android.tradefed.result.BazelExitCodeResultReporter",
+ "com.android.tradefed.result.BazelXmlResultReporter",
+ ]
+ for result_reporter in result_reporters:
+ config_lines.append(" <result_reporter class=\"%s\" />" % result_reporter)
+ config_lines.append("</configuration>")
+
+ ctx.actions.write(result_reporters_config_file, "\n".join(config_lines))
+ return result_reporters_config_file
# Generate and run tradefed bash script.
def _tradefed_test_impl(ctx):
- # Generate tradefed configs.
- configs = _create_tradefed_test_configs(ctx)
+ # Get or generate test config.
+ test_config = _get_or_generate_test_config(ctx)
+
+ # Generate result reporter config file.
+ report_config = _create_result_reporter_config(ctx)
+
+ # Gather runfiles.
+ runfiles = ctx.runfiles()
+ runfiles = runfiles.merge_all([
+ ctx.attr.test.default_runfiles,
+ ctx.runfiles(files = ctx.files._tradefed_dependencies + [test_config, report_config]),
+ ])
+
+ # Gather directories of runfiles to put on the PATH.
+ dependency_paths = {}
+ for f in runfiles.files.to_list():
+ dependency_paths[f.dirname] = True
+ for f in runfiles.symlinks.to_list():
+ dependency_paths[f.dirname] = True
+ path_additions = ":".join(dependency_paths.keys())
# Generate script to run tradefed.
script = ctx.actions.declare_file("tradefed_test_%s.sh" % ctx.label.name)
@@ -108,14 +143,12 @@ def _tradefed_test_impl(ctx):
template = ctx.file._tradefed_test_sh_template,
output = script,
is_executable = True,
- substitutions = {},
+ substitutions = {
+ "{MODULE}": ctx.attr.test.label.name,
+ "{PATH_ADDITIONS}": path_additions,
+ },
)
- # Gather runfiles.
- runfiles = ctx.runfiles()
- runfiles = runfiles.merge(ctx.attr.test.default_runfiles)
- runfiles = runfiles.merge(ctx.runfiles(files = configs))
-
return [DefaultInfo(
executable = script,
runfiles = runfiles,
diff --git a/rules/tradefed/tradefed.sh.tpl b/rules/tradefed/tradefed.sh.tpl
index a38163ea..13a2368e 100644
--- a/rules/tradefed/tradefed.sh.tpl
+++ b/rules/tradefed/tradefed.sh.tpl
@@ -1 +1,62 @@
-echo "Will be replace with tradefed call in future CL"
+#!/bin/bash
+set -e
+set -x
+
+TEST_PATH="${TEST_SRCDIR}"
+RUN_PATH="${TEST_SRCDIR}/${TEST_WORKSPACE}/build/bazel/rules/tradefed/"
+PATH_ADDITIONS="{PATH_ADDITIONS}"
+
+# Add tradefed dependencies to PATH
+for dep in ${PATH_ADDITIONS//:/ }; do
+ export PATH="${TEST_SRCDIR}/${TEST_WORKSPACE}/$dep:${PATH}"
+done
+
+# Prepend the REMOTE_JAVA_HOME environment variable to the path to ensure
+# that all Java invocations throughout the test execution flow use the same
+# version.
+if [ ! -z "${REMOTE_JAVA_HOME}" ]; then
+ export PATH="${REMOTE_JAVA_HOME}/bin:${PATH}"
+fi
+
+exit_code_file="$(mktemp /tmp/tf-exec-XXXXXXXXXX)"
+
+atest_tradefed.sh template/atest_local_min \
+ --template:map test=atest \
+ --template:map reporters="${RUN_PATH}/result-reporters.xml" \
+ --tests-dir "$TEST_PATH" \
+ --logcat-on-failure \
+ --no-enable-granular-attempts \
+ --no-early-device-release \
+ --skip-host-arch-check \
+ --include-filter "{MODULE}" \
+ --skip-loading-config-jar \
+ --log-level-display VERBOSE \
+ --log-level VERBOSE \
+ "${ADDITIONAL_TRADEFED_OPTIONS[@]}" \
+ --bazel-exit-code-result-reporter:file=${exit_code_file} \
+ --bazel-xml-result-reporter:file=${XML_OUTPUT_FILE} \
+ --proto-output-file="${TEST_UNDECLARED_OUTPUTS_DIR}/proto-results" \
+ --log-file-path="${TEST_UNDECLARED_OUTPUTS_DIR}" \
+ "$@"
+
+# Use the TF exit code if it terminates abnormally.
+tf_exit=$?
+if [ ${tf_exit} -ne 0 ]
+then
+ echo "Tradefed command failed with exit code ${tf_exit}"
+ exit ${tf_exit}
+fi
+
+# Set the exit code based on the exit code in the reporter-generated file.
+exit_code=$(<${exit_code_file})
+if [ $? -ne 0 ]
+then
+ echo "Could not read exit code file: ${exit_code_file}"
+ exit 36
+fi
+
+if [ ${exit_code} -ne 0 ]
+then
+ echo "Test failed with exit code ${exit_code}"
+ exit ${exit_code}
+fi
diff --git a/rules/tradefed/tradefed_test.bzl b/rules/tradefed/tradefed_test.bzl
index 2cbe4cf1..2316f9da 100644
--- a/rules/tradefed/tradefed_test.bzl
+++ b/rules/tradefed/tradefed_test.bzl
@@ -60,6 +60,7 @@ def tradefed_cc_outputs():
name = name,
tags = ["manual"],
test = target,
+ test_config = "//build/bazel/rules/tradefed/test:example_config.xml",
target_compatible_with = ["//build/bazel/platforms/os:linux"],
)
@@ -69,11 +70,12 @@ def tradefed_cc_outputs():
target_under_test = name,
expected_outputs = [
"tradefed_test_" + name + ".sh",
- name + ".tradefed.config",
+ "result-reporters.xml",
+ "example_config.xml.test.config",
],
target_compatible_with = ["//build/bazel/platforms/os:linux"],
)
- return name
+ return name + "_test"
def tradefed_cc_host_outputs():
name = "cc_host"
@@ -87,6 +89,7 @@ def tradefed_cc_host_outputs():
name = name,
tags = ["manual"],
test = target,
+ test_config = "//build/bazel/rules/tradefed/test:example_config.xml",
target_compatible_with = ["//build/bazel/platforms/os:linux"],
)
@@ -96,15 +99,16 @@ def tradefed_cc_host_outputs():
target_under_test = name,
expected_outputs = [
"tradefed_test_" + name + ".sh",
- name + ".tradefed.config",
+ "result-reporters.xml",
+ "example_config.xml.test.config",
],
target_compatible_with = ["//build/bazel/platforms/os:linux"],
)
- return name
+ return name + "_test"
-def tradefed_cc_host_outputs_with_existing_tf_config():
- name = "cc_host_with_example_config"
- target = "cc_host_target_with_example_config"
+def tradefed_cc_host_outputs_generate_test_config():
+ name = "cc_host_generate_config"
+ target = "cc_host_target_generate_config"
cc_object(
name = target,
@@ -114,10 +118,12 @@ def tradefed_cc_host_outputs_with_existing_tf_config():
name = name,
tags = ["manual"],
test = target,
- target_compatible_with = ["//build/bazel/platforms/os:linux"],
- tradefed_configs = [
- "//build/bazel/rules/tradefed/test:example_configs",
+ template_test_config = "//build/make/core:native_host_test_config_template.xml",
+ template_configs = [
+ "<option name=\"config-descriptor:metadata\" key=\"parameter\" value=\"not_multi_abi\" />",
+ "<option name=\"config-descriptor:metadata\" key=\"parameter\" value=\"secondary_user\" />",
],
+ target_compatible_with = ["//build/bazel/platforms/os:linux"],
)
# check for expected output files (.config file and .sh script)
@@ -126,11 +132,12 @@ def tradefed_cc_host_outputs_with_existing_tf_config():
target_under_test = name,
expected_outputs = [
"tradefed_test_" + name + ".sh",
- "example_config.xml.tradefed.config",
+ "result-reporters.xml",
+ "cc_host_generate_config.test.config",
],
target_compatible_with = ["//build/bazel/platforms/os:linux"],
)
- return name
+ return name + "_test"
def tradefed_test_suite(name):
native.test_suite(
@@ -138,6 +145,6 @@ def tradefed_test_suite(name):
tests = [
tradefed_cc_outputs(),
tradefed_cc_host_outputs(),
- tradefed_cc_host_outputs_with_existing_tf_config(),
+ tradefed_cc_host_outputs_generate_test_config(),
],
)