From 65463d86bb9ced97b6242b2be35db2600e227407 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Wed, 24 Jul 2024 15:37:41 +0000 Subject: [PATCH 01/35] Partial implementation to show ideal location for pw_unit_test overrides --- src/test_driver/efr32/BUILD.gn | 13 +++++-------- src/test_driver/efr32/args.gni | 4 ++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 947ed482f4622e..bf36495848c5b6 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -19,7 +19,6 @@ import("//build_overrides/pigweed.gni") import("${build_root}/config/defaults.gni") import("${efr32_sdk_build_root}/efr32_sdk.gni") -import("${efr32_sdk_build_root}/silabs_executable.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") import("${chip_root}/src/platform/device.gni") @@ -62,9 +61,8 @@ efr32_sdk("sdk") { ] } -silabs_executable("efr32_device_tests") { - output_name = "matter-silabs-device_tests.out" - +# This is the test runner. `pw_test` will dep this for each `silabs_executable` target. +source_set("efr32_test_main") { defines = [ "PW_RPC_ENABLED" ] sources = [ "${chip_root}/examples/common/pigweed/RpcService.cpp", @@ -83,7 +81,6 @@ silabs_executable("efr32_device_tests") { "$dir_pw_unit_test:rpc_service", "${chip_root}/config/efr32/lib/pw_rpc:pw_rpc", "${chip_root}/examples/common/pigweed:system_rpc_server", - "${chip_root}/src:tests", "${chip_root}/src/lib", "${chip_root}/src/lib/support:pw_tests_wrapper", "${chip_root}/src/platform/silabs/provision:provision-headers", @@ -115,12 +112,12 @@ silabs_executable("efr32_device_tests") { "-T" + rebase_path(ldscript, root_build_dir), "-Wl,--no-warn-rwx-segment", ] - - output_dir = root_out_dir } group("efr32") { - deps = [ ":efr32_device_tests" ] + deps = [ + "${chip_root}/src:tests", + ] } group("runner") { diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 71bf093f3e3a16..e950c0da1848fd 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -35,3 +35,7 @@ pw_assert_BACKEND = "$dir_pw_assert_log" pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:light" + +pw_unit_test_MAIN = "${chip_root}/src/test_driver/efr32:efr32_test_main" +pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" +pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" From e07e5191fdf4515dabc3ad7465573820571bb90d Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 06:21:41 +0000 Subject: [PATCH 02/35] Modifed silabs_executable and flashable_executable so that we can build multiple executables for both the chip unit tests and the pigweed internal unit tests. --- build/chip/chip_test_suite.gni | 58 ++++++++++++++++++- build/toolchain/flashable_executable.gni | 10 ++-- src/test_driver/efr32/BUILD.gn | 9 --- src/test_driver/efr32/args.gni | 2 +- .../efr32/test_executable_args.gni | 27 +++++++++ third_party/silabs/silabs_executable.gni | 12 ++-- 6 files changed, 96 insertions(+), 22 deletions(-) create mode 100644 src/test_driver/efr32/test_executable_args.gni diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 60f29346a48fa6..473355f0bd7f7e 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -19,6 +19,10 @@ import("${chip_root}/build/chip/chip_test.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") +if (chip_device_platform == "efr32") { + import("//test_executable_args.gni") +} + assert(chip_build_tests) # Define CHIP unit tests @@ -173,8 +177,58 @@ template("chip_test_suite") { } } } else { - group(_suite_name) { - deps = [ ":${_suite_name}.lib" ] + + # Specified a platform executable type. + if (defined(test_executable_output_name) && defined(invoker.test_sources)) { + tests = [] + + foreach(_test, invoker.test_sources) { + _test_name = string_replace(_test, ".cpp", "") + + _test_output_dir = "${root_out_dir}/tests" + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir + } + + pw_test(_test_name) { + # Forward certain varibles from the invoker + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) + + # Set `output_name` if the platform executable needs it. + if (!defined(test_executable_output_name_suffix)) { + test_executable_output_name_suffix = "" + } + output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix + + # Set `ldflags` if the platform executable needs it. + if (defined(test_executable_ldflags)) { ldflags = test_executable_ldflags } + + # Add the individual test source file (e.g. "TestSomething.cpp") + sources = [ _test ] + + output_dir = _test_output_dir + } + tests += [ _test_name ] + } + + group(_suite_name) { + deps = [] + foreach(_test, tests) { + deps += [ ":${_test}" ] + } + } + + } else { + + group(_suite_name) { + deps = [ ":${_suite_name}.lib" ] + } } } } diff --git a/build/toolchain/flashable_executable.gni b/build/toolchain/flashable_executable.gni index 6233d58382b43d..09578850d6ac2e 100644 --- a/build/toolchain/flashable_executable.gni +++ b/build/toolchain/flashable_executable.gni @@ -110,7 +110,7 @@ template("flashable_executable") { data_deps += invoker.data_deps } - write_runtime_deps = "${root_out_dir}/${flashbundle_name}" + write_runtime_deps = "${invoker.output_dir}/${flashbundle_name}" } if (defined(invoker.objcopy_image_name)) { @@ -124,8 +124,8 @@ template("flashable_executable") { objcopy = invoker.objcopy objcopy_convert(image_target) { - conversion_input = "${root_out_dir}/${invoker.output_name}" - conversion_output = "${root_out_dir}/${image_name}" + conversion_input = "${invoker.output_dir}/${invoker.output_name}" + conversion_output = "${invoker.output_dir}/${image_name}" conversion_target_format = image_format deps = [ ":$executable_target" ] } @@ -141,7 +141,7 @@ template("flashable_executable") { gen_flashing_script("$target_name.flashing") { flashing_script_generator = invoker.flashing_script_generator flashing_script_inputs = invoker.flashing_script_inputs - flashing_script_name = "$root_out_dir/${invoker.flashing_script_name}" + flashing_script_name = "${invoker.output_dir}/${invoker.flashing_script_name}" if (defined(invoker.flashing_options)) { flashing_options = invoker.flashing_options } else { @@ -155,7 +155,7 @@ template("flashable_executable") { flashing_options += [ "--application", - rebase_path(image_name, root_out_dir, root_out_dir), + rebase_path(image_name, invoker.output_dir, root_out_dir), ] data_deps = [ ":$image_target" ] } diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index bf36495848c5b6..2b22f176f85691 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -103,15 +103,6 @@ source_set("efr32_test_main") { ] include_dirs = [ "${chip_root}/examples/common/pigweed/efr32" ] - - ldscript = "${examples_common_plat_dir}/ldscripts/${silabs_family}.ld" - - inputs = [ ldscript ] - - ldflags = [ - "-T" + rebase_path(ldscript, root_build_dir), - "-Wl,--no-warn-rwx-segment", - ] } group("efr32") { diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index e950c0da1848fd..4178a6626be177 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -36,6 +36,6 @@ pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:light" -pw_unit_test_MAIN = "${chip_root}/src/test_driver/efr32:efr32_test_main" +pw_unit_test_MAIN = "//:efr32_test_main" pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" diff --git a/src/test_driver/efr32/test_executable_args.gni b/src/test_driver/efr32/test_executable_args.gni new file mode 100644 index 00000000000000..d33454b1927322 --- /dev/null +++ b/src/test_driver/efr32/test_executable_args.gni @@ -0,0 +1,27 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") # Defines chip_root +import("//build_overrides/efr32_sdk.gni") # Defines efr32_sdk_build_root +import("${efr32_sdk_build_root}/efr32_sdk.gni") # Defines silabs_family + +test_executable_output_name = "matter-silabs-device_tests_" +test_executable_output_name_suffix = ".out" + +_ldscript = "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" +test_executable_ldflags = [ + "-T" + rebase_path(_ldscript, root_build_dir), + "-Wl,--no-warn-rwx-segment", +] +#test_executable_inputs = [ _ldscript ] #++++ Is this needed? diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index a639a4d19ae62d..e48494b75ff1d5 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -47,6 +47,8 @@ template("generate_rps_file") { } template("silabs_executable") { + if (!defined(invoker.output_dir)) {invoker.output_dir = root_out_dir} + if (!defined(invoker.output_name)) {invoker.output_name = target_name + ".bin"} #++++ Added to support internal Pigweed tests that don't set output_name. output_base_name = get_path_info(invoker.output_name, "name") objcopy_image_name = output_base_name + ".s37" objcopy_image_format = "srec" @@ -68,7 +70,7 @@ template("silabs_executable") { ] copy(flashing_runtime_target) { sources = flashing_script_inputs - outputs = [ "${root_out_dir}/{{source_file_part}}" ] + outputs = [ "${invoker.output_dir}/${output_base_name}--{{source_file_part}}" ] #++++ FIXME: Can we remove the output_base_name-- prefix?. } flashing_script_generator = @@ -88,8 +90,8 @@ template("silabs_executable") { hex_image_name = output_base_name + ".hex" hex_target_name = target_name + ".hex" objcopy_convert(hex_target_name) { - conversion_input = "${root_out_dir}/${invoker.output_name}" - conversion_output = "${root_out_dir}/${hex_image_name}" + conversion_input = "${invoker.output_dir}/${invoker.output_name}" + conversion_output = "${invoker.output_dir}/${hex_image_name}" conversion_target_format = "ihex" deps = [ ":$executable_target" ] } @@ -97,8 +99,8 @@ template("silabs_executable") { if (use_rps_extension) { rps_target_name = target_name + ".rps" generate_rps_file(rps_target_name) { - conversion_input = "${root_out_dir}/${objcopy_image_name}" - conversion_output = "${root_out_dir}/${flashing_image_name}" + conversion_input = "${invoker.output_dir}/${objcopy_image_name}" + conversion_output = "${invoker.output_dir}/${flashing_image_name}" deps = [ ":$executable_target", ":$flash_target_name.image", From d3aaaebc51d2546062cec6d898033848e5d149af Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 06:23:40 +0000 Subject: [PATCH 03/35] Formatting change --- src/test_driver/efr32/BUILD.gn | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 2b22f176f85691..3d9742036abe7c 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -106,9 +106,7 @@ source_set("efr32_test_main") { } group("efr32") { - deps = [ - "${chip_root}/src:tests", - ] + deps = [ "${chip_root}/src:tests" ] } group("runner") { From 432a889af6ec53be6425f14d40ecfeeea01cb6dc Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 06:25:09 +0000 Subject: [PATCH 04/35] Changed order of variable declarations --- src/test_driver/efr32/args.gni | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 4178a6626be177..1a8ca1e71263a4 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -36,6 +36,6 @@ pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:light" -pw_unit_test_MAIN = "//:efr32_test_main" pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" +pw_unit_test_MAIN = "//:efr32_test_main" From 83bbb12375aa824b21508fdc6d9e2dd7c25312dd Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 07:30:54 +0000 Subject: [PATCH 05/35] Removed unused chip_test.gni --- build/chip/chip_test.gni | 71 ---------------------------------- build/chip/chip_test_suite.gni | 1 - 2 files changed, 72 deletions(-) delete mode 100644 build/chip/chip_test.gni diff --git a/build/chip/chip_test.gni b/build/chip/chip_test.gni deleted file mode 100644 index b5b32f24d0b0b7..00000000000000 --- a/build/chip/chip_test.gni +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/build.gni") -import("//build_overrides/chip.gni") -import("//build_overrides/pigweed.gni") - -import("$dir_pw_build/python_action.gni") - -import("${chip_root}/build/chip/tests.gni") -import("${chip_root}/src/platform/device.gni") -import("${dir_pw_unit_test}/test.gni") - -assert(chip_build_tests) - -if (chip_link_tests) { - template("chip_test") { - _test_name = target_name - - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - executable(_test_name) { - forward_variables_from(invoker, "*", [ "output_dir" ]) - output_dir = _test_output_dir - } - - group(_test_name + ".lib") { - } - - if (chip_pw_run_tests) { - pw_python_action(_test_name + ".run") { - deps = [ ":${_test_name}" ] - inputs = [ pw_unit_test_AUTOMATIC_RUNNER ] - module = "pw_unit_test.test_runner" - python_deps = [ - "$dir_pw_cli/py", - "$dir_pw_unit_test/py", - ] - args = [ - "--runner", - rebase_path(pw_unit_test_AUTOMATIC_RUNNER, root_build_dir), - "--test", - rebase_path("$_test_output_dir/$_test_name", root_build_dir), - ] - stamp = true - } - } - } -} else { - template("chip_test") { - group(target_name) { - } - group(target_name + ".lib") { - } - not_needed(invoker, "*") - } -} diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 473355f0bd7f7e..f8d3bddc80f678 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -15,7 +15,6 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("${chip_root}/build/chip/chip_test.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") From 193086006514b407c7637811ff64af082701ff37 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 07:41:25 +0000 Subject: [PATCH 06/35] Added import to get dir_pw_unit_test --- build/chip/chip_test_suite.gni | 1 + 1 file changed, 1 insertion(+) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index f8d3bddc80f678..d22b39d26ae7a8 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") From bf9ea481ddc0e194eaa627c5332a5cbe585e8daa Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 18:22:34 +0000 Subject: [PATCH 07/35] Allowed variables for platform-specific building to be overridden in args.gni --- build/chip/chip_test_suite.gni | 26 +++++++++--------- src/test_driver/efr32/args.gni | 9 +++++++ .../efr32/test_executable_args.gni | 27 ------------------- 3 files changed, 21 insertions(+), 41 deletions(-) delete mode 100644 src/test_driver/efr32/test_executable_args.gni diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index d22b39d26ae7a8..29ace84cb5df84 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -19,12 +19,15 @@ import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") -if (chip_device_platform == "efr32") { - import("//test_executable_args.gni") -} - assert(chip_build_tests) +declare_args() { + # These may be overridden in args.gni to build platform-specific test binaries. + test_executable_output_name = "" + test_executable_output_name_suffix = "" + test_executable_ldflags = [] +} + # Define CHIP unit tests # # Simple usage @@ -179,7 +182,7 @@ template("chip_test_suite") { } else { # Specified a platform executable type. - if (defined(test_executable_output_name) && defined(invoker.test_sources)) { + if (test_executable_output_name != "" && defined(invoker.test_sources)) { tests = [] foreach(_test, invoker.test_sources) { @@ -191,7 +194,7 @@ template("chip_test_suite") { } pw_test(_test_name) { - # Forward certain varibles from the invoker + # Forward certain varibles from the invoker. forward_variables_from(invoker, [ "deps", @@ -200,16 +203,11 @@ template("chip_test_suite") { "configs", ]) - # Set `output_name` if the platform executable needs it. - if (!defined(test_executable_output_name_suffix)) { - test_executable_output_name_suffix = "" - } + # Set variables that the platform executable may need. output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix + ldflags = test_executable_ldflags - # Set `ldflags` if the platform executable needs it. - if (defined(test_executable_ldflags)) { ldflags = test_executable_ldflags } - - # Add the individual test source file (e.g. "TestSomething.cpp") + # Add the individual test source file (e.g. "TestSomething.cpp"). sources = [ _test ] output_dir = _test_output_dir diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 1a8ca1e71263a4..33962174e29645 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -17,6 +17,7 @@ import("//build_overrides/pigweed.gni") import("${chip_root}/config/efr32/lib/pw_rpc/pw_rpc.gni") import("${chip_root}/examples/platform/silabs/args.gni") import("${chip_root}/src/platform/silabs/efr32/args.gni") +import("${chip_root}/third_party/silabs/silabs_board.gni") # Defines silabs_family silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") @@ -39,3 +40,11 @@ pw_unit_test_BACKEND = "$dir_pw_unit_test:light" pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" pw_unit_test_MAIN = "//:efr32_test_main" + +test_executable_output_name = "matter-silabs-device_tests_" +test_executable_output_name_suffix = ".out" +_ldscript = "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" +test_executable_ldflags = [ + "-T" + rebase_path(_ldscript, root_build_dir), + "-Wl,--no-warn-rwx-segment", +] diff --git a/src/test_driver/efr32/test_executable_args.gni b/src/test_driver/efr32/test_executable_args.gni deleted file mode 100644 index d33454b1927322..00000000000000 --- a/src/test_driver/efr32/test_executable_args.gni +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/chip.gni") # Defines chip_root -import("//build_overrides/efr32_sdk.gni") # Defines efr32_sdk_build_root -import("${efr32_sdk_build_root}/efr32_sdk.gni") # Defines silabs_family - -test_executable_output_name = "matter-silabs-device_tests_" -test_executable_output_name_suffix = ".out" - -_ldscript = "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" -test_executable_ldflags = [ - "-T" + rebase_path(_ldscript, root_build_dir), - "-Wl,--no-warn-rwx-segment", -] -#test_executable_inputs = [ _ldscript ] #++++ Is this needed? From 41e4476f81f5dfe290f9ef57bb732096ab6d5f69 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 18:43:19 +0000 Subject: [PATCH 08/35] Removed define check of test_sources. Undid removal of chip_test.gni --- build/chip/chip_test.gni | 71 ++++++++++++++++++++++++++++++++++ build/chip/chip_test_suite.gni | 51 +++++++++++------------- 2 files changed, 94 insertions(+), 28 deletions(-) create mode 100644 build/chip/chip_test.gni diff --git a/build/chip/chip_test.gni b/build/chip/chip_test.gni new file mode 100644 index 00000000000000..b5b32f24d0b0b7 --- /dev/null +++ b/build/chip/chip_test.gni @@ -0,0 +1,71 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/python_action.gni") + +import("${chip_root}/build/chip/tests.gni") +import("${chip_root}/src/platform/device.gni") +import("${dir_pw_unit_test}/test.gni") + +assert(chip_build_tests) + +if (chip_link_tests) { + template("chip_test") { + _test_name = target_name + + _test_output_dir = "${root_out_dir}/tests" + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir + } + + executable(_test_name) { + forward_variables_from(invoker, "*", [ "output_dir" ]) + output_dir = _test_output_dir + } + + group(_test_name + ".lib") { + } + + if (chip_pw_run_tests) { + pw_python_action(_test_name + ".run") { + deps = [ ":${_test_name}" ] + inputs = [ pw_unit_test_AUTOMATIC_RUNNER ] + module = "pw_unit_test.test_runner" + python_deps = [ + "$dir_pw_cli/py", + "$dir_pw_unit_test/py", + ] + args = [ + "--runner", + rebase_path(pw_unit_test_AUTOMATIC_RUNNER, root_build_dir), + "--test", + rebase_path("$_test_output_dir/$_test_name", root_build_dir), + ] + stamp = true + } + } + } +} else { + template("chip_test") { + group(target_name) { + } + group(target_name + ".lib") { + } + not_needed(invoker, "*") + } +} diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 29ace84cb5df84..80950626d1a5ad 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -16,6 +16,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("//build_overrides/pigweed.gni") +import("${chip_root}/build/chip/chip_test.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") @@ -77,13 +78,9 @@ template("chip_test_suite") { # Ensures that the common library has sources containing both common # and individual unit tests. - if (!defined(invoker.sources)) { - invoker.sources = [] - } - - if (defined(invoker.test_sources)) { - invoker.sources += invoker.test_sources - } + if (!defined(invoker.sources)) { invoker.sources = [] } + if (!defined(invoker.test_sources)) { invoker.test_sources = [] } + invoker.sources += invoker.test_sources if (chip_build_test_static_libraries) { _target_type = "static_library" @@ -112,29 +109,27 @@ template("chip_test_suite") { if (chip_link_tests) { tests = [] - if (defined(invoker.test_sources)) { - foreach(_test, invoker.test_sources) { - _test_name = string_replace(_test, ".cpp", "") + foreach(_test, invoker.test_sources) { + _test_name = string_replace(_test, ".cpp", "") - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } + _test_output_dir = "${root_out_dir}/tests" + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir + } - pw_test(_test_name) { - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - public_deps += [ ":${_suite_name}.lib" ] - sources = [ _test ] - output_dir = _test_output_dir - } - tests += [ _test_name ] + pw_test(_test_name) { + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) + public_deps += [ ":${_suite_name}.lib" ] + sources = [ _test ] + output_dir = _test_output_dir } + tests += [ _test_name ] } if (defined(invoker.tests)) { @@ -182,7 +177,7 @@ template("chip_test_suite") { } else { # Specified a platform executable type. - if (test_executable_output_name != "" && defined(invoker.test_sources)) { + if (test_executable_output_name != "") { tests = [] foreach(_test, invoker.test_sources) { From 7e22edc6adcd56ab41ad5d6336d1aa6f32c4020a Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 18:50:38 +0000 Subject: [PATCH 09/35] Comment updates --- src/test_driver/efr32/args.gni | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 33962174e29645..51d88a7e6bdf90 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -37,10 +37,12 @@ pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:light" +# Override the executable type and the target for the test main. pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" pw_unit_test_MAIN = "//:efr32_test_main" +# Additional variables needed by silabs_executable that must be passed in to pw_test. test_executable_output_name = "matter-silabs-device_tests_" test_executable_output_name_suffix = ".out" _ldscript = "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" From 685b1cc6d512b4b3084099561b546d624efd9098 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Thu, 25 Jul 2024 23:00:17 +0000 Subject: [PATCH 10/35] Removed chip_link_tests == false branch. pw_test is now used for this case as well. --- build/chip/chip_test_suite.gni | 148 +++++++++++++-------------------- src/test_driver/efr32/args.gni | 1 - 2 files changed, 56 insertions(+), 93 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 80950626d1a5ad..9ba467b4288d5d 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -106,18 +106,54 @@ template("chip_test_suite") { public_deps += [ "${chip_root}/src/platform/logging:default" ] } } - if (chip_link_tests) { - tests = [] - foreach(_test, invoker.test_sources) { - _test_name = string_replace(_test, ".cpp", "") + tests = [] + foreach(_test, invoker.test_sources) { + _test_name = string_replace(_test, ".cpp", "") + + _test_output_dir = "${root_out_dir}/tests" + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir + } + + pw_test(_test_name) { + # Forward certain varibles from the invoker. + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) + + # Link to the common library for this test suite. + if (chip_link_tests) { + public_deps += [ ":${_suite_name}.lib" ] + } + + # Set variables that the platform executable may need. + if (test_executable_output_name != "") { + output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix + } + ldflags = test_executable_ldflags + + # Add the individual test source file (e.g. "TestSomething.cpp"). + sources = [ _test ] + + output_dir = _test_output_dir + } + tests += [ _test_name ] + } + + if (defined(invoker.tests)) { + foreach(_test, invoker.tests) { _test_output_dir = "${root_out_dir}/tests" if (defined(invoker.output_dir)) { _test_output_dir = invoker.output_dir } - pw_test(_test_name) { + pw_test(_test) { forward_variables_from(invoker, [ "deps", @@ -126,101 +162,29 @@ template("chip_test_suite") { "configs", ]) public_deps += [ ":${_suite_name}.lib" ] - sources = [ _test ] + test_main = "" + sources = [ + "${_test}.cpp", + "${_test}Driver.cpp", + ] output_dir = _test_output_dir } - tests += [ _test_name ] + tests += [ _test ] } + } - if (defined(invoker.tests)) { - foreach(_test, invoker.tests) { - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - pw_test(_test) { - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - public_deps += [ ":${_suite_name}.lib" ] - test_main = "" - sources = [ - "${_test}.cpp", - "${_test}Driver.cpp", - ] - output_dir = _test_output_dir - } - tests += [ _test ] - } + group(_suite_name) { + deps = [] + foreach(_test, tests) { + deps += [ ":${_test}" ] } + } - group(_suite_name) { + if (chip_pw_run_tests) { + group("${_suite_name}_run") { deps = [] foreach(_test, tests) { - deps += [ ":${_test}" ] - } - } - - if (chip_pw_run_tests) { - group("${_suite_name}_run") { - deps = [] - foreach(_test, tests) { - deps += [ ":${_test}.run" ] - } - } - } - } else { - - # Specified a platform executable type. - if (test_executable_output_name != "") { - tests = [] - - foreach(_test, invoker.test_sources) { - _test_name = string_replace(_test, ".cpp", "") - - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - pw_test(_test_name) { - # Forward certain varibles from the invoker. - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - - # Set variables that the platform executable may need. - output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix - ldflags = test_executable_ldflags - - # Add the individual test source file (e.g. "TestSomething.cpp"). - sources = [ _test ] - - output_dir = _test_output_dir - } - tests += [ _test_name ] - } - - group(_suite_name) { - deps = [] - foreach(_test, tests) { - deps += [ ":${_test}" ] - } - } - - } else { - - group(_suite_name) { - deps = [ ":${_suite_name}.lib" ] + deps += [ ":${_test}.run" ] } } } diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 51d88a7e6bdf90..4e576924f9af50 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -25,7 +25,6 @@ chip_enable_pw_rpc = true chip_build_tests = true chip_enable_openthread = true chip_openthread_ftd = false # use mtd as it is smaller. -chip_monolithic_tests = true openthread_external_platform = "${chip_root}/third_party/openthread/platforms/efr32:libopenthread-efr32" From 3a6250394614dfec26a75234077a1a0f1e76c2a5 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Fri, 26 Jul 2024 01:11:21 +0000 Subject: [PATCH 11/35] Updated test runner script. Removed unneeded NL stuff. --- .github/.wordlist.txt | 2 - scripts/build/builders/efr32.py | 4 +- scripts/build/builders/host.py | 2 +- src/test_driver/efr32/BUILD.gn | 4 +- src/test_driver/efr32/README.md | 12 +- src/test_driver/efr32/py/BUILD.gn | 26 ---- .../efr32/py/nl_test_runner/nl_test_runner.py | 141 ------------------ .../__init__.py | 0 .../efr32/py/pw_test_runner/pw_test_runner.py | 43 ++++-- src/test_driver/efr32/py/setup.cfg | 2 +- 10 files changed, 43 insertions(+), 193 deletions(-) delete mode 100644 src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py rename src/test_driver/efr32/py/{nl_test_runner => pw_test_runner}/__init__.py (100%) diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 25c9ef8daa6594..84bafaad1cab4c 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -943,8 +943,6 @@ NitricOxideConcentrationMeasurement NitrogenDioxideConcentrationMeasurement nl nltest -NLUnitTest -NLUnitTests nmcli nmtui noc diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 3972dc7bb48eff..89f81e86fc93ef 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -269,11 +269,11 @@ def build_outputs(self): if self.app == Efr32App.UNIT_TEST: # Include test runner python wheels - for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_nl_test_runner_wheels')): + for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_pw_test_runner_wheels')): for file in files: yield BuilderOutput( os.path.join(root, file), - os.path.join("chip_nl_test_runner_wheels", file)) + os.path.join("chip_pw_test_runner_wheels", file)) # Figure out flash bundle files and build accordingly with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 79d6b849a32aeb..62069ccc90050f 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -216,7 +216,7 @@ def OutputNames(self): elif self == HostApp.PYTHON_BINDINGS: yield 'controller/python' # Directory containing WHL files elif self == HostApp.EFR32_TEST_RUNNER: - yield 'chip_nl_test_runner_wheels' + yield 'chip_pw_test_runner_wheels' elif self == HostApp.TV_CASTING: yield 'chip-tv-casting-app' yield 'chip-tv-casting-app.map' diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 3d9742036abe7c..0aaf7fe903a635 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -111,8 +111,8 @@ group("efr32") { group("runner") { deps = [ - "${efr32_project_dir}/py:nl_test_runner.install", - "${efr32_project_dir}/py:nl_test_runner_wheel", + "${efr32_project_dir}/py:pw_test_runner.install", + "${efr32_project_dir}/py:pw_test_runner_wheel", ] } diff --git a/src/test_driver/efr32/README.md b/src/test_driver/efr32/README.md index c36812e484fdee..907ea5a5054ad2 100644 --- a/src/test_driver/efr32/README.md +++ b/src/test_driver/efr32/README.md @@ -1,6 +1,6 @@ #CHIP EFR32 Test Driver -This builds and runs the NLUnitTest on the efr32 device +This builds and runs the unit tests on the efr32 device
@@ -14,7 +14,7 @@ This builds and runs the NLUnitTest on the efr32 device ## Introduction -This builds a test binary which contains the NLUnitTests and can be flashed onto +This builds a set of test binaries which contain the unit tests and can be flashed onto a device. The device is controlled using the included RPCs, through the python test runner. @@ -83,7 +83,7 @@ Or build using build script from the root ``` cd - ./scripts/build/build_examples.py --target linux-x64-nl-test-runner build + ./scripts/build/build_examples.py --target linux-x64-pw-test-runner build ``` The runner will be installed into the venv and python wheels will be packaged in @@ -92,7 +92,7 @@ the output folder for deploying. Then the python wheels need to installed using pip3. ``` - pip3 install out/debug/chip_nl_test_runner_wheels/*.whl + pip3 install out/debug/chip_pw_test_runner_wheels/*.whl ``` Other python libraries may need to be installed such as @@ -101,8 +101,8 @@ Other python libraries may need to be installed such as pip3 install pyserial ``` -- To run the tests: +- To run all tests: ``` - python -m nl_test_runner.nl_test_runner -d /dev/ttyACM1 -f out/debug/matter-silabs-device_tests.s37 -o out.log + python -m pw_test_runner.pw_test_runner -d /dev/ttyACM1 -f out/debug -o out.log ``` diff --git a/src/test_driver/efr32/py/BUILD.gn b/src/test_driver/efr32/py/BUILD.gn index 615fe5603d00c9..6f36e8f3e4a839 100644 --- a/src/test_driver/efr32/py/BUILD.gn +++ b/src/test_driver/efr32/py/BUILD.gn @@ -19,32 +19,6 @@ import("$dir_pw_build/python.gni") import("$dir_pw_build/python_dist.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") -# TODO [PW_MIGRATION]: remove nl test runner script once transition away from nlunit-test is completed -pw_python_package("nl_test_runner") { - setup = [ - "pyproject.toml", - "setup.cfg", - "setup.py", - ] - - sources = [ - "nl_test_runner/__init__.py", - "nl_test_runner/nl_test_runner.py", - ] - - python_deps = [ - "$dir_pw_hdlc/py", - "$dir_pw_protobuf_compiler/py", - "$dir_pw_rpc/py", - "${chip_root}/src/test_driver/efr32:nl_test_service.python", - ] -} - -pw_python_wheels("nl_test_runner_wheel") { - packages = [ ":nl_test_runner" ] - directory = "$root_out_dir/chip_nl_test_runner_wheels" -} - pw_python_package("pw_test_runner") { setup = [ "pw_test_runner/pyproject.toml", diff --git a/src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py b/src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py deleted file mode 100644 index 0fdb2e7aea7e3d..00000000000000 --- a/src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py +++ /dev/null @@ -1,141 +0,0 @@ -# -# Copyright (c) 2021 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -import argparse -import logging -import subprocess -import sys -import time -from typing import Any - -import serial # type: ignore -from pw_hdlc import rpc - -# RPC Protos -from nl_test_service import nl_test_pb2 # isort:skip - -PW_LOG = logging.getLogger(__name__) - -PROTOS = [nl_test_pb2] - - -class colors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - - -PASS_STRING = colors.OKGREEN + u'\N{check mark}' + colors.ENDC -FAIL_STRING = colors.FAIL + 'FAILED' + colors.ENDC - - -def _parse_args(): - """Parses and returns the command line arguments.""" - parser = argparse.ArgumentParser( - description="CHIP on device unit test runner.") - parser.add_argument('-d', '--device', help='the serial port to use') - parser.add_argument('-b', - '--baudrate', - type=int, - default=115200, - help='the baud rate to use') - parser.add_argument('-f', '--flash_image', - help='a firmware image which will be flashed berfore runnning the test') - parser.add_argument( - '-o', - '--output', - type=argparse.FileType('wb'), - default=sys.stdout.buffer, - help=('The file to which to write device output (HDLC channel 1); ' - 'provide - or omit for stdout.')) - return parser.parse_args() - - -def flash_device(device: str, flash_image: str, **kwargs): - """flashes the EFR32 device using commander""" - err = subprocess.call( - ['commander', 'flash', '--device', 'EFR32', flash_image]) - if err: - raise Exception("flash failed") - - -def get_hdlc_rpc_client(device: str, baudrate: int, output: Any, **kwargs): - """Get the HdlcRpcClient based on arguments.""" - serial_device = serial.Serial(device, baudrate, timeout=1) - reader = rpc.SerialReader(serial_device, 8192) - write = serial_device.write - return rpc.HdlcRpcClient(reader, PROTOS, rpc.default_channels(write), - lambda data: rpc.write_to_file(data, output)) - - -def runner(client) -> int: - """ Run the tests""" - def on_error_callback(call_object, error): - raise Exception("Error running test RPC: {}".format(error)) - - rpc = client.client.channel(1).rpcs.chip.rpc.NlTest.Run - invoke = rpc.invoke(rpc.request(), on_error=on_error_callback) - - total_failed = 0 - total_run = 0 - for streamed_data in invoke.get_responses(): - if streamed_data.HasField("test_suite_start"): - print("\n{}".format( - colors.HEADER + streamed_data.test_suite_start.suite_name) + colors.ENDC) - if streamed_data.HasField("test_case_run"): - print("\t{}: {}".format(streamed_data.test_case_run.test_case_name, - FAIL_STRING if streamed_data.test_case_run.failed else PASS_STRING)) - if streamed_data.HasField("test_suite_tests_run_summary"): - total_run += streamed_data.test_suite_tests_run_summary.total_count - total_failed += streamed_data.test_suite_tests_run_summary.failed_count - print("{}Total tests failed: {} of {}".format( - colors.OKGREEN if streamed_data.test_suite_tests_run_summary.failed_count == 0 else colors.FAIL, - streamed_data.test_suite_tests_run_summary.failed_count, - streamed_data.test_suite_tests_run_summary.total_count) + colors.ENDC) - if streamed_data.HasField("test_suite_asserts_summary"): - print("{}Total asserts failed: {} of {}".format( - colors.OKGREEN if streamed_data.test_suite_asserts_summary.failed_count == 0 else colors.FAIL, - streamed_data.test_suite_asserts_summary.failed_count, - streamed_data.test_suite_asserts_summary.total_count) + colors.ENDC) - for step in ["test_suite_setup", "test_suite_teardown", "test_case_initialize", "test_case_terminate"]: - if streamed_data.HasField(step): - print(colors.OKCYAN + "\t{}: {}".format(step, - FAIL_STRING if getattr(streamed_data, step).failed else PASS_STRING)) - print(colors.OKBLUE + colors.BOLD + - "\n\nAll tests completed" + colors.ENDC) - print("{}Total of all tests failed: {} of {}".format( - colors.OKGREEN if total_failed == 0 else colors.FAIL, - total_failed, total_run) + colors.ENDC) - return total_failed - - -def main() -> int: - args = _parse_args() - if args.flash_image: - flash_device(**vars(args)) - time.sleep(1) # Give time for device to boot - with get_hdlc_rpc_client(**vars(args)) as client: - return runner(client) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/src/test_driver/efr32/py/nl_test_runner/__init__.py b/src/test_driver/efr32/py/pw_test_runner/__init__.py similarity index 100% rename from src/test_driver/efr32/py/nl_test_runner/__init__.py rename to src/test_driver/efr32/py/pw_test_runner/__init__.py diff --git a/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py index c8fca307f015ff..9ec8142ab5ebd5 100644 --- a/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py +++ b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py @@ -16,6 +16,7 @@ # import argparse +import glob import logging import os import subprocess @@ -60,7 +61,7 @@ def _parse_args(): parser.add_argument( "-f", "--flash_image", - help="a firmware image which will be flashed berfore runnning the test", + help="A firmware image which will be flashed berfore runnning the test. Or a directory containing firmware images, each of which will be flashed and then run.", ) parser.add_argument( "-o", @@ -75,7 +76,7 @@ def _parse_args(): return parser.parse_args() -def flash_device(device: str, flash_image: str, **kwargs): +def flash_device(device: str, flash_image: str): """flashes the EFR32 device using commander""" err = subprocess.call( ["commander", "flash", "--device", "EFR32", flash_image]) @@ -96,23 +97,41 @@ def get_hdlc_rpc_client(device: str, baudrate: int, output: Any, **kwargs): ) -def runner(client: rpc.HdlcRpcClient) -> int: - """Run the tests""" +def run(args) -> int: + """Run the tests. Return the number of failed tests.""" + with get_hdlc_rpc_client(**vars(args)) as client: + test_records = run_tests(client.rpcs()) + return len(test_records.failing_tests) - test_records = run_tests(client.rpcs()) - return len(test_records.failing_tests) +def list_images(flash_directory: str) -> list[str]: + filenames: list[str] = glob.glob(os.path.join(flash_directory, "*.s37")) + return list(map(lambda x: os.path.join(flash_directory, x), filenames)) def main() -> int: args = _parse_args() - if args.flash_image: - flash_device(**vars(args)) - time.sleep(1) # Give time for device to boot - - with get_hdlc_rpc_client(**vars(args)) as client: - return runner(client) + failures = 0 + if args.flash_image: + if os.path.isdir(args.flash_image): + images = list_images(args.flash_image) + if not images: + raise Exception(f"No images found in `{args.flash_image}`") + elif os.path.isfile(args.flash_image): + images = [args.flash_image] + else: + raise Exception(f"File or directory not found `{args.flash_image}`") + + for image in images: + flash_device(args.device, image) + time.sleep(1) # Give time for device to boot + + failures += run(args) + else: # No image provided. Just run what's on the device. + failures += run(args) + + return failures if __name__ == "__main__": sys.exit(main()) diff --git a/src/test_driver/efr32/py/setup.cfg b/src/test_driver/efr32/py/setup.cfg index 77108ab8288747..cb949a38092b07 100644 --- a/src/test_driver/efr32/py/setup.cfg +++ b/src/test_driver/efr32/py/setup.cfg @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. [metadata] -name = nl_test_runner +name = pw_test_runner version = 0.0.1 [options] From 890b68f210ce5ec03fe1128510d63a79b0cef682 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sat, 27 Jul 2024 14:16:27 +0000 Subject: [PATCH 12/35] Comment updates --- src/test_driver/efr32/args.gni | 2 +- third_party/silabs/silabs_executable.gni | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 4e576924f9af50..a6e40ae85c99bb 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -36,7 +36,7 @@ pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:light" -# Override the executable type and the target for the test main. +# Override the executable type and the test main's target. pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" pw_unit_test_MAIN = "//:efr32_test_main" diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index e48494b75ff1d5..be6f599c6b1ff2 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -48,7 +48,7 @@ template("generate_rps_file") { template("silabs_executable") { if (!defined(invoker.output_dir)) {invoker.output_dir = root_out_dir} - if (!defined(invoker.output_name)) {invoker.output_name = target_name + ".bin"} #++++ Added to support internal Pigweed tests that don't set output_name. + if (!defined(invoker.output_name)) {invoker.output_name = target_name + ".bin"} output_base_name = get_path_info(invoker.output_name, "name") objcopy_image_name = output_base_name + ".s37" objcopy_image_format = "srec" From 3a46c5d86e9140187a9d04df10d2a3f8d934f0fa Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sat, 27 Jul 2024 18:20:45 +0000 Subject: [PATCH 13/35] Add the common library as a dep if chip_link_tests is false. Applied changes to the deprecated user-defined-driver feature in case anyone is still using it. --- build/chip/chip_test_suite.gni | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 9ba467b4288d5d..8db07eac287720 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -146,33 +146,6 @@ template("chip_test_suite") { tests += [ _test_name ] } - if (defined(invoker.tests)) { - foreach(_test, invoker.tests) { - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - pw_test(_test) { - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - public_deps += [ ":${_suite_name}.lib" ] - test_main = "" - sources = [ - "${_test}.cpp", - "${_test}Driver.cpp", - ] - output_dir = _test_output_dir - } - tests += [ _test ] - } - } - group(_suite_name) { deps = [] foreach(_test, tests) { From 398d2adc6933e5ece12b65f11b09c09a357645a2 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sat, 27 Jul 2024 18:21:21 +0000 Subject: [PATCH 14/35] Same as previous commit. --- build/chip/chip_test_suite.gni | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 8db07eac287720..3f5d426c2ca6f2 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -146,11 +146,60 @@ template("chip_test_suite") { tests += [ _test_name ] } + # Deprecated usage (user-defined driver) + if (defined(invoker.tests)) { + foreach(_test, invoker.tests) { + _test_output_dir = "${root_out_dir}/tests" + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir + } + + pw_test(_test) { + # Forward certain varibles from the invoker. + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) + + # Link to the common library for this test suite. + if (chip_link_tests) { + public_deps += [ ":${_suite_name}.lib" ] + } + + # Set variables that the platform executable may need. + if (test_executable_output_name != "") { + output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix + } + ldflags = test_executable_ldflags + + # Add the individual test source file (e.g. "TestSomething.cpp") and its driver. + sources = [ + "${_test}.cpp", + "${_test}Driver.cpp", + ] + + test_main = "" + output_dir = _test_output_dir + } + tests += [ _test ] + } + } + group(_suite_name) { deps = [] + + # Add each individual unit test. foreach(_test, tests) { deps += [ ":${_test}" ] } + + # Add the common library if none of the above tests did. + if (!chip_link_tests) { + deps += [ ":${_suite_name}.lib" ] + } } if (chip_pw_run_tests) { From 62f1ac2441cab4a7b534892d8feb0a8ef597f185 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sat, 27 Jul 2024 18:38:38 +0000 Subject: [PATCH 15/35] Comment update --- third_party/silabs/silabs_executable.gni | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index be6f599c6b1ff2..ce91a2ad0aff24 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -70,7 +70,7 @@ template("silabs_executable") { ] copy(flashing_runtime_target) { sources = flashing_script_inputs - outputs = [ "${invoker.output_dir}/${output_base_name}--{{source_file_part}}" ] #++++ FIXME: Can we remove the output_base_name-- prefix?. + outputs = [ "${invoker.output_dir}/${output_base_name}--{{source_file_part}}" ] #++++ FIXME: Can we avoid adding the "output_base_name--" prefix?. } flashing_script_generator = From 2d9629a348ee318cb7898b99fd6e6a97051ab7a6 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sun, 28 Jul 2024 02:53:53 +0000 Subject: [PATCH 16/35] Set default for output_dir --- build/toolchain/flashable_executable.gni | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/toolchain/flashable_executable.gni b/build/toolchain/flashable_executable.gni index 09578850d6ac2e..91eba914040f3e 100644 --- a/build/toolchain/flashable_executable.gni +++ b/build/toolchain/flashable_executable.gni @@ -86,6 +86,8 @@ template("gen_flashing_script") { template("flashable_executable") { executable_target = "$target_name.executable" + if (!defined(invoker.output_dir)) {invoker.output_dir = root_out_dir} + if (defined(invoker.flashing_script_name)) { # Generating the flashing script is the final target. final_target = "$target_name.flashing" From bd4a54fc156b8519f1a55c9f9518e585e7f687e2 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 29 Jul 2024 14:31:57 +0000 Subject: [PATCH 17/35] Removed deprecated features --- build/chip/chip_test.gni | 71 ---------------------------------- build/chip/chip_test_suite.gni | 65 ------------------------------- 2 files changed, 136 deletions(-) delete mode 100644 build/chip/chip_test.gni diff --git a/build/chip/chip_test.gni b/build/chip/chip_test.gni deleted file mode 100644 index b5b32f24d0b0b7..00000000000000 --- a/build/chip/chip_test.gni +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright (c) 2020 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build_overrides/build.gni") -import("//build_overrides/chip.gni") -import("//build_overrides/pigweed.gni") - -import("$dir_pw_build/python_action.gni") - -import("${chip_root}/build/chip/tests.gni") -import("${chip_root}/src/platform/device.gni") -import("${dir_pw_unit_test}/test.gni") - -assert(chip_build_tests) - -if (chip_link_tests) { - template("chip_test") { - _test_name = target_name - - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - executable(_test_name) { - forward_variables_from(invoker, "*", [ "output_dir" ]) - output_dir = _test_output_dir - } - - group(_test_name + ".lib") { - } - - if (chip_pw_run_tests) { - pw_python_action(_test_name + ".run") { - deps = [ ":${_test_name}" ] - inputs = [ pw_unit_test_AUTOMATIC_RUNNER ] - module = "pw_unit_test.test_runner" - python_deps = [ - "$dir_pw_cli/py", - "$dir_pw_unit_test/py", - ] - args = [ - "--runner", - rebase_path(pw_unit_test_AUTOMATIC_RUNNER, root_build_dir), - "--test", - rebase_path("$_test_output_dir/$_test_name", root_build_dir), - ] - stamp = true - } - } - } -} else { - template("chip_test") { - group(target_name) { - } - group(target_name + ".lib") { - } - not_needed(invoker, "*") - } -} diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 3f5d426c2ca6f2..7d1c973590a1d1 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -16,7 +16,6 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("//build_overrides/pigweed.gni") -import("${chip_root}/build/chip/chip_test.gni") import("${chip_root}/build/chip/tests.gni") import("${dir_pw_unit_test}/test.gni") @@ -49,28 +48,6 @@ declare_args() { # "${chip_root}/src/lib/foo", # add dependencies here # ] # } -# -# -# Deprecated usage (writing own driver files): -# -# chip_test_suite("tests") { -# output_name = "libFooTests" -# -# sources = [ -# "TestDeclarations.h", -# "TestFoo.cpp", -# "TestBar.cpp", -# ] -# -# public_deps = [ -# "${chip_root}/src/lib/foo", # add dependencies here -# ] -# -# tests = [ -# "TestFoo", # Assumes TestFooDriver.cpp exists -# "TestBar", # Assumes TestBarDriver.cpp exists -# ] -# } # template("chip_test_suite") { @@ -146,48 +123,6 @@ template("chip_test_suite") { tests += [ _test_name ] } - # Deprecated usage (user-defined driver) - if (defined(invoker.tests)) { - foreach(_test, invoker.tests) { - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } - - pw_test(_test) { - # Forward certain varibles from the invoker. - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - - # Link to the common library for this test suite. - if (chip_link_tests) { - public_deps += [ ":${_suite_name}.lib" ] - } - - # Set variables that the platform executable may need. - if (test_executable_output_name != "") { - output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix - } - ldflags = test_executable_ldflags - - # Add the individual test source file (e.g. "TestSomething.cpp") and its driver. - sources = [ - "${_test}.cpp", - "${_test}Driver.cpp", - ] - - test_main = "" - output_dir = _test_output_dir - } - tests += [ _test ] - } - } - group(_suite_name) { deps = [] From 35d89d24821e29c54d40166238cfb1f9a683f860 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sat, 3 Aug 2024 02:19:08 +0000 Subject: [PATCH 18/35] Better solution to generating flash scripts, but incomplete --- build/toolchain/flashable_executable.gni | 2 +- third_party/silabs/silabs_executable.gni | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/build/toolchain/flashable_executable.gni b/build/toolchain/flashable_executable.gni index 91eba914040f3e..1520e4d2e6b41c 100644 --- a/build/toolchain/flashable_executable.gni +++ b/build/toolchain/flashable_executable.gni @@ -157,7 +157,7 @@ template("flashable_executable") { flashing_options += [ "--application", - rebase_path(image_name, invoker.output_dir, root_out_dir), + rebase_path(image_name, invoker.output_dir, invoker.output_dir), ] data_deps = [ ":$image_target" ] } diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index ce91a2ad0aff24..877b2b841c6556 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -68,9 +68,14 @@ template("silabs_executable") { "${chip_root}/scripts/flashing/silabs_firmware_utils.py", "${chip_root}/scripts/flashing/firmware_utils.py", ] - copy(flashing_runtime_target) { + action_foreach(flashing_runtime_target) { + script = "${build_root}/chip/copy.py" + args = [ + "{{source}}", + rebase_path(invoker.output_dir, "") + "/{{source_file_part}}", + ] sources = flashing_script_inputs - outputs = [ "${invoker.output_dir}/${output_base_name}--{{source_file_part}}" ] #++++ FIXME: Can we avoid adding the "output_base_name--" prefix?. + outputs = [ "${invoker.output_dir}/${output_base_name}--{{source_file_part}}" ] #++++ FIXME: This causes the wrong value to be written to flashbundle.txt by write_runtime_deps. } flashing_script_generator = From 0af37635390d3b810c2a3230d08c3a124de8e6f4 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sat, 3 Aug 2024 02:19:37 +0000 Subject: [PATCH 19/35] Added copy.py script --- build/chip/copy.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 build/chip/copy.py diff --git a/build/chip/copy.py b/build/chip/copy.py new file mode 100644 index 00000000000000..26494e15423328 --- /dev/null +++ b/build/chip/copy.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys, subprocess +subprocess.run(["cp", sys.argv[1], sys.argv[2]]) \ No newline at end of file From ef330a3da96b3debd5b20d486251005b13f7a502 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Sun, 4 Aug 2024 20:46:20 +0000 Subject: [PATCH 20/35] Generating flashbundle via a new script gen_flashbundle.py --- build/chip/copy.py | 17 ----------- build/toolchain/flashable_executable.gni | 5 +++- scripts/flashing/gen_flashbundle.py | 37 ++++++++++++++++++++++++ third_party/silabs/silabs_executable.gni | 24 ++++++++------- 4 files changed, 55 insertions(+), 28 deletions(-) delete mode 100644 build/chip/copy.py create mode 100644 scripts/flashing/gen_flashbundle.py diff --git a/build/chip/copy.py b/build/chip/copy.py deleted file mode 100644 index 26494e15423328..00000000000000 --- a/build/chip/copy.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys, subprocess -subprocess.run(["cp", sys.argv[1], sys.argv[2]]) \ No newline at end of file diff --git a/build/toolchain/flashable_executable.gni b/build/toolchain/flashable_executable.gni index 1520e4d2e6b41c..e34a01e5d05e30 100644 --- a/build/toolchain/flashable_executable.gni +++ b/build/toolchain/flashable_executable.gni @@ -112,7 +112,10 @@ template("flashable_executable") { data_deps += invoker.data_deps } - write_runtime_deps = "${invoker.output_dir}/${flashbundle_name}" + # Invoker can stop this template from creating the flashbundle.txt by setting flashbundle_name to empty string. + if (flashbundle_name != "") { + write_runtime_deps = "${invoker.output_dir}/${flashbundle_name}" + } } if (defined(invoker.objcopy_image_name)) { diff --git a/scripts/flashing/gen_flashbundle.py b/scripts/flashing/gen_flashbundle.py new file mode 100644 index 00000000000000..3f2bb48a4bb207 --- /dev/null +++ b/scripts/flashing/gen_flashbundle.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os +import subprocess +import sys +import textwrap + +# Copy two dependencies to the base output dir. +subprocess.run(["cp", sys.argv[4], "."]) +subprocess.run(["cp", sys.argv[5], "."]) + +# Create TestSomething.flashbundle.txt +flashbundle_contents = textwrap.dedent(f""" + {os.path.basename(sys.argv[2])} + {os.path.basename(sys.argv[3])} + {os.path.basename(sys.argv[4])} + {os.path.basename(sys.argv[5])} +""").strip() +try: + with open(sys.argv[1], 'w') as flashbundle_file: + flashbundle_file.write(flashbundle_contents) +except OSError as exception: + print(exception, sys.stderr) + sys.exit(1) diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index 877b2b841c6556..ed6ce070117515 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -68,15 +68,6 @@ template("silabs_executable") { "${chip_root}/scripts/flashing/silabs_firmware_utils.py", "${chip_root}/scripts/flashing/firmware_utils.py", ] - action_foreach(flashing_runtime_target) { - script = "${build_root}/chip/copy.py" - args = [ - "{{source}}", - rebase_path(invoker.output_dir, "") + "/{{source_file_part}}", - ] - sources = flashing_script_inputs - outputs = [ "${invoker.output_dir}/${output_base_name}--{{source_file_part}}" ] #++++ FIXME: This causes the wrong value to be written to flashbundle.txt by write_runtime_deps. - } flashing_script_generator = "${chip_root}/scripts/flashing/gen_flashing_script.py" @@ -84,12 +75,25 @@ template("silabs_executable") { flashing_options = [ "silabs" ] flash_target_name = target_name + ".flash_executable" - flashbundle_name = "${target_name}.flashbundle.txt" + flashbundle_name = "" # Stop flashable_executable from generating flashbundle.txt flashable_executable(flash_target_name) { forward_variables_from(invoker, "*") data_deps = [ ":${flashing_runtime_target}" ] } + # Generate TestSomething.flashbundle.txt + flashbundle_filepath = "${invoker.output_dir}/${target_name}.flashbundle.txt" + action(flashing_runtime_target) { + script = "${chip_root}/scripts/flashing/gen_flashbundle.py" + sources = flashing_script_inputs + args = [ + rebase_path(flashbundle_filepath, root_build_dir), # Write to here. + flashing_script_name, # Write file name. + objcopy_image_name, # Write file name. + ] + rebase_path(sources, root_build_dir) # Copy files and write file names. + outputs = [ flashbundle_filepath ] + } + # Add a target which generates the hex file in addition to s37. executable_target = "$flash_target_name.executable" hex_image_name = output_base_name + ".hex" From e77f79231b61a518028c29cb3722302925e14e69 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 02:45:24 +0000 Subject: [PATCH 21/35] Moved flashbundle generation and copying into silabs_firmware_utils --- scripts/flashing/silabs_firmware_utils.py | 40 +++++++++++++++++++++++ third_party/silabs/silabs_executable.gni | 37 +++++++++------------ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/scripts/flashing/silabs_firmware_utils.py b/scripts/flashing/silabs_firmware_utils.py index 5e0a689f5a62f4..47a9938f2159a3 100755 --- a/scripts/flashing/silabs_firmware_utils.py +++ b/scripts/flashing/silabs_firmware_utils.py @@ -49,6 +49,8 @@ Do not reset device after flashing """ +import os +import subprocess import sys import firmware_utils @@ -169,6 +171,44 @@ def actions(self): return self + def _platform_wrapper_args(self, args): + """Called from make_wrapper() to optionally manipulate arguments.""" + # Generate the flashbundle.txt file and copy the firmware utils. + if args.flashbundle_file is not None: + # Generate the flashbundle contents. + # Copy the platform-specific and general firmware utils to the same directory as the wrapper. + flashbundle_contents = os.path.basename(args.output) + if args.application is not None: + flashbundle_contents += "\n" + os.path.basename(args.application) + if args.platform_firmware_utils is not None: + flashbundle_contents += "\n" + os.path.basename(args.platform_firmware_utils) + subprocess.run(["cp", args.platform_firmware_utils, os.path.dirname(args.output)]) + if args.firmware_utils is not None: + flashbundle_contents += "\n" + os.path.basename(args.firmware_utils) + subprocess.run(["cp", args.firmware_utils, os.path.dirname(args.output)]) + + # Create the flashbundle file. + try: + with open(args.flashbundle_file, 'w') as flashbundle_file: + flashbundle_file.write(flashbundle_contents.strip()) + except OSError as exception: + print(exception, sys.stderr) + + def make_wrapper(self, argv): + self.parser.add_argument( + '--flashbundle-file', + metavar='FILENAME', + help='path and name of the flashbundle text file to create') + self.parser.add_argument( + '--platform-firmware-utils', + metavar='FILENAME', + help='path and file of the platform-specific firmware utils script') + self.parser.add_argument( + '--firmware-utils', + metavar='FILENAME', + help='path and file of the general firmware utils script') + super().make_wrapper(argv) + if __name__ == '__main__': sys.exit(Flasher().flash_command(sys.argv)) diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index ed6ce070117515..91abdcc0675eed 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -63,35 +63,30 @@ template("silabs_executable") { flashing_image_name = output_base_name + ".rps" } - flashing_runtime_target = target_name + ".flashing_runtime" - flashing_script_inputs = [ - "${chip_root}/scripts/flashing/silabs_firmware_utils.py", - "${chip_root}/scripts/flashing/firmware_utils.py", - ] - flashing_script_generator = "${chip_root}/scripts/flashing/gen_flashing_script.py" flashing_script_name = output_base_name + ".flash.py" - flashing_options = [ "silabs" ] + _flashbundle_file = "${invoker.output_dir}/${target_name}.flashbundle.txt" + _platform_firmware_utils = "${chip_root}/scripts/flashing/silabs_firmware_utils.py" + _firmware_utils = "${chip_root}/scripts/flashing/firmware_utils.py" + flashing_options = [ + "silabs", # Use module "{this}_firmware_utils.py" + "--flashbundle-file", + rebase_path(_flashbundle_file, root_build_dir), + "--platform-firmware-utils", # Platform-specific flashing module. + rebase_path(_platform_firmware_utils, root_build_dir), + "--firmware-utils", # General flashing module. + rebase_path(_firmware_utils, root_build_dir), + ] + flashing_script_inputs = [ + _platform_firmware_utils, + _firmware_utils, + ] flash_target_name = target_name + ".flash_executable" flashbundle_name = "" # Stop flashable_executable from generating flashbundle.txt flashable_executable(flash_target_name) { forward_variables_from(invoker, "*") - data_deps = [ ":${flashing_runtime_target}" ] - } - - # Generate TestSomething.flashbundle.txt - flashbundle_filepath = "${invoker.output_dir}/${target_name}.flashbundle.txt" - action(flashing_runtime_target) { - script = "${chip_root}/scripts/flashing/gen_flashbundle.py" - sources = flashing_script_inputs - args = [ - rebase_path(flashbundle_filepath, root_build_dir), # Write to here. - flashing_script_name, # Write file name. - objcopy_image_name, # Write file name. - ] + rebase_path(sources, root_build_dir) # Copy files and write file names. - outputs = [ flashbundle_filepath ] } # Add a target which generates the hex file in addition to s37. From 5e81b00d903ac867b21aeb2bbdb0464fa7811d75 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 02:45:42 +0000 Subject: [PATCH 22/35] Moved flashbundle generation and copying into silabs_firmware_utils --- third_party/silabs/silabs_executable.gni | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index 91abdcc0675eed..25a8ad154bcb7a 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -70,12 +70,12 @@ template("silabs_executable") { _platform_firmware_utils = "${chip_root}/scripts/flashing/silabs_firmware_utils.py" _firmware_utils = "${chip_root}/scripts/flashing/firmware_utils.py" flashing_options = [ - "silabs", # Use module "{this}_firmware_utils.py" + "silabs", # Use module "{platform}_firmware_utils.py" "--flashbundle-file", rebase_path(_flashbundle_file, root_build_dir), - "--platform-firmware-utils", # Platform-specific flashing module. + "--platform-firmware-utils", # Platform-specific firmware module. rebase_path(_platform_firmware_utils, root_build_dir), - "--firmware-utils", # General flashing module. + "--firmware-utils", # General firmware module. rebase_path(_firmware_utils, root_build_dir), ] flashing_script_inputs = [ From 9ac9d41f2c58a7398c1bcb6f0078803581b51887 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 02:49:48 +0000 Subject: [PATCH 23/35] Comment typo. --- build/chip/chip_test_suite.gni | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 7d1c973590a1d1..930ef5db9328f3 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -95,7 +95,7 @@ template("chip_test_suite") { } pw_test(_test_name) { - # Forward certain varibles from the invoker. + # Forward certain variables from the invoker. forward_variables_from(invoker, [ "deps", From 91212d21522ac17fa8f48c646c309f17bcce86e7 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 5 Aug 2024 03:06:41 +0000 Subject: [PATCH 24/35] Restyled by gn --- build/chip/chip_test_suite.gni | 25 ++++++++++++++---------- build/toolchain/flashable_executable.gni | 7 +++++-- src/test_driver/efr32/args.gni | 13 +++++++----- third_party/silabs/silabs_executable.gni | 14 +++++++++---- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 930ef5db9328f3..0a2cfcbb26a1bc 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -55,8 +55,12 @@ template("chip_test_suite") { # Ensures that the common library has sources containing both common # and individual unit tests. - if (!defined(invoker.sources)) { invoker.sources = [] } - if (!defined(invoker.test_sources)) { invoker.test_sources = [] } + if (!defined(invoker.sources)) { + invoker.sources = [] + } + if (!defined(invoker.test_sources)) { + invoker.test_sources = [] + } invoker.sources += invoker.test_sources if (chip_build_test_static_libraries) { @@ -97,13 +101,13 @@ template("chip_test_suite") { pw_test(_test_name) { # Forward certain variables from the invoker. forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) + # Link to the common library for this test suite. if (chip_link_tests) { public_deps += [ ":${_suite_name}.lib" ] @@ -111,7 +115,8 @@ template("chip_test_suite") { # Set variables that the platform executable may need. if (test_executable_output_name != "") { - output_name = test_executable_output_name + _test_name + test_executable_output_name_suffix + output_name = test_executable_output_name + _test_name + + test_executable_output_name_suffix } ldflags = test_executable_ldflags diff --git a/build/toolchain/flashable_executable.gni b/build/toolchain/flashable_executable.gni index e34a01e5d05e30..b7f96b95f46f08 100644 --- a/build/toolchain/flashable_executable.gni +++ b/build/toolchain/flashable_executable.gni @@ -86,7 +86,9 @@ template("gen_flashing_script") { template("flashable_executable") { executable_target = "$target_name.executable" - if (!defined(invoker.output_dir)) {invoker.output_dir = root_out_dir} + if (!defined(invoker.output_dir)) { + invoker.output_dir = root_out_dir + } if (defined(invoker.flashing_script_name)) { # Generating the flashing script is the final target. @@ -146,7 +148,8 @@ template("flashable_executable") { gen_flashing_script("$target_name.flashing") { flashing_script_generator = invoker.flashing_script_generator flashing_script_inputs = invoker.flashing_script_inputs - flashing_script_name = "${invoker.output_dir}/${invoker.flashing_script_name}" + flashing_script_name = + "${invoker.output_dir}/${invoker.flashing_script_name}" if (defined(invoker.flashing_options)) { flashing_options = invoker.flashing_options } else { diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index a6e40ae85c99bb..5139c35469a4ed 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -17,7 +17,8 @@ import("//build_overrides/pigweed.gni") import("${chip_root}/config/efr32/lib/pw_rpc/pw_rpc.gni") import("${chip_root}/examples/platform/silabs/args.gni") import("${chip_root}/src/platform/silabs/efr32/args.gni") -import("${chip_root}/third_party/silabs/silabs_board.gni") # Defines silabs_family +import("${chip_root}/third_party/silabs/silabs_board.gni") # Defines + # silabs_family silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") @@ -38,14 +39,16 @@ pw_unit_test_BACKEND = "$dir_pw_unit_test:light" # Override the executable type and the test main's target. pw_unit_test_EXECUTABLE_TARGET_TYPE = "silabs_executable" -pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = "${efr32_sdk_build_root}/silabs_executable.gni" +pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = + "${efr32_sdk_build_root}/silabs_executable.gni" pw_unit_test_MAIN = "//:efr32_test_main" # Additional variables needed by silabs_executable that must be passed in to pw_test. test_executable_output_name = "matter-silabs-device_tests_" test_executable_output_name_suffix = ".out" -_ldscript = "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" +_ldscript = + "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" test_executable_ldflags = [ - "-T" + rebase_path(_ldscript, root_build_dir), - "-Wl,--no-warn-rwx-segment", + "-T" + rebase_path(_ldscript, root_build_dir), + "-Wl,--no-warn-rwx-segment", ] diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index 25a8ad154bcb7a..55616e407ecb04 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -47,8 +47,12 @@ template("generate_rps_file") { } template("silabs_executable") { - if (!defined(invoker.output_dir)) {invoker.output_dir = root_out_dir} - if (!defined(invoker.output_name)) {invoker.output_name = target_name + ".bin"} + if (!defined(invoker.output_dir)) { + invoker.output_dir = root_out_dir + } + if (!defined(invoker.output_name)) { + invoker.output_name = target_name + ".bin" + } output_base_name = get_path_info(invoker.output_name, "name") objcopy_image_name = output_base_name + ".s37" objcopy_image_format = "srec" @@ -67,7 +71,8 @@ template("silabs_executable") { "${chip_root}/scripts/flashing/gen_flashing_script.py" flashing_script_name = output_base_name + ".flash.py" _flashbundle_file = "${invoker.output_dir}/${target_name}.flashbundle.txt" - _platform_firmware_utils = "${chip_root}/scripts/flashing/silabs_firmware_utils.py" + _platform_firmware_utils = + "${chip_root}/scripts/flashing/silabs_firmware_utils.py" _firmware_utils = "${chip_root}/scripts/flashing/firmware_utils.py" flashing_options = [ "silabs", # Use module "{platform}_firmware_utils.py" @@ -84,7 +89,8 @@ template("silabs_executable") { ] flash_target_name = target_name + ".flash_executable" - flashbundle_name = "" # Stop flashable_executable from generating flashbundle.txt + flashbundle_name = + "" # Stop flashable_executable from generating flashbundle.txt flashable_executable(flash_target_name) { forward_variables_from(invoker, "*") } From 6f9863c2d2f7c830e7f2f0d2008fe0d06ca9aacb Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 5 Aug 2024 03:06:50 +0000 Subject: [PATCH 25/35] Restyled by prettier-markdown --- src/test_driver/efr32/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test_driver/efr32/README.md b/src/test_driver/efr32/README.md index 907ea5a5054ad2..dd1cdf6f93c57e 100644 --- a/src/test_driver/efr32/README.md +++ b/src/test_driver/efr32/README.md @@ -14,9 +14,9 @@ This builds and runs the unit tests on the efr32 device ## Introduction -This builds a set of test binaries which contain the unit tests and can be flashed onto -a device. The device is controlled using the included RPCs, through the python -test runner. +This builds a set of test binaries which contain the unit tests and can be +flashed onto a device. The device is controlled using the included RPCs, through +the python test runner. From 42655dec763d7ad739f03d77c4ca61afe653659d Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 5 Aug 2024 03:07:00 +0000 Subject: [PATCH 26/35] Restyled by autopep8 --- src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py index 9ec8142ab5ebd5..8e10903920cc77 100644 --- a/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py +++ b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py @@ -133,5 +133,6 @@ def main() -> int: return failures + if __name__ == "__main__": sys.exit(main()) From 48709c5364fa983b6bfb47d10e36105bc1c67039 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 03:13:05 +0000 Subject: [PATCH 27/35] Comment updates after Restyled --- src/test_driver/efr32/args.gni | 3 +-- third_party/silabs/silabs_executable.gni | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 5139c35469a4ed..8a5e01920dd5df 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -17,8 +17,7 @@ import("//build_overrides/pigweed.gni") import("${chip_root}/config/efr32/lib/pw_rpc/pw_rpc.gni") import("${chip_root}/examples/platform/silabs/args.gni") import("${chip_root}/src/platform/silabs/efr32/args.gni") -import("${chip_root}/third_party/silabs/silabs_board.gni") # Defines - # silabs_family +import("${chip_root}/third_party/silabs/silabs_board.gni") # silabs_family silabs_sdk_target = get_label_info(":sdk", "label_no_toolchain") diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index 55616e407ecb04..be81c974afd89c 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -89,8 +89,7 @@ template("silabs_executable") { ] flash_target_name = target_name + ".flash_executable" - flashbundle_name = - "" # Stop flashable_executable from generating flashbundle.txt + flashbundle_name = "" # Stop flashable_executable from making flashbundle. flashable_executable(flash_target_name) { forward_variables_from(invoker, "*") } From ab935e803828ba4888196122f0f868ed4d3c4658 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 03:58:35 +0000 Subject: [PATCH 28/35] Removed gen_flashbundle --- scripts/flashing/gen_flashbundle.py | 37 ----------------------------- 1 file changed, 37 deletions(-) delete mode 100644 scripts/flashing/gen_flashbundle.py diff --git a/scripts/flashing/gen_flashbundle.py b/scripts/flashing/gen_flashbundle.py deleted file mode 100644 index 3f2bb48a4bb207..00000000000000 --- a/scripts/flashing/gen_flashbundle.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import subprocess -import sys -import textwrap - -# Copy two dependencies to the base output dir. -subprocess.run(["cp", sys.argv[4], "."]) -subprocess.run(["cp", sys.argv[5], "."]) - -# Create TestSomething.flashbundle.txt -flashbundle_contents = textwrap.dedent(f""" - {os.path.basename(sys.argv[2])} - {os.path.basename(sys.argv[3])} - {os.path.basename(sys.argv[4])} - {os.path.basename(sys.argv[5])} -""").strip() -try: - with open(sys.argv[1], 'w') as flashbundle_file: - flashbundle_file.write(flashbundle_contents) -except OSError as exception: - print(exception, sys.stderr) - sys.exit(1) From 32d49e63cf790631be8fa4aa18733ebbcc4093da Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 04:17:06 +0000 Subject: [PATCH 29/35] Added comments to flashing_options --- third_party/silabs/silabs_executable.gni | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index be81c974afd89c..bd80b1f9623837 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -75,12 +75,19 @@ template("silabs_executable") { "${chip_root}/scripts/flashing/silabs_firmware_utils.py" _firmware_utils = "${chip_root}/scripts/flashing/firmware_utils.py" flashing_options = [ - "silabs", # Use module "{platform}_firmware_utils.py" + # Use module "{platform}_firmware_utils.py" + "silabs", + + # flashbundle.txt file to create. "--flashbundle-file", rebase_path(_flashbundle_file, root_build_dir), - "--platform-firmware-utils", # Platform-specific firmware module. + + # Platform-specific firmware module to copy. + "--platform-firmware-utils", rebase_path(_platform_firmware_utils, root_build_dir), - "--firmware-utils", # General firmware module. + + # General firmware module to copy. + "--firmware-utils", rebase_path(_firmware_utils, root_build_dir), ] flashing_script_inputs = [ From 6f04bde4043cfefeb76a69e9324af5757fb3a7e2 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 5 Aug 2024 04:39:49 +0000 Subject: [PATCH 30/35] Added comments to silabs_executable --- third_party/silabs/silabs_executable.gni | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/third_party/silabs/silabs_executable.gni b/third_party/silabs/silabs_executable.gni index bd80b1f9623837..37b853c5df84b8 100644 --- a/third_party/silabs/silabs_executable.gni +++ b/third_party/silabs/silabs_executable.gni @@ -47,25 +47,32 @@ template("generate_rps_file") { } template("silabs_executable") { + # output_dir is optional and will default to root_out_dir if (!defined(invoker.output_dir)) { invoker.output_dir = root_out_dir } + + # output_name is optional and will default to "$target_name.bin" if (!defined(invoker.output_name)) { invoker.output_name = target_name + ".bin" } + output_base_name = get_path_info(invoker.output_name, "name") objcopy_image_name = output_base_name + ".s37" objcopy_image_format = "srec" objcopy = "arm-none-eabi-objcopy" + if (use_rps_extension) { + flashing_image_name = output_base_name + ".rps" + } + + # flashable_executable calls a generator script to do the following: + # Create a flash.py script with the name of the binary hardcoded in it. # Copy flashing dependencies to the output directory so that the output # is collectively self-contained; this allows flashing to work reliably # even if the build and flashing steps take place on different machines # or in different containers. - - if (use_rps_extension) { - flashing_image_name = output_base_name + ".rps" - } + # Create *.flashbundle.txt with a list of all files needed for flashing flashing_script_generator = "${chip_root}/scripts/flashing/gen_flashing_script.py" @@ -94,14 +101,15 @@ template("silabs_executable") { _platform_firmware_utils, _firmware_utils, ] + flashbundle_name = "" # Stop flashable_executable from making flashbundle. + # Target to generate the s37 file, flashing script, and flashbundle. flash_target_name = target_name + ".flash_executable" - flashbundle_name = "" # Stop flashable_executable from making flashbundle. flashable_executable(flash_target_name) { forward_variables_from(invoker, "*") } - # Add a target which generates the hex file in addition to s37. + # Target to generate the hex file. executable_target = "$flash_target_name.executable" hex_image_name = output_base_name + ".hex" hex_target_name = target_name + ".hex" @@ -112,6 +120,7 @@ template("silabs_executable") { deps = [ ":$executable_target" ] } + # Target to generate the rps file. if (use_rps_extension) { rps_target_name = target_name + ".rps" generate_rps_file(rps_target_name) { @@ -123,6 +132,8 @@ template("silabs_executable") { ] } } + + # Main target that deps the targets defined above. group(target_name) { deps = [ ":$flash_target_name", From ec94bd8d40019636aa7baccb7ca51eea4e5e0723 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Wed, 7 Aug 2024 18:13:20 +0000 Subject: [PATCH 31/35] Test suite's common lib now contains only `sources`, not `test_sources` and is dep'd by each pw_test --- build/chip/chip_test_suite.gni | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 0a2cfcbb26a1bc..be07af9523d581 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -53,15 +53,9 @@ declare_args() { template("chip_test_suite") { _suite_name = target_name - # Ensures that the common library has sources containing both common - # and individual unit tests. - if (!defined(invoker.sources)) { - invoker.sources = [] - } if (!defined(invoker.test_sources)) { invoker.test_sources = [] } - invoker.sources += invoker.test_sources if (chip_build_test_static_libraries) { _target_type = "static_library" @@ -69,7 +63,7 @@ template("chip_test_suite") { _target_type = "source_set" } target(_target_type, "${_suite_name}.lib") { - forward_variables_from(invoker, "*", [ "tests" ]) + forward_variables_from(invoker, "*", [ "tests", "test_sources", ]) output_dir = "${root_out_dir}/lib" @@ -108,10 +102,8 @@ template("chip_test_suite") { "configs", ]) - # Link to the common library for this test suite. - if (chip_link_tests) { - public_deps += [ ":${_suite_name}.lib" ] - } + # Link to the common lib for this suite so we get its `sources`. + public_deps += [ ":${_suite_name}.lib" ] # Set variables that the platform executable may need. if (test_executable_output_name != "") { @@ -135,11 +127,6 @@ template("chip_test_suite") { foreach(_test, tests) { deps += [ ":${_test}" ] } - - # Add the common library if none of the above tests did. - if (!chip_link_tests) { - deps += [ ":${_suite_name}.lib" ] - } } if (chip_pw_run_tests) { From 0ec522ddea8086d9ebcddb42787eaa411438198c Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Wed, 7 Aug 2024 19:36:48 +0000 Subject: [PATCH 32/35] changed how test_sources is checked for undefined. Tried adding common lib back into group() target --- build/chip/chip_test_suite.gni | 71 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index be07af9523d581..383f512f877b52 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -53,17 +53,13 @@ declare_args() { template("chip_test_suite") { _suite_name = target_name - if (!defined(invoker.test_sources)) { - invoker.test_sources = [] - } - if (chip_build_test_static_libraries) { _target_type = "static_library" } else { _target_type = "source_set" } target(_target_type, "${_suite_name}.lib") { - forward_variables_from(invoker, "*", [ "tests", "test_sources", ]) + forward_variables_from(invoker, "*", [ "tests", "test_sources" ]) output_dir = "${root_out_dir}/lib" @@ -84,40 +80,42 @@ template("chip_test_suite") { tests = [] - foreach(_test, invoker.test_sources) { - _test_name = string_replace(_test, ".cpp", "") - - _test_output_dir = "${root_out_dir}/tests" - if (defined(invoker.output_dir)) { - _test_output_dir = invoker.output_dir - } + if (defined(invoker.test_sources)) { + foreach(_test, invoker.test_sources) { + _test_name = string_replace(_test, ".cpp", "") - pw_test(_test_name) { - # Forward certain variables from the invoker. - forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - - # Link to the common lib for this suite so we get its `sources`. - public_deps += [ ":${_suite_name}.lib" ] - - # Set variables that the platform executable may need. - if (test_executable_output_name != "") { - output_name = test_executable_output_name + _test_name + - test_executable_output_name_suffix + _test_output_dir = "${root_out_dir}/tests" + if (defined(invoker.output_dir)) { + _test_output_dir = invoker.output_dir } - ldflags = test_executable_ldflags - # Add the individual test source file (e.g. "TestSomething.cpp"). - sources = [ _test ] - - output_dir = _test_output_dir + pw_test(_test_name) { + # Forward certain variables from the invoker. + forward_variables_from(invoker, + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) + + # Link to the common lib for this suite so we get its `sources`. + public_deps += [ ":${_suite_name}.lib" ] + + # Set variables that the platform executable may need. + if (test_executable_output_name != "") { + output_name = test_executable_output_name + _test_name + + test_executable_output_name_suffix + } + ldflags = test_executable_ldflags + + # Add the individual test source file (e.g. "TestSomething.cpp"). + sources = [ _test ] + + output_dir = _test_output_dir + } + tests += [ _test_name ] } - tests += [ _test_name ] } group(_suite_name) { @@ -127,6 +125,9 @@ template("chip_test_suite") { foreach(_test, tests) { deps += [ ":${_test}" ] } + + # Add the common library. + deps += [ ":${_suite_name}.lib" ] } if (chip_pw_run_tests) { From 6a8641b492e6aeb8861a14846a357f57d59f1e90 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Fri, 9 Aug 2024 11:42:44 -0400 Subject: [PATCH 33/35] Fixed copying of firmware utils in cases where directory is "." --- scripts/flashing/silabs_firmware_utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/flashing/silabs_firmware_utils.py b/scripts/flashing/silabs_firmware_utils.py index 47a9938f2159a3..52e952db2ae5e2 100755 --- a/scripts/flashing/silabs_firmware_utils.py +++ b/scripts/flashing/silabs_firmware_utils.py @@ -180,12 +180,13 @@ def _platform_wrapper_args(self, args): flashbundle_contents = os.path.basename(args.output) if args.application is not None: flashbundle_contents += "\n" + os.path.basename(args.application) + output_dir = os.path.dirname(args.output) or "." if args.platform_firmware_utils is not None: flashbundle_contents += "\n" + os.path.basename(args.platform_firmware_utils) - subprocess.run(["cp", args.platform_firmware_utils, os.path.dirname(args.output)]) + subprocess.run(["cp", args.platform_firmware_utils, output_dir]) if args.firmware_utils is not None: flashbundle_contents += "\n" + os.path.basename(args.firmware_utils) - subprocess.run(["cp", args.firmware_utils, os.path.dirname(args.output)]) + subprocess.run(["cp", args.firmware_utils, output_dir]) # Create the flashbundle file. try: From 4e057b704dac2aefafffb90114a6b205b1ea368f Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Tue, 13 Aug 2024 16:00:48 -0400 Subject: [PATCH 34/35] Modified the builder script for efr32-brdxxxx-unit-test to generate the flashbundle for the whole set of tests, and fixed what files get copied to the artifacts directory. --- build/chip/chip_test_suite.gni | 24 +++++++++------- scripts/build/builders/efr32.py | 51 +++++++++++++++++++++++++++++---- src/test_driver/efr32/BUILD.gn | 2 ++ src/test_driver/efr32/args.gni | 2 +- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 383f512f877b52..590dd45612541b 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -59,7 +59,12 @@ template("chip_test_suite") { _target_type = "source_set" } target(_target_type, "${_suite_name}.lib") { - forward_variables_from(invoker, "*", [ "tests", "test_sources" ]) + forward_variables_from(invoker, + "*", + [ + "tests", + "test_sources", + ]) output_dir = "${root_out_dir}/lib" @@ -92,15 +97,12 @@ template("chip_test_suite") { pw_test(_test_name) { # Forward certain variables from the invoker. forward_variables_from(invoker, - [ - "deps", - "public_deps", - "cflags", - "configs", - ]) - - # Link to the common lib for this suite so we get its `sources`. - public_deps += [ ":${_suite_name}.lib" ] + [ + "deps", + "public_deps", + "cflags", + "configs", + ]) # Set variables that the platform executable may need. if (test_executable_output_name != "") { @@ -126,7 +128,7 @@ template("chip_test_suite") { deps += [ ":${_test}" ] } - # Add the common library. + # Add the common lib for this suite so we get its `sources`. deps += [ ":${_suite_name}.lib" ] } diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 89f81e86fc93ef..7b518ff1227b89 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import glob +import logging import os import shlex import subprocess @@ -78,7 +80,7 @@ def FlashBundleName(self): elif self == Efr32App.PUMP: return 'pump_app.flashbundle.txt' elif self == Efr32App.UNIT_TEST: - return 'efr32_device_tests.flashbundle.txt' + return os.path.join('tests', 'efr32_device_tests.flashbundle.txt') else: raise Exception('Unknown app type: %r' % self) @@ -259,13 +261,44 @@ def __init__(self, def GnBuildArgs(self): return self.extra_gn_options + def _bundle(self): + # Only unit-test needs to generate the flashbundle here. All other examples will generate a flashbundle via the silabs_executable template. + if self.app == Efr32App.UNIT_TEST: + flash_bundle_path = os.path.join(self.output_dir, self.app.FlashBundleName()) + logging.info(f'Generating flashbundle {flash_bundle_path}') + + patterns = [ + os.path.join(self.output_dir, "tests", "*.flash.py"), + os.path.join(self.output_dir, "tests", "*.s37"), + os.path.join(self.output_dir, "tests", "silabs_firmware_utils.py"), + os.path.join(self.output_dir, "tests", "firmware_utils.py"), + ] + + # Generate the list of files by globbing each pattern. + files = [] + for pattern in patterns: + files += list(map(lambda x: os.path.basename(x), glob.glob(pattern))) + + # Create the bundle file. + with open(flash_bundle_path, 'w') as bundle_file: + bundle_file.write("\n".join(files)) + def build_outputs(self): extensions = ["out", "hex"] if self.options.enable_link_map_file: extensions.append("out.map") - for ext in extensions: - name = f"{self.app.AppNamePrefix()}.{ext}" - yield BuilderOutput(os.path.join(self.output_dir, name), name) + + if self.app == Efr32App.UNIT_TEST: + # Efr32 unit-test generates the "tests" subdir with a set of files for each individual unit test source. + for ext in extensions: + pattern = os.path.join(self.output_dir, "tests", f"*.{ext}") + for name in map(lambda x: os.path.basename(x), glob.glob(pattern)): + yield BuilderOutput(os.path.join(self.output_dir, "tests", name), name) + else: + # All other examples have just one set of files. + for ext in extensions: + name = f"{self.app.AppNamePrefix()}.{ext}" + yield BuilderOutput(os.path.join(self.output_dir, name), name) if self.app == Efr32App.UNIT_TEST: # Include test runner python wheels @@ -275,11 +308,17 @@ def build_outputs(self): os.path.join(root, file), os.path.join("chip_pw_test_runner_wheels", file)) - # Figure out flash bundle files and build accordingly + def bundle_outputs(self): + # If flashbundle creation is enabled, the outputs will include the s37 and flash.py files, plus the two firmware utils scripts that support flash.py. + # For the unit-test example, there will be a s37 and flash.py file for each unit test source. with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: for name in filter(None, [x.strip() for x in f.readlines()]): + if self.app == Efr32App.UNIT_TEST: + sourcepath = os.path.join(self.output_dir, "tests", name) # Unit tests are in the "tests" subdir. + else: + sourcepath = os.path.join(self.output_dir, name) yield BuilderOutput( - os.path.join(self.output_dir, name), + sourcepath, os.path.join("flashbundle", name)) def generate(self): diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 0aaf7fe903a635..68543d8a3c73c5 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -105,6 +105,8 @@ source_set("efr32_test_main") { include_dirs = [ "${chip_root}/examples/common/pigweed/efr32" ] } +# This target is referred to by BuildRoot in scripts/build/builders/efr32.py, as well as the example in README.md. +# It builds the root target "src:tests", which builds the chip_test_suite target in each test directory, which builds a pw_test target for each test source file, which builds a silabs_executable, which includes the "efr32_test_main" target defined above. group("efr32") { deps = [ "${chip_root}/src:tests" ] } diff --git a/src/test_driver/efr32/args.gni b/src/test_driver/efr32/args.gni index 8a5e01920dd5df..199f46a5f2b61c 100644 --- a/src/test_driver/efr32/args.gni +++ b/src/test_driver/efr32/args.gni @@ -43,7 +43,7 @@ pw_unit_test_EXECUTABLE_TARGET_TYPE_FILE = pw_unit_test_MAIN = "//:efr32_test_main" # Additional variables needed by silabs_executable that must be passed in to pw_test. -test_executable_output_name = "matter-silabs-device_tests_" +test_executable_output_name = "matter-silabs-device_tests-" test_executable_output_name_suffix = ".out" _ldscript = "${chip_root}/examples/platform/silabs/ldscripts/${silabs_family}.ld" From 3276433c7a7b94d9c2af6a7e29e2c4fed46ff098 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Tue, 13 Aug 2024 16:07:13 -0400 Subject: [PATCH 35/35] Move common lib linkage to the pw_test instead of the group target. --- build/chip/chip_test_suite.gni | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 590dd45612541b..43eb4ec39fb768 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -104,6 +104,9 @@ template("chip_test_suite") { "configs", ]) + # Link to the common lib for this suite so we get its `sources`. + public_deps += [ ":${_suite_name}.lib" ] + # Set variables that the platform executable may need. if (test_executable_output_name != "") { output_name = test_executable_output_name + _test_name + @@ -127,9 +130,6 @@ template("chip_test_suite") { foreach(_test, tests) { deps += [ ":${_test}" ] } - - # Add the common lib for this suite so we get its `sources`. - deps += [ ":${_suite_name}.lib" ] } if (chip_pw_run_tests) {