diff options
author | Craig Hesling <hesling@chromium.org> | 2019-06-12 17:52:23 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-06-25 05:49:38 +0000 |
commit | e539acc27b4500d74b0e72b397816b8fcfe7b18c (patch) | |
tree | 4ce36b8a7ff299ff70e648d52ceeda50ce40caa4 /test | |
parent | dbaf95d616543fb89b9d6d2e79f81bd232b95e4c (diff) | |
download | chrome-ec-e539acc27b4500d74b0e72b397816b8fcfe7b18c.tar.gz |
printf: Add unit tests for printf.c
These tests solidify the current behavior of the print formatter
in order to verify future changes.
Some commented out tests expose odd behavior that will be
addressed in the follow up patch.
BUG=chromium:974084
TEST=make V=1 run-printf
BRANCH=none
Change-Id: I9c45a075692992c7713a15d7f83099a2d13441e6
Signed-off-by: Craig Hesling <hesling@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1659834
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/build.mk | 2 | ||||
-rw-r--r-- | test/printf.c | 205 | ||||
-rw-r--r-- | test/printf.tasklist | 9 |
3 files changed, 216 insertions, 0 deletions
diff --git a/test/build.mk b/test/build.mk index 1ede361b28..5ebfeb2553 100644 --- a/test/build.mk +++ b/test/build.mk @@ -53,6 +53,7 @@ test-list-host += nvmem test-list-host += pingpong test-list-host += pinweaver test-list-host += power_button +test-list-host += printf test-list-host += queue test-list-host += rma_auth test-list-host += rsa @@ -121,6 +122,7 @@ pingpong-y=pingpong.o pinweaver-y=pinweaver.o power_button-y=power_button.o powerdemo-y=powerdemo.o +printf-y=printf.o queue-y=queue.o rma_auth-y=rma_auth.o rsa-y=rsa.o diff --git a/test/printf.c b/test/printf.c new file mode 100644 index 0000000000..d739da3606 --- /dev/null +++ b/test/printf.c @@ -0,0 +1,205 @@ +/* Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <stdarg.h> /* For va_list */ +#include <stddef.h> + +#include "common.h" +#include "printf.h" +#include "test_util.h" +#include "util.h" + +#define INIT_VALUE 0x5E +static const char err_str[] = "ERROR"; +static char output[1024]; + +int run(const char *expect, size_t size_limit, int expect_ret, + const char *format, va_list args) +{ + size_t expect_size = expect ? strlen(expect) + 1 : 0; + int rv; + + ccprintf("\n"); + ccprintf("expect='%s'\n", expect); + + TEST_ASSERT(expect_size <= sizeof(output)); + TEST_ASSERT(expect_size <= size_limit); + memset(output, INIT_VALUE, sizeof(output)); + + rv = vsnprintf(output, size_limit, format, args); + ccprintf("output='%s'\n", output); + + TEST_ASSERT_ARRAY_EQ(output, expect, expect_size); + TEST_ASSERT_MEMSET(&output[expect_size], INIT_VALUE, + sizeof(output)-expect_size); + + if (rv >= 0) { + ccprintf("expect_size = %ld\n", expect_size); + ccprintf("rv = %d\n", rv); + TEST_ASSERT(rv == expect_size-1); + TEST_ASSERT(EC_SUCCESS == expect_ret); + } else { + TEST_ASSERT(rv == -expect_ret); + } + + return EC_SUCCESS; +} + +int expect_success(const char *expect, const char *format, ...) +{ + va_list args; + int rv; + + va_start(args, format); + rv = run(expect, sizeof(output), EC_SUCCESS, format, args); + va_end(args); + + return rv; +} + +int expect(int expect_ret, size_t size_limit, const char *expect, + const char *format, ...) +{ + va_list args; + int rv; + + va_start(args, format); + rv = run(expect, size_limit, expect_ret, format, args); + va_end(args); + + return rv; +} + +#define T(n) do { int rv = (n); if (rv != EC_SUCCESS) return rv; } while (0) + +test_static int test_vsnprintf_args(void) +{ + T(expect_success("", "")); + T(expect_success("a", "a")); + /* T(expect(NULL, 0, EC_ERROR_INVAL, "")); fail */ + T(expect(EC_ERROR_OVERFLOW, 2, "a", "abc")); + return EC_SUCCESS; +} + +test_static int test_vsnprintf_int(void) +{ + T(expect_success("123", "%d", 123)); + T(expect_success("-123", "%d", -123)); + T(expect_success("+123", "%+d", 123)); + T(expect_success("-123", "%+d", -123)); + T(expect_success("123", "%-d", 123)); + T(expect_success("-123", "%-d", -123)); + + T(expect_success(" 123", "%5d", 123)); + T(expect_success(" +123", "%+5d", 123)); + T(expect_success("00123", "%05d", 123)); + T(expect_success("00123", "%005d", 123)); + /* T(expect_success("+0123", "%+05d", 123)); actual "0+123" */ + /* T(expect_success("+0123", "%+005d", 123)); actual "0+123" */ + + T(expect_success(" 123", "%*d", 5, 123)); + T(expect_success(" +123", "%+*d", 5, 123)); + T(expect_success("00123", "%0*d", 5, 123)); + /* T(expect_success("00123", "%00*d", 5, 123)); actual "ERROR" */ + T(expect_success("0+123", "%+0*d", 5, 123)); + /* T(expect_success("0+123", "%+00*d", 5, 123)); actual "ERROR" */ + + T(expect_success("123 ", "%-5d", 123)); + T(expect_success("+123 ", "%-+5d", 123)); + T(expect_success(err_str, "%+-5d", 123)); + T(expect_success("123 ", "%-05d", 123)); + T(expect_success("123 ", "%-005d", 123)); + T(expect_success("+123 ", "%-+05d", 123)); + T(expect_success("+123 ", "%-+005d", 123)); + + T(expect_success("0.00123", "%.5d", 123)); + T(expect_success("+0.00123", "%+.5d", 123)); + T(expect_success("0.00123", "%7.5d", 123)); + T(expect_success(" 0.00123", "%9.5d", 123)); + T(expect_success(" +0.00123", "%+9.5d", 123)); + + T(expect_success("-1", "%ld", (int64_t)-1)); + T(expect_success("4294967295", "%ld", (uint32_t)-1)); + + T(expect_success("123", "%u", 123)); + T(expect_success("4294967295", "%u", -1)); + T(expect_success("18446744073709551615", "%lu", (uint64_t)-1)); + + T(expect_success("0", "%x", 0)); + T(expect_success("0", "%X", 0)); + T(expect_success("5e", "%x", 0X5E)); + T(expect_success("5E", "%X", 0X5E)); + + T(expect_success("0", "%b", 0)); + T(expect_success("1011110", "%b", 0X5E)); + + return EC_SUCCESS; +} + +test_static int test_vsnprintf_pointers(void) +{ + void *ptr = (void *)0x55005E00; + + T(expect_success("55005e00", "%p", ptr)); + T(expect_success(err_str, "%P", ptr)); + return EC_SUCCESS; +} + +test_static int test_vsnprintf_chars(void) +{ + T(expect_success("a", "%c", 'a')); + T(expect_success("*", "%c", '*')); + return EC_SUCCESS; +} + +test_static int test_vsnprintf_strings(void) +{ + T(expect_success("abc", "%s", "abc")); + T(expect_success(" abc", "%5s", "abc")); + T(expect_success("abc", "%0s", "abc")); + T(expect_success("abc ", "%-5s", "abc")); + T(expect_success("abc", "%*s", 0, "abc")); + T(expect_success("a", "%.1s", "abc")); + T(expect_success("a", "%.*s", 1, "abc")); + /* T(expect_success("", "%.0s", "abc")); actual "abc" */ + /* T(expect_success("", "%.*s", 0, "abc")); actual "abc" */ + T(expect_success("ab", "%5.2s", "abc")); /* intentional */ + /* TODO(hesling): test for overruns on malformed strings */ + return EC_SUCCESS; +} + +test_static int test_vsnprintf_hexdump(void) +{ + const char bytes[] = {0x00, 0x5E}; + + T(expect_success(err_str, "%h", bytes)); + T(expect_success("005e", "%.*h", 2, bytes)); + /* T(expect_success("", "%.*h", 0, bytes)); actual "ERROR" */ + /* T(expect_success(" 005e", "%5.*h", 2, bytes)); actual "005e" */ + /* T(expect_success("005e ", "%-5.*h", 2, bytes)); actual "005e" */ + return EC_SUCCESS; +} + +test_static int test_vsnprintf_combined(void) +{ + T(expect_success("abc", "%c%s", 'a', "bc")); + T(expect_success("12\tbc", "%d\t%s", 12, "bc")); + return EC_SUCCESS; +} + +void run_test(void) +{ + test_reset(); + + RUN_TEST(test_vsnprintf_args); + RUN_TEST(test_vsnprintf_int); + RUN_TEST(test_vsnprintf_pointers); + RUN_TEST(test_vsnprintf_chars); + RUN_TEST(test_vsnprintf_strings); + RUN_TEST(test_vsnprintf_hexdump); + RUN_TEST(test_vsnprintf_combined); + + test_print_result(); +} diff --git a/test/printf.tasklist b/test/printf.tasklist new file mode 100644 index 0000000000..9fc1a80f4d --- /dev/null +++ b/test/printf.tasklist @@ -0,0 +1,9 @@ +/* Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * See CONFIG_TASK_LIST in config.h for details. + */ +#define CONFIG_TEST_TASK_LIST |