summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/base32.c200
-rw-r--r--test/base32.tasklist17
-rw-r--r--test/build.mk4
-rw-r--r--test/test_config.h4
4 files changed, 224 insertions, 1 deletions
diff --git a/test/base32.c b/test/base32.c
new file mode 100644
index 0000000000..f49b28dd11
--- /dev/null
+++ b/test/base32.c
@@ -0,0 +1,200 @@
+/* Copyright 2017 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.
+ *
+ * Test Base-32 encoding/decoding
+ */
+
+#include <stdio.h>
+#include "common.h"
+#include "base32.h"
+#include "test_util.h"
+#include "util.h"
+
+static int test_crc5(void)
+{
+ uint32_t seen;
+ int i, j, c;
+ int errors = 0;
+
+ /*
+ * For every current CRC value and symbol, new CRC value is unique.
+ * This guarantees a single-character typo will be detected.
+ */
+ for (i = 0; i < 32; i++) {
+ seen = 0;
+ for (j = 0; j < 32; j++)
+ seen |= 1 << crc5_sym(j, i);
+ TEST_ASSERT(seen == 0xffffffff);
+ }
+
+ /* Transposing different symbols generates distinct CRCs */
+ for (c = 0; c < 32; c++) {
+ for (i = 0; i < 32; i++) {
+ for (j = i + 1; j < 32; j++) {
+ if (crc5_sym(j, crc5_sym(i, c)) ==
+ crc5_sym(i, crc5_sym(j, c)))
+ errors++;
+ }
+ }
+ }
+ TEST_ASSERT(errors == 0);
+
+ return EC_SUCCESS;
+}
+
+static int enctest(const void *src, int srcbits, int crc_every,
+ const char *enc)
+{
+ char dest[32];
+
+ if (base32_encode(dest, sizeof(dest), src, srcbits, crc_every))
+ return -1;
+ if (strlen(dest) != strlen(enc) || strncmp(dest, enc, strlen(dest))) {
+ fprintf(stderr, "expected encode: \"%s\"\n", enc);
+ fprintf(stderr, "got encode: \"%s\"\n", dest);
+ return -2;
+ }
+ return 0;
+}
+
+#define ENCTEST(a, b, c, d) TEST_ASSERT(enctest(a, b, c, d) == 0)
+
+static int test_encode(void)
+{
+ const uint8_t src1[5] = {0xff, 0x00, 0xff, 0x00, 0xff};
+ char enc[32];
+
+ /* Test for enough space; error produces null string */
+ *enc = 1;
+ TEST_ASSERT(base32_encode(enc, 3, src1, 15, 0) == EC_ERROR_INVAL);
+ TEST_ASSERT(*enc == 0);
+
+ /* Empty source */
+ ENCTEST("\x00", 0, 0, "");
+
+ /* Single symbol uses top 5 bits */
+ ENCTEST("\x07", 5, 0, "A");
+ ENCTEST("\xb8", 5, 0, "Z");
+ ENCTEST("\xc0", 5, 0, "2");
+ ENCTEST("\xf8", 5, 0, "9");
+
+ /* Multiples of 5 bits use top bits */
+ ENCTEST("\x08\x86", 10, 0, "BC");
+ ENCTEST("\x08\x86", 15, 0, "BCD");
+
+ /* Multiples of 8 bits pad with 0 bits */
+ ENCTEST("\xff", 8, 0, "96");
+ ENCTEST("\x08\x87", 16, 0, "BCDS");
+
+ /* Multiples of 40 bits use all the bits */
+ ENCTEST("\xff\x00\xff\x00\xff", 40, 0, "96AR8AH9");
+
+ /* CRC requires exact multiple of symbol count */
+ ENCTEST("\xff\x00\xff\x00\xff", 40, 4, "96ARL8AH9V");
+ ENCTEST("\xff\x00\xff\x00\xff", 40, 8, "96AR8AH9V");
+ TEST_ASSERT(
+ base32_encode(enc, 16, (uint8_t *)"\xff\x00\xff\x00\xff", 40, 6)
+ == EC_ERROR_INVAL);
+ /* But what matters is symbol count, not bit count */
+ ENCTEST("\xff\x00\xff\x00\xfe", 39, 4, "96ARL8AH8W");
+
+ return EC_SUCCESS;
+}
+
+static int cmpbytes(const uint8_t *expect, const uint8_t *got, int len,
+ const char *desc)
+{
+ int i;
+
+ if (!memcmp(expect, got, len))
+ return 0;
+
+ fprintf(stderr, "expected %s:", desc);
+ for (i = 0; i < len; i++)
+ fprintf(stderr, " %02x", expect[i]);
+ fprintf(stderr, "\ngot %s: ", desc);
+ for (i = 0; i < len; i++)
+ fprintf(stderr, " %02x", got[i]);
+ fprintf(stderr, "\n");
+
+ return -2;
+}
+
+static int dectest(const void *dec, int decbits, int crc_every, const char *enc)
+{
+ uint8_t dest[32];
+ int destbits = decbits > 0 ? decbits : sizeof(dest) * 8;
+ int wantbits = decbits > 0 ? decbits : 5 * strlen(enc);
+ int gotbits = base32_decode(dest, destbits, enc, crc_every);
+
+ TEST_ASSERT(gotbits == wantbits);
+ if (gotbits != wantbits)
+ return -1;
+ return cmpbytes(dec, dest, (decbits + 7) / 8, "decode");
+}
+
+#define DECTEST(a, b, c, d) TEST_ASSERT(dectest(a, b, c, d) == 0)
+
+static int test_decode(void)
+{
+ uint8_t dec[32];
+
+ /* Decode tests, dest-limited */
+ DECTEST("\xf8", 5, 0, "97");
+ DECTEST("\x08", 5, 0, "BCDS");
+ DECTEST("\x08\x80", 10, 0, "BCDS");
+ DECTEST("\x08\x86", 15, 0, "BCDS");
+ DECTEST("\xff", 8, 0, "96");
+ DECTEST("\x08\x87", 16, 0, "BCDS");
+ DECTEST("\xff\x00\xff\x00\xff", 40, 0, "96AR8AH9");
+ DECTEST("\xff\x00\xff\x00\xfe", 39, 4, "96ARL8AH8W");
+
+ /* Decode ignores whitespace and dashes */
+ DECTEST("\xff\x00\xff\x00\xff", 40, 0, " 96\tA-R\r8A H9\n");
+
+ /* Invalid symbol fails */
+ TEST_ASSERT(base32_decode(dec, 16, "AI", 0) == -1);
+
+ /* If dest buffer is big, use all the source bits */
+ DECTEST("", 0, 0, "");
+ DECTEST("\xf8", 0, 0, "9");
+ DECTEST("\x07\xc0", 0, 0, "A9");
+ DECTEST("\x00\x3e", 0, 0, "AA9");
+ DECTEST("\x00\x01\xf0", 0, 0, "AAA9");
+ DECTEST("\xff\x00\xff\x00\xff", 0, 0, "96AR8AH9");
+
+ /* Decode always overwrites destination */
+ memset(dec, 0xff, sizeof(dec));
+ DECTEST("\x00\x00\x00\x00\x00", 0, 0, "AAAAAAAA");
+ memset(dec, 0x00, sizeof(dec));
+ DECTEST("\xff\xff\xff\xff\xff", 0, 0, "99999999");
+
+ /* Good CRCs */
+ DECTEST("\xff\x00\xff\x00\xff", 40, 4, "96ARL8AH9V");
+ DECTEST("\xff\x00\xff\x00\xff", 40, 8, "96AR8AH9V");
+ /* Detect errors in data, CRC, and transposition */
+
+ /* CRC requires exact multiple of symbol count */
+ TEST_ASSERT(base32_decode(dec, 40, "96ARL8AH9", 4) == -1);
+ /* But what matters is symbol count, not bit count */
+ DECTEST("\xff\x00\xff\x00\xfe", 39, 4, "96ARL8AH8W");
+
+ /* Detect errors in data, CRC, and transposition */
+ TEST_ASSERT(base32_decode(dec, 40, "96AQL", 4) == -1);
+ TEST_ASSERT(base32_decode(dec, 40, "96ARM", 4) == -1);
+ TEST_ASSERT(base32_decode(dec, 40, "96RAL", 4) == -1);
+
+ return EC_SUCCESS;
+}
+
+void run_test(void)
+{
+ test_reset();
+
+ RUN_TEST(test_crc5);
+ RUN_TEST(test_encode);
+ RUN_TEST(test_decode);
+
+ test_print_result();
+}
diff --git a/test/base32.tasklist b/test/base32.tasklist
new file mode 100644
index 0000000000..e241aab4bb
--- /dev/null
+++ b/test/base32.tasklist
@@ -0,0 +1,17 @@
+/* Copyright 2017 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.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_TEST(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TEST_TASK_LIST /* No test task */
diff --git a/test/build.mk b/test/build.mk
index 2ba81fb85b..b7ba92fcbc 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -36,7 +36,8 @@ test-list-$(BOARD_SAMUS_PD)=
ifneq ($(TEST_LIST_HOST),)
test-list-host=$(TEST_LIST_HOST)
else
-test-list-host = battery_get_params_smart
+test-list-host = base32
+test-list-host += battery_get_params_smart
test-list-host += bklight_lid
test-list-host += bklight_passthru
test-list-host += button
@@ -80,6 +81,7 @@ test-list-host += utils_str
test-list-host += x25519
endif
+base32-y=base32.o
battery_get_params_smart-y=battery_get_params_smart.o
bklight_lid-y=bklight_lid.o
bklight_passthru-y=bklight_passthru.o
diff --git a/test/test_config.h b/test/test_config.h
index bbcd1172ee..e01218bc10 100644
--- a/test/test_config.h
+++ b/test/test_config.h
@@ -18,6 +18,10 @@
#undef CONFIG_VBOOT_HASH
#undef CONFIG_USB_PD_LOGGING
+#ifdef TEST_BASE32
+#define CONFIG_BASE32
+#endif
+
#ifdef TEST_BKLIGHT_LID
#define CONFIG_BACKLIGHT_LID
#endif