diff options
Diffstat (limited to 'pw_build/python_action_test.gni')
-rw-r--r-- | pw_build/python_action_test.gni | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/pw_build/python_action_test.gni b/pw_build/python_action_test.gni new file mode 100644 index 000000000..2de0fee4f --- /dev/null +++ b/pw_build/python_action_test.gni @@ -0,0 +1,187 @@ +# Copyright 2023 The Pigweed Authors +# +# 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 +# +# https://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. + +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/python.gni") +import("$dir_pw_build/test_info.gni") + +# Creates a Python action to use as a test and associated metadata. +# +# This template derives several additional targets: +# - <target_name>.metadata produces the test metadata when included in a +# `pw_test_group`. This metadata includes the Ninja target that runs the +# test. +# - <target_name>.script creates a `pw_python_action` to run the test and +# wraps it as a standalone `pw_python_package`. +# - <target_name>.group creates a `pw_python_group` in order to apply tools, +# e.g. linters, to the standalone package. +# - <target_name>.lib is an empty group for compatibility with +# `pw_test_group`. +# - <target_name>.run invokes the test. +# +# Targets defined using this template will produce test metadata with a +# `test_type` of "action_test" and a `ninja_target` value that will invoke the +# test when passed to Ninja, i.e. `ninja -C out <ninja_target>`. +# +# Args: +# - The following args have the same meaning as for `pw_test`: +# enable_if +# envvars (may also use `environment`) +# tags +# extra_metadata +# source_gen_deps +# +# - The following args have the same meaning as for `pw_python_action`: +# script (may be omitted if `sources` has length=1) +# args +# deps +# environment (may also use `envvars`) +# working_directory +# command_launcher +# venv +# +# - The following args have the same meaning as for `pw_python_package`: +# sources +# python_deps +# other_deps +# inputs +# static_analysis +# pylintrc +# mypy_ini +# +# - action: Optional string or scope. If a string, this should be a label to +# a `pw_python_action` target that performs the test. If a scope, this +# has the same meaning as for `pw_python_script`. +template("pw_python_action_test") { + _test_target_name = target_name + _deps = [] + _run_deps = [] + _metadata = { + } + + _test_is_enabled = !defined(invoker.enable_if) || invoker.enable_if + if (_test_is_enabled) { + # Metadata for this test when used as part of a pw_test_group target. + _test_metadata = "${target_name}.metadata" + _ninja_target = "$target_out_dir/$target_name.run.stamp" + _extra_metadata = { + forward_variables_from(invoker, [ "extra_metadata" ]) + ninja_target = rebase_path(_ninja_target, root_build_dir) + } + pw_test_info(_test_metadata) { + test_type = "action_test" + test_name = _test_target_name + forward_variables_from(invoker, [ "tags" ]) + extra_metadata = _extra_metadata + } + _deps += [ ":$_test_metadata" ] + _metadata = { + test_barrier = [ ":$_test_metadata" ] + } + + if (defined(invoker.action) && invoker.action == "${invoker.action}") { + # `action` is a label to an existing Python action. + _run_deps = [ invoker.action ] + if (defined(invoker.deps)) { + _deps += invoker.deps + } + } else { + # Wrap the action in a Python script target for additional flexibility. + _test_script_name = _test_target_name + ".script" + + _sources = [] + if (defined(invoker.script)) { + _sources += [ invoker.script ] + } + if (defined(invoker.sources)) { + _sources += invoker.sources + } + + pw_python_script(_test_script_name) { + other_deps = [] + forward_variables_from(invoker, + [ + "action", + "python_deps", + "other_deps", + "inputs", + "static_analysis", + "testonly", + "pylintrc", + "mypy_ini", + ]) + sources = _sources + if (defined(invoker.source_gen_deps)) { + other_deps += invoker.source_gen_deps + } + if (!defined(pylintrc)) { + pylintrc = "$dir_pigweed/.pylintrc" + } + if (!defined(mypy_ini)) { + mypy_ini = "$dir_pigweed/.mypy.ini" + } + if (!defined(action)) { + action = { + environment = [] + forward_variables_from(invoker, + [ + "script", + "args", + "deps", + "environment", + "working_directory", + "command_launcher", + "venv", + ]) + if (defined(invoker.envvars)) { + environment += invoker.envvars + } + stamp = true + } + } + } + _deps += [ ":$_test_script_name" ] + _run_deps = [ ":$_test_script_name.action" ] + + # Create a Python group in order to ensure the package is linted. + _test_python_group = _test_target_name + ".group" + pw_python_group(_test_python_group) { + python_deps = [ ":$_test_script_name" ] + } + _deps += [ ":$_test_python_group" ] + } + } else { + if (defined(invoker.source_gen_deps)) { + _deps += invoker.source_gen_deps + } + } + + # For compatibility with `pw_test_group`. + group(_test_target_name + ".lib") { + forward_variables_from(invoker, [ "testonly" ]) + } + + # For compatibility with `pw_test_group`. + group(_test_target_name + ".run") { + forward_variables_from(invoker, [ "testonly" ]) + deps = _run_deps + } + + group(_test_target_name) { + forward_variables_from(invoker, [ "testonly" ]) + deps = _deps + metadata = _metadata + } +} |