mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-26 17:05:29 +00:00
After processing by hex_dump_to_buffer() check all the parts to be expected. Part 1. The actual expected hex dump with or without ASCII part. Part 2. Check if the buffer is dirty beyond needed. Part 3. Return code should be as expected. This is done by using comparison of the return code and memcmp() against the test buffer. We fill the buffer by FILL_CHAR ('#') characters, so, we expect to have a tail of the buffer will be left untouched. The terminating NUL is also checked by memcmp(). Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
203 lines
4.9 KiB
C
203 lines
4.9 KiB
C
/*
|
|
* Test cases for lib/hexdump.c module.
|
|
*/
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/random.h>
|
|
#include <linux/string.h>
|
|
|
|
static const unsigned char data_b[] = {
|
|
'\xbe', '\x32', '\xdb', '\x7b', '\x0a', '\x18', '\x93', '\xb2', /* 00 - 07 */
|
|
'\x70', '\xba', '\xc4', '\x24', '\x7d', '\x83', '\x34', '\x9b', /* 08 - 0f */
|
|
'\xa6', '\x9c', '\x31', '\xad', '\x9c', '\x0f', '\xac', '\xe9', /* 10 - 17 */
|
|
'\x4c', '\xd1', '\x19', '\x99', '\x43', '\xb1', '\xaf', '\x0c', /* 18 - 1f */
|
|
};
|
|
|
|
static const unsigned char data_a[] = ".2.{....p..$}.4...1.....L...C...";
|
|
|
|
static const char * const test_data_1_le[] __initconst = {
|
|
"be", "32", "db", "7b", "0a", "18", "93", "b2",
|
|
"70", "ba", "c4", "24", "7d", "83", "34", "9b",
|
|
"a6", "9c", "31", "ad", "9c", "0f", "ac", "e9",
|
|
"4c", "d1", "19", "99", "43", "b1", "af", "0c",
|
|
};
|
|
|
|
static const char * const test_data_2_le[] __initconst = {
|
|
"32be", "7bdb", "180a", "b293",
|
|
"ba70", "24c4", "837d", "9b34",
|
|
"9ca6", "ad31", "0f9c", "e9ac",
|
|
"d14c", "9919", "b143", "0caf",
|
|
};
|
|
|
|
static const char * const test_data_4_le[] __initconst = {
|
|
"7bdb32be", "b293180a", "24c4ba70", "9b34837d",
|
|
"ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143",
|
|
};
|
|
|
|
static const char * const test_data_8_le[] __initconst = {
|
|
"b293180a7bdb32be", "9b34837d24c4ba70",
|
|
"e9ac0f9cad319ca6", "0cafb1439919d14c",
|
|
};
|
|
|
|
#define FILL_CHAR '#'
|
|
|
|
static void __init test_hexdump_prepare_test(size_t len, int rowsize,
|
|
int groupsize, char *test,
|
|
size_t testlen, bool ascii)
|
|
{
|
|
char *p;
|
|
const char * const *result;
|
|
size_t l = len;
|
|
int gs = groupsize, rs = rowsize;
|
|
unsigned int i;
|
|
|
|
if (rs != 16 && rs != 32)
|
|
rs = 16;
|
|
|
|
if (l > rs)
|
|
l = rs;
|
|
|
|
if (!is_power_of_2(gs) || gs > 8 || (len % gs != 0))
|
|
gs = 1;
|
|
|
|
if (gs == 8)
|
|
result = test_data_8_le;
|
|
else if (gs == 4)
|
|
result = test_data_4_le;
|
|
else if (gs == 2)
|
|
result = test_data_2_le;
|
|
else
|
|
result = test_data_1_le;
|
|
|
|
/* hex dump */
|
|
p = test;
|
|
for (i = 0; i < l / gs; i++) {
|
|
const char *q = *result++;
|
|
size_t amount = strlen(q);
|
|
|
|
strncpy(p, q, amount);
|
|
p += amount;
|
|
|
|
*p++ = ' ';
|
|
}
|
|
if (i)
|
|
p--;
|
|
|
|
/* ASCII part */
|
|
if (ascii) {
|
|
do {
|
|
*p++ = ' ';
|
|
} while (p < test + rs * 2 + rs / gs + 1);
|
|
|
|
strncpy(p, data_a, l);
|
|
p += l;
|
|
}
|
|
|
|
*p = '\0';
|
|
}
|
|
|
|
#define TEST_HEXDUMP_BUF_SIZE (32 * 3 + 2 + 32 + 1)
|
|
|
|
static void __init test_hexdump(size_t len, int rowsize, int groupsize,
|
|
bool ascii)
|
|
{
|
|
char test[TEST_HEXDUMP_BUF_SIZE];
|
|
char real[TEST_HEXDUMP_BUF_SIZE];
|
|
|
|
memset(real, FILL_CHAR, sizeof(real));
|
|
hex_dump_to_buffer(data_b, len, rowsize, groupsize, real, sizeof(real),
|
|
ascii);
|
|
|
|
memset(test, FILL_CHAR, sizeof(test));
|
|
test_hexdump_prepare_test(len, rowsize, groupsize, test, sizeof(test),
|
|
ascii);
|
|
|
|
if (memcmp(test, real, TEST_HEXDUMP_BUF_SIZE)) {
|
|
pr_err("Len: %zu row: %d group: %d\n", len, rowsize, groupsize);
|
|
pr_err("Result: '%s'\n", real);
|
|
pr_err("Expect: '%s'\n", test);
|
|
}
|
|
}
|
|
|
|
static void __init test_hexdump_set(int rowsize, bool ascii)
|
|
{
|
|
size_t d = min_t(size_t, sizeof(data_b), rowsize);
|
|
size_t len = get_random_int() % d + 1;
|
|
|
|
test_hexdump(len, rowsize, 4, ascii);
|
|
test_hexdump(len, rowsize, 2, ascii);
|
|
test_hexdump(len, rowsize, 8, ascii);
|
|
test_hexdump(len, rowsize, 1, ascii);
|
|
}
|
|
|
|
static void __init test_hexdump_overflow(size_t buflen, bool ascii)
|
|
{
|
|
char test[TEST_HEXDUMP_BUF_SIZE];
|
|
char buf[TEST_HEXDUMP_BUF_SIZE];
|
|
int rs = rowsize, gs = groupsize;
|
|
int ae, he, e, f, r;
|
|
bool a;
|
|
|
|
memset(buf, FILL_CHAR, sizeof(buf));
|
|
|
|
r = hex_dump_to_buffer(data_b, len, rs, gs, buf, buflen, ascii);
|
|
|
|
/*
|
|
* Caller must provide the data length multiple of groupsize. The
|
|
* calculations below are made with that assumption in mind.
|
|
*/
|
|
ae = rs * 2 /* hex */ + rs / gs /* spaces */ + 1 /* space */ + len /* ascii */;
|
|
he = (gs * 2 /* hex */ + 1 /* space */) * len / gs - 1 /* no trailing space */;
|
|
|
|
if (ascii)
|
|
e = ae;
|
|
else
|
|
e = he;
|
|
|
|
f = min_t(int, e + 1, buflen);
|
|
if (buflen) {
|
|
test_hexdump_prepare_test(len, rs, gs, test, sizeof(test), ascii);
|
|
test[f - 1] = '\0';
|
|
}
|
|
memset(test + f, FILL_CHAR, sizeof(test) - f);
|
|
|
|
a = r == e && !memcmp(test, buf, TEST_HEXDUMP_BUF_SIZE);
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
if (!a) {
|
|
pr_err("Len: %zu buflen: %zu strlen: %zu\n",
|
|
len, buflen, strnlen(buf, sizeof(buf)));
|
|
pr_err("Result: %d '%s'\n", r, buf);
|
|
pr_err("Expect: %d '%s'\n", e, test);
|
|
}
|
|
}
|
|
|
|
static int __init test_hexdump_init(void)
|
|
{
|
|
unsigned int i;
|
|
int rowsize;
|
|
|
|
pr_info("Running tests...\n");
|
|
|
|
rowsize = (get_random_int() % 2 + 1) * 16;
|
|
for (i = 0; i < 16; i++)
|
|
test_hexdump_set(rowsize, false);
|
|
|
|
rowsize = (get_random_int() % 2 + 1) * 16;
|
|
for (i = 0; i < 16; i++)
|
|
test_hexdump_set(rowsize, true);
|
|
|
|
for (i = 0; i <= TEST_HEXDUMP_BUF_SIZE; i++)
|
|
test_hexdump_overflow(i, false);
|
|
|
|
for (i = 0; i <= TEST_HEXDUMP_BUF_SIZE; i++)
|
|
test_hexdump_overflow(i, true);
|
|
|
|
return -EINVAL;
|
|
}
|
|
module_init(test_hexdump_init);
|
|
MODULE_LICENSE("Dual BSD/GPL");
|