diff options
author | Heinrich Schuchardt | 2019-01-30 07:53:31 +0100 |
---|---|---|
committer | Tom Rini | 2019-02-09 07:50:53 -0500 |
commit | 2dd0111adc8a5a03388f557d1ca91295276fbb54 (patch) | |
tree | 39c36f8509e08b5463e09d6aa7dfadef8492204d /test/lib | |
parent | eca61ae70c80ce42272ab8b999750d925f0ad85c (diff) |
test: provide unit test for memory functions
Memory functions may have architecture specific implementations. These
should be tested.
Provide unit tests for memset(), memcpy(), memmove().
Provide a 'ut lib' sub-command to execute the tests.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'test/lib')
-rw-r--r-- | test/lib/Makefile | 2 | ||||
-rw-r--r-- | test/lib/cmd_ut_lib.c | 20 | ||||
-rw-r--r-- | test/lib/string.c | 194 |
3 files changed, 216 insertions, 0 deletions
diff --git a/test/lib/Makefile b/test/lib/Makefile index 5a636aac740..308c61708ee 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -2,5 +2,7 @@ # # (C) Copyright 2018 # Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc +obj-y += cmd_ut_lib.o obj-y += hexdump.o obj-y += lmb.o +obj-y += string.o diff --git a/test/lib/cmd_ut_lib.c b/test/lib/cmd_ut_lib.c new file mode 100644 index 00000000000..eb90e539148 --- /dev/null +++ b/test/lib/cmd_ut_lib.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * Unit tests for library functions + */ + +#include <common.h> +#include <command.h> +#include <test/lib.h> +#include <test/suites.h> +#include <test/ut.h> + +int do_ut_lib(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct unit_test *tests = ll_entry_start(struct unit_test, lib_test); + const int n_ents = ll_entry_count(struct unit_test, lib_test); + + return cmd_ut_category("lib", tests, n_ents, argc, argv); +} diff --git a/test/lib/string.c b/test/lib/string.c new file mode 100644 index 00000000000..8e246ab4ed9 --- /dev/null +++ b/test/lib/string.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * Unit tests for memory functions + * + * The architecture dependent implementations run through different lines of + * code depending on the alignment and length of memory regions copied or set. + * This has to be considered in testing. + */ + +#include <common.h> +#include <command.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> + +/* Xor mask used for marking memory regions */ +#define MASK 0xA5 +/* Number of different alignment values */ +#define SWEEP 16 +/* Allow for copying up to 32 bytes */ +#define BUFLEN (SWEEP + 33) + +/** + * init_buffer() - initialize buffer + * + * The buffer is filled with incrementing values xor'ed with the mask. + * + * @buf: buffer + * @mask: xor mask + */ +static void init_buffer(u8 buf[], u8 mask) +{ + int i; + + for (i = 0; i < BUFLEN; ++i) + buf[i] = i ^ mask; +} + +/** + * test_memset() - test result of memset() + * + * @uts: unit test state + * @buf: buffer + * @mask: value set by memset() + * @offset: relative start of region changed by memset() in buffer + * @len: length of region changed by memset() + * Return: 0 = success, 1 = failure + */ +static int test_memset(struct unit_test_state *uts, u8 buf[], u8 mask, + int offset, int len) +{ + int i; + + for (i = 0; i < BUFLEN; ++i) { + if (i < offset || i >= offset + len) { + ut_asserteq(i, buf[i]); + } else { + ut_asserteq(mask, buf[i]); + } + } + return 0; +} + +/** + * lib_memset() - unit test for memset() + * + * Test memset() with varied alignment and length of the changed buffer. + * + * @uts: unit test state + * Return: 0 = success, 1 = failure + */ +static int lib_memset(struct unit_test_state *uts) +{ + u8 buf[BUFLEN]; + int offset, len; + void *ptr; + + for (offset = 0; offset <= SWEEP; ++offset) { + for (len = 1; len < BUFLEN - SWEEP; ++len) { + init_buffer(buf, 0); + ptr = memset(buf + offset, MASK, len); + ut_asserteq_ptr(buf + offset, (u8 *)ptr); + if (test_memset(uts, buf, MASK, offset, len)) { + debug("%s: failure %d, %d\n", + __func__, offset, len); + return CMD_RET_FAILURE; + } + } + } + return 0; +} + +LIB_TEST(lib_memset, 0); + +/** + * test_memmove() - test result of memcpy() or memmove() + * + * @uts: unit test state + * @buf: buffer + * @mask: xor mask used to initialize source buffer + * @offset1: relative start of copied region in source buffer + * @offset2: relative start of copied region in destination buffer + * @len: length of region changed by memset() + * Return: 0 = success, 1 = failure + */ +static int test_memmove(struct unit_test_state *uts, u8 buf[], u8 mask, + int offset1, int offset2, int len) +{ + int i; + + for (i = 0; i < BUFLEN; ++i) { + if (i < offset2 || i >= offset2 + len) { + ut_asserteq(i, buf[i]); + } else { + ut_asserteq((i + offset1 - offset2) ^ mask, buf[i]); + } + } + return 0; +} + +/** + * lib_memcpy() - unit test for memcpy() + * + * Test memcpy() with varied alignment and length of the copied buffer. + * + * @uts: unit test state + * Return: 0 = success, 1 = failure + */ +static int lib_memcpy(struct unit_test_state *uts) +{ + u8 buf1[BUFLEN]; + u8 buf2[BUFLEN]; + int offset1, offset2, len; + void *ptr; + + init_buffer(buf1, MASK); + + for (offset1 = 0; offset1 <= SWEEP; ++offset1) { + for (offset2 = 0; offset2 <= SWEEP; ++offset2) { + for (len = 1; len < BUFLEN - SWEEP; ++len) { + init_buffer(buf2, 0); + ptr = memcpy(buf2 + offset2, buf1 + offset1, + len); + ut_asserteq_ptr(buf2 + offset2, (u8 *)ptr); + if (test_memmove(uts, buf2, MASK, offset1, + offset2, len)) { + debug("%s: failure %d, %d, %d\n", + __func__, offset1, offset2, len); + return CMD_RET_FAILURE; + } + } + } + } + return 0; +} + +LIB_TEST(lib_memcpy, 0); + +/** + * lib_memmove() - unit test for memmove() + * + * Test memmove() with varied alignment and length of the copied buffer. + * + * @uts: unit test state + * Return: 0 = success, 1 = failure + */ +static int lib_memmove(struct unit_test_state *uts) +{ + u8 buf[BUFLEN]; + int offset1, offset2, len; + void *ptr; + + for (offset1 = 0; offset1 <= SWEEP; ++offset1) { + for (offset2 = 0; offset2 <= SWEEP; ++offset2) { + for (len = 1; len < BUFLEN - SWEEP; ++len) { + init_buffer(buf, 0); + ptr = memmove(buf + offset2, buf + offset1, + len); + ut_asserteq_ptr(buf + offset2, (u8 *)ptr); + if (test_memmove(uts, buf, 0, offset1, offset2, + len)) { + debug("%s: failure %d, %d, %d\n", + __func__, offset1, offset2, len); + return CMD_RET_FAILURE; + } + } + } + } + return 0; +} + +LIB_TEST(lib_memmove, 0); |