test: Add compression tests to pytest
cover test: Add compression tests to pytest
At present the compression tests do not use the unit test framework, nor are they executed by the 'make tests' command. This series converts these tests to use the unit test framework, adding a few other minor improvements along the way.
The overlay tests do not currently run for me, and we lack instructions on how to run them.
./b/sandbox/u-boot -c "ut overlay"
did not work:
Running 9 overlay tests
Test: fdt_overlay_add_node_by_path
Segmentation fault (core dumped)
It would be useful to have instructions for how to run these somewhere, along with a README for the feature. The tests should run with 'make tests'.
Simon Glass (5):
test: Add a command function for test execution
test: overlay: Use cmd_ut_category()
test: compression: Put test variables in a struct test/py: Allow any unit test suite to be found
test: compression: Convert to unit test framework
include/test/compression.h | 17 +++ include/test/suites.h | 17 +++ test/cmd_ut.c | 32 +++++ test/compression.c | 295 ++++++++++++++++++++++++++---------------- test/env/cmd_ut_env.c | 19 +-- test/overlay/cmd_ut_overlay.c | 21 +-- test/py/conftest.py | 2 +- 7 files changed, 251 insertions(+), 152 deletions(-) create mode 100644 include/test/compression.h
Signature · 1 line
2.15.0.417.g466bffb3ac-goog
PATCH 1/5 test: Add a command function for test execution
The logic to either iterate through a list of tests or pick a named test is common to at lest two test suits. Move this logic into a new function and call it from the environment tests.
---
include/test/suites.h | 16 ++++++++++++++++ test/cmd_ut.c | 25 +++++++++++++++++++++++++ test/env/cmd_ut_env.c | 19 +------------------ 3 files changed, 42 insertions(+), 18 deletions(-)
include/test/suites.h +16 -0
@@ -8,6 +8,22 @@#ifndef __TEST_SUITES_H__#define __TEST_SUITES_H__ +struct unit_test ; + +/** +* cmd_ut_category() - Run a category of unit tests +* +* @name: Category 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 (const char *name,struct unit_test *tests,int n_ents, +int argc,char *const argv[]); +int do_ut_dm (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_env (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_overlay (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);
test/cmd_ut.c +25 -0
@@ -8,9 +8,34 @@#include <common.h> #include <command.h> #include <test/suites.h> +#include <test/test.h> static int do_ut_all (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); +int cmd_ut_category (const char *name,struct unit_test *tests,int n_ents, +int argc,char *const argv[]) +{ +struct unit_test_state uts = { .fail_count =0 }; +struct unit_test *test; + +if (argc ==1 ) +printf ("Running %d %s tests\n" , n_ents, name); + +for (test = tests; test < tests + n_ents; test++) { +if (argc >1 &&strcmp (argv[1 ], test->name)) +continue ; +printf ("Test: %s\n" , test->name); + + uts.start =mallinfo (); + + test->func (&uts); + } + +printf ("Failures: %d\n" , uts.fail_count); + +return uts.fail_count ?CMD_RET_FAILURE :0 ; +} +static cmd_tbl_t cmd_ut_sub[] = {U_BOOT_CMD_MKENT (all,CONFIG_SYS_MAXARGS ,1 , do_ut_all,"" ,"" ), #if defined(CONFIG_UT_DM)
test/env/cmd_ut_env.c +1 -18
@@ -15,23 +15,6 @@ int do_ut_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct unit_test *tests = ll_entry_start(struct unit_test, env_test); const int n_ents = ll_entry_count(struct unit_test, env_test); -struct unit_test_state uts = { .fail_count =0 }; -struct unit_test *test; -if (argc ==1 ) -printf ("Running %d environment tests\n" , n_ents); - -for (test = tests; test < tests + n_ents; test++) { -if (argc >1 &&strcmp (argv[1 ], test->name)) -continue ; -printf ("Test: %s\n" , test->name); - - uts.start =mallinfo (); - - test->func (&uts); - } - -printf ("Failures: %d\n" , uts.fail_count); - -return uts.fail_count ?CMD_RET_FAILURE :0 ; +return cmd_ut_category ("environment" , tests, n_ents, argc, argv); }
Signature · 1 line
2.15.0.417.g466bffb3ac-goog
PATCH 1/5 test: Add a command function for test execution
Quoted 5 lines · Simon Glass
The logic to either iterate through a list of tests or pick a named test is common to at lest two test suits. Move this logic into a new function and call it from the environment tests.
Signed-off-by Simon Glass <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171204/cef73217/attachment.sig>
PATCH 2/5 test: overlay: Use cmd_ut_category()
In reply to Simon GlassAdjust the code to use the common test-execution function.
---
test/overlay/cmd_ut_overlay.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-)
test/overlay/cmd_ut_overlay.c +2 -19
@@ -14,6 +14,7 @@#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)
@@ -221,7 +222,6 @@ int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) overlay_test); const int n_ents = ll_entry_count(struct unit_test, overlay_test);struct unit_test_state *uts; -struct unit_test *test;void *fdt_base = &__dtb_test_fdt_base_begin;void *fdt_overlay = &__dtb_test_fdt_overlay_begin;void *fdt_overlay_stacked = &__dtb_test_fdt_overlay_stacked_begin;
@@ -280,24 +280,7 @@ int do_ut_overlay(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])/* Apply the stacked overlay */ ut_assertok (fdt_overlay_apply (fdt_base_copy, fdt_overlay_stacked_copy)); -if (argc ==1 ) -printf ("Running %d environment tests\n" , n_ents); - -for (test = tests; test < tests + n_ents; test++) { -if (argc >1 &&strcmp (argv[1 ], test->name)) -continue ; -printf ("Test: %s\n" , test->name); - - uts->start =mallinfo (); - - test->func (uts); - } - -printf ("Failures: %d\n" , uts->fail_count); -if (!uts->fail_count) - ret =0 ; -else - ret =CMD_RET_FAILURE ; + ret =cmd_ut_category ("overlay" , tests, n_ents, argc, argv);free (fdt_overlay_stacked_copy); err3:
Signature · 1 line
2.15.0.417.g466bffb3ac-goog
PATCH 2/5 test: overlay: Use cmd_ut_category()
Quoted 3 lines · Simon Glass
Adjust the code to use the common test-execution function.
Signed-off-by Simon Glass <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171204/4514ddef/attachment.sig>
PATCH 2/5 test: overlay: Use cmd_ut_category()
In reply to Simon GlassQuoted 3 lines · Simon Glass
Adjust the code to use the common test-execution function.
Signed-off-by Simon Glass <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171204/6424b31c/attachment.sig>
PATCH 3/5 test: compression: Put test variables in a struct
In reply to Simon GlassAt present the test setup is somewhat mixed with the test itself. But if the test setup fails (which it should not) then the test is actually invalid. Put all the test buffers and sizes in a struct and separate out the core code into a function.
This will make it easier to move the code to use the unit test framework.
---
test/compression.c | 128 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 74 insertions(+), 54 deletions(-)
test/compression.c +74 -54
@@ -288,85 +288,105 @@ static int uncompress_using_lz4(void *in, unsigned long in_size, goto out; \ } -static int run_test (char *name,mutate_func compress,mutate_func uncompress) -{ -ulong orig_size, compressed_size, uncompressed_size; +struct buf_state { +ulong orig_size; +ulong compressed_size; +ulong uncompressed_size;void *orig_buf; -void *compressed_buf =NULL ; -void *uncompressed_buf =NULL ; -void *compare_buf =NULL ; +void *compressed_buf; +void *uncompressed_buf; +void *compare_buf; +}; + +static int run_test_internal (char *name, +mutate_func compress,mutate_func uncompress, +struct buf_state *buf) +{int ret; -printf (" testing %s ...\n" , name); - - orig_buf = (void *)plain; - orig_size =strlen (orig_buf);/* Trailing NULL not included. */ -errcheck (orig_size >0 ); - - compressed_size = uncompressed_size =TEST_BUFFER_SIZE ; - compressed_buf =malloc (compressed_size); -errcheck (compressed_buf !=NULL ); - uncompressed_buf =malloc (uncompressed_size); -errcheck (uncompressed_buf !=NULL ); - compare_buf =malloc (uncompressed_size); -errcheck (compare_buf !=NULL ); -/* Compress works as expected. */ -printf ("\torig_size:%lu\n" , orig_size); -memset (compressed_buf,'A' ,TEST_BUFFER_SIZE ); -errcheck (compress (orig_buf, orig_size, - compressed_buf, compressed_size, - &compressed_size) ==0 ); -printf ("\tcompressed_size:%lu\n" , compressed_size); -errcheck (compressed_size >0 ); -errcheck (compressed_size < orig_size); -errcheck (((char *)compressed_buf)[compressed_size-1 ] !='A' ); -errcheck (((char *)compressed_buf)[compressed_size] =='A' ); +printf ("\torig_size:%lu\n" , buf->orig_size); +memset (buf->compressed_buf,'A' ,TEST_BUFFER_SIZE ); +errcheck (compress (buf->orig_buf, buf->orig_size, buf->compressed_buf, + buf->compressed_size, &buf->compressed_size) ==0 ); +printf ("\tcompressed_size:%lu\n" , buf->compressed_size); +errcheck (buf->compressed_size >0 ); +errcheck (buf->compressed_size < buf->orig_size); +errcheck (((char *)buf->compressed_buf)[buf->compressed_size -1 ] != +'A' ); +errcheck (((char *)buf->compressed_buf)[buf->compressed_size] =='A' );/* Uncompresses with space remaining. */ -errcheck (uncompress (compressed_buf, compressed_size, - uncompressed_buf, uncompressed_size, - &uncompressed_size) ==0 ); -printf ("\tuncompressed_size:%lu\n" , uncompressed_size); -errcheck (uncompressed_size == orig_size); -errcheck (memcmp (orig_buf, uncompressed_buf, orig_size) ==0 ); +errcheck (uncompress (buf->compressed_buf, buf->compressed_size, + buf->uncompressed_buf, buf->uncompressed_size, + &buf->uncompressed_size) ==0 ); +printf ("\tuncompressed_size:%lu\n" , buf->uncompressed_size); +errcheck (buf->uncompressed_size == buf->orig_size); +errcheck (memcmp (buf->orig_buf, buf->uncompressed_buf, + buf->orig_size) ==0 );/* Uncompresses with exactly the right size output buffer. */ -memset (uncompressed_buf,'A' ,TEST_BUFFER_SIZE ); -errcheck (uncompress (compressed_buf, compressed_size, - uncompressed_buf, orig_size, - &uncompressed_size) ==0 ); -errcheck (uncompressed_size == orig_size); -errcheck (memcmp (orig_buf, uncompressed_buf, orig_size) ==0 ); -errcheck (((char *)uncompressed_buf)[orig_size] =='A' ); +memset (buf->uncompressed_buf,'A' ,TEST_BUFFER_SIZE ); +errcheck (uncompress (buf->compressed_buf, buf->compressed_size, + buf->uncompressed_buf, buf->orig_size, + &buf->uncompressed_size) ==0 ); +errcheck (buf->uncompressed_size == buf->orig_size); +errcheck (memcmp (buf->orig_buf, buf->uncompressed_buf, + buf->orig_size) ==0 ); +errcheck (((char *)buf->uncompressed_buf)[buf->orig_size] =='A' );/* Make sure compression does not over-run. */ -memset (compare_buf,'A' ,TEST_BUFFER_SIZE ); - ret =compress (orig_buf, orig_size, - compare_buf, compressed_size -1 , +memset (buf->compare_buf,'A' ,TEST_BUFFER_SIZE ); + ret =compress (buf->orig_buf, buf->orig_size, + buf->compare_buf, buf->compressed_size -1 ,NULL ); -errcheck (((char *)compare_buf)[compressed_size] =='A' ); +errcheck (((char *)buf->compare_buf)[buf->compressed_size] =='A' );errcheck (ret !=0 );printf ("\tcompress does not overrun\n" );/* Make sure decompression does not over-run. */ -memset (compare_buf,'A' ,TEST_BUFFER_SIZE ); - ret =uncompress (compressed_buf, compressed_size, - compare_buf, uncompressed_size -1 , +memset (buf->compare_buf,'A' ,TEST_BUFFER_SIZE ); + ret =uncompress (buf->compressed_buf, buf->compressed_size, + buf->compare_buf, buf->uncompressed_size -1 ,NULL ); -errcheck (((char *)compare_buf)[uncompressed_size -1 ] =='A' ); +errcheck (((char *)buf->compare_buf)[buf->uncompressed_size -1 ] =='A' );errcheck (ret !=0 );printf ("\tuncompress does not overrun\n" );/* Got here, everything is fine. */ ret =0 ; +out: +return ret; +} + +static int run_test (char *name,mutate_func compress,mutate_func uncompress) +{ +struct buf_state sbuf, *buf = &sbuf; +int ret; + +printf (" testing %s ...\n" , name); + + buf->orig_buf = (void *)plain; + buf->orig_size =strlen (buf->orig_buf);/* Trailing NUL not included */ +errcheck (buf->orig_size >0 ); + + buf->compressed_size =TEST_BUFFER_SIZE ; + buf->uncompressed_size =TEST_BUFFER_SIZE ; + buf->compressed_buf =malloc (buf->compressed_size); +errcheck (buf->compressed_buf); + buf->uncompressed_buf =malloc (buf->uncompressed_size); +errcheck (buf->uncompressed_buf); + buf->compare_buf =malloc (buf->uncompressed_size); +errcheck (buf->compare_buf); + + ret =run_test_internal (name, compress, uncompress, buf); out:printf (" %s: %s\n" , name, ret ==0 ?"ok" :"FAILED" ); -free (compare_buf); -free (uncompressed_buf); -free (compressed_buf); +free (buf->compare_buf); +free (buf->uncompressed_buf); +free (buf->compressed_buf);return ret; }
Signature · 1 line
2.15.0.417.g466bffb3ac-goog
PATCH 3/5 test: compression: Put test variables in a struct
Quoted 8 lines · Simon Glass
At present the test setup is somewhat mixed with the test itself. But if the test setup fails (which it should not) then the test is actually invalid. Put all the test buffers and sizes in a struct and separate out the core code into a function.
This will make it easier to move the code to use the unit test framework.
Signed-off-by Simon Glass <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171204/f395a819/attachment.sig>
PATCH 4/5 test/py: Allow any unit test suite to be found
In reply to Simon GlassThe u-boot.sym file is scanned to find unit test suites for execution. At present it only finds those whose names start with 'dm' or 'env'. This code is buried in the bowels of the test code so when adding a new suite it is not easy to discover why it is ignored by the test framework.
There seems to be no need to make this restriction. Drop it.
---
test/py/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
test/py/conftest.py +1 -1
@@ -200,7 +200,7 @@ def pytest_configure(config): import u_boot_console_exec_attach console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig) -re_ut_test_list = re.compile(r'_u_boot_list_2_(dm|env)_test_2_\1_test_(.*)\s*$') +re_ut_test_list = re.compile(r'_u_boot_list_2_(.*)_test_2_\1_test_(.*)\s*$') def generate_ut_subtest(metafunc, fixture_name): """Provide parametrization for a ut_subtest fixture.
Signature · 1 line
2.15.0.417.g466bffb3ac-goog
PATCH 4/5 test/py: Allow any unit test suite to be found
Quoted 6 lines · Simon Glass
The u-boot.sym file is scanned to find unit test suites for execution. At present it only finds those whose names start with 'dm' or 'env'. This code is buried in the bowels of the test code so when adding a new suite it is not easy to discover why it is ignored by the test framework.
There seems to be no need to make this restriction. Drop it.
test/py/conftest.py def pytest_configure(config): · line 203
Quoted 4 lines
test/py/conftest.py +1
-1-re_ut_test_list = re.compile(r'_u_boot_list_2_(dm|env)_test_2_\1_test_(.*)\s*$') +re_ut_test_list = re.compile(r'_u_boot_list_2_(.*)_test_2_\1_test_(.*)\s*$')
I think I made this regex restrictive to avoid accidentally matching lists (symbols) with "test" in the name that weren't known unit tests. Or maybe there were some unit tests that didn't work yet when I wrote it? If we're confident that won't happen, this change seems fine. If we do have a problem in the future, I guess we could just rename the symbol to s/test/unit_test/ or something to make matching more explicit.
PATCH 4/5 test/py: Allow any unit test suite to be found
In reply to Simon GlassQuoted 9 lines · Simon Glass
The u-boot.sym file is scanned to find unit test suites for execution. At present it only finds those whose names start with 'dm' or 'env'. This code is buried in the bowels of the test code so when adding a new suite it is not easy to discover why it is ignored by the test framework.
There seems to be no need to make this restriction. Drop it.
Signed-off-by Simon Glass <[email protected]>Acked-by Stephen Warren <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171204/bd52ff22/attachment.sig>
PATCH 5/5 test: compression: Convert to unit test framework
In reply to Simon GlassAdjust this test to use the unit test framework. Drop the two existing commands for running the tests and replace them with a single 'ut compression' command, with sub-commands.
---
include/test/compression.h | 17 +++++ include/test/suites.h | 1 + test/cmd_ut.c | 7 ++ test/compression.c | 185 ++++++++++++++++++++++++++++----------------- 4 files changed, 141 insertions(+), 69 deletions(-) create mode 100644 include/test/compression.h
include/test/compression.h new file +17 -0
@@ -0,0 +1,17 @@ +/* +* Copyright (c) 2017 Google, Inc +* Written by Simon Glass <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef __TEST_COMPRESSION_H__ +#define __TEST_COMPRESSION_H__ + +#include <test/test.h> + +/* Declare a new compression test */ +#define COMPRESSION_TEST (_name, _flags) \ + UNIT_TEST(_name, _flags, compression_test) + +#endif /* __TEST_ENV_H__ */
include/test/suites.h +1 -0
@@ -28,5 +28,6 @@ int do_ut_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);int do_ut_env (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_overlay (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);int do_ut_time (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]); +int do_ut_compression (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[]);#endif /* __TEST_SUITES_H__ */
test/cmd_ut.c +7 -0
@@ -50,6 +50,10 @@ static cmd_tbl_t cmd_ut_sub[] = {#ifdef CONFIG_UT_TIME U_BOOT_CMD_MKENT(time, CONFIG_SYS_MAXARGS, 1, do_ut_time, "", ""),#endif +#ifdef CONFIG_SANDBOX + U_BOOT_CMD_MKENT(compression, CONFIG_SYS_MAXARGS, 1, do_ut_compression, + "", ""), +#endif };static int do_ut_all (cmd_tbl_t *cmdtp,int flag,int argc,char *const argv[])
@@ -101,6 +105,9 @@ static char ut_help_text[] =#endif #ifdef CONFIG_UT_TIME "ut time - Very basic test of time functions\n" +#endif +#ifdef CONFIG_SANDBOX + "ut compression - Test compressors and bootm decompression\n"#endif ;#endif
test/compression.c +116 -69
369 lines not on this page · raw message
Signature · 1 line
2.15.0.417.g466bffb3ac-goog
PATCH 5/5 test: compression: Convert to unit test framework
Quoted 5 lines · Simon Glass
Adjust this test to use the unit test framework. Drop the two existing commands for running the tests and replace them with a single 'ut compression' command, with sub-commands.
Signed-off-by Simon Glass <[email protected]>
Applied to u-boot/master, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171204/b3304bef/attachment.sig>