| Component | Compile | Lines | Branches |
|---|---|---|---|
| Core |
| Plugin / suite | Compile | Lines | Branches |
|---|---|---|---|
| EEPROM | |||
| Encoder | |||
| Keypad | |||
| Networking | |||
| Odometer | |||
| Plasma/THC | |||
SD card / plugin_sdcard_stream |
|||
SD card / plugin_sdcard_fatfs |
|||
Spindle / plugin_spindle_vfd |
|||
Spindle / plugin_spindle_onoff |
|||
Spindle / plugin_spindle_pwm |
|||
Spindle / plugin_spindle_select |
|||
Spindle / plugin_spindle_offset |
|||
Spindle / plugin_spindle_clone |
|||
Spindle / plugin_spindle_stepper |
|||
| Trinamic | |||
Laser/PPI / plugin_laser_ppi |
|||
Laser/PPI / plugin_laser_cluster |
|||
Laser/PPI / plugin_laser_coolant |
|||
Laser/PPI / plugin_laser_overdrive |
|||
| Fans | |||
| Bluetooth | |||
| WebUI | |||
| OpenPNP | |||
| Embroidery | |||
| Miscellaneous | |||
| Add status of digital aux outputs to real-time report | |||
| 'Datron like' RGB indicator lights | |||
| Control panel | |||
| CRC ensured MPG communication | |||
| FlexGPIO I2C I/O expander | |||
| Homing acceleration | |||
| Interlock | |||
| PicoHAL | |||
| Pneumaseal | |||
| Sienci ATCi | |||
| Sienci Lights | |||
| Thermistor | |||
| Virtual inputs |
| Driver / suite | Compile | Lines | Branches |
|---|---|---|---|
STM32H7xx / driver_stm32h7_flash |
|||
STM32H7xx / driver_stm32h7_serial |
|||
| ESP32 | |||
| LPC176x | |||
| MSP430F5529 | |||
| MSP432E401Y | |||
| MSP432P401R | |||
PSoC5 / driver_psoc5_serial_reference |
|||
| RP2040 (Pi Pico & Pi Pico W) | |||
| SAM3X8E (Arduino Due) | |||
| SAMD21 | |||
STM32F1xx / driver_stm32f1_flash |
|||
STM32F1xx / driver_stm32f1_serial |
|||
STM32F3xx / driver_stm32f3_flash |
|||
STM32F3xx / driver_stm32f3_serial |
|||
STM32F4xx / driver_stm32f4_flash |
|||
STM32F4xx / driver_stm32f4_serial |
|||
STM32F7xx / driver_stm32f7_flash |
|||
STM32F7xx / driver_stm32f7_serial |
|||
Simulator / driver_simulator |
|||
Simulator / driver_simulator_vfs |
|||
TM4C123 / driver_tm4c123_eeprom |
|||
TM4C123 / driver_tm4c123_serial |
|||
| TM4C1294 | |||
| iMXRT1062 (Teensy 4.x) | |||
TI SimpleLink shared EEPROM and UART / driver_ti_shared_eeprom |
|||
TI SimpleLink shared EEPROM and UART / driver_ti_shared_serial_reference |
Host tests compile original source with simulated hardware callbacks. Badge percentages cover selected files and configurations. Local pass and hosted pass describe host builds; known regressions are tracked separately. Grey badges mark work not added or measured. Legacy only uses an older CORE. Component revisions and scope.
- Known CORE defects and fix guidance
- Pending features and contract questions
- Coverage gaps and coverage closeout
- Plugin and driver backlog and progress
- Component defects:
tests/plugins/<name>/KNOWN_BUGS.mdortests/drivers/<name>/KNOWN_BUGS.md
Open Actions, choose Core tests, Plugin tests or Driver tests,
then select Run workflow. Choose the harness branch to run; for plugins and
drivers, also choose a registered suite.
| Input | Use |
|---|---|
source_repository |
Source owner/repo or GitHub URL; blank uses the suite default |
source_ref |
Branch, tag or commit SHA; blank uses the default branch |
source_pr |
PR number in the selected repository; leave source_ref blank |
core_ref |
CORE dependency branch, tag or SHA for plugin/driver suites |
source_base_ref, source_base_repository |
Optional comparison base for changed-code coverage; available in Core tests |
Defaults are in ci/suites.json; CORE defaults to
grblHAL/core at master. A different source repository requires an explicit
ref or PR number. PR selection tests its head commit, including fork PRs.
Each run records exact harness and source commits in source-lock.json.
Use commit SHAs to repeat the same source selection.
gh workflow run tests.yml --repo grblHAL/Unit_tests --ref master -f source_pr=123
gh workflow run plugins.yml --repo grblHAL/Unit_tests --ref master \
-f suite=plugin_eeprom -f source_ref=my-fix -f core_ref=CORE_SHAReplace CORE_SHA with a real commit, or omit core_ref to use the default.
Manual runs require write access. GCC and Clang run sanitizer tests; GCC also
publishes coverage. Selected ARM driver suites include module compile checks.
These checks do not replace firmware builds or controller testing.
Call reusable-tests.yml from another repository's workflow. Start with the CORE caller or the plugin caller template. The run appears in the calling repository's Actions and PR checks.
| Input | Set it to |
|---|---|
harness_repository |
Tests repository, normally grblHAL/Unit_tests (required) |
harness_ref |
Same branch, tag or SHA as the reusable workflow's uses: ...@ref (required) |
suite |
Key in ci/suites.json; defaults to core |
source_repository |
Repository containing the code to test; blank uses the suite default |
source_ref |
Source branch, tag or SHA; omit when using source_pr |
source_pr |
PR number in the selected source repository |
source_base_ref |
Optional comparison-base branch, tag or SHA |
source_base_repository |
Base repository; defaults to the selected source repository |
core_ref |
CORE dependency revision for a plugin/driver suite; leave blank for CORE tests |
run_label |
Unique artifact name suffix when calling more than once; defaults to core |
The harness revision selects the tests; the source revision selects the code
being tested. Keep the workflow uses ref and harness_ref on the same version.
No dispatch token or inherited secrets are needed.
Install Python 3, CMake and GCC or GNU-compatible Clang. Windows builds can use llvm-mingw with Ninja; MSVC supports only standalone modules.
git clone https://github.com/grblHAL/Unit_tests.git
cd Unit_tests
python scripts/resolve_source.py
python scripts/prepare_sources.py
python scripts/configure_suite.py --mode sanitizers --compiler clang
python scripts/build_suite.py
python scripts/run_suite.py test
python scripts/run_suite.py summaryFor another suite or source, pass the selection to resolve_source.py:
python scripts/resolve_source.py --suite plugin_eeprom --ref my-fix --core-ref CORE_SHAUse a fresh checkout when switching locked sources; preparation refuses to
overwrite dirty or mismatched source directories. On Windows, put the compiler's
bin directory on PATH for sanitizer DLLs and set
$env:CMAKE_GENERATOR = "Ninja" before configuring.
The ignored core directory can be a fresh ordinary clone, an existing local
checkout or a worktree. It is not staged in this test repository. You can test
uncommitted fixes without publishing them. Hosted CI needs a reachable commit,
but pushing to your fork is enough; no upstream merge is required.
For a fresh checkout, resolve and fetch:
python scripts/resolve_source.py --repository yourname/core --ref my-fix
python scripts/prepare_sources.pyThe fetch helper refuses to overwrite dirty checkouts or silently change existing revisions. For an existing checkout, preserve local changes and switch explicitly:
git -C core status --short
git -C core fetch origin my-fix
git -C core checkout --detach FETCH_HEAD
git -C core rev-parse HEADUse a fresh build directory when switching revisions. Save the tested SHA with your results, then follow the regression cleanup steps below.
Use a sanitizer build, including the summary check. For Windows llvm-mingw,
replace the compiler path below with your installation and put its bin
directory on PATH as described under Run locally.
cmake -S . -B build-asan -G Ninja -DCMAKE_C_COMPILER=C:/path/to/llvm-mingw/bin/clang.exe -DCMAKE_BUILD_TYPE=Debug -DENABLE_SANITIZERS=ON
cmake --build build-asan --parallel
ctest --test-dir build-asan --output-on-failure --output-junit results.xml
python scripts/summary.py tests build-asan/results.xmlOn Linux, use -DCMAKE_C_COMPILER=clang or gcc instead. If an existing build
uses another compiler or generator, use a new build directory. Reconfigure after
changing exception registrations so CTest picks up the changes.
A fixed assertion regression may initially appear as a CTest failure because its
WILL_FAIL exception expects the executable to fail. Confirm the executable now
passes its correct assertions; do not change those assertions to match the old
bug. For one test, inspect its output with:
ctest --test-dir build-asan -V -R '^utf8\.ascii$'Replace utf8.ascii with the test name listed in the defect entry. Run the full
suite as well: a core update can affect more than the defect being fixed.
Start with its entry in tests/KNOWN_BUGS.md. Each entry links to the affected tests and says exactly which exception registrations or scripts need cleanup. Depending on the defect, cleanup is in these places:
- Wrong result / expected assertion failure: remove the matching complete
if(TEST ...) ... endif()block from tests/known_bugs.cmake. This removesWILL_FAILand theknown_buglabel, making the test an ordinary passing test. - Correct result with an undefined-behavior warning: delete every JSON object
with that defect's
issueidentifier from tests/known_sanitizer_diagnostics.json. These exceptions are documented inKNOWN_BUGS.md, but the actual warning allowance is stored in this JSON file. One defect can have several objects. Remove all objects for the resolved issue, keeping valid JSON (an empty manifest is[]). Also remove that test'sknown_sanitizer_buglabel block from tests/known_bugs.cmake. The label applies only to sanitizer builds: if its expected diagnostic disappears, reporting fails with cleanup guidance. An unrelated diagnostic or assertion still fails. Keep the correct output assertions; the summary must then report a clean pass. - Memory defect checked by a diagnostic wrapper: follow the defect's linked
instructions to replace its special Python-wrapper registration in
CMakeLists.txt with a normal executable test. Remove the
matching exception in
tests/known_bugs.cmakeand any obsolete matcher. The executable must pass under sanitizers without relying on the old diagnostic. - Feature configuration that previously could not compile: replace the linked diagnostic-matching compile check with a normal successful compile check for that configuration. Remove its expected-failure registration and obsolete matcher, following the links in the defect entry.
Keep the regression test means keep its file in tests/cases/ and its check
for the correct behavior. For example, tests/cases/utf8/ascii.c must continue
checking that A encodes as byte 0x41 after the encoding bug is fixed. The test
then guards against a future change reintroducing that bug. Delete the exception
that tolerates the bug, rather than deleting the test that catches it.
After removing the exceptions, reconfigure, rebuild and rerun the full sanitizer suite and summary using the commands above. All affected tests must be ordinary clean passes. Also run the coverage build under Measure coverage locally. Do not weaken expectations or broaden diagnostic allowances to make an update green.
Once the fix passes without its exceptions, delete the entire resolved defect section from tests/KNOWN_BUGS.md. That file lists outstanding defects only. Put the fix date and core commit in the Git commit message, where history preserves them. If only part of a multi-test defect is fixed, retain an entry covering the remaining failures and their exceptions.
Check that remaining documentation links still point to the correct exception blocks and source lines; deleting blocks can shift line numbers. Refresh any remaining diagnostic source-line matches if upstream edits moved them, after confirming the same defect still reproduces.
git diff --check
git diffStage the documentation, exception and registration files you actually changed as well. Commit the test and exception cleanup, then push and verify both GCC and Clang sanitizer jobs and the coverage job in GitHub Actions. If the new core introduces an additional defect, add a separate correctly expected regression and dated known-bug entry; do not silently waive it.
Use a separate build without sanitizers. Install the CI reporter:
python -m pip install gcovr==8.4.
cmake -S . -B build-coverage -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=gcc -DENABLE_COVERAGE=ON
cmake --build build-coverage --parallel
ctest --test-dir build-coverage --output-on-failure
gcovr --merge-mode-functions=separate --root . --filter 'core/.*\.[ch]$' --html-details coverage.html --xml coverage.xml --print-summary build-coverage
python scripts/summary.py coverage coverage.xmlFor Clang, select clang when configuring and add
--gcov-executable "llvm-cov gcov" to gcovr. Coverage combines the configured
feature variants, including emitted header code. Use a new build directory for
a fresh measurement. On Windows, verify .gcda files are produced; long paths
can prevent LLVM from writing them even when tests pass.
Compile original source; do not copy implementations into tests. Use public commands and APIs, shared fixtures, and assertions about observable behavior. Keep unrelated behaviors in separate files. Include useful expected/actual values when an assertion alone would be ambiguous.
- CORE: add
tests/cases/<module>/<case>.c; CMake discovers it automatically. Add required module dependencies inadd_core_test(). - Plugin or driver: add a CMake project under
tests/plugins/<name>ortests/drivers/<name>, register its suite in ci/suites.json, then add the suite to the matching workflow's choices. Reuse an existing component project as a starting point. - Regression: retain the correct assertions. Document confirmed defects and
narrow exceptions in the suite's
KNOWN_BUGS.md; remove exceptions after a fix using the steps above.
| Field | Purpose |
|---|---|
repository, ref |
Source repository and default branch/tag |
path |
Ignored source checkout directory |
dependencies |
Direct registry entries to fetch; source must still be linked explicitly |
source_only |
Dependency checkout with no selectable test suite |
cmake_source, cmake_options |
CMake project and configure arguments |
test_regex |
CTest names selected by the suite; zero selected tests fails |
coverage_filter |
gcovr filter for measured source files |
diagnostics_directory |
Suite directory containing its exception inventory |
host_bits |
Optional 32-bit host build; defaults to 64 |
Register implementation repositories from the plugin and driver catalogues. Dependencies are resolved directly; arbitrary nested dependency graphs are not supported. Firmware fixes belong in the source repository.