1*61c4878aSAndroid Build Coastguard Worker# Copyright 2023 The Pigweed Authors 2*61c4878aSAndroid Build Coastguard Worker# 3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of 5*61c4878aSAndroid Build Coastguard Worker# the License at 6*61c4878aSAndroid Build Coastguard Worker# 7*61c4878aSAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 8*61c4878aSAndroid Build Coastguard Worker# 9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under 13*61c4878aSAndroid Build Coastguard Worker# the License. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Workerimport("//build_overrides/pigweed.gni") 16*61c4878aSAndroid Build Coastguard Worker 17*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/python.gni") 18*61c4878aSAndroid Build Coastguard Workerimport("$dir_pw_build/test_info.gni") 19*61c4878aSAndroid Build Coastguard Worker 20*61c4878aSAndroid Build Coastguard Worker# Creates a Python action to use as a test and associated metadata. 21*61c4878aSAndroid Build Coastguard Worker# 22*61c4878aSAndroid Build Coastguard Worker# This template derives several additional targets: 23*61c4878aSAndroid Build Coastguard Worker# - <target_name>.metadata produces the test metadata when included in a 24*61c4878aSAndroid Build Coastguard Worker# `pw_test_group`. This metadata includes the Ninja target that runs the 25*61c4878aSAndroid Build Coastguard Worker# test. 26*61c4878aSAndroid Build Coastguard Worker# - <target_name>.script creates a `pw_python_action` to run the test and 27*61c4878aSAndroid Build Coastguard Worker# wraps it as a standalone `pw_python_package`. 28*61c4878aSAndroid Build Coastguard Worker# - <target_name>.group creates a `pw_python_group` in order to apply tools, 29*61c4878aSAndroid Build Coastguard Worker# e.g. linters, to the standalone package. 30*61c4878aSAndroid Build Coastguard Worker# - <target_name>.lib is an empty group for compatibility with 31*61c4878aSAndroid Build Coastguard Worker# `pw_test_group`. 32*61c4878aSAndroid Build Coastguard Worker# - <target_name>.run invokes the test. 33*61c4878aSAndroid Build Coastguard Worker# 34*61c4878aSAndroid Build Coastguard Worker# Targets defined using this template will produce test metadata with a 35*61c4878aSAndroid Build Coastguard Worker# `test_type` of "action_test" and a `ninja_target` value that will invoke the 36*61c4878aSAndroid Build Coastguard Worker# test when passed to Ninja, i.e. `ninja -C out <ninja_target>`. 37*61c4878aSAndroid Build Coastguard Worker# 38*61c4878aSAndroid Build Coastguard Worker# Args: 39*61c4878aSAndroid Build Coastguard Worker# - The following args have the same meaning as for `pw_test`: 40*61c4878aSAndroid Build Coastguard Worker# enable_if 41*61c4878aSAndroid Build Coastguard Worker# envvars (may also use `environment`) 42*61c4878aSAndroid Build Coastguard Worker# tags 43*61c4878aSAndroid Build Coastguard Worker# extra_metadata 44*61c4878aSAndroid Build Coastguard Worker# source_gen_deps 45*61c4878aSAndroid Build Coastguard Worker# 46*61c4878aSAndroid Build Coastguard Worker# - The following args have the same meaning as for `pw_python_action`: 47*61c4878aSAndroid Build Coastguard Worker# script (may be omitted if `sources` has length=1) 48*61c4878aSAndroid Build Coastguard Worker# args 49*61c4878aSAndroid Build Coastguard Worker# deps 50*61c4878aSAndroid Build Coastguard Worker# environment (may also use `envvars`) 51*61c4878aSAndroid Build Coastguard Worker# working_directory 52*61c4878aSAndroid Build Coastguard Worker# command_launcher 53*61c4878aSAndroid Build Coastguard Worker# venv 54*61c4878aSAndroid Build Coastguard Worker# 55*61c4878aSAndroid Build Coastguard Worker# - The following args have the same meaning as for `pw_python_package`: 56*61c4878aSAndroid Build Coastguard Worker# sources 57*61c4878aSAndroid Build Coastguard Worker# python_deps 58*61c4878aSAndroid Build Coastguard Worker# other_deps 59*61c4878aSAndroid Build Coastguard Worker# inputs 60*61c4878aSAndroid Build Coastguard Worker# static_analysis 61*61c4878aSAndroid Build Coastguard Worker# pylintrc 62*61c4878aSAndroid Build Coastguard Worker# mypy_ini 63*61c4878aSAndroid Build Coastguard Worker# ruff_toml 64*61c4878aSAndroid Build Coastguard Worker# 65*61c4878aSAndroid Build Coastguard Worker# - action: Optional string or scope. If a string, this should be a label to 66*61c4878aSAndroid Build Coastguard Worker# a `pw_python_action` target that performs the test. If a scope, this 67*61c4878aSAndroid Build Coastguard Worker# has the same meaning as for `pw_python_script`. 68*61c4878aSAndroid Build Coastguard Workertemplate("pw_python_action_test") { 69*61c4878aSAndroid Build Coastguard Worker _test_target_name = target_name 70*61c4878aSAndroid Build Coastguard Worker _deps = [] 71*61c4878aSAndroid Build Coastguard Worker _run_deps = [] 72*61c4878aSAndroid Build Coastguard Worker _metadata = { 73*61c4878aSAndroid Build Coastguard Worker } 74*61c4878aSAndroid Build Coastguard Worker 75*61c4878aSAndroid Build Coastguard Worker _test_is_enabled = !defined(invoker.enable_if) || invoker.enable_if 76*61c4878aSAndroid Build Coastguard Worker if (_test_is_enabled) { 77*61c4878aSAndroid Build Coastguard Worker # Metadata for this test when used as part of a pw_test_group target. 78*61c4878aSAndroid Build Coastguard Worker _test_metadata = "${target_name}.metadata" 79*61c4878aSAndroid Build Coastguard Worker _ninja_target = "$target_out_dir/$target_name.run.stamp" 80*61c4878aSAndroid Build Coastguard Worker _extra_metadata = { 81*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, [ "extra_metadata" ]) 82*61c4878aSAndroid Build Coastguard Worker ninja_target = rebase_path(_ninja_target, root_build_dir) 83*61c4878aSAndroid Build Coastguard Worker } 84*61c4878aSAndroid Build Coastguard Worker pw_test_info(_test_metadata) { 85*61c4878aSAndroid Build Coastguard Worker test_type = "action_test" 86*61c4878aSAndroid Build Coastguard Worker test_name = _test_target_name 87*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, [ "tags" ]) 88*61c4878aSAndroid Build Coastguard Worker extra_metadata = _extra_metadata 89*61c4878aSAndroid Build Coastguard Worker } 90*61c4878aSAndroid Build Coastguard Worker _deps += [ ":$_test_metadata" ] 91*61c4878aSAndroid Build Coastguard Worker _metadata = { 92*61c4878aSAndroid Build Coastguard Worker test_barrier = [ ":$_test_metadata" ] 93*61c4878aSAndroid Build Coastguard Worker } 94*61c4878aSAndroid Build Coastguard Worker 95*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.action) && invoker.action == "${invoker.action}") { 96*61c4878aSAndroid Build Coastguard Worker # `action` is a label to an existing Python action. 97*61c4878aSAndroid Build Coastguard Worker _run_deps = [ invoker.action ] 98*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.deps)) { 99*61c4878aSAndroid Build Coastguard Worker _deps += invoker.deps 100*61c4878aSAndroid Build Coastguard Worker } 101*61c4878aSAndroid Build Coastguard Worker } else { 102*61c4878aSAndroid Build Coastguard Worker # Wrap the action in a Python script target for additional flexibility. 103*61c4878aSAndroid Build Coastguard Worker _test_script_name = _test_target_name + ".script" 104*61c4878aSAndroid Build Coastguard Worker 105*61c4878aSAndroid Build Coastguard Worker _sources = [] 106*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.script)) { 107*61c4878aSAndroid Build Coastguard Worker _sources += [ invoker.script ] 108*61c4878aSAndroid Build Coastguard Worker } 109*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.sources)) { 110*61c4878aSAndroid Build Coastguard Worker _sources += invoker.sources 111*61c4878aSAndroid Build Coastguard Worker } 112*61c4878aSAndroid Build Coastguard Worker 113*61c4878aSAndroid Build Coastguard Worker pw_python_script(_test_script_name) { 114*61c4878aSAndroid Build Coastguard Worker other_deps = [] 115*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, 116*61c4878aSAndroid Build Coastguard Worker [ 117*61c4878aSAndroid Build Coastguard Worker "action", 118*61c4878aSAndroid Build Coastguard Worker "python_deps", 119*61c4878aSAndroid Build Coastguard Worker "other_deps", 120*61c4878aSAndroid Build Coastguard Worker "inputs", 121*61c4878aSAndroid Build Coastguard Worker "static_analysis", 122*61c4878aSAndroid Build Coastguard Worker "testonly", 123*61c4878aSAndroid Build Coastguard Worker "pylintrc", 124*61c4878aSAndroid Build Coastguard Worker "mypy_ini", 125*61c4878aSAndroid Build Coastguard Worker "ruff_toml", 126*61c4878aSAndroid Build Coastguard Worker ]) 127*61c4878aSAndroid Build Coastguard Worker sources = _sources 128*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.source_gen_deps)) { 129*61c4878aSAndroid Build Coastguard Worker other_deps += invoker.source_gen_deps 130*61c4878aSAndroid Build Coastguard Worker } 131*61c4878aSAndroid Build Coastguard Worker if (!defined(pylintrc)) { 132*61c4878aSAndroid Build Coastguard Worker pylintrc = "$dir_pigweed/.pylintrc" 133*61c4878aSAndroid Build Coastguard Worker } 134*61c4878aSAndroid Build Coastguard Worker if (!defined(mypy_ini)) { 135*61c4878aSAndroid Build Coastguard Worker mypy_ini = "$dir_pigweed/.mypy.ini" 136*61c4878aSAndroid Build Coastguard Worker } 137*61c4878aSAndroid Build Coastguard Worker if (!defined(ruff_toml)) { 138*61c4878aSAndroid Build Coastguard Worker ruff_toml = "$dir_pigweed/.ruff.toml" 139*61c4878aSAndroid Build Coastguard Worker } 140*61c4878aSAndroid Build Coastguard Worker if (!defined(action)) { 141*61c4878aSAndroid Build Coastguard Worker action = { 142*61c4878aSAndroid Build Coastguard Worker environment = [] 143*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, 144*61c4878aSAndroid Build Coastguard Worker [ 145*61c4878aSAndroid Build Coastguard Worker "script", 146*61c4878aSAndroid Build Coastguard Worker "args", 147*61c4878aSAndroid Build Coastguard Worker "deps", 148*61c4878aSAndroid Build Coastguard Worker "environment", 149*61c4878aSAndroid Build Coastguard Worker "working_directory", 150*61c4878aSAndroid Build Coastguard Worker "command_launcher", 151*61c4878aSAndroid Build Coastguard Worker "venv", 152*61c4878aSAndroid Build Coastguard Worker ]) 153*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.envvars)) { 154*61c4878aSAndroid Build Coastguard Worker environment += invoker.envvars 155*61c4878aSAndroid Build Coastguard Worker } 156*61c4878aSAndroid Build Coastguard Worker stamp = true 157*61c4878aSAndroid Build Coastguard Worker } 158*61c4878aSAndroid Build Coastguard Worker } 159*61c4878aSAndroid Build Coastguard Worker } 160*61c4878aSAndroid Build Coastguard Worker _deps += [ ":$_test_script_name" ] 161*61c4878aSAndroid Build Coastguard Worker _run_deps = [ ":$_test_script_name.action" ] 162*61c4878aSAndroid Build Coastguard Worker 163*61c4878aSAndroid Build Coastguard Worker # Create a Python group in order to ensure the package is linted. 164*61c4878aSAndroid Build Coastguard Worker _test_python_group = _test_target_name + ".group" 165*61c4878aSAndroid Build Coastguard Worker pw_python_group(_test_python_group) { 166*61c4878aSAndroid Build Coastguard Worker python_deps = [ ":$_test_script_name" ] 167*61c4878aSAndroid Build Coastguard Worker } 168*61c4878aSAndroid Build Coastguard Worker _deps += [ ":$_test_python_group" ] 169*61c4878aSAndroid Build Coastguard Worker } 170*61c4878aSAndroid Build Coastguard Worker } else { 171*61c4878aSAndroid Build Coastguard Worker if (defined(invoker.source_gen_deps)) { 172*61c4878aSAndroid Build Coastguard Worker _deps += invoker.source_gen_deps 173*61c4878aSAndroid Build Coastguard Worker } 174*61c4878aSAndroid Build Coastguard Worker } 175*61c4878aSAndroid Build Coastguard Worker 176*61c4878aSAndroid Build Coastguard Worker # For compatibility with `pw_test_group`. 177*61c4878aSAndroid Build Coastguard Worker group(_test_target_name + ".lib") { 178*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, [ "testonly" ]) 179*61c4878aSAndroid Build Coastguard Worker } 180*61c4878aSAndroid Build Coastguard Worker 181*61c4878aSAndroid Build Coastguard Worker # For compatibility with `pw_test_group`. 182*61c4878aSAndroid Build Coastguard Worker group(_test_target_name + ".run") { 183*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, [ "testonly" ]) 184*61c4878aSAndroid Build Coastguard Worker deps = _run_deps 185*61c4878aSAndroid Build Coastguard Worker } 186*61c4878aSAndroid Build Coastguard Worker 187*61c4878aSAndroid Build Coastguard Worker group(_test_target_name) { 188*61c4878aSAndroid Build Coastguard Worker forward_variables_from(invoker, [ "testonly" ]) 189*61c4878aSAndroid Build Coastguard Worker deps = _deps 190*61c4878aSAndroid Build Coastguard Worker metadata = _metadata 191*61c4878aSAndroid Build Coastguard Worker } 192*61c4878aSAndroid Build Coastguard Worker} 193