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:
Craig Hesling 2019-06-12 17:52:23 -07:00 committed by Commit Bot
parent dbaf95d616
commit e539acc27b
3 changed files with 216 additions and 0 deletions

View File

@ -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

205
test/printf.c Normal file
View File

@ -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();
}

9
test/printf.tasklist Normal file
View File

@ -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