xref: /aosp_15_r20/external/pigweed/pw_unit_test/BUILD.gn (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2020 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/module_config.gni")
18import("$dir_pw_build/python_action_test.gni")
19import("$dir_pw_build/target_types.gni")
20import("$dir_pw_docgen/docs.gni")
21import("$dir_pw_protobuf_compiler/proto.gni")
22import("$dir_pw_toolchain/traits.gni")
23import("$dir_pw_unit_test/test.gni")
24
25declare_args() {
26  # The build target that overrides the default configuration options for this
27  # module. This should point to a source set that provides defines through a
28  # public config (which may -include a file or add defines directly).
29  pw_unit_test_CONFIG = pw_build_DEFAULT_MODULE_CONFIG
30}
31
32# This pool limits the maximum number of unit tests that may run in parallel.
33# Despite the fact that this is a single GN "target", each toolchain owns its
34# own version of this pool, meaning pw_unit_test_POOL_DEPTH may be set
35# differently across targets in a single build, and build steps in one toolchain
36# will not consume pool resources of steps from another toolchain.
37pool("unit_test_pool") {
38  depth = pw_unit_test_POOL_DEPTH
39}
40
41config("public_include_path") {
42  include_dirs = [ "public" ]
43}
44
45config("public_overrides_include_path") {
46  include_dirs = [ "public_overrides" ]
47}
48
49config("light_public_overrides_include_path") {
50  include_dirs = [ "light_public_overrides" ]
51}
52
53config("googletest_public_overrides_include_path") {
54  include_dirs = [ "googletest_public_overrides" ]
55}
56
57pw_source_set("config") {
58  public = [ "public/pw_unit_test/config.h" ]
59  public_configs = [ ":public_include_path" ]
60  public_deps = [
61    dir_pw_polyfill,
62    pw_unit_test_CONFIG,
63  ]
64  visibility = [ ":*" ]
65}
66
67# pw_unit_test facade. This provides a GoogleTest-compatible test framework.
68pw_source_set("pw_unit_test") {
69  testonly = pw_unit_test_TESTONLY
70  public = [ "public/pw_unit_test/framework.h" ]
71  public_configs = [ ":public_include_path" ]
72  public_deps = [
73    ":status_macros",
74    pw_unit_test_BACKEND,
75  ]
76
77  # Temporarily redirect deprecated googletest pointer to new pointer.
78  if ("$pw_unit_test_GOOGLETEST_BACKEND" == "$dir_pw_third_party/googletest" &&
79      "$pw_unit_test_MAIN" == "$dir_pw_third_party/googletest:gmock_main" &&
80      "$pw_unit_test_BACKEND" == "$dir_pw_unit_test:light") {
81    print("Warning: pw_unit_test_GOOGLETEST_BACKEND is deprecated.")
82    print("Set pw_unit_test_BACKEND to //pw_unit_test:googletest.")
83    public_deps = []  # The list must be empty before overriding.
84    public_deps = [ ":googletest" ]
85  }
86}
87
88# Lightweight unit test backend that implements a subset of GoogleTest.
89pw_source_set("light") {
90  public_configs = [
91    ":light_public_overrides_include_path",
92    ":public_include_path",
93    ":public_overrides_include_path",
94  ]
95  public_deps = [
96    ":config",
97    ":event_handler",
98    ":status_macros",
99    "$dir_pw_bytes:alignment",
100    "$dir_pw_string:builder",
101    dir_pw_polyfill,
102    dir_pw_preprocessor,
103    dir_pw_span,
104    dir_pw_status,
105  ]
106
107  deps = [ dir_pw_assert ]
108
109  public = [
110    "light_public_overrides/pw_unit_test/framework_backend.h",
111
112    # The facade header is included here since public_overrides/gtest/gtest.h
113    # includes it. This avoids a circular dependency in the build system.
114    "public/pw_unit_test/framework.h",
115    "public_overrides/gtest/gtest.h",
116  ]
117  sources = [ "framework_light.cc" ]
118}
119
120# Unit test framework backend that redirects to GoogleTest.
121if (pw_unit_test_BACKEND != "") {
122  pw_source_set("googletest") {
123    public_configs = [ ":googletest_public_overrides_include_path" ]
124    public = [ "googletest_public_overrides/pw_unit_test/framework_backend.h" ]
125
126    public_deps = [
127      dir_pw_result,
128      dir_pw_status,
129      pw_unit_test_GOOGLETEST_BACKEND,
130    ]
131  }
132}
133
134pw_source_set("event_handler") {
135  public_configs = [ ":public_include_path" ]
136  public = [ "public/pw_unit_test/event_handler.h" ]
137}
138
139pw_source_set("status_macros") {
140  public_configs = [ ":public_include_path" ]
141  public = [ "public/pw_unit_test/status_macros.h" ]
142}
143
144# Unit test event handler that provides GoogleTest-style output.
145pw_source_set("googletest_style_event_handler") {
146  public_deps = [
147    ":event_handler",
148    dir_pw_preprocessor,
149  ]
150  public = [ "public/pw_unit_test/googletest_style_event_handler.h" ]
151  sources = [ "googletest_style_event_handler.cc" ]
152}
153
154pw_source_set("googletest_handler_adapter") {
155  public_configs = [ ":public_include_path" ]
156  public_deps = [
157    ":event_handler",
158    "$dir_pw_third_party/googletest",
159    dir_pw_preprocessor,
160  ]
161  public = [ "public/pw_unit_test/googletest_handler_adapter.h" ]
162  sources = [ "googletest_handler_adapter.cc" ]
163}
164
165pw_source_set("googletest_test_matchers") {
166  public_configs = [ ":public_include_path" ]
167  public = [ "public/pw_unit_test/googletest_test_matchers.h" ]
168  public_deps = [
169    "$dir_pw_third_party/googletest",
170    dir_pw_result,
171    dir_pw_status,
172  ]
173}
174
175pw_test("googletest_test_matchers_test") {
176  enable_if = pw_unit_test_BACKEND != "" &&
177              pw_unit_test_BACKEND != "$dir_pw_unit_test:light"
178  sources = [ "googletest_test_matchers_test.cc" ]
179  deps = [ ":googletest_test_matchers" ]
180}
181
182# Library providing an event handler which outputs human-readable text.
183pw_source_set("simple_printing_event_handler") {
184  public_deps = [
185    ":googletest_style_event_handler",
186    "$dir_pw_preprocessor",
187  ]
188  public = [ "public/pw_unit_test/simple_printing_event_handler.h" ]
189  sources = [ "simple_printing_event_handler.cc" ]
190}
191
192# Library providing a standard desktop main function for the pw_unit_test
193# framework. Unit test files can link against this library to build runnable
194# unit test executables.
195pw_source_set("simple_printing_main") {
196  testonly = pw_unit_test_TESTONLY
197  deps = [
198    ":pw_unit_test",
199    ":simple_printing_event_handler",
200    "$dir_pw_sys_io",
201    dir_pw_span,
202  ]
203  sources = [ "simple_printing_main.cc" ]
204}
205
206pw_source_set("printf_event_handler") {
207  public_deps = [
208    ":googletest_style_event_handler",
209    dir_pw_preprocessor,
210  ]
211  public = [ "public/pw_unit_test/printf_event_handler.h" ]
212}
213
214pw_source_set("printf_main") {
215  testonly = pw_unit_test_TESTONLY
216  deps = [
217    ":printf_event_handler",
218    ":pw_unit_test",
219  ]
220  sources = [ "printf_main.cc" ]
221}
222
223# Library providing an event handler which logs using pw_log.
224pw_source_set("logging_event_handler") {
225  public_deps = [
226    ":googletest_style_event_handler",
227    dir_pw_log,
228  ]
229  public = [ "public/pw_unit_test/logging_event_handler.h" ]
230  sources = [ "logging_event_handler.cc" ]
231}
232
233# Provides logging to either the light framework or an external GoogleTest.
234group("logging") {
235  public_deps = [ ":logging_event_handler" ]
236  deps = []
237  if (pw_unit_test_BACKEND != "$dir_pw_unit_test:light") {
238    deps += [ ":googletest_handler_adapter" ]
239  }
240}
241
242pw_source_set("logging_main") {
243  testonly = pw_unit_test_TESTONLY
244  deps = [
245    ":logging",
246    ":pw_unit_test",
247  ]
248  sources = [ "logging_main.cc" ]
249}
250
251# Library providing an event handler adapter that allows for multiple
252# event handlers to be registered for a given test run
253pw_source_set("multi_event_handler") {
254  public_deps = [ ":event_handler" ]
255  public = [ "public/pw_unit_test/multi_event_handler.h" ]
256}
257
258pw_test("multi_event_handler_test") {
259  sources = [ "multi_event_handler_test.cc" ]
260  deps = [
261    ":multi_event_handler",
262    ":pw_unit_test",
263  ]
264}
265
266# Library providing an event handler which outputs a test summary artifact.
267pw_source_set("test_record_event_handler") {
268  public_deps = [
269    ":googletest_style_event_handler",
270    "$dir_pw_json:builder",
271  ]
272  deps = [ "$dir_pw_assert" ]
273  public = [ "public/pw_unit_test/test_record_event_handler.h" ]
274  sources = [ "public/pw_unit_test/internal/test_record_trie.h" ]
275}
276
277pw_test("test_record_event_handler_test") {
278  sources = [ "test_record_event_handler_test.cc" ]
279  deps = [
280    ":pw_unit_test",
281    ":test_record_event_handler",
282  ]
283}
284
285config("rpc_service_backend_light") {
286  include_dirs = [ "rpc_light_public" ]
287}
288
289config("rpc_service_backend_gtest") {
290  include_dirs = [ "rpc_gtest_public" ]
291}
292
293pw_source_set("rpc_service") {
294  testonly = pw_unit_test_TESTONLY
295  public_configs = [ ":public_include_path" ]
296  public_deps = [
297    ":config",
298    ":event_handler",
299    ":pw_unit_test",
300    ":unit_test_proto.pwpb",
301    ":unit_test_proto.raw_rpc",
302    "$dir_pw_containers:vector",
303  ]
304  deps = [ dir_pw_log ]
305  public = [ "public/pw_unit_test/unit_test_service.h" ]
306  sources = [ "unit_test_service.cc" ]
307  defines = []
308
309  if (pw_unit_test_BACKEND == "$dir_pw_unit_test:light") {
310    public_configs += [ ":rpc_service_backend_light" ]
311    sources += [ "rpc_light_event_handler.cc" ]
312    public += [ "rpc_light_public/pw_unit_test/internal/rpc_event_handler.h" ]
313  } else {
314    public_configs += [ ":rpc_service_backend_gtest" ]
315    sources += [ "rpc_gtest_event_handler.cc" ]
316    public += [ "rpc_gtest_public/pw_unit_test/internal/rpc_event_handler.h" ]
317  }
318}
319
320pw_source_set("rpc_main") {
321  testonly = pw_unit_test_TESTONLY
322  public_deps = [ ":pw_unit_test" ]
323  deps = [
324    ":rpc_service",
325    "$dir_pw_rpc/system_server",
326    dir_pw_log,
327  ]
328  sources = [ "rpc_main.cc" ]
329}
330
331if (pw_unit_test_BACKEND == "$dir_pw_unit_test:light") {
332  pw_source_set("static_library_support") {
333    public_configs = [ ":public_include_path" ]
334    public_deps = [ pw_unit_test_BACKEND ]
335    public = [ "public/pw_unit_test/static_library_support.h" ]
336    sources = [ "static_library_support.cc" ]
337  }
338} else {
339  group("static_library_support") {
340  }
341}
342
343pw_executable("test_rpc_server") {
344  testonly = pw_unit_test_TESTONLY
345  sources = [ "test_rpc_server.cc" ]
346  deps = [
347    ":pw_unit_test",
348    ":rpc_service",
349    "$dir_pw_rpc/system_server",
350    "$dir_pw_rpc/system_server:socket",
351    dir_pw_log,
352  ]
353}
354
355pw_proto_library("unit_test_proto") {
356  sources = [ "pw_unit_test_proto/unit_test.proto" ]
357}
358
359pw_doc_group("docs") {
360  sources = [ "docs.rst" ]
361  other_deps = [ "py" ]
362}
363
364pw_test("metadata_only_test") {
365  extra_metadata = {
366    extra_key = "extra_value"
367  }
368}
369
370# pw_test_group produces the metadata file for its tests.
371pw_test_group("metadata_only_group") {
372  tests = [ ":metadata_only_test" ]
373  output_metadata = true
374}
375
376pw_python_action_test("test_group_metadata_test") {
377  _metadata_path =
378      rebase_path(get_label_info(":metadata_only_group", "target_out_dir")) +
379      "/metadata_only_group.testinfo.json"
380  testonly = pw_unit_test_TESTONLY
381  sources = [ "py/test_group_metadata_test.py" ]
382  args = [
383    "--metadata-path",
384    "$_metadata_path",
385  ]
386  deps = [ ":metadata_only_group" ]
387}
388
389pw_test("framework_test") {
390  sources = [ "framework_test.cc" ]
391  deps = [
392    dir_pw_assert,
393    dir_pw_result,
394    dir_pw_status,
395  ]
396
397  # TODO: https://pwbug.dev/325509758 - Passes but hangs on cleanup.
398  if (pw_build_EXECUTABLE_TARGET_TYPE == "pico_executable") {
399    enable_if = false
400  }
401}
402
403pw_test("framework_light_test") {
404  enable_if = pw_unit_test_BACKEND == "$dir_pw_unit_test:light"
405  sources = [ "framework_light_test.cc" ]
406  deps = [
407    "$dir_pw_string:builder",
408    dir_pw_status,
409  ]
410}
411
412pw_static_library("tests_in_archive") {
413  testonly = pw_unit_test_TESTONLY
414  sources = [
415    "static_library_archived_tests.cc",
416    "static_library_missing_archived_tests.cc",
417  ]
418  deps = [ ":pw_unit_test" ]
419  visibility = [ ":*" ]
420}
421
422pw_test("static_library_support_test") {
423  enable_if = pw_unit_test_BACKEND == "$dir_pw_unit_test:light"
424  sources = [ "static_library_support_test.cc" ]
425  deps = [
426    ":static_library_support",
427    ":tests_in_archive",
428    dir_pw_assert,
429  ]
430}
431
432pw_test_group("tests") {
433  tests = [
434    ":framework_test",
435    ":framework_light_test",
436    ":static_library_support_test",
437    ":multi_event_handler_test",
438    ":test_record_event_handler_test",
439  ]
440  if (dir_pw_third_party_googletest != "") {
441    tests += [ ":googletest_test_matchers_test" ]
442  }
443}
444