summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Hesling <hesling@chromium.org>2019-06-12 17:52:23 -0700
committerCommit Bot <commit-bot@chromium.org>2019-06-25 05:49:38 +0000
commite539acc27b4500d74b0e72b397816b8fcfe7b18c (patch)
tree4ce36b8a7ff299ff70e648d52ceeda50ce40caa4
parentdbaf95d616543fb89b9d6d2e79f81bd232b95e4c (diff)
downloadchrome-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>
-rw-r--r--test/build.mk2
-rw-r--r--test/printf.c205
-rw-r--r--test/printf.tasklist9
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