xref: /aosp_15_r20/external/pigweed/pw_build/python_action_test.gni (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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