Repository navigation
test: ztest: port fft and fft_multi CMocka tests to ztest - #11369
Merged
lgirdwood merged 5 commits intoOct 28, 2026
Merged
Conversation
tmleman
requested review from
dabekjakub,
dbaluta,
kv2019i,
lbetlej,
lgirdwood,
mmaka1 and
plbossart
as code owners
October 28, 2026 13:07
2 tasks
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the FFT and multi-size FFT test migration to Zephyr ztest.
No open issues 🎉
What changed in this PR
Ports the FFT and multi-size FFT tests to Zephyr ztest as part of #10110, while retaining the existing CMocka tests and sharing their reference vectors.
Changes:
- Adds native-simulator suites covering FFT/IFFT accuracy, signal-to-noise ratios, and peak detection.
- Adds shared test allocation tracking and minimal SOF context support.
- Enables address and leak sanitizers in CI and adds object-pool cleanup.
| File | Description |
|---|---|
zephyr/lib/alloc.c |
Guards the heap accessor to avoid conflicting with the unit-test stub. |
test/ztest/unit/objpool/test_objpool_ztest.c |
Prunes object pools after tests. |
test/ztest/unit/math/fft/testcase.yaml |
Registers the FFT suite for native_sim. |
test/ztest/unit/math/fft/test_fft_ztest.c |
Ports 16-bit and 32-bit FFT/IFFT tests to ztest. |
test/ztest/unit/math/fft/prj.conf |
Configures sample formats and sanitizer-visible heap allocation. |
test/ztest/unit/math/fft/CMakeLists.txt |
Links FFT tests, shared vectors, and required SOF sources. |
test/ztest/unit/math/fft_multi/testcase.yaml |
Registers the multi-size FFT suite for native_sim. |
test/ztest/unit/math/fft_multi/test_fft_multi_ztest.c |
Checks multi-size FFT/IFFT results against shared reference vectors. |
test/ztest/unit/math/fft_multi/prj.conf |
Configures sanitizer-visible heap allocation. |
test/ztest/unit/math/fft_multi/CMakeLists.txt |
Links multi-size FFT tests and supporting sources. |
test/ztest/unit/common/sof_context.c |
Supplies a minimal SOF context for standalone tests. |
test/ztest/unit/common/mod_alloc.h |
Declares allocation tracking and cleanup helpers. |
test/ztest/unit/common/mod_alloc.c |
Implements the test allocator and post-test leak checks. |
.github/workflows/zephyr-unit-tests.yml |
Enables sanitizers and disables debuginfod queries during test execution. |
Review effort: Balanced
The three objpool test cases allocate objects from a local objpool_head
but never release the pools themselves. objpool_free() only clears the
in-use bit of an object, the backing pool stays allocated, so every test
case leaks the pools it created: 772 bytes in 9 objects for the suite.
Call objpool_prune(), which unlinks and frees every pool of a head, at
the end of each test case.
Without this the suite fails once the unit tests run under LeakSanitizer:
west twister --testsuite-root sof/test/ztest/unit/ --platform native_sim \
--enable-asan --enable-lsan
Assisted-by: Copilot:claude-opus-5
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
…r app zephyr/lib/alloc.c is compiled by the firmware only when CONFIG_SOF_FULL_ZEPHYR_APPLICATION=y. Without that option rtos/alloc.h already provides a static inline sof_sys_heap_get() returning NULL, so a standalone application that links alloc.c directly, such as a ztest unit test, gets two conflicting definitions of the symbol. Guard the out-of-line definition with the same condition as the header, so the two always agree. Firmware builds are not affected: they set CONFIG_SOF_FULL_ZEPHYR_APPLICATION and keep the out-of-line version. Assisted-by: Copilot:claude-opus-5 Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Suites that exercise code calling the mod_alloc() API cannot link the production allocator in src/audio/module_adapter/module/generic.c without pulling in the whole module adapter, IPC and objpool infrastructure. Suites that link src/audio/component.c need sof_get(), which lives in src/init/init.c and drags in the full firmware init path. Add two reusable pieces under test/ztest/unit/common/: mod_alloc.c/.h implements mod_alloc_ext(), mod_balloc_align(), mod_free() and mod_free_all() on top of sof_ctx_alloc()/sof_ctx_free(), with the same allocation flags and the same zero-size and unknown-pointer handling as generic.c. Like generic.c it keeps a list of the live allocations, so mod_free_all() works without an objpool and a suite can detect leaked, double-freed or foreign pointers on its own. mod_alloc_test_after() is ready to install as the ztest after-hook, so a leaking test case is named instead of only producing an allocation stack at exit. sof_context.c provides the minimal sof_get(), created on first use with only its component driver list initialised, which is what buffer_new() and the component infrastructure need. Both files are unused until a suite links them, so no existing test changes behaviour. Assisted-by: Copilot:claude-opus-5 Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
Port the legacy CMocka unit tests test/cmocka/src/math/fft/fft.c and
fft_multi.c to Zephyr ztest suites under
test/ztest/unit/math/{fft,fft_multi}/.
sof.unit.math.fft mirrors fft.c: it links comp_buffer/audio_buffer and
the surrounding module_adapter/pipeline/ipc plumbing (as
test/ztest/unit/audio/drc already does) so buffer_new()/rzalloc() work
standalone, and converts each of the 9 SNR/peak-bin checks (16- and
32-bit FFT/IFFT, mono and 2-channel) into its own ZTEST case.
sof.unit.math.fft_multi mirrors fft_multi.c: it only links
fft_multi[.c/_generic.c/_hifi3.c] and fft_common.c/fft_32.c (no
comp_buffer/pipeline needed, matching the legacy CMakeLists.txt), and
splits the single CMocka group test into 11 ZTEST cases, one per FFT/
IFFT size, each still checked against the same max-error-abs/RMS
thresholds. The debug fopen()/fclose() dumps in the original
fft_multi_32_test() were unused diagnostics and are dropped; everything
else is unchanged. Reference vectors (input.h, ref_*fft_multi_*_32.h)
are #included in place from the CMocka tree via the include path, shared
verbatim between both frameworks, as test/ztest/unit/math/{a_law,mu_law}
already do. The CMocka tests keep running unchanged.
Both suites link the real SOF allocator, zephyr/lib/alloc.c, instead of a
per-suite malloc() replacement of rmalloc()/rzalloc()/rfree()/
sof_heap_alloc(). alloc.c has two native_sim back ends: the Zephyr
sys_heap, the default and the same allocator as firmware, and host
malloc()/free() through nsi_host_malloc()
(CONFIG_SOF_NATIVE_SIM_HOST_HEAP). ASan and LSan cannot see blocks carved
out of the static sys_heap arena, so the suites select the host back end
and stay checkable; the arena is still reserved and initialised by
heap_init(), hence CONFIG_SYS_HEAP_BIG_ONLY=y, its 256 KiB being too
large for SYS_HEAP_SMALL_ONLY. Firmware and the libfuzzer build do not
set the option and keep sys_heap.
The module allocator and the minimal sof_get() come from
test/ztest/unit/common/. mod_alloc_test_after() is installed as the ztest
after-hook of both suites, so a test case leaking an FFT plan is named
rather than only reported as an allocation stack at exit. ASan builds get
-fno-omit-frame-pointer, so the reports show the full allocation stack.
Verified with:
west twister --testsuite-root sof/test/ztest/unit/ --platform native_sim
-> sof.unit.math.fft: 9/9 cases PASSED
-> sof.unit.math.fft_multi: 11/11 cases PASSED
-> whole unit tree: 14/14 configurations, 118/118 cases PASSED, with
and without --enable-asan --enable-lsan
ctest --test-dir <cmocka build> -R '^fft$|^fft_multi$'
-> fft, fft_multi: PASSED (unchanged)
A leaked mod_alloc() is reported by mod_alloc_test_after() and a leaked
rzalloc() by LSan, both naming test_fft_ztest.c. The sof/app native_sim
build works with both heap back ends and the mtl firmware build is
unchanged.
Coverage of the sources under test, CMocka (gcc) vs ztest (clang);
totals differ because clang does not instrument bare
variable-declaration lines that gcc counts:
file CMocka line% ztest line%
src/math/fft/fft_16.c 100% 94.4%
src/math/fft/fft_32.c 100% 94.7%
src/math/fft/fft_common.c 73.2% 70.9%
src/math/fft/fft_multi.c 72.9% 73.6%
src/math/fft/fft_multi_generic.c 100% 100%
For fft_16.c that is 42 lines counted by gcc against 36 by clang. The
executed logic (bit-reverse loop, FFT butterfly stages, ifft branch) is
fully exercised by both and the function-entry counts match exactly, for
example 5 calls to fft_execute_16().
Assisted-by: Copilot:claude-opus-5
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
The Zephyr Unit tests workflow builds and runs the whole test/ztest/unit/ tree on native_sim, but without any sanitizer, so a suite that leaks memory still reports as passed. Add --enable-asan --enable-lsan to the twister invocation, so a leak fails CI. DEBUGINFOD_URLS has to be empty there. Otherwise llvm-symbolizer queries debuginfod while LSan prints the leak report, which takes longer than twister's post-verdict grace period; twister then kills the binary, ignores its exit code and reports the leaking suite as passed. The whole tree is clean under ASan and LSan: 14/14 configurations, 118/118 cases passed. Assisted-by: Copilot:claude-opus-5 Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
lgirdwood
approved these changes
Oct 28, 2026
PR 11369: test resultsRun date: 2026-10-28 14:46 UTC Tested commit: 27e2e9f0130385430bfed313cb7d469244cc874e |
Member
|
CI failure, not PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the
fftandfft_multiCMocka unit tests to the Zephyr ztest framework, plus the shared infrastructure and the CI change needed to run them. Part of #10110.The CMocka tests are left in place and keep running unchanged; the ztest suites
#includetheir reference vectors directly from the CMocka tree, so both frameworks exercise identical fixed-point data.