From cc7d6d767486d9db3f5b1113715fffeff6370959 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Mon, 9 Feb 2026 00:06:15 +0100 Subject: [PATCH] Add DevicetreeCompiler tests --- .github/workflows/tests.yml | 13 ++- .../tests/data/bindings/test,device.yaml | 14 +++ .../tests/data/bindings/test,root.yaml | 5 + .../tests/data/devicetree.yaml | 2 + .../DevicetreeCompiler/tests/data/test.dts | 17 +++ .../tests/test_integration.py | 101 ++++++++++++++++++ 6 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 Buildscripts/DevicetreeCompiler/tests/data/bindings/test,device.yaml create mode 100644 Buildscripts/DevicetreeCompiler/tests/data/bindings/test,root.yaml create mode 100644 Buildscripts/DevicetreeCompiler/tests/data/devicetree.yaml create mode 100644 Buildscripts/DevicetreeCompiler/tests/data/test.dts create mode 100644 Buildscripts/DevicetreeCompiler/tests/test_integration.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 34f4da79..f6b8f1b7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,7 +6,7 @@ on: pull_request: types: [ opened, synchronize, reopened ] jobs: - run: + TactilityTests: runs-on: ubuntu-latest steps: - name: "Checkout repo" @@ -27,3 +27,14 @@ jobs: run: build/Tests/Tactility/TactilityTests - name: "Run TactilityKernel Tests" run: build/Tests/TactilityKernel/TactilityKernelTests + DevicetreeTests: + runs-on: ubuntu-latest + steps: + - name: "Checkout repo" + uses: actions/checkout@v2 + with: + submodules: recursive + - name: "Run Devicetree Tests" + shell: bash + working-directory: Buildscripts/DevicetreeCompiler/Tests + run: python test_integration.py diff --git a/Buildscripts/DevicetreeCompiler/tests/data/bindings/test,device.yaml b/Buildscripts/DevicetreeCompiler/tests/data/bindings/test,device.yaml new file mode 100644 index 00000000..cbb16527 --- /dev/null +++ b/Buildscripts/DevicetreeCompiler/tests/data/bindings/test,device.yaml @@ -0,0 +1,14 @@ +description: Test device binding +compatible: "test,device" +properties: + reg: + type: int + required: true + status: + type: string + boolean-prop: + type: boolean + int-prop: + type: int + string-prop: + type: string diff --git a/Buildscripts/DevicetreeCompiler/tests/data/bindings/test,root.yaml b/Buildscripts/DevicetreeCompiler/tests/data/bindings/test,root.yaml new file mode 100644 index 00000000..3d2b130b --- /dev/null +++ b/Buildscripts/DevicetreeCompiler/tests/data/bindings/test,root.yaml @@ -0,0 +1,5 @@ +description: Test root binding +compatible: "test,root" +properties: + model: + type: string diff --git a/Buildscripts/DevicetreeCompiler/tests/data/devicetree.yaml b/Buildscripts/DevicetreeCompiler/tests/data/devicetree.yaml new file mode 100644 index 00000000..52538f38 --- /dev/null +++ b/Buildscripts/DevicetreeCompiler/tests/data/devicetree.yaml @@ -0,0 +1,2 @@ +dts: test.dts +bindings: bindings diff --git a/Buildscripts/DevicetreeCompiler/tests/data/test.dts b/Buildscripts/DevicetreeCompiler/tests/data/test.dts new file mode 100644 index 00000000..78702277 --- /dev/null +++ b/Buildscripts/DevicetreeCompiler/tests/data/test.dts @@ -0,0 +1,17 @@ +/dts-v1/; + +#include + +/ { + compatible = "test,root"; + model = "Test Model"; + + test_device: test-device@0 { + compatible = "test,device"; + reg = <0>; + status = "okay"; + boolean-prop; + int-prop = <42>; + string-prop = "hello"; + }; +}; diff --git a/Buildscripts/DevicetreeCompiler/tests/test_integration.py b/Buildscripts/DevicetreeCompiler/tests/test_integration.py new file mode 100644 index 00000000..343d8d81 --- /dev/null +++ b/Buildscripts/DevicetreeCompiler/tests/test_integration.py @@ -0,0 +1,101 @@ +import os +import subprocess +import shutil +import sys +import tempfile + +# Path to the compile.py script +# We assume this script is in Buildscripts/DevicetreeCompiler/tests/ +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, "..")) +COMPILE_SCRIPT = os.path.join(PROJECT_ROOT, "compile.py") +TEST_DATA_DIR = os.path.join(SCRIPT_DIR, "data") + +def run_compiler(config_path, output_path): + result = subprocess.run( + [sys.executable, COMPILE_SCRIPT, config_path, output_path], + capture_output=True, + text=True, + cwd=PROJECT_ROOT + ) + return result + +def test_compile_success(): + print("Running test_compile_success...") + with tempfile.TemporaryDirectory() as output_dir: + result = run_compiler(TEST_DATA_DIR, output_dir) + + if result.returncode != 0: + print(f"FAILED: Compilation failed: {result.stderr}") + return False + + if not os.path.exists(os.path.join(output_dir, "devicetree.c")): + print("FAILED: devicetree.c not generated") + return False + + if not os.path.exists(os.path.join(output_dir, "devicetree.h")): + print("FAILED: devicetree.h not generated") + return False + + print("PASSED") + return True + +def test_compile_invalid_dts(): + print("Running test_compile_invalid_dts...") + with tempfile.TemporaryDirectory() as tmp_dir: + bad_data_dir = os.path.join(tmp_dir, "bad_data") + os.makedirs(bad_data_dir) + output_dir = os.path.join(tmp_dir, "output") + os.makedirs(output_dir) + + with open(os.path.join(bad_data_dir, "devicetree.yaml"), "w") as f: + f.write("dts: bad.dts\nbindings: bindings") + + with open(os.path.join(bad_data_dir, "bad.dts"), "w") as f: + f.write("/dts-v1/;\n / { invalid syntax }") + + os.makedirs(os.path.join(bad_data_dir, "bindings")) + + result = run_compiler(bad_data_dir, output_dir) + + if result.returncode == 0: + print("FAILED: Compilation should have failed but succeeded") + return False + + print("PASSED") + return True + +def test_compile_missing_config(): + print("Running test_compile_missing_config...") + with tempfile.TemporaryDirectory() as output_dir: + result = run_compiler("/non/existent/path", output_dir) + + if result.returncode == 0: + print("FAILED: Compilation should have failed for non-existent path") + return False + + if "Directory not found" not in result.stdout: + print(f"FAILED: Expected 'Directory not found' error message, got: {result.stdout}") + return False + + print("PASSED") + return True + +if __name__ == "__main__": + tests = [ + test_compile_success, + test_compile_invalid_dts, + test_compile_missing_config + ] + + failed = 0 + for test in tests: + if not test(): + failed += 1 + + if failed > 0: + print(f"\n{failed} tests failed") + sys.exit(1) + else: + print("\nAll tests passed") + sys.exit(0)