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