diff options
author | Aseda Aboagye <aaboagye@google.com> | 2022-01-10 17:26:56 -0600 |
---|---|---|
committer | Aseda Aboagye <aaboagye@google.com> | 2022-01-10 17:26:56 -0600 |
commit | dc11829e169a9c425860ec5cca949ef80df9e0b7 (patch) | |
tree | 0517b0831c6e52b347926a1b727741df380e908c /docs/zephyr/ztest.md | |
parent | c5bd23a4b204565dab616f7fa4ee8a0b7b433d4c (diff) | |
parent | b44d10f8f79cadb259cc7ab79714a0919fc0c4c8 (diff) | |
download | chrome-ec-firmware-keeby-14119.B-main.tar.gz |
Merge remote-tracking branch cros/main into firmware-keeby-14119.B-mainfirmware-keeby-14119.B-main
Relevant changes:
git log --oneline c5bd23a4b..b44d10f8f -- baseboard/dedede board/cappy2
board/corori board/driblee board/gooey board/haboki board/lalala
board/waddledoo2 common/charge_state_v2.c common/mkbp_* common/ocpc.c
common/usbc/usb_tc_drp_acc_trysrc_sm.c common/usbc/usb_sm.c
common/usbc/*_pd_* common/usbc/dp_alt_mode.c common/usbc/usb_prl_sm.c
common/usbc/usb_pe_drp_sm.c common/usb_charger.c common/usb_common.c
common/usbc_ocp.c driver/charger/sm5803.* driver/charger/isl923x.*
driver/tcpm/raa489000.* driver/tcpm/it83* include/power/icelake.h
include/intel_x86.h power/icelake.c power/intel_x86.c util/getversion.sh
42d03a001 config: change temp_sensor_power from config to gpio
e296efb28 usb_common: Fix CONFIG_USB_PD_DISCHARGE_TCPC typo
c346481f4 atomic: cast to unsigned when shifting
9b972a0f2 driver/tcpm/it83xx, it8xxx2: ITE inactive port return from HOOK
a499d8fd4 driver/tcpm/it83xx, it8xxx2: set sleep mask for mixed TCPC case
ed62e2583 TCPMv2: don't set the sleep mask for TCPC embedded in EC
c962696e8 motion_sensor: Remove |int_signal| field
86b216794 ocpc: modify pre-charge target condition
6f8336eb4 dedede: Set MKBP event wake mask to 0
02d034df0 dedede: add stylus fw_config
4f7cd7509 atomic: use atomic_t where it is possible
e3ffa0519 mkbp: change the type fifo_entries to atomic_t
bb4c47af0 usb: use atomic_t where possible
c6e513ee2 power/icelake: Add SLP_S5 as a watched power signal
d89e49b20 power: Introduce S4 as a real power state
ba8a3c9c0 chgstv2: Use chipset_in_state instead of naming states
23a975d12 i2c: Use declared initializers for i2c_ports: boards a-l
35865dbec TCPMv2: Guard DATA_RESET using CONFIG_USB_PD_DATA_RESET_MSG
d4d8243ed i2c: Use declared initializers for i2c_ports: baseboards
eba8d0305 RAA489000: Fixed RAA489000 max charging current
e78b83e0f TCPMv2: Delay Data Reset until mode entry request
6230e60fc TCPMv2: Support Data Reset as DFP, initiator
412246836 intel_x86: Apply chipset resume init and suspend complete hooks
f2809b72c config: rename CONFIG_HOSTCMD_ESPI to CONFIG_HOST_INTERFACE_ESPI
BRANCH=None
BUG=b:202796060 b:207805856 b:167983049 b:208318528 b:181983966
BUG=b:207328258 b:195416058 b:205285137 b:199919093 b:207055975
BUG=b:129159505 b:204947672 b:141363146 b:207082842 b:205675485
TEST=`make -j buildall`
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Change-Id: I980351977e11088a130e478df0701be4715f049b
Diffstat (limited to 'docs/zephyr/ztest.md')
-rw-r--r-- | docs/zephyr/ztest.md | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/docs/zephyr/ztest.md b/docs/zephyr/ztest.md new file mode 100644 index 0000000000..021b3391bd --- /dev/null +++ b/docs/zephyr/ztest.md @@ -0,0 +1,200 @@ +# Porting EC unit tests to Ztest + +[TOC] + +This HOWTO shows the process for porting the EC's `base32` unit test to Zephyr's +Ztest framework. All of the work is done in `src/platform/ec`. + +See +[Test Framework - Zephyr Project Documentation](https://docs.zephyrproject.org/1.12.0/subsystems/test/ztest.html#quick-start-unit-testing) +for details about Zephyr's Ztest framework. + +For examples of porting an EC unit test to the Ztest API, see: * +[base32](https://crrev.com/c/2492527) and +[improvements](https://crrev.com/c/2634401) * +[accel_cal](https://crrev.com/c/2645198) + +## Porting Considerations + +Not every EC unit test can be ported to Ztest. This section describes cases that +are not supported and cases where caveats apply. + +### EC Mocks Are Not Supported + +If a test has a `$TEST.mocklist` file associated with the unit test, it is using +the EC mocking framework, which is unsupported in the Ztest framework. Ztest has +its own mocking framework which the EC does not support. + +### Multiple Task Caveats + +The EC unit test framework starts a single task to call `run_test`, and this +task will then call the functions for the various test cases. Some unit tests +have multiple threads of execution, which is enabled by a `$TEST.tasklist` file +associated with the unit test. The test runner task has a task ID of +`TASK_ID_TEST_RUNNER`, which can be used as an argument to any of the task +functions. See for example the +[`charge_ramp` unit test](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/test/charge_ramp.c#81) +and the +[`host_command` unit test](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/test/host_command.c#32) + +When a unit test is ported to Ztest, `test_main` doesn't have a thread ID, so +`TASK_ID_TEST_RUNNER` is undefined. `charge_ramp` and `host_command` cannot be +ported at this time. `test_main` also cannot call any of the task functions that +must be called from a task, such as `task_wake`; these functions can pend the +calling task, but since `test_main` doesn't have a thread ID, the pend will +fail. See the +[`mutex` unit test](https://chromium.googlesource.com/chromiumos/platform/ec/+/HEAD/test/mutex.c#116) +for an example. + +## Determine source files being tested + +Determine which C files the unit test requires by finding the test in +`test/test_config.h`: + +``` +#ifdef TEST_BASE32 +#define CONFIG_BASE32 +#endif +``` + +Locate the `CONFIG` item(s) in `common/build.mk`: + +``` +common-$(CONFIG_BASE32)+=base32.o +``` + +So for the `base32` test, we only need to shim `common/base32.c`. + +Add the C files to `zephyr/shim/CMakeLists.txt`, in the "Shimmed modules" +section: + +``` +# Shimmed modules +zephyr_sources_ifdef(CONFIG_PLATFORM_EC "${PLATFORM_EC}/common/base32.c") +``` + +Refer to [zephyr: shim in base32.c](https://crrev.com/c/2468631). + +## Create test directory + +Create a new directory for the unit test in `zephyr/test/base32`. + +Create `zephyr/test/base32/prj.conf` with these contents: + +``` +CONFIG_ZTEST=y +CONFIG_PLATFORM_EC=y +``` + +Create `zephyr/test/base32/CMakeLists.txt` with these contents: + +``` +target_sources(app PRIVATE ${PLATFORM_EC}/test/base32.c) +``` + +## Modify test source code + +### Test cases + +In the unit test, replace `run_test` with `TEST_MAIN()`. This will allow both +platform/ec tests and Ztests to share the same entry point. + +Change `RUN_TEST` to `ztest_unit_test` and add the `ztest_test_suite` wrapper +plus the call to `ztest_run_test_suite`. + +```c +/* + * Define the test cases to run. We need to do this twice, once in the format + * that Ztest uses, and again in the format the the EC test framework uses. + * If you add a test to one of them, make sure to add it to the other. + */ +TEST_MAIN() +{ + ztest_test_suite(test_base32_lib, + ztest_unit_test(test_crc5), + ztest_unit_test(test_encode), + ztest_unit_test(test_decode)); + ztest_run_test_suite(test_base32_lib); +} +``` + +Each function that is called by `ztest_unit_test` needs to be declared using +`DECLARE_EC_TEST`. Keep the `return EC_SUCCESS;` at the end of the test +function. Note that for the EC build, `TEST_MAIN` will call `test_reset` before +running the test cases, and `test_print_result` after. + +### Assert macros + +Change the `TEST_ASSERT` macros to `zassert` macros. There are plans to automate +this process, but for now, it's a manual process involving some intelligent +find-and-replace. + +* `TEST_ASSERT(n)` to `zassert_true(n, NULL)` +* `TEST_EQ(a, b, fmt)` to `zassert_equal(a, b, fmt ## ", " ## fmt, a, b)` + * e.g. `TEST_EQ(a, b, "%d")` becomes `zassert_equal(a, b, "%d, %d", a, b)` +* `TEST_NE(a, b, fmt)` to `zassert_not_equal(a, b, fmt ## ", " ## fmt, a, b)` +* `TEST_LT(a, b, fmt)` to `zassert_true(a < b, fmt ## ", " ## fmt, a, b)` +* `TEST_LE(a, b, fmt)` to `zassert_true(a <= b, fmt ## ", " ## fmt, a, b)` +* `TEST_GT(a, b, fmt)` to `zassert_true(a > b, fmt ## ", " ## fmt, a, b)` +* `TEST_GE(a, b, fmt)` tp `zassert_true(a >= b, fmt ## ", " ## fmt, a, b)` +* `TEST_BITS_SET(a, bits)` to `zassert_true(a & (int)bits == (int)bits, "%u, + %u", a & (int)bits, (int)bits)` +* `TEST_BITS_CLEARED(a, bits)` to `zassert_true(a & (int)bits == 0, "%u, 0", a + & (int)bits)` +* `TEST_ASSERT_ARRAY_EQ(s, d, n)` to `zassert_mem_equal(s, d, b, NULL)` +* `TEST_CHECK(n)` to `zassert_true(n, NULL)` +* `TEST_NEAR(a, b, epsilon, fmt)` to `zassert_within(a, b, epsilon, fmt, a)` + * Currently, every usage of `TEST_NEAR` involves floating point values +* `TEST_ASSERT_ABS_LESS(n, t)` to `zassert_true(abs(n) < t, "%d, %d", n, t)` + * Currently, every usage of `TEST_ASSERT_ANS_LESS` involves signed + integers. + +There isn't a good replacement for `TEST_ASSERT_MEMSET(d, c, n)`, but it is only +used in two tests, `printf.c` and `utils.c`. If you need this test, you'll need +to code up a loop over the `n` bytes starting at `d`, and `zassert_equal` that +each byte is equal to `c`. + +Also note that some tests use constructs like `TEST_ASSERT(var == const)`, which +would have been better write as `TEST_EQ(var, const)`. These should be rewritten +to use `zassert_equal`. + +Refer to +[test: Allow EC unit test to use Ztest API](https://crrev.com/c/2492527) for the +changes to the base32.c source code. + +### Tasklist + +For any test that has a corresponding `${TESTNAME}.tasklist`, add the file +`shimmed_test_tasks.h` in the zephyr test directory, and in that file, +`#include` the tasklist file. See [accel_cal](https://crrev.com/c/2645198) for +an example. + +Add `CONFIG_HAS_TEST_TASKS=y` to the `prj.conf` file, as well as the appropriate +`CONFIG_PLATFORM_EC` defines to include or exclude code that the unit under test +uses. + +## Build and run + +Use `zmake` to build and run the test: + +``` +(cr) $ zmake -l DEBUG configure --test -B build/ztest/base32 zephyr/test/base32 +... +UART_0 connected to pseudotty: /dev/pts/1 +*** Booting Zephyr OS build zephyr-v2.4.0-1-g63b2330a85cd *** +Running test suite test_base32_lib +=================================================================== +START - test_crc5 + PASS - test_crc5 +=================================================================== +START - test_encode + PASS - test_encode +=================================================================== +START - test_decode + PASS - test_decode +=================================================================== +Test suite test_base32_lib succeeded +=================================================================== +PROJECT EXECUTION SUCCESSFUL +(cr) $ +``` |