From 25ebd41ac813a3769fef53fbdbafb8ff895d20a1 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 3 Jun 2024 13:00:24 +0000 Subject: [PATCH 1/4] Updated test runner to support running all tests in a directory --- .../efr32/py/pw_test_runner/pw_test_runner.py | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) 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..7ee740983fdb7b 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 @@ -62,6 +62,11 @@ def _parse_args(): "--flash_image", help="a firmware image which will be flashed berfore runnning the test", ) + parser.add_argument( + "-y", + "--flash_directory", + help="A directory containing image files, each of which will be flashed and then run.", + ) parser.add_argument( "-o", "--output", @@ -96,22 +101,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, **kwargs) -> list[str]: + filenames: list[str] = os.listdir(flash_directory) + # filenames = filter(lambda x: not x.endswith('.map'), filenames) + 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) + images: list[str] = None + if args.flash_directory: + images = list_images(**vars(args)) + if not images: + raise Exception(f"No images found in `{args.flash_directory}`") + elif args.flash_image: + images = [args.flash_image] + + failures: int = 0 + if images: + 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. + failures += run(args) + + return failures if __name__ == "__main__": From 9e1a79e7db2468d7589cdcf0980f7d9dc6aff8d1 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 3 Jun 2024 19:48:57 +0000 Subject: [PATCH 2/4] Fixed the build process for the test runner, updated the test runner to use glob, and updated the test runner to use the flash_image parameter for directories --- scripts/build/builders/efr32.py | 5 +++ scripts/build/builders/host.py | 1 + src/BUILD.gn | 24 ++++++++----- src/test_driver/efr32/BUILD.gn | 3 ++ src/test_driver/efr32/README.md | 12 +++---- .../efr32/py/pw_test_runner/pw_test_runner.py | 36 +++++++++---------- src/test_driver/efr32/py/setup.cfg | 2 +- 7 files changed, 47 insertions(+), 36 deletions(-) diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 1144cfc8c54a16..baa98b76db2b91 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -270,6 +270,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_pw_test_runner_wheels')): + for file in files: + items["chip_pw_test_runner_wheels/" + + file] = os.path.join(root, file) + # TODO [PW_MIGRATION]: remove the nl wheels once transition away from nlunit-test is completed for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_nl_test_runner_wheels')): for file in files: items["chip_nl_test_runner_wheels/" + diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 667cd39d47da99..889c7de85e7878 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -215,6 +215,7 @@ def OutputNames(self): elif self == HostApp.PYTHON_BINDINGS: yield 'controller/python' # Directory containing WHL files elif self == HostApp.EFR32_TEST_RUNNER: + yield 'chip_pw_test_runner_wheels' yield 'chip_nl_test_runner_wheels' elif self == HostApp.TV_CASTING: yield 'chip-tv-casting-app' diff --git a/src/BUILD.gn b/src/BUILD.gn index cf15f40ec00629..7c468a017256fe 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -59,17 +59,23 @@ if (chip_build_tests) { "${chip_root}/src/access/tests", "${chip_root}/src/crypto/tests", "${chip_root}/src/inet/tests", - "${chip_root}/src/lib/address_resolve/tests", - "${chip_root}/src/lib/asn1/tests", - "${chip_root}/src/lib/core/tests", - "${chip_root}/src/messaging/tests", - "${chip_root}/src/protocols/bdx/tests", - "${chip_root}/src/protocols/interaction_model/tests", - "${chip_root}/src/protocols/user_directed_commissioning/tests", - "${chip_root}/src/transport/retransmit/tests", - "${chip_root}/src/app/icd/server/tests", ] + # Skip on efr32 due to flash limitations. + if (chip_device_platform != "efr32") { + tests += [ + "${chip_root}/src/lib/address_resolve/tests", + "${chip_root}/src/lib/asn1/tests", + "${chip_root}/src/lib/core/tests", + "${chip_root}/src/messaging/tests", + "${chip_root}/src/protocols/bdx/tests", + "${chip_root}/src/protocols/interaction_model/tests", + "${chip_root}/src/protocols/user_directed_commissioning/tests", + "${chip_root}/src/transport/retransmit/tests", + "${chip_root}/src/app/icd/server/tests", + ] + } + # Skip DNSSD tests for Mbed platform due to flash memory size limitations if (current_os != "mbed") { tests += [ diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 66676e197c983d..ab3771a2522cb5 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -130,6 +130,9 @@ group("efr32") { group("runner") { deps = [ + "${efr32_project_dir}/py:pw_test_runner.install", + "${efr32_project_dir}/py:pw_test_runner_wheel", + # TODO [PW_MIGRATION]: remove the following when transition from nlunit-test is complete. "${efr32_project_dir}/py:nl_test_runner.install", "${efr32_project_dir}/py:nl_test_runner_wheel", ] diff --git a/src/test_driver/efr32/README.md b/src/test_driver/efr32/README.md index 0f4ea0b33176d4..7366eb3e13b810 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 PW 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 test binary which contains the pw_unit_test and can be flashed onto a device. The device is controlled using the included RPCs, through the python test runner. @@ -99,7 +99,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 @@ -108,7 +108,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 @@ -117,8 +117,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/pw_test_runner/pw_test_runner.py b/src/test_driver/efr32/py/pw_test_runner/pw_test_runner.py index 7ee740983fdb7b..874600d6c3b674 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,12 +61,7 @@ def _parse_args(): parser.add_argument( "-f", "--flash_image", - help="a firmware image which will be flashed berfore runnning the test", - ) - parser.add_argument( - "-y", - "--flash_directory", - help="A directory containing image files, each of which will be flashed and then run.", + 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", @@ -80,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]) @@ -108,31 +104,31 @@ def run(args) -> int: return len(test_records.failing_tests) -def list_images(flash_directory: str, **kwargs) -> list[str]: - filenames: list[str] = os.listdir(flash_directory) - # filenames = filter(lambda x: not x.endswith('.map'), filenames) +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() - images: list[str] = None - if args.flash_directory: - images = list_images(**vars(args)) - if not images: - raise Exception(f"No images found in `{args.flash_directory}`") - elif args.flash_image: - images = [args.flash_image] + 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.isdir(args.flash_image): + images = [args.flash_image] + else: + raise Exception(f"File or directory not found `{args.flash_image}`") - failures: int = 0 - if images: 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. + else: # No image provided. Just run what's on the device. failures += run(args) return failures 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 6aea2b2555fe6ac31e8d424af18ccb9547a4c879 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Mon, 3 Jun 2024 20:42:16 +0000 Subject: [PATCH 3/4] added init file to pw_test_runner --- src/test_driver/efr32/py/pw_test_runner/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/test_driver/efr32/py/pw_test_runner/__init__.py diff --git a/src/test_driver/efr32/py/pw_test_runner/__init__.py b/src/test_driver/efr32/py/pw_test_runner/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 From fa92b5c71c9ddb8a3395fb8bfb0b88af4118e326 Mon Sep 17 00:00:00 2001 From: Jeff Feasel Date: Tue, 11 Jun 2024 00:55:42 +0000 Subject: [PATCH 4/4] Removed NL infrastructure --- scripts/build/builders/efr32.py | 6 - scripts/build/builders/host.py | 1 - src/test_driver/efr32/BUILD.gn | 3 - src/test_driver/efr32/py/BUILD.gn | 29 +--- .../__init__.py | 0 .../lib/pw_test_runner/pw_test_runner.py | 138 +++++++++++++++++ .../efr32/py/nl_test_runner/__init__.py | 0 .../efr32/py/nl_test_runner/nl_test_runner.py | 141 ------------------ .../efr32/py/pw_test_runner/pyproject.toml | 16 -- .../efr32/py/pw_test_runner/setup.cfg | 20 --- .../efr32/py/pw_test_runner/setup.py | 17 --- src/test_driver/efr32/py/pyproject.toml | 2 +- src/test_driver/efr32/py/setup.cfg | 2 +- src/test_driver/efr32/py/setup.py | 2 +- src/test_driver/efr32/src/main.cpp | 106 +------------ 15 files changed, 145 insertions(+), 338 deletions(-) rename src/test_driver/efr32/py/build/lib/{nl_test_runner => pw_test_runner}/__init__.py (100%) create mode 100644 src/test_driver/efr32/py/build/lib/pw_test_runner/pw_test_runner.py delete mode 100644 src/test_driver/efr32/py/nl_test_runner/__init__.py delete mode 100644 src/test_driver/efr32/py/nl_test_runner/nl_test_runner.py delete mode 100644 src/test_driver/efr32/py/pw_test_runner/pyproject.toml delete mode 100644 src/test_driver/efr32/py/pw_test_runner/setup.cfg delete mode 100644 src/test_driver/efr32/py/pw_test_runner/setup.py diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 4d9cfb8db314b9..afa6f46a5e7efa 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -277,12 +277,6 @@ def build_outputs(self): for file in files: items["chip_pw_test_runner_wheels/" + file] = os.path.join(root, file) - # TODO [PW_MIGRATION]: remove the nl wheels once transition away from nlunit-test is completed - for root, dirs, files in os.walk(os.path.join(self.output_dir, 'chip_nl_test_runner_wheels')): - for file in files: - yield BuilderOutput( - os.path.join(root, file), - os.path.join("chip_nl_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 079e0a8203b6ea..b959534296bf96 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -217,7 +217,6 @@ def OutputNames(self): yield 'controller/python' # Directory containing WHL files elif self == HostApp.EFR32_TEST_RUNNER: yield 'chip_pw_test_runner_wheels' - yield 'chip_nl_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 ab3771a2522cb5..50204df842515a 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -132,9 +132,6 @@ group("runner") { deps = [ "${efr32_project_dir}/py:pw_test_runner.install", "${efr32_project_dir}/py:pw_test_runner_wheel", - # TODO [PW_MIGRATION]: remove the following when transition from nlunit-test is complete. - "${efr32_project_dir}/py:nl_test_runner.install", - "${efr32_project_dir}/py:nl_test_runner_wheel", ] } diff --git a/src/test_driver/efr32/py/BUILD.gn b/src/test_driver/efr32/py/BUILD.gn index 615fe5603d00c9..c548c0c8026f1e 100644 --- a/src/test_driver/efr32/py/BUILD.gn +++ b/src/test_driver/efr32/py/BUILD.gn @@ -19,39 +19,13 @@ 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") { +pw_python_package("pw_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", - "pw_test_runner/setup.cfg", - "pw_test_runner/setup.py", - ] - sources = [ "pw_test_runner/__init__.py", "pw_test_runner/pw_test_runner.py", @@ -61,6 +35,7 @@ pw_python_package("pw_test_runner") { "$dir_pw_hdlc/py", "$dir_pw_protobuf_compiler/py", "$dir_pw_rpc/py", + #"${chip_root}/src/test_driver/efr32:nl_test_service.python", #++++ is this still needed? ] } diff --git a/src/test_driver/efr32/py/build/lib/nl_test_runner/__init__.py b/src/test_driver/efr32/py/build/lib/pw_test_runner/__init__.py similarity index 100% rename from src/test_driver/efr32/py/build/lib/nl_test_runner/__init__.py rename to src/test_driver/efr32/py/build/lib/pw_test_runner/__init__.py diff --git a/src/test_driver/efr32/py/build/lib/pw_test_runner/pw_test_runner.py b/src/test_driver/efr32/py/build/lib/pw_test_runner/pw_test_runner.py new file mode 100644 index 00000000000000..874600d6c3b674 --- /dev/null +++ b/src/test_driver/efr32/py/build/lib/pw_test_runner/pw_test_runner.py @@ -0,0 +1,138 @@ +# +# Copyright (c) 2024 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 glob +import logging +import os +import subprocess +import sys +import time +from pathlib import Path +from typing import Any + +import serial # type: ignore +from pw_hdlc import rpc +from pw_unit_test.rpc import run_tests + +PW_LOG = logging.getLogger(__name__) + +PROTO = Path(os.environ["PW_ROOT"], + "pw_unit_test/pw_unit_test_proto/unit_test.proto") + + +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 + "\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. Or a directory containing firmware images, each of which will be flashed and then run.", + ) + 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): + """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, + PROTO, + rpc.default_channels(write), + lambda data: rpc.write_to_file(data, output), + ) + + +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) + + +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() + + 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.isdir(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/nl_test_runner/__init__.py b/src/test_driver/efr32/py/nl_test_runner/__init__.py deleted file mode 100644 index e69de29bb2d1d6..00000000000000 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/pw_test_runner/pyproject.toml b/src/test_driver/efr32/py/pw_test_runner/pyproject.toml deleted file mode 100644 index 278e51755df04f..00000000000000 --- a/src/test_driver/efr32/py/pw_test_runner/pyproject.toml +++ /dev/null @@ -1,16 +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. -[build-system] -requires = ['setuptools', 'wheel'] -build-backend = 'setuptools.build_meta' diff --git a/src/test_driver/efr32/py/pw_test_runner/setup.cfg b/src/test_driver/efr32/py/pw_test_runner/setup.cfg deleted file mode 100644 index ceca50517ea520..00000000000000 --- a/src/test_driver/efr32/py/pw_test_runner/setup.cfg +++ /dev/null @@ -1,20 +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. -[metadata] -name = pw_test_runner -version = 0.0.1 - -[options] -packages = find: -zip_safe = False diff --git a/src/test_driver/efr32/py/pw_test_runner/setup.py b/src/test_driver/efr32/py/pw_test_runner/setup.py deleted file mode 100644 index ab0a7f39adca20..00000000000000 --- a/src/test_driver/efr32/py/pw_test_runner/setup.py +++ /dev/null @@ -1,17 +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 setuptools # type: ignore - -setuptools.setup() # Package definition in setup.cfg diff --git a/src/test_driver/efr32/py/pyproject.toml b/src/test_driver/efr32/py/pyproject.toml index bc6b8958f9666c..278e51755df04f 100644 --- a/src/test_driver/efr32/py/pyproject.toml +++ b/src/test_driver/efr32/py/pyproject.toml @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Project CHIP Authors +# 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. diff --git a/src/test_driver/efr32/py/setup.cfg b/src/test_driver/efr32/py/setup.cfg index cb949a38092b07..ceca50517ea520 100644 --- a/src/test_driver/efr32/py/setup.cfg +++ b/src/test_driver/efr32/py/setup.cfg @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Project CHIP Authors +# 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. diff --git a/src/test_driver/efr32/py/setup.py b/src/test_driver/efr32/py/setup.py index ba255890ff2490..ab0a7f39adca20 100644 --- a/src/test_driver/efr32/py/setup.py +++ b/src/test_driver/efr32/py/setup.py @@ -1,4 +1,4 @@ -# Copyright (c) 2022 Project CHIP Authors +# 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. diff --git a/src/test_driver/efr32/src/main.cpp b/src/test_driver/efr32/src/main.cpp index 2634d9413df95e..7815fcd3f390fc 100644 --- a/src/test_driver/efr32/src/main.cpp +++ b/src/test_driver/efr32/src/main.cpp @@ -58,114 +58,12 @@ class NlTest : public pw_rpc::nanopb::NlTest::Service public: void Run(const pw_protobuf_Empty & request, ServerWriter & writer) { - stream_writer = &writer; - nlTestSetLogger(&nl_test_logger); - - printf("--- Running nltest ---"); - int status = RunRegisteredUnitTests(); - printf("--- Running gtest ---"); - status += chip::test::RunAllTests(); + printf("--- Running pw_unit_test ---"); + int status = chip::test::RunAllTests(); printf("Test status: %d", status); - stream_writer = nullptr; - writer.Finish(); - } - -private: - static ServerWriter * stream_writer; - nl_test_output_logger_t nl_test_logger = { - chip_nl_test_log_name, chip_nl_test_log_initialize, chip_nl_test_log_terminate, chip_nl_test_log_setup, - chip_nl_test_log_test, chip_nl_test_log_teardown, chip_nl_test_log_statTest, chip_nl_test_log_statAssert, - }; - - static void StreamLogEvent(const chip_rpc_Event & event) - { - if (!stream_writer) - { - return; - } - stream_writer->Write(event); - } - - static void chip_nl_test_log_name(struct _nlTestSuite * inSuite) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_suite_start_tag; - snprintf(event.type.test_suite_start.suite_name, sizeof(event.type.test_suite_start.suite_name), "%s", inSuite->name); - StreamLogEvent(event); - } - - static void chip_nl_test_log_initialize(struct _nlTestSuite * inSuite, int inResult, int inWidth) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_case_initialize_tag; - snprintf(event.type.test_case_initialize.suite_name, sizeof(event.type.test_case_initialize.suite_name), "%s", - inSuite->name); - event.type.test_case_initialize.failed = inResult == FAILURE; - StreamLogEvent(event); - } - static void chip_nl_test_log_terminate(struct _nlTestSuite * inSuite, int inResult, int inWidth) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_case_terminate_tag; - snprintf(event.type.test_case_terminate.suite_name, sizeof(event.type.test_case_terminate.suite_name), "%s", inSuite->name); - event.type.test_case_terminate.failed = inResult == FAILURE; - StreamLogEvent(event); - } - - static void chip_nl_test_log_setup(struct _nlTestSuite * inSuite, int inResult, int inWidth) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_suite_setup_tag; - snprintf(event.type.test_suite_setup.suite_name, sizeof(event.type.test_suite_setup.suite_name), "%s", inSuite->name); - event.type.test_suite_setup.failed = inResult == FAILURE; - StreamLogEvent(event); - } - - static void chip_nl_test_log_teardown(struct _nlTestSuite * inSuite, int inResult, int inWidth) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_suite_teardown_tag; - snprintf(event.type.test_suite_teardown.suite_name, sizeof(event.type.test_suite_teardown.suite_name), "%s", inSuite->name); - event.type.test_suite_teardown.failed = inResult == FAILURE; - StreamLogEvent(event); - } - - static void chip_nl_test_log_test(struct _nlTestSuite * inSuite, int inWidth, int inIndex) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_case_run_tag; - snprintf(event.type.test_case_run.suite_name, sizeof(event.type.test_case_run.suite_name), "%s", inSuite->name); - snprintf(event.type.test_case_run.test_case_name, sizeof(event.type.test_case_run.test_case_name), "%s", - inSuite->tests[inIndex].name); - event.type.test_case_run.failed = inSuite->flagError; - StreamLogEvent(event); - } - - static void chip_nl_test_log_statTest(struct _nlTestSuite * inSuite) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_suite_tests_run_summary_tag; - snprintf(event.type.test_suite_tests_run_summary.suite_name, sizeof(event.type.test_suite_tests_run_summary.suite_name), - "%s", inSuite->name); - event.type.test_suite_tests_run_summary.total_count = inSuite->runTests; - event.type.test_suite_tests_run_summary.failed_count = inSuite->failedTests; - StreamLogEvent(event); - } - - static void chip_nl_test_log_statAssert(struct _nlTestSuite * inSuite) - { - chip_rpc_Event event = chip_rpc_Event_init_default; - event.which_type = chip_rpc_Event_test_suite_asserts_summary_tag; - snprintf(event.type.test_suite_asserts_summary.suite_name, sizeof(event.type.test_suite_asserts_summary.suite_name), "%s", - inSuite->name); - event.type.test_suite_asserts_summary.total_count = inSuite->performedAssertions; - event.type.test_suite_asserts_summary.failed_count = inSuite->failedAssertions; - StreamLogEvent(event); } }; -NlTest::ServerWriter * NlTest::stream_writer = 0; - } // namespace chip::rpc namespace {