mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
Merge patch series "test: Complete the suite migration"
Simon Glass <sjg@chromium.org> says: This series completes the removal of test commands for suites. With this it is possible to declare a suite (including init and uninit functions) without needing to write a command. It also adds timing for test suites, so we can keep track of how long things take. Link: https://lore.kernel.org/all/20250207183121.117663-1-sjg@chromium.org/
This commit is contained in:
3
Makefile
3
Makefile
@@ -893,9 +893,6 @@ ifdef CONFIG_POST
|
||||
libs-y += post/
|
||||
endif
|
||||
libs-$(CONFIG_$(PHASE_)UNIT_TEST) += test/
|
||||
libs-$(CONFIG_UT_ENV) += test/env/
|
||||
libs-$(CONFIG_UT_OPTEE) += test/optee/
|
||||
libs-$(CONFIG_UT_OVERLAY) += test/overlay/
|
||||
|
||||
libs-y += $(if $(wildcard $(srctree)/board/$(BOARDDIR)/Makefile),board/$(BOARDDIR)/)
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ with the suite. For example, to add a new mem_search test::
|
||||
/* Test 'ms' command with 32-bit values */
|
||||
static int mem_test_ms_new_thing(struct unit_test_state *uts)
|
||||
{
|
||||
/* test code here*/
|
||||
/* test code here */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -291,32 +291,20 @@ suite. For example::
|
||||
/* Declare a new wibble test */
|
||||
#define WIBBLE_TEST(_name, _flags) UNIT_TEST(_name, _flags, wibble_test)
|
||||
|
||||
/* Tetss go here */
|
||||
|
||||
/* At the bottom of the file: */
|
||||
|
||||
int do_ut_wibble(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
struct unit_test *tests = UNIT_TEST_SUITE_START(wibble_test);
|
||||
const int n_ents = UNIT_TEST_SUITE_COUNT(wibble_test);
|
||||
|
||||
return cmd_ut_category("cmd_wibble", "wibble_test_", tests, n_ents, argc, argv);
|
||||
}
|
||||
/* Tests go here */
|
||||
|
||||
Then add new tests to it as above.
|
||||
|
||||
Register this new suite in test/cmd_ut.c by adding to cmd_ut_sub[]::
|
||||
|
||||
/* Within cmd_ut_sub[]... */
|
||||
/* with the other SUITE_DECL() declarations */
|
||||
SUITE_DECL(wibble);
|
||||
|
||||
U_BOOT_CMD_MKENT(wibble, CONFIG_SYS_MAXARGS, 1, do_ut_wibble, "", ""),
|
||||
/* Within suites[]... */
|
||||
SUITE(wibble, "my test of wibbles");
|
||||
|
||||
and adding new help to ut_help_text[]::
|
||||
|
||||
"ut wibble - Test the wibble feature\n"
|
||||
|
||||
If your feature is conditional on a particular Kconfig, then you can use #ifdef
|
||||
to control that.
|
||||
If your feature is conditional on a particular Kconfig, you do not need to add
|
||||
an #ifdef since the suite will automatically be compiled out in that case.
|
||||
|
||||
Finally, add the test to the build by adding to the Makefile in the same
|
||||
directory::
|
||||
@@ -326,17 +314,35 @@ directory::
|
||||
Note that CMDLINE is never enabled in SPL, so this test will only be present in
|
||||
U-Boot proper. See below for how to do SPL tests.
|
||||
|
||||
As before, you can add an extra Kconfig check if needed::
|
||||
You can add an extra Kconfig check if needed::
|
||||
|
||||
ifneq ($(CONFIG_$(XPL_)WIBBLE),)
|
||||
obj-$(CONFIG_$(XPL_)CMDLINE) += wibble.o
|
||||
endif
|
||||
|
||||
Each suite can have an optional init and uninit function. These are run before
|
||||
and after any suite tests, respectively::
|
||||
|
||||
Example commit: 919e7a8fb64 ("test: Add a simple test for bloblist") [1]
|
||||
#define WIBBLE_TEST_INIT(_name, _flags) UNIT_TEST_INIT(_name, _flags, wibble_test)
|
||||
#define WIBBLE_TEST_UNINIT(_name, _flags) UNIT_TEST_UNINIT(_name, _flags, wibble_test)
|
||||
|
||||
[1] https://gitlab.denx.de/u-boot/u-boot/-/commit/919e7a8fb64
|
||||
static int wibble_test_init(struct unit_test_state *uts)
|
||||
{
|
||||
/* init code here */
|
||||
|
||||
return 0;
|
||||
}
|
||||
WIBBLE_TEST_INIT(wibble_test_init, 0);
|
||||
|
||||
static int wibble_test_uninit(struct unit_test_state *uts)
|
||||
{
|
||||
/* uninit code here */
|
||||
|
||||
return 0;
|
||||
}
|
||||
WIBBLE_TEST_INIT(wibble_test_uninit, 0);
|
||||
|
||||
Both functions are included in the totals for each suite.
|
||||
|
||||
Making the test run from pytest
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -11,34 +11,44 @@ Synopsis
|
||||
|
||||
::
|
||||
|
||||
ut [-r<runs>] [-fs] [-I<n>:<one_test>] [<suite> [<test>]]
|
||||
|
||||
<runs> Number of times to run each test
|
||||
-f Force 'manual' tests to run as well
|
||||
<n> Run <one test> after <n> other tests have run
|
||||
<one_test> Name of the 'one' test to run
|
||||
<suite> Test suite to run, or `all`
|
||||
<test> Name of single test to run
|
||||
ut [-r<runs>] [-f] [-I<n>:<one_test>] [-r<n>] [<suite> | 'all' [<test>]]
|
||||
ut [-s] info
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The ut command runs unit tests written in C.
|
||||
|
||||
suite
|
||||
Specifies the suite to run, This can be a single suite, or a comma-separated
|
||||
list
|
||||
|
||||
test
|
||||
Speciifes a particular test to run, within a suite, or all suites
|
||||
|
||||
-f
|
||||
Forces running of a manual test.
|
||||
|
||||
-r <n>
|
||||
Specifies the number of types to run each test
|
||||
|
||||
-I <n>:<one_test>
|
||||
Test to run after <n> other tests have run. This is used to find which test
|
||||
causes another test to fail. If the one test fails, testing stops
|
||||
immediately.
|
||||
|
||||
Typically the command is run on :ref:`arch/sandbox/sandbox:sandbox` since it
|
||||
includes a near-complete set of emulators, no code-size limits, many CONFIG
|
||||
options enabled and runs easily in CI without needing QEMU. It is also possible
|
||||
to run some tests on real boards.
|
||||
|
||||
For a list of available test suites, type `ut info -s`.
|
||||
|
||||
Each test is normally run once, although those marked with `UTF_DM` are
|
||||
run with livetree and flattree where possible. To run a test more than once,
|
||||
use the `-r` flag.
|
||||
|
||||
Manual tests are normally skipped by this command. Use `-f` to run them. See
|
||||
See :ref:`develop/tests_writing:mixing python and c` for more information on
|
||||
manual test.
|
||||
:ref:`develop/tests_writing:mixing python and c` for more information on manual
|
||||
tests.
|
||||
|
||||
When running unit tests, some may have side effects which cause a subsequent
|
||||
test to break. This can sometimes be seen when using 'ut dm' or similar. To
|
||||
@@ -50,9 +60,22 @@ the problem.
|
||||
Generally all tests in the suite are run. To run just a single test from the
|
||||
suite, provide the <test> argument.
|
||||
|
||||
To specify a list of suites to run, <suites> can also be a comma-separated list.
|
||||
|
||||
See :ref:`develop/tests_writing:writing c tests` for more information on how to
|
||||
write unit tests.
|
||||
|
||||
ut all
|
||||
~~~~~~
|
||||
|
||||
Instead of a suite name 'all' may be used to run all tests.
|
||||
|
||||
ut info
|
||||
~~~~~~~
|
||||
|
||||
This provides information about the total number of suites and tests. Use the
|
||||
`-s` flag to show a detailed list of suites.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
@@ -97,26 +120,84 @@ List available unit-test suites::
|
||||
|
||||
Run one of the suites::
|
||||
|
||||
=> ut bloblist
|
||||
Running 14 bloblist tests
|
||||
Test: bloblist_test_align: bloblist.c
|
||||
Test: bloblist_test_bad_blob: bloblist.c
|
||||
Test: bloblist_test_blob: bloblist.c
|
||||
Test: bloblist_test_blob_ensure: bloblist.c
|
||||
Test: bloblist_test_blob_maxsize: bloblist.c
|
||||
Test: bloblist_test_checksum: bloblist.c
|
||||
Test: bloblist_test_cmd_info: bloblist.c
|
||||
Test: bloblist_test_cmd_list: bloblist.c
|
||||
Test: bloblist_test_grow: bloblist.c
|
||||
Test: bloblist_test_init: bloblist.c
|
||||
Test: bloblist_test_reloc: bloblist.c
|
||||
Test: bloblist_test_resize_fail: bloblist.c
|
||||
Test: bloblist_test_resize_last: bloblist.c
|
||||
Test: bloblist_test_shrink: bloblist.c
|
||||
Failures: 0
|
||||
=> ut common
|
||||
Running 14 common tests
|
||||
Test: cli_ch_test: cread.c
|
||||
Test: cread_test: cread.c
|
||||
Test: dm_test_cyclic_running: cyclic.c
|
||||
Test: print_display_buffer: print.c
|
||||
Test: print_do_hex_dump: print.c
|
||||
Test: print_efi_ut: print.c
|
||||
Test: print_guid: print.c
|
||||
Test: print_hexdump_line: print.c
|
||||
Test: print_printf: print.c
|
||||
Test: snprint: print.c
|
||||
Test: test_autoboot: test_autoboot.c
|
||||
Enter password "a" in 1 seconds to stop autoboot
|
||||
Enter password "a" in 1 seconds to stop autoboot
|
||||
Enter password "a" in 1 seconds to stop autoboot
|
||||
Enter password "a" in 1 seconds to stop autoboot
|
||||
Enter password "a" in 1 seconds to stop autoboot
|
||||
Enter password "a" in 1 seconds to stop autoboot
|
||||
Autoboot password unlock not successful
|
||||
Test: test_event_base: event.c
|
||||
Test: test_event_probe: event.c
|
||||
Test: test_event_probe: event.c (flat tree)
|
||||
Test: test_event_simple: event.c
|
||||
Tests run: 14, 2611 ms, average 186 ms, skipped: 2, failures: 0
|
||||
|
||||
Run just a single test in a suite::
|
||||
|
||||
=> ut bloblist bloblist_test_grow
|
||||
Test: bloblist_test_grow: bloblist.c
|
||||
Failures: 0
|
||||
=> ut fdt_overlay change_int_property
|
||||
Test: fdt_overlay_init: cmd_ut_fdt_overlay.c
|
||||
Test: change_int_property: cmd_ut_fdt_overlay.c
|
||||
Tests run: 2, 0 ms, average 0 ms, failures: 0
|
||||
|
||||
Run a selection of three suites::
|
||||
|
||||
=> ut bloblist,mem,fdt_overlay
|
||||
Running 14 bloblist tests
|
||||
Test: align: bloblist.c
|
||||
Test: bad_blob: bloblist.c
|
||||
Test: blob: bloblist.c
|
||||
Test: blob_ensure: bloblist.c
|
||||
Test: blob_maxsize: bloblist.c
|
||||
Test: checksum: bloblist.c
|
||||
Test: cmd_info: bloblist.c
|
||||
Test: cmd_list: bloblist.c
|
||||
Test: grow: bloblist.c
|
||||
Test: init: bloblist.c
|
||||
Test: reloc: bloblist.c
|
||||
Test: resize_fail: bloblist.c
|
||||
Test: resize_last: bloblist.c
|
||||
Test: shrink: bloblist.c
|
||||
Tests run: 14, 1 ms, average: 0 ms, failures: 0
|
||||
Running 13 mem tests
|
||||
Test: cp_b: mem_copy.c
|
||||
Test: cp_l: mem_copy.c
|
||||
Test: cp_q: mem_copy.c
|
||||
Test: cp_w: mem_copy.c
|
||||
Test: ms_b: mem_search.c
|
||||
Test: ms_cont: mem_search.c
|
||||
Test: ms_cont_end: mem_search.c
|
||||
Test: ms_l: mem_search.c
|
||||
Test: ms_limit: mem_search.c
|
||||
Test: ms_mult: mem_search.c
|
||||
Test: ms_quiet: mem_search.c
|
||||
Test: ms_s: mem_search.c
|
||||
Test: ms_w: mem_search.c
|
||||
Tests run: 13, 13 ms, average: 1 ms, failures: 0
|
||||
Running 10 fdt_overlay tests
|
||||
Test: fdt_overlay_init: cmd_ut_fdt_overlay.c
|
||||
Test: add_node_by_path: cmd_ut_fdt_overlay.c
|
||||
Test: add_node_by_phandle: cmd_ut_fdt_overlay.c
|
||||
Test: add_str_property: cmd_ut_fdt_overlay.c
|
||||
Test: add_subnode_property: cmd_ut_fdt_overlay.c
|
||||
Test: change_int_property: cmd_ut_fdt_overlay.c
|
||||
Test: change_str_property: cmd_ut_fdt_overlay.c
|
||||
Test: local_phandle: cmd_ut_fdt_overlay.c
|
||||
Test: local_phandles: cmd_ut_fdt_overlay.c
|
||||
Test: stacked: cmd_ut_fdt_overlay.c
|
||||
Tests run: 10, 12 ms, average: 1 ms, failures: 0
|
||||
Suites run: 3, total tests run: 37, 26 ms, average: 0 ms, failures: 0
|
||||
Average test time: 0 ms, worst case 'mem' took 1 ms
|
||||
|
||||
@@ -18,6 +18,11 @@ void timer_test_add_offset(unsigned long offset)
|
||||
sandbox_timer_offset += offset;
|
||||
}
|
||||
|
||||
ulong timer_test_get_offset(void)
|
||||
{
|
||||
return sandbox_timer_offset;
|
||||
};
|
||||
|
||||
u64 notrace timer_early_get_count(void)
|
||||
{
|
||||
return os_get_nsec() / 1000 + sandbox_timer_offset * 1000;
|
||||
|
||||
19
include/test/fdt_overlay.h
Normal file
19
include/test/fdt_overlay.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2016 NextThing Co
|
||||
* Copyright (c) 2016 Free Electrons
|
||||
*/
|
||||
|
||||
#ifndef __TEST_OVERLAY_H__
|
||||
#define __TEST_OVERLAY_H__
|
||||
|
||||
#include <test/test.h>
|
||||
|
||||
/* Declare a new FDT-overlay test */
|
||||
#define FDT_OVERLAY_TEST(_name, _flags) UNIT_TEST(_name, _flags, fdt_overlay)
|
||||
|
||||
/* Declare init for FDT-overlay test */
|
||||
#define FDT_OVERLAY_TEST_INIT(_name, _flags) \
|
||||
UNIT_TEST_INIT(_name, _flags, fdt_overlay)
|
||||
|
||||
#endif /* __TEST_OVERLAY_H__ */
|
||||
@@ -8,7 +8,9 @@
|
||||
|
||||
#include <test/test.h>
|
||||
|
||||
/* Declare a new environment test */
|
||||
/* Declare a new optee test */
|
||||
#define OPTEE_TEST(_name, _flags) UNIT_TEST(_name, _flags, optee)
|
||||
#define OPTEE_TEST_INIT(_name, _flags) UNIT_TEST_INIT(_name, _flags, optee)
|
||||
#define OPTEE_TEST_UNINIT(_name, _flags) UNIT_TEST_UNINIT(_name, _flags, optee)
|
||||
|
||||
#endif /* __TEST_OPTEE_H__ */
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2016 NextThing Co
|
||||
* Copyright (c) 2016 Free Electrons
|
||||
*/
|
||||
|
||||
#ifndef __TEST_OVERLAY_H__
|
||||
#define __TEST_OVERLAY_H__
|
||||
|
||||
#include <test/test.h>
|
||||
|
||||
/* Declare a new environment test */
|
||||
#define OVERLAY_TEST(_name, _flags) UNIT_TEST(_name, _flags, overlay)
|
||||
|
||||
#endif /* __TEST_OVERLAY_H__ */
|
||||
@@ -1,43 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* (C) Copyright 2015
|
||||
* Joe Hershberger, National Instruments, joe.hershberger@ni.com
|
||||
*/
|
||||
|
||||
#ifndef __TEST_SUITES_H__
|
||||
#define __TEST_SUITES_H__
|
||||
|
||||
struct cmd_tbl;
|
||||
struct unit_test;
|
||||
struct unit_test_state;
|
||||
|
||||
/* 'command' functions normally called do_xxx where xxx is the command name */
|
||||
typedef int (*ut_cmd_func)(struct unit_test_state *uts, struct cmd_tbl *cmd,
|
||||
int flags, int argc, char *const argv[]);
|
||||
|
||||
/**
|
||||
* cmd_ut_category() - Run a category of unit tests
|
||||
*
|
||||
* @uts: Unit-test state, which must be ready for use, i.e. ut_init_state()
|
||||
* has been called. The caller is responsible for calling
|
||||
* ut_uninit_state() after this function returns
|
||||
* @name: Category name
|
||||
* @prefix: Prefix of test name
|
||||
* @tests: List of tests to run
|
||||
* @n_ents: Number of tests in @tests
|
||||
* @argc: Argument count provided. Must be >= 1. If this is 1 then all
|
||||
* tests are run, otherwise only the one named @argv[1] is run.
|
||||
* @argv: Arguments: argv[1] is the test to run (if @argc >= 2)
|
||||
* Return: 0 if OK, CMD_RET_FAILURE on failure
|
||||
*/
|
||||
int cmd_ut_category(struct unit_test_state *uts, const char *name,
|
||||
const char *prefix, struct unit_test *tests, int n_ents,
|
||||
int argc, char *const argv[]);
|
||||
|
||||
int do_ut_bootstd(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char *const argv[]);
|
||||
int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ut_overlay(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char *const argv[]);
|
||||
|
||||
#endif /* __TEST_SUITES_H__ */
|
||||
@@ -16,11 +16,15 @@
|
||||
* @skip_count: Number of tests that were skipped
|
||||
* @test_count: Number of tests run. If a test is run muiltiple times, only one
|
||||
* is counted
|
||||
* @start: Timer value when test started
|
||||
* @duration_ms: Suite duration in milliseconds
|
||||
*/
|
||||
struct ut_stats {
|
||||
int fail_count;
|
||||
int skip_count;
|
||||
int test_count;
|
||||
ulong start;
|
||||
ulong duration_ms;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -29,6 +33,8 @@ struct ut_stats {
|
||||
* @cur: Statistics for the current run
|
||||
* @total: Statistics for all test runs
|
||||
* @run_count: Number of times ut_run_list() has been called
|
||||
* @worst: Sute which had the first per-text run time
|
||||
* @worst_ms: Time taken by that test
|
||||
* @start: Store the starting mallinfo when doing leak test
|
||||
* @of_live: true to use livetree if available, false to use flattree
|
||||
* @of_root: Record of the livetree root node (used for setting up tests)
|
||||
@@ -52,6 +58,8 @@ struct unit_test_state {
|
||||
struct ut_stats cur;
|
||||
struct ut_stats total;
|
||||
int run_count;
|
||||
const struct suite *worst;
|
||||
int worst_ms;
|
||||
struct mallinfo start;
|
||||
struct device_node *of_root;
|
||||
bool of_live;
|
||||
@@ -92,6 +100,8 @@ enum ut_flags {
|
||||
UTF_ETH_BOOTDEV = BIT(9), /* enable Ethernet bootdevs */
|
||||
UTF_SF_BOOTDEV = BIT(10), /* enable SPI flash bootdevs */
|
||||
UFT_BLOBLIST = BIT(11), /* test changes gd->bloblist */
|
||||
UTF_INIT = BIT(12), /* test inits a suite */
|
||||
UTF_UNINIT = BIT(13), /* test uninits a suite */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -139,6 +149,24 @@ struct unit_test {
|
||||
.func = _name, \
|
||||
}
|
||||
|
||||
/* init function for unit-test suite (the 'A' makes it first) */
|
||||
#define UNIT_TEST_INIT(_name, _flags, _suite) \
|
||||
ll_entry_declare(struct unit_test, A ## _name, ut_ ## _suite) = { \
|
||||
.file = __FILE__, \
|
||||
.name = #_name, \
|
||||
.flags = (_flags) | UTF_INIT, \
|
||||
.func = _name, \
|
||||
}
|
||||
|
||||
/* uninit function for unit-test suite (the 'aaa' makes it last) */
|
||||
#define UNIT_TEST_UNINIT(_name, _flags, _suite) \
|
||||
ll_entry_declare(struct unit_test, zzz ## _name, ut_ ## _suite) = { \
|
||||
.file = __FILE__, \
|
||||
.name = #_name, \
|
||||
.flags = (_flags) | UTF_UNINIT, \
|
||||
.func = _name, \
|
||||
}
|
||||
|
||||
/* Get the start of a list of unit tests for a particular suite */
|
||||
#define UNIT_TEST_SUITE_START(_suite) \
|
||||
ll_entry_start(struct unit_test, ut_ ## _suite)
|
||||
|
||||
@@ -28,7 +28,7 @@ uint64_t get_timer_us(uint64_t base);
|
||||
*/
|
||||
unsigned long get_timer_us_long(unsigned long base);
|
||||
|
||||
/*
|
||||
/**
|
||||
* timer_test_add_offset()
|
||||
*
|
||||
* Allow tests to add to the time reported through lib/time.c functions
|
||||
@@ -36,6 +36,19 @@ unsigned long get_timer_us_long(unsigned long base);
|
||||
*/
|
||||
void timer_test_add_offset(unsigned long offset);
|
||||
|
||||
#ifdef CONFIG_SANDBOX
|
||||
/**
|
||||
* timer_test_get_offset()
|
||||
*
|
||||
* Get the total offset currently being added the time
|
||||
*
|
||||
* Return:: number of milliseconds the system time has been advanced
|
||||
*/
|
||||
ulong timer_test_get_offset(void);
|
||||
#else
|
||||
static inline ulong timer_test_get_offset(void) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* usec_to_tick() - convert microseconds to clock ticks
|
||||
*
|
||||
|
||||
23
test/Kconfig
23
test/Kconfig
@@ -20,9 +20,18 @@ config SPL_UNIT_TEST
|
||||
of-platdata and SPL handover. To run these tests with the sandbox_spl
|
||||
board, use the -u (unit test) option.
|
||||
|
||||
if UNIT_TEST
|
||||
|
||||
config UNIT_TEST_DURATION
|
||||
bool "Report unit-test duration"
|
||||
default y
|
||||
help
|
||||
Enable this short the time taken by each test suite. This is reported
|
||||
after the suite runs, alongside the pass/fail results. In addition,
|
||||
an overall total is reported if multiple suites are run.
|
||||
|
||||
config UT_LIB
|
||||
bool "Unit tests for library functions"
|
||||
depends on UNIT_TEST
|
||||
default y if !SANDBOX_VPL
|
||||
help
|
||||
Enables the 'ut lib' command which tests library functions like
|
||||
@@ -63,16 +72,15 @@ config UT_LIB_RSA
|
||||
Enables rsa_verify() test, currently rsa_verify_with_pkey only()
|
||||
only, at the 'ut lib' command.
|
||||
|
||||
endif
|
||||
endif # UT_LIB
|
||||
|
||||
config UT_BOOTSTD
|
||||
bool "Unit tests for standard boot"
|
||||
depends on UNIT_TEST && BOOTSTD && SANDBOX
|
||||
depends on BOOTSTD && SANDBOX
|
||||
default y
|
||||
|
||||
config UT_COMPRESSION
|
||||
bool "Unit test for compression"
|
||||
depends on UNIT_TEST
|
||||
depends on CMDLINE && GZIP_COMPRESSED && BZIP2 && LZMA && LZO && LZ4 && ZSTD
|
||||
default y
|
||||
help
|
||||
@@ -81,7 +89,6 @@ config UT_COMPRESSION
|
||||
|
||||
config UT_LOG
|
||||
bool "Unit tests for logging functions"
|
||||
depends on UNIT_TEST
|
||||
default y
|
||||
help
|
||||
Enables the 'ut log' command which tests logging functions like
|
||||
@@ -90,7 +97,6 @@ config UT_LOG
|
||||
|
||||
config UT_TIME
|
||||
bool "Unit tests for time functions"
|
||||
depends on UNIT_TEST
|
||||
help
|
||||
Enables the 'ut time' command which tests that the time functions
|
||||
work correctly. The test is fairly simple and will not catch all
|
||||
@@ -99,7 +105,6 @@ config UT_TIME
|
||||
|
||||
config UT_UNICODE
|
||||
bool "Unit tests for Unicode functions"
|
||||
depends on UNIT_TEST
|
||||
default y
|
||||
select CHARSET
|
||||
help
|
||||
@@ -111,7 +116,9 @@ source "test/env/Kconfig"
|
||||
source "test/image/Kconfig"
|
||||
source "test/lib/Kconfig"
|
||||
source "test/optee/Kconfig"
|
||||
source "test/overlay/Kconfig"
|
||||
source "test/fdt_overlay/Kconfig"
|
||||
|
||||
endif # UNIT_TEST
|
||||
|
||||
config POST
|
||||
bool "Power On Self Test support"
|
||||
|
||||
@@ -14,11 +14,14 @@ endif
|
||||
ifneq ($(CONFIG_HUSH_PARSER),)
|
||||
obj-$(CONFIG_$(XPL_)CMDLINE) += hush/
|
||||
endif
|
||||
obj-$(CONFIG_UT_OPTEE) += optee/
|
||||
obj-y += ut.o
|
||||
|
||||
ifeq ($(CONFIG_XPL_BUILD),)
|
||||
obj-y += boot/
|
||||
obj-$(CONFIG_UNIT_TEST) += common/
|
||||
obj-$(CONFIG_UT_ENV) += env/
|
||||
obj-$(CONFIG_UT_FDT_OVERLAY) += fdt_overlay/
|
||||
obj-y += log/
|
||||
else
|
||||
obj-$(CONFIG_SPL_UT_LOAD) += image/
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <bootflow.h>
|
||||
#include <mapmem.h>
|
||||
#include <os.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#endif
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
#include "../../boot/bootflow_internal.h"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include <bootm.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <bootmeth.h>
|
||||
#include <bootstd.h>
|
||||
#include <dm.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <mmc.h>
|
||||
#include <usb.h>
|
||||
#include <linux/log2.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include "bootstd_common.h"
|
||||
@@ -21,8 +20,14 @@
|
||||
/* tracks whether bootstd_setup_for_tests() has been run yet */
|
||||
bool vbe_setup_done;
|
||||
|
||||
/* set up MMC for VBE tests */
|
||||
int bootstd_setup_for_tests(void)
|
||||
/**
|
||||
* bootstd_setup_for_tests() - Set up MMC data for VBE tests
|
||||
*
|
||||
* Some data is needed for VBE tests to work. This function sets that up.
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
static int bootstd_setup_for_tests(struct unit_test_state *uts)
|
||||
{
|
||||
ALLOC_CACHE_ALIGN_BUFFER(u8, buf, MMC_MAX_BLOCK_LEN);
|
||||
struct udevice *mmc;
|
||||
@@ -55,6 +60,7 @@ int bootstd_setup_for_tests(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
BOOTSTD_TEST_INIT(bootstd_setup_for_tests, 0);
|
||||
|
||||
int bootstd_test_drop_bootdev_order(struct unit_test_state *uts)
|
||||
{
|
||||
@@ -93,20 +99,3 @@ void bootstd_reset_usb(void)
|
||||
{
|
||||
usb_started = false;
|
||||
}
|
||||
|
||||
int do_ut_bootstd(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char *const argv[])
|
||||
{
|
||||
struct unit_test *tests = UNIT_TEST_SUITE_START(bootstd);
|
||||
const int n_ents = UNIT_TEST_SUITE_COUNT(bootstd);
|
||||
int ret;
|
||||
|
||||
ret = bootstd_setup_for_tests();
|
||||
if (ret) {
|
||||
printf("Failed to set up for bootstd tests (err=%d)\n", ret);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return cmd_ut_category(uts, "bootstd", "bootstd_",
|
||||
tests, n_ents, argc, argv);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
/* Declare a new bootdev test */
|
||||
#define BOOTSTD_TEST(_name, _flags) UNIT_TEST(_name, _flags, bootstd)
|
||||
#define BOOTSTD_TEST_INIT(_name, _flags) UNIT_TEST_INIT(_name, _flags, bootstd)
|
||||
|
||||
#define NVDATA_START_BLK ((0x400 + 0x400) / MMC_MAX_BLOCK_LEN)
|
||||
#define VERSION_START_BLK ((0x400 + 0x800) / MMC_MAX_BLOCK_LEN)
|
||||
@@ -35,15 +36,6 @@ struct unit_test_state;
|
||||
*/
|
||||
int bootstd_test_drop_bootdev_order(struct unit_test_state *uts);
|
||||
|
||||
/**
|
||||
* bootstd_setup_for_tests() - Set up MMC data for VBE tests
|
||||
*
|
||||
* Some data is needed for VBE tests to work. This function sets that up.
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int bootstd_setup_for_tests(void);
|
||||
|
||||
/**
|
||||
* bootstd_test_check_mmc_hunter() - Check that the mmc bootdev hunter was used
|
||||
*
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <menu.h>
|
||||
#include <video.h>
|
||||
#include <linux/input.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
#include <test/cedit-test.h>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include <image.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <bootm.h>
|
||||
#include <malloc.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <mapmem.h>
|
||||
#include <upl.h>
|
||||
#include <dm/ofnode.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <image.h>
|
||||
#include <of_live.h>
|
||||
#include <vbe.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include "bootstd_common.h"
|
||||
|
||||
@@ -33,9 +32,6 @@ static int vbe_simple_test_base(struct unit_test_state *uts)
|
||||
ofnode node;
|
||||
u32 vernum;
|
||||
|
||||
/* Set up the VBE info */
|
||||
ut_assertok(bootstd_setup_for_tests());
|
||||
|
||||
/* Read the version back */
|
||||
ut_assertok(vbe_find_by_any("firmware0", &dev));
|
||||
ut_assertok(bootmeth_get_state_desc(dev, info, sizeof(info)));
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
#include <console.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
/* Declare a new addrmap test */
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <mapmem.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <dm/uclass.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include <dm.h>
|
||||
#include <env.h>
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <console.h>
|
||||
#include <mapmem.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <mapmem.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <console.h>
|
||||
#include <dm.h>
|
||||
#include <video_console.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
/* Declare a new fdt test */
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <mapmem.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <console.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
#define PCI_MPS_TEST(_name, _flags) UNIT_TEST(_name, _flags, pci_mps)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include <command.h>
|
||||
#include <dm.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <console.h>
|
||||
#include <mapmem.h>
|
||||
#include <dm/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
#define BUF_SIZE 0x100
|
||||
|
||||
243
test/cmd_ut.c
243
test/cmd_ut.c
@@ -7,7 +7,6 @@
|
||||
#include <command.h>
|
||||
#include <console.h>
|
||||
#include <vsprintf.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
@@ -20,77 +19,31 @@
|
||||
* @name: Name of suite
|
||||
* @start: First test in suite
|
||||
* @end: End test in suite (points to the first test in the next suite)
|
||||
* @cmd: Command to use to run the suite
|
||||
* @help: Help-string to show for this suite
|
||||
*/
|
||||
struct suite {
|
||||
const char *name;
|
||||
struct unit_test *start;
|
||||
struct unit_test *end;
|
||||
ut_cmd_func cmd;
|
||||
const char *help;
|
||||
};
|
||||
|
||||
static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp,
|
||||
int flag, int argc, char *const argv[]);
|
||||
static int do_ut_all(struct unit_test_state *uts, const char *select_name,
|
||||
int runs_per_test, bool force_run,
|
||||
const char *test_insert);
|
||||
|
||||
static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[]);
|
||||
|
||||
int cmd_ut_category(struct unit_test_state *uts, const char *name,
|
||||
const char *prefix, struct unit_test *tests, int n_ents,
|
||||
int argc, char *const argv[])
|
||||
{
|
||||
const char *test_insert = NULL;
|
||||
int runs_per_text = 1;
|
||||
bool force_run = false;
|
||||
int ret;
|
||||
|
||||
while (argc > 1 && *argv[1] == '-') {
|
||||
const char *str = argv[1];
|
||||
|
||||
switch (str[1]) {
|
||||
case 'r':
|
||||
runs_per_text = dectoul(str + 2, NULL);
|
||||
break;
|
||||
case 'f':
|
||||
force_run = true;
|
||||
break;
|
||||
case 'I':
|
||||
test_insert = str + 2;
|
||||
break;
|
||||
}
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
|
||||
ret = ut_run_list(uts, name, prefix, tests, n_ents,
|
||||
cmd_arg1(argc, argv), runs_per_text, force_run,
|
||||
test_insert);
|
||||
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
}
|
||||
static int do_ut_info(bool show_suites);
|
||||
|
||||
/* declare linker-list symbols for the start and end of a suite */
|
||||
#define SUITE_DECL(_name) \
|
||||
ll_start_decl(suite_start_ ## _name, struct unit_test, ut_ ## _name); \
|
||||
ll_end_decl(suite_end_ ## _name, struct unit_test, ut_ ## _name)
|
||||
|
||||
/* declare a test suite which uses a subcommand to run */
|
||||
#define SUITE_CMD(_name, _cmd_func, _help) { \
|
||||
#_name, \
|
||||
suite_start_ ## _name, \
|
||||
suite_end_ ## _name, \
|
||||
_cmd_func, \
|
||||
_help, \
|
||||
}
|
||||
|
||||
/* declare a test suite which can be run directly without a subcommand */
|
||||
#define SUITE(_name, _help) { \
|
||||
#_name, \
|
||||
suite_start_ ## _name, \
|
||||
suite_end_ ## _name, \
|
||||
NULL, \
|
||||
_help, \
|
||||
}
|
||||
|
||||
@@ -105,6 +58,7 @@ SUITE_DECL(dm);
|
||||
SUITE_DECL(env);
|
||||
SUITE_DECL(exit);
|
||||
SUITE_DECL(fdt);
|
||||
SUITE_DECL(fdt_overlay);
|
||||
SUITE_DECL(font);
|
||||
SUITE_DECL(hush);
|
||||
SUITE_DECL(lib);
|
||||
@@ -114,7 +68,6 @@ SUITE_DECL(mbr);
|
||||
SUITE_DECL(measurement);
|
||||
SUITE_DECL(mem);
|
||||
SUITE_DECL(optee);
|
||||
SUITE_DECL(overlay);
|
||||
SUITE_DECL(pci_mps);
|
||||
SUITE_DECL(seama);
|
||||
SUITE_DECL(setexpr);
|
||||
@@ -125,15 +78,14 @@ static struct suite suites[] = {
|
||||
SUITE(bdinfo, "bdinfo (board info) command"),
|
||||
SUITE(bloblist, "bloblist implementation"),
|
||||
SUITE(bootm, "bootm command"),
|
||||
#ifdef CONFIG_UT_BOOTSTD
|
||||
SUITE_CMD(bootstd, do_ut_bootstd, "standard boot implementation"),
|
||||
#endif
|
||||
SUITE(bootstd, "standard boot implementation"),
|
||||
SUITE(cmd, "various commands"),
|
||||
SUITE(common, "tests for common/ directory"),
|
||||
SUITE(dm, "driver model"),
|
||||
SUITE(env, "environment"),
|
||||
SUITE(exit, "shell exit and variables"),
|
||||
SUITE(fdt, "fdt command"),
|
||||
SUITE(fdt_overlay, "device tree overlays"),
|
||||
SUITE(font, "font command"),
|
||||
SUITE(hush, "hush behaviour"),
|
||||
SUITE(lib, "library functions"),
|
||||
@@ -142,12 +94,7 @@ static struct suite suites[] = {
|
||||
SUITE(mbr, "mbr command"),
|
||||
SUITE(measurement, "TPM-based measured boot"),
|
||||
SUITE(mem, "memory-related commands"),
|
||||
#ifdef CONFIG_UT_OPTEE
|
||||
SUITE_CMD(optee, do_ut_optee, "OP-TEE"),
|
||||
#endif
|
||||
#ifdef CONFIG_UT_OVERLAY
|
||||
SUITE_CMD(overlay, do_ut_overlay, "device tree overlays"),
|
||||
#endif
|
||||
SUITE(optee, "OP-TEE"),
|
||||
SUITE(pci_mps, "PCI Express Maximum Payload Size"),
|
||||
SUITE(seama, "seama command parameters loading and decoding"),
|
||||
SUITE(setexpr, "setexpr command"),
|
||||
@@ -167,33 +114,59 @@ static bool has_tests(struct suite *ste)
|
||||
{
|
||||
int n_ents = ste->end - ste->start;
|
||||
|
||||
return n_ents || ste->cmd;
|
||||
return n_ents;
|
||||
}
|
||||
|
||||
/** run_suite() - Run a suite of tests */
|
||||
static int run_suite(struct unit_test_state *uts, struct suite *ste,
|
||||
struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
const char *select_name, int runs_per_test, bool force_run,
|
||||
const char *test_insert)
|
||||
{
|
||||
int n_ents = ste->end - ste->start;
|
||||
char prefix[30];
|
||||
int ret;
|
||||
|
||||
if (ste->cmd) {
|
||||
ret = ste->cmd(uts, cmdtp, flag, argc, argv);
|
||||
} else {
|
||||
int n_ents = ste->end - ste->start;
|
||||
char prefix[30];
|
||||
/* use a standard prefix */
|
||||
snprintf(prefix, sizeof(prefix), "%s_test_", ste->name);
|
||||
|
||||
/* use a standard prefix */
|
||||
snprintf(prefix, sizeof(prefix), "%s_test", ste->name);
|
||||
ret = cmd_ut_category(uts, ste->name, prefix, ste->start,
|
||||
n_ents, argc, argv);
|
||||
}
|
||||
ret = ut_run_list(uts, ste->name, prefix, ste->start, n_ents,
|
||||
select_name, runs_per_test, force_run, test_insert);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp,
|
||||
int flag, int argc, char *const argv[])
|
||||
static void show_stats(struct unit_test_state *uts)
|
||||
{
|
||||
if (uts->run_count < 2)
|
||||
return;
|
||||
|
||||
ut_report(&uts->total, uts->run_count);
|
||||
if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION) &&
|
||||
uts->total.test_count && uts->worst) {
|
||||
ulong avg = uts->total.duration_ms / uts->total.test_count;
|
||||
|
||||
printf("Average test time: %ld ms, worst case '%s' took %d ms\n",
|
||||
avg, uts->worst->name, uts->worst_ms);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_stats(struct unit_test_state *uts, const struct suite *ste)
|
||||
{
|
||||
if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION) && uts->cur.test_count) {
|
||||
ulong avg;
|
||||
|
||||
avg = uts->cur.duration_ms ?
|
||||
uts->cur.duration_ms /
|
||||
uts->cur.test_count : 0;
|
||||
if (avg > uts->worst_ms) {
|
||||
uts->worst_ms = avg;
|
||||
uts->worst = ste;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int do_ut_all(struct unit_test_state *uts, const char *select_name,
|
||||
int runs_per_test, bool force_run, const char *test_insert)
|
||||
{
|
||||
int i;
|
||||
int retval;
|
||||
@@ -201,25 +174,23 @@ static int do_ut_all(struct unit_test_state *uts, struct cmd_tbl *cmdtp,
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(suites); i++) {
|
||||
struct suite *ste = &suites[i];
|
||||
char *const argv[] = {(char *)ste->name, NULL};
|
||||
|
||||
if (has_tests(ste)) {
|
||||
printf("----Running %s tests----\n", ste->name);
|
||||
retval = run_suite(uts, ste, cmdtp, flag, 1, argv);
|
||||
retval = run_suite(uts, ste, select_name, runs_per_test,
|
||||
force_run, test_insert);
|
||||
if (!any_fail)
|
||||
any_fail = retval;
|
||||
update_stats(uts, ste);
|
||||
}
|
||||
}
|
||||
ut_report(&uts->total, uts->run_count);
|
||||
|
||||
return any_fail;
|
||||
}
|
||||
|
||||
static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
static int do_ut_info(bool show_suites)
|
||||
{
|
||||
int suite_count, i;
|
||||
const char *flags;
|
||||
|
||||
for (suite_count = 0, i = 0; i < ARRAY_SIZE(suites); i++) {
|
||||
struct suite *ste = &suites[i];
|
||||
@@ -231,24 +202,26 @@ static int do_ut_info(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
printf("Test suites: %d\n", suite_count);
|
||||
printf("Total tests: %d\n", (int)UNIT_TEST_ALL_COUNT());
|
||||
|
||||
flags = cmd_arg1(argc, argv);
|
||||
if (flags && !strcmp("-s", flags)) {
|
||||
int i;
|
||||
if (show_suites) {
|
||||
int i, total;
|
||||
|
||||
puts("\nTests Suite Purpose");
|
||||
puts("\n----- ------------ -------------------------\n");
|
||||
for (i = 0; i < ARRAY_SIZE(suites); i++) {
|
||||
for (i = 0, total = 0; i < ARRAY_SIZE(suites); i++) {
|
||||
struct suite *ste = &suites[i];
|
||||
long n_ent = ste->end - ste->start;
|
||||
|
||||
if (n_ent)
|
||||
printf("%5ld", n_ent);
|
||||
else if (ste->cmd)
|
||||
printf("%5s", "?");
|
||||
else /* suite is not present */
|
||||
continue;
|
||||
printf(" %-13.13s %s\n", ste->name, ste->help);
|
||||
if (n_ent) {
|
||||
printf("%5ld %-13.13s %s\n", n_ent, ste->name,
|
||||
ste->help);
|
||||
total += n_ent;
|
||||
}
|
||||
}
|
||||
puts("----- ------------ -------------------------\n");
|
||||
printf("%5d %-13.13s\n", total, "Total");
|
||||
|
||||
if (UNIT_TEST_ALL_COUNT() != total)
|
||||
puts("Error: Suite test-count does not match total\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -269,37 +242,77 @@ static struct suite *find_suite(const char *name)
|
||||
|
||||
static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
const char *test_insert = NULL, *select_name;
|
||||
struct unit_test_state uts;
|
||||
bool show_suites = false;
|
||||
bool force_run = false;
|
||||
int runs_per_text = 1;
|
||||
struct suite *ste;
|
||||
const char *name;
|
||||
char *name;
|
||||
int ret;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
/* drop initial "ut" arg */
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while (argc > 0 && *argv[0] == '-') {
|
||||
const char *str = argv[0];
|
||||
|
||||
switch (str[1]) {
|
||||
case 'r':
|
||||
runs_per_text = dectoul(str + 2, NULL);
|
||||
break;
|
||||
case 'f':
|
||||
force_run = true;
|
||||
break;
|
||||
case 'I':
|
||||
test_insert = str + 2;
|
||||
if (!strchr(test_insert, ':'))
|
||||
return CMD_RET_USAGE;
|
||||
break;
|
||||
case 's':
|
||||
show_suites = true;
|
||||
break;
|
||||
}
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (argc < 1)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
ut_init_state(&uts);
|
||||
name = argv[0];
|
||||
select_name = cmd_arg1(argc, argv);
|
||||
if (!strcmp(name, "all")) {
|
||||
ret = do_ut_all(&uts, cmdtp, flag, argc, argv);
|
||||
ret = do_ut_all(&uts, select_name, runs_per_text, force_run,
|
||||
test_insert);
|
||||
} else if (!strcmp(name, "info")) {
|
||||
ret = do_ut_info(cmdtp, flag, argc, argv);
|
||||
ret = do_ut_info(show_suites);
|
||||
} else {
|
||||
ste = find_suite(argv[0]);
|
||||
if (!ste) {
|
||||
printf("Suite '%s' not found\n", argv[0]);
|
||||
return CMD_RET_FAILURE;
|
||||
} else if (!has_tests(ste)) {
|
||||
/* perhaps a Kconfig option needs to be set? */
|
||||
printf("Suite '%s' is not enabled\n", argv[0]);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
int any_fail = 0;
|
||||
const char *p;
|
||||
|
||||
ret = run_suite(&uts, ste, cmdtp, flag, argc, argv);
|
||||
for (; p = strsep(&name, ","), p; name = NULL) {
|
||||
ste = find_suite(p);
|
||||
if (!ste) {
|
||||
printf("Suite '%s' not found\n", p);
|
||||
return CMD_RET_FAILURE;
|
||||
} else if (!has_tests(ste)) {
|
||||
/* perhaps a Kconfig option needs to be set? */
|
||||
printf("Suite '%s' is not enabled\n", p);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
ret = run_suite(&uts, ste, select_name, runs_per_text,
|
||||
force_run, test_insert);
|
||||
if (!any_fail)
|
||||
any_fail = ret;
|
||||
update_stats(&uts, ste);
|
||||
}
|
||||
ret = any_fail;
|
||||
}
|
||||
show_stats(&uts);
|
||||
if (ret)
|
||||
return ret;
|
||||
ut_uninit_state(&uts);
|
||||
@@ -308,14 +321,16 @@ static int do_ut(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
}
|
||||
|
||||
U_BOOT_LONGHELP(ut,
|
||||
"[-r] [-f] [<suite>] - run unit tests\n"
|
||||
"[-rs] [-f] [-I<n>:<one_test>][<suites>] - run unit tests\n"
|
||||
" -r<runs> Number of times to run each test\n"
|
||||
" -f Force 'manual' tests to run as well\n"
|
||||
" <suite> Test suite to run, or all\n"
|
||||
" -I Test to run after <n> other tests have run\n"
|
||||
" -s Show all suites with ut info\n"
|
||||
" <suites> Comma-separated list of suites to run\n"
|
||||
"\n"
|
||||
"\nOptions for <suite>:"
|
||||
"\nall - execute all enabled tests"
|
||||
"\ninfo [-s] - show info about tests [and suites]"
|
||||
"Options for <suite>:\n"
|
||||
"all - execute all enabled tests\n"
|
||||
"info - show info about tests [and suites]"
|
||||
);
|
||||
|
||||
U_BOOT_CMD(
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <bloblist.h>
|
||||
#include <log.h>
|
||||
#include <mapmem.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/test.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
config UT_DM
|
||||
bool "Enable driver model unit test command"
|
||||
depends on SANDBOX && UNIT_TEST
|
||||
depends on SANDBOX
|
||||
help
|
||||
This enables the 'ut dm' command which runs a series of unit
|
||||
tests on the driver model code. Each subsystem (uclass) is tested.
|
||||
|
||||
@@ -26,8 +26,6 @@ static int dm_test_cmd_mux_list(struct unit_test_state *uts)
|
||||
int i;
|
||||
unsigned long val;
|
||||
|
||||
sandbox_set_enable_memio(true);
|
||||
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller",
|
||||
&dev));
|
||||
chip = dev_get_uclass_priv(dev);
|
||||
@@ -119,8 +117,6 @@ static int dm_test_cmd_mux_select(struct unit_test_state *uts)
|
||||
char cmd[BUF_SIZE];
|
||||
unsigned int i, state;
|
||||
|
||||
sandbox_set_enable_memio(true);
|
||||
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller",
|
||||
&dev));
|
||||
chip = dev_get_uclass_priv(dev);
|
||||
@@ -153,8 +149,6 @@ static int dm_test_cmd_mux_deselect(struct unit_test_state *uts)
|
||||
char cmd[BUF_SIZE];
|
||||
unsigned int i, state;
|
||||
|
||||
sandbox_set_enable_memio(true);
|
||||
|
||||
ut_assertok(uclass_get_device_by_name(UCLASS_MUX, "a-mux-controller",
|
||||
&dev));
|
||||
chip = dev_get_uclass_priv(dev);
|
||||
|
||||
1
test/env/Kconfig
vendored
1
test/env/Kconfig
vendored
@@ -1,6 +1,5 @@
|
||||
config UT_ENV
|
||||
bool "Enable env unit tests"
|
||||
depends on UNIT_TEST
|
||||
default y
|
||||
help
|
||||
This enables the 'ut env' command which runs a series of unit
|
||||
|
||||
1
test/env/cmd_ut_env.c
vendored
1
test/env/cmd_ut_env.c
vendored
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
#include <test/env.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
static int env_test_env_cmd(struct unit_test_state *uts)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
config UT_OVERLAY
|
||||
config UT_FDT_OVERLAY
|
||||
bool "Enable Device Tree Overlays Unit Tests"
|
||||
depends on UNIT_TEST && OF_CONTROL && SANDBOX
|
||||
depends on OF_CONTROL && SANDBOX
|
||||
default y
|
||||
select OF_LIBFDT_OVERLAY
|
||||
help
|
||||
@@ -4,7 +4,7 @@
|
||||
# Copyright (c) 2016 Free Electrons
|
||||
|
||||
# Test files
|
||||
obj-y += cmd_ut_overlay.o
|
||||
obj-y += cmd_ut_fdt_overlay.o
|
||||
|
||||
DTC_FLAGS += -@
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <command.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <fdt_support.h>
|
||||
#include <image.h>
|
||||
#include <log.h>
|
||||
@@ -13,9 +14,8 @@
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include <test/fdt_overlay.h>
|
||||
#include <test/ut.h>
|
||||
#include <test/overlay.h>
|
||||
#include <test/suites.h>
|
||||
|
||||
/* 4k ought to be enough for anybody */
|
||||
#define FDT_COPY_SIZE (4 * SZ_1K)
|
||||
@@ -26,215 +26,22 @@ extern u32 __dtbo_test_fdt_overlay_stacked_begin;
|
||||
|
||||
static void *fdt;
|
||||
|
||||
static int ut_fdt_getprop_u32_by_index(void *fdt, const char *path,
|
||||
const char *name, int index,
|
||||
u32 *out)
|
||||
static int fdt_overlay_init(struct unit_test_state *uts)
|
||||
{
|
||||
const fdt32_t *val;
|
||||
int node_off;
|
||||
int len;
|
||||
|
||||
node_off = fdt_path_offset(fdt, path);
|
||||
if (node_off < 0)
|
||||
return node_off;
|
||||
|
||||
val = fdt_getprop(fdt, node_off, name, &len);
|
||||
if (!val || (len < (sizeof(uint32_t) * (index + 1))))
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
|
||||
*out = fdt32_to_cpu(*(val + index));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ut_fdt_getprop_u32(void *fdt, const char *path, const char *name,
|
||||
u32 *out)
|
||||
{
|
||||
return ut_fdt_getprop_u32_by_index(fdt, path, name, 0, out);
|
||||
}
|
||||
|
||||
static int fdt_getprop_str(void *fdt, const char *path, const char *name,
|
||||
const char **out)
|
||||
{
|
||||
int node_off;
|
||||
int len;
|
||||
|
||||
node_off = fdt_path_offset(fdt, path);
|
||||
if (node_off < 0)
|
||||
return node_off;
|
||||
|
||||
*out = fdt_stringlist_get(fdt, node_off, name, 0, &len);
|
||||
|
||||
return len < 0 ? len : 0;
|
||||
}
|
||||
|
||||
static int fdt_overlay_change_int_property(struct unit_test_state *uts)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
ut_assertok(ut_fdt_getprop_u32(fdt, "/test-node", "test-int-property",
|
||||
&val));
|
||||
ut_asserteq(43, val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_change_int_property, 0);
|
||||
|
||||
static int fdt_overlay_change_str_property(struct unit_test_state *uts)
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property",
|
||||
&val));
|
||||
ut_asserteq_str("foobar", val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_change_str_property, 0);
|
||||
|
||||
static int fdt_overlay_add_str_property(struct unit_test_state *uts)
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property-2",
|
||||
&val));
|
||||
ut_asserteq_str("foobar2", val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_add_str_property, 0);
|
||||
|
||||
static int fdt_overlay_add_node_by_phandle(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node/new-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_add_node_by_phandle, 0);
|
||||
|
||||
static int fdt_overlay_add_node_by_path(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_add_node_by_path, 0);
|
||||
|
||||
static int fdt_overlay_add_subnode_property(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node/sub-test-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "sub-test-property", NULL));
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "new-sub-test-property", NULL));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_add_subnode_property, 0);
|
||||
|
||||
static int fdt_overlay_local_phandle(struct unit_test_state *uts)
|
||||
{
|
||||
uint32_t local_phandle;
|
||||
u32 val = 0;
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-local-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
local_phandle = fdt_get_phandle(fdt, off);
|
||||
ut_assert(local_phandle);
|
||||
|
||||
ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
|
||||
0, &val));
|
||||
ut_asserteq(local_phandle, val);
|
||||
|
||||
ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-several-phandle",
|
||||
1, &val));
|
||||
ut_asserteq(local_phandle, val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_local_phandle, 0);
|
||||
|
||||
static int fdt_overlay_local_phandles(struct unit_test_state *uts)
|
||||
{
|
||||
uint32_t local_phandle, test_phandle;
|
||||
u32 val = 0;
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-local-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
local_phandle = fdt_get_phandle(fdt, off);
|
||||
ut_assert(local_phandle);
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
test_phandle = fdt_get_phandle(fdt, off);
|
||||
ut_assert(test_phandle);
|
||||
|
||||
ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 0,
|
||||
&val));
|
||||
ut_asserteq(test_phandle, val);
|
||||
|
||||
ut_assertok(ut_fdt_getprop_u32_by_index(fdt, "/", "test-phandle", 1,
|
||||
&val));
|
||||
ut_asserteq(local_phandle, val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_local_phandles, 0);
|
||||
|
||||
static int fdt_overlay_stacked(struct unit_test_state *uts)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
ut_assertok(ut_fdt_getprop_u32(fdt, "/new-local-node",
|
||||
"stacked-test-int-property", &val));
|
||||
ut_asserteq(43, val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OVERLAY_TEST(fdt_overlay_stacked, 0);
|
||||
|
||||
int do_ut_overlay(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag,
|
||||
int argc, char *const argv[])
|
||||
{
|
||||
struct unit_test *tests = UNIT_TEST_SUITE_START(overlay);
|
||||
const int n_ents = UNIT_TEST_SUITE_COUNT(overlay);
|
||||
void *fdt_base = &__dtb_test_fdt_base_begin;
|
||||
void *fdt_overlay = &__dtbo_test_fdt_overlay_begin;
|
||||
void *fdt_overlay_stacked = &__dtbo_test_fdt_overlay_stacked_begin;
|
||||
void *fdt_overlay_copy, *fdt_overlay_stacked_copy;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
ut_assertok(fdt_check_header(fdt_base));
|
||||
ut_assertok(fdt_check_header(fdt_overlay));
|
||||
|
||||
fdt = malloc(FDT_COPY_SIZE);
|
||||
if (!fdt)
|
||||
goto err1;
|
||||
|
||||
fdt_overlay_copy = malloc(FDT_COPY_SIZE);
|
||||
if (!fdt_overlay_copy)
|
||||
goto err2;
|
||||
|
||||
fdt_overlay_stacked_copy = malloc(FDT_COPY_SIZE);
|
||||
if (!fdt_overlay_stacked_copy)
|
||||
goto err3;
|
||||
ut_assertnonnull(fdt);
|
||||
ut_assertnonnull(fdt_overlay_copy);
|
||||
ut_assertnonnull(fdt_overlay_stacked_copy);
|
||||
|
||||
/*
|
||||
* Resize the FDT to 4k so that we have room to operate on
|
||||
@@ -268,13 +75,163 @@ int do_ut_overlay(struct unit_test_state *uts, struct cmd_tbl *cmdtp, int flag,
|
||||
/* Apply the stacked overlay */
|
||||
ut_assertok(fdt_overlay_apply(fdt, fdt_overlay_stacked_copy));
|
||||
|
||||
ret = cmd_ut_category(uts, "overlay", "", tests, n_ents, argc, argv);
|
||||
|
||||
free(fdt_overlay_stacked_copy);
|
||||
err3:
|
||||
free(fdt_overlay_copy);
|
||||
err2:
|
||||
free(fdt);
|
||||
err1:
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
FDT_OVERLAY_TEST_INIT(fdt_overlay_init, 0);
|
||||
|
||||
static int fdt_getprop_str(void *fdt, const char *path, const char *name,
|
||||
const char **out)
|
||||
{
|
||||
int node_off;
|
||||
int len;
|
||||
|
||||
node_off = fdt_path_offset(fdt, path);
|
||||
if (node_off < 0)
|
||||
return node_off;
|
||||
|
||||
*out = fdt_stringlist_get(fdt, node_off, name, 0, &len);
|
||||
|
||||
return len < 0 ? len : 0;
|
||||
}
|
||||
|
||||
static int fdt_overlay_test_change_int_property(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_asserteq(43, fdtdec_get_uint(fdt, off, "test-int-property", 0));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_change_int_property, 0);
|
||||
|
||||
static int fdt_overlay_test_change_str_property(struct unit_test_state *uts)
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property",
|
||||
&val));
|
||||
ut_asserteq_str("foobar", val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_change_str_property, 0);
|
||||
|
||||
static int fdt_overlay_test_add_str_property(struct unit_test_state *uts)
|
||||
{
|
||||
const char *val = NULL;
|
||||
|
||||
ut_assertok(fdt_getprop_str(fdt, "/test-node", "test-str-property-2",
|
||||
&val));
|
||||
ut_asserteq_str("foobar2", val);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_add_str_property, 0);
|
||||
|
||||
static int fdt_overlay_test_add_node_by_phandle(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node/new-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_add_node_by_phandle, 0);
|
||||
|
||||
static int fdt_overlay_test_add_node_by_path(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "new-property", NULL));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_add_node_by_path, 0);
|
||||
|
||||
static int fdt_overlay_test_add_subnode_property(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node/sub-test-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "sub-test-property", NULL));
|
||||
ut_assertnonnull(fdt_getprop(fdt, off, "new-sub-test-property", NULL));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_add_subnode_property, 0);
|
||||
|
||||
static int fdt_overlay_test_local_phandle(struct unit_test_state *uts)
|
||||
{
|
||||
uint32_t local_phandle;
|
||||
u32 val[2];
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-local-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
local_phandle = fdt_get_phandle(fdt, off);
|
||||
ut_assert(local_phandle);
|
||||
|
||||
ut_assertok(fdtdec_get_int_array(fdt, 0, "test-several-phandle", val,
|
||||
ARRAY_SIZE(val)));
|
||||
ut_asserteq(local_phandle, val[0]);
|
||||
ut_asserteq(local_phandle, val[1]);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_local_phandle, 0);
|
||||
|
||||
static int fdt_overlay_test_local_phandles(struct unit_test_state *uts)
|
||||
{
|
||||
uint32_t local_phandle, test_phandle;
|
||||
u32 val[2];
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-local-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
local_phandle = fdt_get_phandle(fdt, off);
|
||||
ut_assert(local_phandle);
|
||||
|
||||
off = fdt_path_offset(fdt, "/test-node");
|
||||
ut_assert(off >= 0);
|
||||
|
||||
test_phandle = fdt_get_phandle(fdt, off);
|
||||
ut_assert(test_phandle);
|
||||
|
||||
ut_assertok(fdtdec_get_int_array(fdt, 0, "test-phandle", val,
|
||||
ARRAY_SIZE(val)));
|
||||
ut_asserteq(test_phandle, val[0]);
|
||||
ut_asserteq(local_phandle, val[1]);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_local_phandles, 0);
|
||||
|
||||
static int fdt_overlay_test_stacked(struct unit_test_state *uts)
|
||||
{
|
||||
int off;
|
||||
|
||||
off = fdt_path_offset(fdt, "/new-local-node");
|
||||
ut_assert(off > 0);
|
||||
|
||||
ut_asserteq(43,
|
||||
fdtdec_get_uint(fdt, off, "stacked-test-int-property", 0));
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
FDT_OVERLAY_TEST(fdt_overlay_test_stacked, 0);
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <asm/global_data.h>
|
||||
#include <test/log.h>
|
||||
#include <test/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <asm/global_data.h>
|
||||
#include <test/log.h>
|
||||
#include <test/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <console.h>
|
||||
#include <test/log.h>
|
||||
#include <test/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <hexdump.h>
|
||||
#include <test/log.h>
|
||||
#include <test/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include <asm/eth.h>
|
||||
#include "syslog_test.h"
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <hexdump.h>
|
||||
#include <test/log.h>
|
||||
#include <test/test.h>
|
||||
#include <test/suites.h>
|
||||
#include <test/ut.h>
|
||||
#include <asm/eth.h>
|
||||
#include "syslog_test.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
config UT_OPTEE
|
||||
bool "Enable OP-TEE Unit Tests"
|
||||
depends on UNIT_TEST && OF_CONTROL && OPTEE
|
||||
depends on OF_CONTROL && OPTEE
|
||||
default y
|
||||
help
|
||||
This enables the 'ut optee' command which runs a series of unit
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Copyright (C) 2019, Theobroma Systems Design und Consulting GmbH
|
||||
|
||||
# Test files
|
||||
obj-y += cmd_ut_optee.o
|
||||
obj-y += optee.o
|
||||
|
||||
DTC_FLAGS += -@
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include <test/ut.h>
|
||||
#include <test/optee.h>
|
||||
#include <test/suites.h>
|
||||
|
||||
/* 4k ought to be enough for anybody */
|
||||
#define FDT_COPY_SIZE (4 * SZ_1K)
|
||||
@@ -26,6 +25,41 @@ extern u32 __dtb_test_optee_no_optee_begin;
|
||||
static void *fdt;
|
||||
static bool expect_success;
|
||||
|
||||
static int optee_test_init(struct unit_test_state *uts)
|
||||
{
|
||||
void *fdt_optee = &__dtb_test_optee_optee_begin;
|
||||
void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
|
||||
void *fdt_base = &__dtb_test_optee_base_begin;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
ut_assertok(fdt_check_header(fdt_base));
|
||||
ut_assertok(fdt_check_header(fdt_optee));
|
||||
ut_assertok(fdt_check_header(fdt_no_optee));
|
||||
|
||||
fdt = malloc(FDT_COPY_SIZE);
|
||||
if (!fdt)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Resize the FDT to 4k so that we have room to operate on
|
||||
*
|
||||
* (and relocate it since the memory might be mapped
|
||||
* read-only)
|
||||
*/
|
||||
ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
|
||||
|
||||
return 0;
|
||||
}
|
||||
OPTEE_TEST_INIT(optee_test_init, 0);
|
||||
|
||||
static int optee_test_uninit(struct unit_test_state *uts)
|
||||
{
|
||||
free(fdt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
OPTEE_TEST_UNINIT(optee_test_uninit, 0);
|
||||
|
||||
static int optee_fdt_firmware(struct unit_test_state *uts)
|
||||
{
|
||||
const void *prop;
|
||||
@@ -46,7 +80,6 @@ static int optee_fdt_firmware(struct unit_test_state *uts)
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OPTEE_TEST(optee_fdt_firmware, 0);
|
||||
|
||||
static int optee_fdt_protected_memory(struct unit_test_state *uts)
|
||||
{
|
||||
@@ -89,60 +122,50 @@ static int optee_fdt_protected_memory(struct unit_test_state *uts)
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
OPTEE_TEST(optee_fdt_protected_memory, 0);
|
||||
|
||||
int do_ut_optee(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
/* (1) Try to copy optee nodes from empty dt */
|
||||
static int optee_fdt_copy_empty(struct unit_test_state *uts)
|
||||
{
|
||||
struct unit_test *tests = UNIT_TEST_SUITE_START(optee);
|
||||
const int n_ents = UNIT_TEST_SUITE_COUNT(optee);
|
||||
struct unit_test_state *uts;
|
||||
void *fdt_optee = &__dtb_test_optee_optee_begin;
|
||||
void *fdt_no_optee = &__dtb_test_optee_no_optee_begin;
|
||||
void *fdt_base = &__dtb_test_optee_base_begin;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
uts = calloc(1, sizeof(*uts));
|
||||
if (!uts)
|
||||
return -ENOMEM;
|
||||
|
||||
ut_assertok(fdt_check_header(fdt_base));
|
||||
ut_assertok(fdt_check_header(fdt_optee));
|
||||
ut_assertok(fdt_check_header(fdt_no_optee));
|
||||
|
||||
fdt = malloc(FDT_COPY_SIZE);
|
||||
if (!fdt)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Resize the FDT to 4k so that we have room to operate on
|
||||
*
|
||||
* (and relocate it since the memory might be mapped
|
||||
* read-only)
|
||||
*/
|
||||
ut_assertok(fdt_open_into(fdt_base, fdt, FDT_COPY_SIZE));
|
||||
|
||||
/*
|
||||
* (1) Try to copy optee nodes from empty dt.
|
||||
* This should still run successfully.
|
||||
*/
|
||||
/* This should still run successfully */
|
||||
ut_assertok(optee_copy_fdt_nodes(fdt_no_optee, fdt));
|
||||
|
||||
expect_success = false;
|
||||
ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
|
||||
ut_assertok(optee_fdt_firmware(uts));
|
||||
ut_assertok(optee_fdt_protected_memory(uts));
|
||||
|
||||
return 0;
|
||||
}
|
||||
OPTEE_TEST(optee_fdt_copy_empty, 0);
|
||||
|
||||
/* (2) Try to copy optee nodes from prefilled dt */
|
||||
static int optee_fdt_copy_prefilled(struct unit_test_state *uts)
|
||||
{
|
||||
void *fdt_optee = &__dtb_test_optee_optee_begin;
|
||||
|
||||
/* (2) Try to copy optee nodes from prefilled dt */
|
||||
ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
|
||||
|
||||
expect_success = true;
|
||||
ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
|
||||
ut_assertok(optee_fdt_firmware(uts));
|
||||
ut_assertok(optee_fdt_protected_memory(uts));
|
||||
|
||||
return 0;
|
||||
}
|
||||
OPTEE_TEST(optee_fdt_copy_prefilled, 0);
|
||||
|
||||
/* (3) Try to copy OP-TEE nodes into a already filled DT */
|
||||
static int optee_fdt_copy_already_filled(struct unit_test_state *uts)
|
||||
{
|
||||
void *fdt_optee = &__dtb_test_optee_optee_begin;
|
||||
|
||||
/* (3) Try to copy OP-TEE nodes into a already filled DT */
|
||||
ut_assertok(fdt_open_into(fdt_optee, fdt, FDT_COPY_SIZE));
|
||||
ut_assertok(optee_copy_fdt_nodes(fdt_optee, fdt));
|
||||
|
||||
expect_success = true;
|
||||
ret = cmd_ut_category("optee", "", tests, n_ents, argc, argv);
|
||||
ut_assertok(optee_fdt_firmware(uts));
|
||||
ut_assertok(optee_fdt_protected_memory(uts));
|
||||
|
||||
free(fdt);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
OPTEE_TEST(optee_fdt_copy_already_filled, 0);
|
||||
@@ -7,10 +7,10 @@ import re
|
||||
# List of test suites we expect to find with 'ut info' and 'ut all'
|
||||
EXPECTED_SUITES = [
|
||||
'addrmap', 'bdinfo', 'bloblist', 'bootm', 'bootstd',
|
||||
'cmd', 'common', 'dm', 'env', 'exit',
|
||||
'cmd', 'common', 'dm', 'env', 'exit', 'fdt_overlay',
|
||||
'fdt', 'font', 'hush', 'lib',
|
||||
'loadm', 'log', 'mbr', 'measurement', 'mem',
|
||||
'overlay', 'pci_mps', 'setexpr', 'upl',
|
||||
'pci_mps', 'setexpr', 'upl',
|
||||
]
|
||||
|
||||
|
||||
@@ -66,11 +66,12 @@ def collect_info(cons, output):
|
||||
msg = m.group(3)
|
||||
if DEBUG_ME:
|
||||
cons.log.info(f"test_name {test_name} msg '{msg}'")
|
||||
if msg == ' (flat tree)' and test_name not in tests:
|
||||
tests.add(test_name)
|
||||
full_name = f'{cur_suite}.{test_name}'
|
||||
if msg == ' (flat tree)' and full_name not in tests:
|
||||
tests.add(full_name)
|
||||
test_count += 1
|
||||
if not msg or 'skipped as it is manual' in msg:
|
||||
tests.add(test_name)
|
||||
tests.add(full_name)
|
||||
test_count += 1
|
||||
if DEBUG_ME:
|
||||
cons.log.info(f'test_count {test_count}')
|
||||
@@ -134,7 +135,7 @@ def xtest_suite(u_boot_console, u_boot_config):
|
||||
|
||||
- The number of suites matches that reported by the 'ut info'
|
||||
- Where available, the number of tests is each suite matches that
|
||||
reported by 'ut info -s'
|
||||
reported by 'ut -s info'
|
||||
- The total number of tests adds up to the total that are actually run
|
||||
with 'ut all'
|
||||
- All suites are run with 'ut all'
|
||||
@@ -166,7 +167,7 @@ def xtest_suite(u_boot_console, u_boot_config):
|
||||
|
||||
# Run 'ut info' and compare with the log results
|
||||
with cons.log.section('Check suite test-counts'):
|
||||
output = cons.run_command('ut info -s')
|
||||
output = cons.run_command('ut -s info')
|
||||
|
||||
suite_count, total_test_count, test_count = process_ut_info(cons,
|
||||
output)
|
||||
@@ -186,3 +187,22 @@ def xtest_suite(u_boot_console, u_boot_config):
|
||||
|
||||
assert suite_count == len(EXPECTED_SUITES)
|
||||
assert total_test_count == len(all_tests)
|
||||
|
||||
# Run three suites
|
||||
with cons.log.section('Check multiple suites'):
|
||||
output = cons.run_command('ut bloblist,setexpr,mem')
|
||||
assert 'Suites run: 3' in output
|
||||
|
||||
# Run a particular test
|
||||
with cons.log.section('Check single test'):
|
||||
output = cons.run_command('ut bloblist reloc')
|
||||
assert 'Test: reloc: bloblist.c' in output
|
||||
|
||||
# Run tests multiple times
|
||||
with cons.log.section('Check multiple runs'):
|
||||
output = cons.run_command('ut -r2 bloblist')
|
||||
lines = output.splitlines()
|
||||
run = len([line for line in lines if 'Test:' in line])
|
||||
count = re.search(r'Tests run: (\d*)', lines[-1]).group(1)
|
||||
|
||||
assert run == 2 * int(count)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <net.h>
|
||||
#include <of_live.h>
|
||||
#include <os.h>
|
||||
#include <spl.h>
|
||||
#include <usb.h>
|
||||
#include <dm/ofnode.h>
|
||||
#include <dm/root.h>
|
||||
@@ -513,11 +514,12 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test,
|
||||
* the first call to this function. On exit, @uts->cur.fail_count is
|
||||
* incremented by the number of failures (0, one hopes)
|
||||
* @test: Test to run
|
||||
* @leaf: Part of the name to show, or NULL to use test->name
|
||||
* Return: 0 if all tests passed, -EAGAIN if the test should be skipped, -1 if
|
||||
* any failed
|
||||
*/
|
||||
static int ut_run_test_live_flat(struct unit_test_state *uts,
|
||||
struct unit_test *test)
|
||||
struct unit_test *test, const char *leaf)
|
||||
{
|
||||
int runs, ret;
|
||||
|
||||
@@ -529,7 +531,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts,
|
||||
if (CONFIG_IS_ENABLED(OF_LIVE)) {
|
||||
if (!(test->flags & UTF_FLAT_TREE)) {
|
||||
uts->of_live = true;
|
||||
ret = ut_run_test(uts, test, test->name);
|
||||
ret = ut_run_test(uts, test, leaf ?: test->name);
|
||||
if (ret != -EAGAIN) {
|
||||
ut_assertok(ret);
|
||||
runs++;
|
||||
@@ -557,7 +559,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts,
|
||||
(!runs || ut_test_run_on_flattree(test)) &&
|
||||
!(gd->flags & GD_FLG_FDT_CHANGED)) {
|
||||
uts->of_live = false;
|
||||
ret = ut_run_test(uts, test, test->name);
|
||||
ret = ut_run_test(uts, test, leaf ?: test->name);
|
||||
if (ret != -EAGAIN) {
|
||||
ut_assertok(ret);
|
||||
runs++;
|
||||
@@ -593,6 +595,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
|
||||
struct unit_test *tests, int count,
|
||||
const char *select_name, const char *test_insert)
|
||||
{
|
||||
int prefix_len = prefix ? strlen(prefix) : 0;
|
||||
struct unit_test *test, *one;
|
||||
int found = 0;
|
||||
int pos = 0;
|
||||
@@ -617,7 +620,8 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
|
||||
const char *test_name = test->name;
|
||||
int ret, i, old_fail_count;
|
||||
|
||||
if (!test_matches(prefix, test_name, select_name))
|
||||
if (!(test->flags & (UTF_INIT | UTF_UNINIT)) &&
|
||||
!test_matches(prefix, test_name, select_name))
|
||||
continue;
|
||||
|
||||
if (test->flags & UTF_MANUAL) {
|
||||
@@ -645,7 +649,7 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
|
||||
|
||||
uts->cur.test_count++;
|
||||
if (one && upto == pos) {
|
||||
ret = ut_run_test_live_flat(uts, one);
|
||||
ret = ut_run_test_live_flat(uts, one, NULL);
|
||||
if (uts->cur.fail_count != old_fail_count) {
|
||||
printf("Test '%s' failed %d times (position %d)\n",
|
||||
one->name,
|
||||
@@ -655,8 +659,11 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
if (prefix_len && !strncmp(test_name, prefix, prefix_len))
|
||||
test_name = test_name + prefix_len;
|
||||
|
||||
for (i = 0; i < uts->runs_per_test; i++)
|
||||
ret = ut_run_test_live_flat(uts, test);
|
||||
ret = ut_run_test_live_flat(uts, test, test_name);
|
||||
if (uts->cur.fail_count != old_fail_count) {
|
||||
printf("Test '%s' failed %d times\n", test_name,
|
||||
uts->cur.fail_count - old_fail_count);
|
||||
@@ -680,6 +687,12 @@ void ut_report(struct ut_stats *stats, int run_count)
|
||||
else
|
||||
printf("Tests");
|
||||
printf(" run: %d, ", stats->test_count);
|
||||
if (stats && stats->test_count) {
|
||||
ulong dur = stats->duration_ms;
|
||||
|
||||
printf("%ld ms, average: %ld ms, ", dur,
|
||||
dur ? dur / stats->test_count : 0);
|
||||
}
|
||||
if (stats->skip_count)
|
||||
printf("skipped: %d, ", stats->skip_count);
|
||||
printf("failures: %d\n", stats->fail_count);
|
||||
@@ -692,16 +705,22 @@ int ut_run_list(struct unit_test_state *uts, const char *category,
|
||||
{
|
||||
;
|
||||
bool has_dm_tests = false;
|
||||
ulong start_offset = 0;
|
||||
ulong test_offset = 0;
|
||||
int ret;
|
||||
|
||||
memset(&uts->cur, '\0', sizeof(struct ut_stats));
|
||||
if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION)) {
|
||||
uts->cur.start = get_timer(0);
|
||||
start_offset = timer_test_get_offset();
|
||||
}
|
||||
|
||||
if (!CONFIG_IS_ENABLED(OF_PLATDATA) &&
|
||||
ut_list_has_dm_tests(tests, count, prefix, select_name)) {
|
||||
has_dm_tests = true;
|
||||
/*
|
||||
* If we have no device tree, or it only has a root node, then
|
||||
* these * tests clearly aren't going to work...
|
||||
* these tests clearly aren't going to work...
|
||||
*/
|
||||
if (!gd->fdt_blob || fdt_next_node(gd->fdt_blob, 0, NULL) < 0) {
|
||||
puts("Please run with test device tree:\n"
|
||||
@@ -732,13 +751,19 @@ int ut_run_list(struct unit_test_state *uts, const char *category,
|
||||
if (has_dm_tests)
|
||||
dm_test_restore(uts->of_root);
|
||||
|
||||
ut_report(&uts->cur, 1);
|
||||
if (ret == -ENOENT)
|
||||
printf("Test '%s' not found\n", select_name);
|
||||
if (CONFIG_IS_ENABLED(UNIT_TEST_DURATION)) {
|
||||
test_offset = timer_test_get_offset() - start_offset;
|
||||
|
||||
uts->cur.duration_ms = get_timer(uts->cur.start) - test_offset;
|
||||
}
|
||||
ut_report(&uts->cur, 1);
|
||||
|
||||
uts->total.skip_count += uts->cur.skip_count;
|
||||
uts->total.fail_count += uts->cur.fail_count;
|
||||
uts->total.test_count += uts->cur.test_count;
|
||||
uts->total.duration_ms += uts->cur.duration_ms;
|
||||
uts->run_count++;
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user