# 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: # - .metadata produces the test metadata when included in a # `pw_test_group`. This metadata includes the Ninja target that runs the # test. # - .script creates a `pw_python_action` to run the test and # wraps it as a standalone `pw_python_package`. # - .group creates a `pw_python_group` in order to apply tools, # e.g. linters, to the standalone package. # - .lib is an empty group for compatibility with # `pw_test_group`. # - .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 `. # # 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 # ruff_toml # # - 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", "ruff_toml", ]) 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(ruff_toml)) { ruff_toml = "$dir_pigweed/.ruff.toml" } 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 } }