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>
This commit is contained in:
parent
dbaf95d616
commit
e539acc27b
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue