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