[PATCH 6/8] membuf: Add some tests
Simon Glass
sjg at chromium.org
Fri Oct 18 05:00:25 CEST 2024
Add tests for the membuf implementation.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
test/lib/Makefile | 1 +
test/lib/membuf.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 240 insertions(+)
create mode 100644 test/lib/membuf.c
diff --git a/test/lib/Makefile b/test/lib/Makefile
index a54387a058e..014cd42efe1 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -12,6 +12,7 @@ obj-y += hexdump.o
obj-$(CONFIG_SANDBOX) += kconfig.o
obj-y += lmb.o
obj-y += longjmp.o
+obj-$(CONFIG_SANDBOX) += membuf.o
obj-$(CONFIG_CONSOLE_RECORD) += test_print.o
obj-$(CONFIG_SSCANF) += sscanf.o
obj-y += string.o
diff --git a/test/lib/membuf.c b/test/lib/membuf.c
new file mode 100644
index 00000000000..3f268a422d5
--- /dev/null
+++ b/test/lib/membuf.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 Google LLC
+ * Written by Simon Glass <sjg at chromium.org>
+ */
+
+#include <membuf.h>
+#include <os.h>
+#include <rand.h>
+#include <string.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#define TEST_SIZE 16
+#define TEST_COUNT 10000
+
+static void membuf_zero(struct membuf *mb)
+{
+ memset(mb->start, '\0', mb->end - mb->start);
+}
+
+static int membuf_check(struct unit_test_state *uts, struct membuf *mb,
+ int value)
+{
+ /* head is out of range */
+ ut_assert(!(mb->head < mb->start || mb->head >= mb->end));
+
+ /* tail is out of range */
+ ut_assert(!(mb->tail < mb->start || mb->tail >= mb->end));
+
+ return 0;
+}
+
+/* write from 1 to test_size bytes, and check they come back OK */
+static int lib_test_membuf_one(struct unit_test_state *uts)
+{
+ char in[TEST_SIZE * 2], out[TEST_SIZE * 2];
+ struct membuf mb;
+ int size, ret, test_size, i;
+
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ /* setup in test */
+ for (i = 0; i < TEST_SIZE; i++) {
+ in[i] = (i & 63) + '0';
+ in[i + TEST_SIZE] = in[i];
+ }
+
+ test_size = TEST_SIZE;
+
+ for (i = 1; i < TEST_COUNT; i++) {
+ membuf_zero(&mb);
+ size = rand() % test_size;
+
+ // now write patterns and check they come back OK
+ ret = membuf_put(&mb, in, 0);
+ ret = membuf_put(&mb, in, size);
+ ut_asserteq(size, ret);
+
+ ret = membuf_put(&mb, in, 0);
+ ut_assertok(membuf_check(uts, &mb, i));
+
+ ret = membuf_get(&mb, out, 0);
+ ret = membuf_get(&mb, out, size);
+ ut_asserteq(size, ret);
+
+ ret = membuf_get(&mb, out, 0);
+ ut_assertok(membuf_check(uts, &mb, i));
+
+ ut_asserteq_mem(in, out, size);
+ }
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_one, 0);
+
+/* write random number of bytes, and check they come back OK */
+static int lib_test_membuf_random(struct unit_test_state *uts)
+{
+ char in[TEST_SIZE * 2];
+ char buf[TEST_SIZE * 2];
+ struct membuf mb;
+ int size, ret, test_size, i;
+ char *inptr, *outptr;
+ int max_avail, min_free;
+
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ for (i = 0; i < TEST_SIZE; i++) {
+ in[i] = (i & 63) + '0';
+ in[i + TEST_SIZE] = in[i];
+ }
+
+ test_size = TEST_SIZE;
+
+ inptr = in;
+ outptr = in;
+ min_free = TEST_COUNT;
+ max_avail = 0;
+ membuf_zero(&mb);
+ for (i = 0; i < TEST_COUNT; i++) {
+ size = rand() % test_size;
+
+ if (membuf_free(&mb) < min_free)
+ min_free = membuf_free(&mb);
+
+ ret = membuf_put(&mb, inptr, size);
+ ut_assertok(membuf_check(uts, &mb, i));
+ inptr += ret;
+ if (inptr >= in + TEST_SIZE)
+ inptr -= TEST_SIZE;
+
+ size = rand() % (test_size - 1);
+
+ if (membuf_avail(&mb) > max_avail)
+ max_avail = membuf_avail(&mb);
+
+ ret = membuf_get(&mb, buf, size);
+ ut_assertok(membuf_check(uts, &mb, i));
+ ut_asserteq_mem(buf, outptr, ret);
+
+ outptr += ret;
+ if (outptr >= in + TEST_SIZE)
+ outptr -= TEST_SIZE;
+ }
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_random, 0);
+
+/* test membuf_extend() with split segments */
+static int lib_test_membuf_extend(struct unit_test_state *uts)
+{
+ char in[TEST_SIZE * 2];
+ char buf[TEST_SIZE * 2];
+ struct membuf mb;
+ int ret, test_size, i, cur;
+ char *data;
+
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ for (i = 0; i < TEST_SIZE; i++) {
+ in[i] = (i & 63) + '0';
+ in[i + TEST_SIZE] = in[i];
+ }
+
+ test_size = TEST_SIZE - 1;
+
+ for (cur = 0; cur <= test_size; cur++) {
+ ut_assertok(membuf_new(&mb, TEST_SIZE));
+
+ membuf_zero(&mb);
+
+ /*
+ * add some bytes, then remove them - this will force the membuf
+ * to have data split into two segments when we fill it
+ */
+ ret = membuf_putraw(&mb, TEST_SIZE / 2, true, &data);
+ membuf_getraw(&mb, ret, true, &data);
+ ut_asserteq(TEST_SIZE / 2, ret);
+
+ /* fill it */
+ ret = membuf_put(&mb, in, cur);
+ ut_assertok(membuf_check(uts, &mb, cur));
+ ut_asserteq(cur, ret);
+
+ /* extend the buffer */
+ ut_assertok(membuf_extend_by(&mb, TEST_SIZE, -1));
+ ut_assertok(membuf_check(uts, &mb, cur));
+
+ /* check our data is still there */
+ ret = membuf_get(&mb, buf, TEST_SIZE * 2);
+ ut_assertok(membuf_check(uts, &mb, cur));
+ ut_asserteq(cur, ret);
+ ut_asserteq_mem(in, buf, cur);
+ membuf_uninit(&mb);
+ }
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_extend, 0);
+
+/* test membuf_readline() with generated data */
+static int lib_test_membuf_readline(struct unit_test_state *uts)
+{
+ char *buf;
+ int size, cur, i, ret, readptr, cmpptr;
+ struct membuf mb;
+ char *data;
+ char str[256];
+ char *s;
+
+ ut_assertok(membuf_new(&mb, 1024));
+ membuf_zero(&mb);
+
+ /* Use the README as test data */
+ ut_assertok(os_read_file("README", (void **)&buf, &size));
+
+ cur = 0;
+ readptr = 0;
+ cmpptr = 0;
+ for (i = 0; i < 100000; i++, cur += 1) {
+ /* fill the buffer with up to 'cur' bytes */
+ ret = membuf_putraw(&mb, cur, false, &data);
+
+ if (ret > 0) {
+ int can_read = min(ret, size - readptr);
+
+ memcpy(data, &buf[readptr], can_read);
+ readptr += can_read;
+
+ membuf_putraw(&mb, can_read, true, &data);
+ ut_assertok(membuf_check(uts, &mb, i));
+ }
+
+ /* read a line and compare */
+ ret = membuf_readline(&mb, str, 256, 0, true);
+ ut_assertok(membuf_check(uts, &mb, i));
+ if (ret) {
+ char *ptr;
+
+ s = &buf[cmpptr];
+ ptr = strchr(s, '\n');
+ *ptr = '\0';
+
+ ut_asserteq_str(s, str);
+ cmpptr += strlen(s) + 1;
+ *ptr = '\n';
+ } else {
+ ut_assert(membuf_free(&mb));
+ }
+ }
+ membuf_dispose(&mb);
+ os_free(buf);
+
+ return 0;
+}
+LIB_TEST(lib_test_membuf_readline, 0);
--
2.34.1
More information about the U-Boot
mailing list