From 25cd5ffafca18e7c12b9418622da77d8e6f8fafa Mon Sep 17 00:00:00 2001 From: Ed Date: Fri, 19 Apr 2024 10:34:56 +0100 Subject: [PATCH] Rejig runner gen --- .gitignore | 1 + tests/xua_unit_tests/CMakeLists.txt | 20 +-- tests/xua_unit_tests/conftest.py | 4 +- tests/xua_unit_tests/generate_unity_runner.py | 59 ++++++++ .../xua_unit_tests/generate_unity_runners.py | 134 ------------------ 5 files changed, 73 insertions(+), 145 deletions(-) create mode 100755 tests/xua_unit_tests/generate_unity_runner.py delete mode 100644 tests/xua_unit_tests/generate_unity_runners.py diff --git a/.gitignore b/.gitignore index 29cab6ac..4ca12179 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ host_usb_mixer_control/xmos_mixer midi_tx_cmds.txt midi_rx_cmds.txt trace.txt +tests/xua_unit_tests/src.runners diff --git a/tests/xua_unit_tests/CMakeLists.txt b/tests/xua_unit_tests/CMakeLists.txt index da0b80a9..f8b0ad6d 100644 --- a/tests/xua_unit_tests/CMakeLists.txt +++ b/tests/xua_unit_tests/CMakeLists.txt @@ -13,17 +13,19 @@ configure_file( conftest.py conftest.py COPYONLY ) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) # Set unity runner generate script -set( GEN_RUNNER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/generate_unity_runner.py ) +set(GEN_RUNNER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/generate_unity_runner.py) # Create directory for runner files -set( RUNNERS_DIR ${CMAKE_CURRENT_BINARY_DIR}/src.runners ) -file( MAKE_DIRECTORY ${RUNNERS_DIR} ) +set(RUNNERS_DIR ${CMAKE_CURRENT_LIST_DIR}/src.runners ) +file(MAKE_DIRECTORY ${RUNNERS_DIR} ) # Find unit test files -file( GLOB_RECURSE TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/test_*/*.c ) +file(GLOB_RECURSE TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/test_*/*.c) # For every source file in xua_unit_tests/ foreach(TESTFILE ${TEST_SOURCES}) + set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) + # Get test name from C file stem cmake_path(GET TESTFILE STEM TESTNAME) project(${TESTNAME}) @@ -39,20 +41,19 @@ foreach(TESTFILE ${TEST_SOURCES}) set( GEN_RUNNER_SCRIPT_BYPRODUCTS ${RUNNER_FILE}) unset(GEN_RUNNER_SCRIPT_ARGS) - list(APPEND GEN_RUNNER_SCRIPT_ARGS --project-root ${UNITY_PATH}/..) + list(APPEND GEN_RUNNER_SCRIPT_ARGS --project-root ${XMOS_SANDBOX_DIR}) list(APPEND GEN_RUNNER_SCRIPT_ARGS --source-file ${TESTFILE}) list(APPEND GEN_RUNNER_SCRIPT_ARGS --runner-file ${RUNNER_FILE}) ## Add command to generate runner file add_custom_command( OUTPUT ${RUNNER_FILE} - COMMAND ${Python3_EXECUTABLE} ${GEN_RUNNER_SCRIPT} ${GEN_RUNNER_SCRIPT_ARGS} - COMMENT "Generating XUA Unit Test Runner" ) + COMMAND python ${GEN_RUNNER_SCRIPT} ${GEN_RUNNER_SCRIPT_ARGS} + COMMENT "Generate XUA Unit Test Runner" ) ########################## ## Do xcommon cmake build ########################## - set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..) set(APP_HW_TARGET XK-EVK-XU316) set(APP_DEPENDENT_MODULES "lib_xua") # set(APP_PCA_ENABLE ON) @@ -77,8 +78,9 @@ foreach(TESTFILE ${TEST_SOURCES}) # Workaround for xcommon cmake pre-pending CMAKE_CURRENT_LIST_DIR string(REPLACE ${CMAKE_CURRENT_LIST_DIR} "" UNIT_TEST_SOURCE_RELATIVE ${TESTFILE}) + string(REPLACE ${CMAKE_CURRENT_LIST_DIR} "" RUNNER_FILE_RELATIVE ${RUNNER_FILE}) - set(APP_C_SRCS runners/${TESTNAME}/${TESTNAME}_Runner.c + set(APP_C_SRCS ${RUNNER_FILE_RELATIVE} ${UNIT_TEST_SOURCE_RELATIVE} ../../../Unity/src/unity.c ) diff --git a/tests/xua_unit_tests/conftest.py b/tests/xua_unit_tests/conftest.py index 2128a9b7..b25f534f 100644 --- a/tests/xua_unit_tests/conftest.py +++ b/tests/xua_unit_tests/conftest.py @@ -1,4 +1,4 @@ -# Copyright 2021-2022 XMOS LIMITED. +# Copyright 2021-2024 XMOS LIMITED. # This Software is subject to the terms of the XMOS Public Licence: Version 1. from __future__ import print_function from builtins import str @@ -28,7 +28,7 @@ class UnityTestSource(pytest.File): # unit_tests/ <- Test root directory # |-- bin/ <- Compiled binaries of the test runners # |-- conftest.py <- This file - # |-- runners/ <- Auto-generated buildable source of test binaries + # |-- src.runners <- Auto-generated buildable source of test binaries # |-- src/ <- Unity test functions # `-- wscript <- Build system file used to generate/build runners xe_name = ((os.path.basename(self.name)).split("."))[0] + ".xe" diff --git a/tests/xua_unit_tests/generate_unity_runner.py b/tests/xua_unit_tests/generate_unity_runner.py new file mode 100755 index 00000000..7d8dfef1 --- /dev/null +++ b/tests/xua_unit_tests/generate_unity_runner.py @@ -0,0 +1,59 @@ +# Copyright 2024 XMOS LIMITED. +# This Software is subject to the terms of the XMOS Public Licence: Version 1. + +import glob +import os.path +import subprocess +import sys +import argparse + +def parse_arguments(): + parser = argparse.ArgumentParser() + parser.add_argument("--project-root", nargs='?', help="Project root directory") + parser.add_argument("--source-file", nargs='?', help="source file.") + parser.add_argument("--runner-file", nargs='?', help="runner file.") + args = parser.parse_args() + return args + +def get_ruby(): + """ + Check ruby is avaliable and return the command to invoke it. + """ + interpreter_name = 'ruby' + try: + dev_null = open(os.devnull, 'w') + # Call the version command to check the interpreter can be run + subprocess.check_call([interpreter_name, '--version'], + stdout=dev_null, + close_fds=True) + except OSError as e: + print("Failed to run Ruby interpreter: {}".format(e), file=sys.stderr) + exit(1) # TODO: Check this is the correct way to kill xwaf on error + + return interpreter_name + +def get_unity_runner_generator(project_root_path): + """ + Check the Unity generate_test_runner script is avaliable, and return the + path to it. + """ + unity_runner_generator = os.path.join( + project_root_path, 'Unity', 'auto', 'generate_test_runner.rb') + if not os.path.exists(unity_runner_generator): + print("Unity repo not found in workspace", file=sys.stderr) + exit(1) # TODO: Check this is the correct way to kill xwaf on error + return unity_runner_generator + +if __name__ == "__main__": + args = parse_arguments() + print(f"in python: root {args.project_root}, source {args.source_file}, runner {args.runner_file}") + + try: + subprocess.check_call([get_ruby(), + get_unity_runner_generator(args.project_root), + args.source_file, + args.runner_file]) + except OSError as e: + print("Ruby generator failed for {}\n\t{}".format(unity_test_path, e), + file=sys.stderr) + exit(1) # TODO: Check this is the correct way to kill xwaf on error diff --git a/tests/xua_unit_tests/generate_unity_runners.py b/tests/xua_unit_tests/generate_unity_runners.py deleted file mode 100644 index 7276d969..00000000 --- a/tests/xua_unit_tests/generate_unity_runners.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright 2021-2022 XMOS LIMITED. -# This Software is subject to the terms of the XMOS Public Licence: Version 1. -import glob -import os.path -import subprocess -import sys - -UNITY_TEST_DIR = "src" -UNITY_TEST_PREFIX = "test_" -UNITY_RUNNER_DIR = "runners" -UNITY_RUNNER_SUFFIX = "_Runner" -project_root = os.path.join("..", "..", "..") - - -def get_ruby(): - """ - Check ruby is avaliable and return the command to invoke it. - """ - interpreter_name = "ruby" - try: - dev_null = open(os.devnull, "w") - # Call the version command to check the interpreter can be run - subprocess.check_call( - [interpreter_name, "--version"], stdout=dev_null, close_fds=True - ) - except OSError as e: - print("Failed to run Ruby interpreter: {}".format(e), file=sys.stderr) - exit(1) # TODO: Check this is the correct way to kill xwaf on error - - return interpreter_name - - -def get_unity_runner_generator(project_root_path): - """ - Check the Unity generate_test_runner script is avaliable, and return the - path to it. - """ - unity_runner_generator = os.path.join( - project_root_path, "Unity", "auto", "generate_test_runner.rb" - ) - if not os.path.exists(unity_runner_generator): - print("Unity repo not found in workspace", file=sys.stderr) - exit(1) # TODO: Check this is the correct way to kill xwaf on error - return unity_runner_generator - - -def get_test_name(test_path): - """ - Return the test name by removing the extension from the filename. - """ - return os.path.splitext(os.path.basename(test_path))[0] - - -def get_file_type(filename): - """ - Return the extension from the filename. - """ - return filename.rsplit(".")[-1:][0] - - -def generate_unity_runner( - project_root_path, unity_test_path, unity_runner_dir, unity_runner_suffix -): - """ - Invoke the Unity runner generation script for the given test file, and - return the path to the generated file. The output directory will be created - if it does not already exist. - """ - runner_path = os.path.join( - os.path.join(unity_runner_dir, get_test_name(unity_test_path)) - ) - if not os.path.exists(runner_path): - os.makedirs(runner_path) - - unity_runner_path = os.path.join( - runner_path, get_test_name(unity_test_path) + unity_runner_suffix + "." + "c" - ) - - try: - subprocess.check_call( - [ - get_ruby(), - get_unity_runner_generator(project_root_path), - unity_test_path, - unity_runner_path, - ] - ) - except OSError as e: - print( - "Ruby generator failed for {}\n\t{}".format(unity_test_path, e), - file=sys.stderr, - ) - exit(1) # TODO: Check this is the correct way to kill xwaf on error - - -def find_unity_test_paths(unity_test_dir, unity_test_prefix): - """ - Return a list of all file paths with the unity_test_prefix found in the - unity_test_dir. - """ - return glob.glob(os.path.join(unity_test_dir, unity_test_prefix + "*")) - - -def find_unity_tests(unity_test_dir, unity_test_prefix): - """ - Return a dictionary of all {test names, test language} pairs with the - unity_test_prefix found in the unity_test_dir. - """ - unity_test_paths = find_unity_test_paths(unity_test_dir, unity_test_prefix) - print("unity_test_paths = ", unity_test_paths) - return {get_test_name(path): get_file_type(path) for path in unity_test_paths} - - -def find_unity_test_paths(unity_test_dir, unity_test_prefix): - """ - Return a list of all file paths with the unity_test_prefix found in the - unity_test_dir. - """ - return glob.glob(os.path.join(unity_test_dir, unity_test_prefix + "*")) - - -def generate_runners(): - UNITY_TESTS = find_unity_tests(UNITY_TEST_DIR, UNITY_TEST_PREFIX) - print("UNITY_TESTS = ", UNITY_TESTS) - unity_test_paths = find_unity_test_paths(UNITY_TEST_DIR, UNITY_TEST_PREFIX) - print("unity_test_paths = ", unity_test_paths) - for unity_test_path in unity_test_paths: - generate_unity_runner( - project_root, unity_test_path, UNITY_RUNNER_DIR, UNITY_RUNNER_SUFFIX - ) - - -if __name__ == "__main__": - generate_runners()