[PATCH 3/3] tests: add tests for wl_buffer_*

Marek Ch mchqwerty at gmail.com
Thu Dec 5 07:38:22 PST 2013


Tests for wl_buffer_* functions from connection.c
---
 src/connection.c      |  10 +-
 src/wayland-private.h |  10 ++
 tests/Makefile.am     |   7 +-
 tests/buffer-test.c   | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 268 insertions(+), 6 deletions(-)
 create mode 100644 tests/buffer-test.c

diff --git a/src/connection.c b/src/connection.c
index c85c669..55f6fae 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -53,7 +53,7 @@ struct wl_connection {
 	int want_flush;
 };
 
-static void
+WL_PRIVATE void
 wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
 {
 	uint32_t head, size;
@@ -70,7 +70,7 @@ wl_buffer_put(struct wl_buffer *b, const void *data, size_t count)
 	b->head += count;
 }
 
-static void
+WL_PRIVATE void
 wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
 {
 	uint32_t head, tail;
@@ -94,7 +94,7 @@ wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count)
 	}
 }
 
-static void
+WL_PRIVATE void
 wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
 {
 	uint32_t head, tail;
@@ -118,7 +118,7 @@ wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count)
 	}
 }
 
-static void
+WL_PRIVATE void
 wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
 {
 	uint32_t tail, size;
@@ -133,7 +133,7 @@ wl_buffer_copy(struct wl_buffer *b, void *data, size_t count)
 	}
 }
 
-static uint32_t
+WL_PRIVATE uint32_t
 wl_buffer_size(struct wl_buffer *b)
 {
 	return b->head - b->tail;
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 251e841..70d338b 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -99,6 +99,16 @@ struct wl_buffer {
 
 #define MASK(i) ((i) & 4095)
 
+#ifdef UNIT_TEST
+struct iovec;
+
+void wl_buffer_put(struct wl_buffer *b, const void *data, size_t count);
+void wl_buffer_put_iov(struct wl_buffer *b, struct iovec *iov, int *count);
+void wl_buffer_get_iov(struct wl_buffer *b, struct iovec *iov, int *count);
+void wl_buffer_copy(struct wl_buffer *b, void *data, size_t count);
+uint32_t wl_buffer_size(struct wl_buffer *b);
+#endif /* UNIT_TEST */
+
 struct wl_connection *wl_connection_create(int fd);
 void wl_connection_destroy(struct wl_connection *connection);
 void wl_connection_copy(struct wl_connection *connection, void *data, size_t size);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 4552159..56c3644 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,7 +12,8 @@ TESTS =						\
 	socket-test				\
 	queue-test				\
 	signal-test				\
-	resources-test
+	resources-test				\
+	buffer-test
 
 check_PROGRAMS =				\
 	$(TESTS)				\
@@ -36,6 +37,10 @@ socket_test_SOURCES = socket-test.c $(test_runner_src)
 queue_test_SOURCES = queue-test.c $(test_runner_src)
 signal_test_SOURCES = signal-test.c $(test_runner_src)
 resources_test_SOURCES = resources-test.c $(test_runner_src)
+buffer_test_SOURCES =			\
+	buffer-test.c			\
+	$(top_srcdir)/src/connection.c	\
+	$(test_runner_src)
 
 fixed_benchmark_SOURCES = fixed-benchmark.c
 
diff --git a/tests/buffer-test.c b/tests/buffer-test.c
new file mode 100644
index 0000000..c454870
--- /dev/null
+++ b/tests/buffer-test.c
@@ -0,0 +1,247 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "test-runner.h"
+#include "wayland-private.h"
+#include <sys/uio.h>
+#include <unistd.h>
+
+/* Assert with formated output */
+#define assertf(cond, ...) 							\
+	do {									\
+		if (!(cond)) {							\
+			fprintf(stderr, "%s (%s: %d): Assertion %s failed!",	\
+					__FUNCTION__, __FILE__, __LINE__, #cond);\
+			fprintf(stderr, " " __VA_ARGS__);			\
+			putc('\n', stderr);					\
+			abort();						\
+		}								\
+	} while (0)
+
+
+static const char data[] = "abcdefghijklmnopqrstuvwxyz";
+
+static int
+fill_buffer(struct wl_buffer *b)
+{
+	int i;
+	for (i = 1; i * (sizeof data) <= sizeof b->data; i++) {
+		wl_buffer_put(b, data, sizeof data);
+
+		assert(b->tail == 0);
+		assertf(b->head == i * (sizeof data),
+			"head is %u instead of %lu", b->head, i * (sizeof data));
+		assertf(wl_buffer_size(b) == i * sizeof data,
+			"wl_buffer_size() = %u instead of %lu",
+			wl_buffer_size(b), i * sizeof data);
+	}
+
+	return i;
+}
+
+TEST(wl_buffer_put_tst)
+{
+	struct wl_buffer b = {.head = 0, .tail = 0};
+	size_t index;
+	int i;
+
+	assert(wl_buffer_size(&b) == 0);
+
+	i = fill_buffer(&b);
+
+	/* do overflow */
+	wl_buffer_put(&b, data, sizeof data);
+
+	/* check for me */
+	assert(i * sizeof data > sizeof b.data);
+
+	/* size should not be cropped */
+	assertf(wl_buffer_size(&b) == i * sizeof data,
+		"head: %u, tail: %u, wl_buffer_size: %u",
+		b.head, b.tail, wl_buffer_size(&b));
+
+	/* head must be somewhere on the begining of the buffer after owerflow */
+	assertf(MASK(b.head) < sizeof b.data);
+	assert(b.tail == 0);
+
+	/* get begining of the last string written to buffer */
+	index = sizeof b.data % sizeof data;
+
+	/* compare if the string is split (after overflow) right */
+	assertf(strncmp((char *) b.data + sizeof b.data - index, data, index - 1) == 0,
+		"Should have '%*s', but have '%*s'\n", (int) (index - 1), data,
+		(int) (index - 1), (char *) b.data + sizeof b.data - index);
+	assertf(strncmp(b.data, (char *) data + index, sizeof data - index) == 0,
+		"Should have '%*s', but have '%*s'\n",
+		(int) (sizeof data - index), data + index,
+		(int) (sizeof data - index), (char *) b.data);
+
+	struct wl_buffer bb = {.head = 0, .tail = 0};
+	wl_buffer_put(&bb, data, sizeof data);
+	assert(strcmp(data, bb.data) == 0);
+}
+
+TEST(wl_buffer_fill_alot)
+{
+	struct wl_buffer b = {.head = 0, .tail = 0};
+	int i;
+
+	/* put a lot of data into buffer (data < sizeof buffer.data) */
+	for (i = 0; i * sizeof data < 100 * sizeof b.data; i++)
+		wl_buffer_put(&b, data, sizeof data);
+}
+
+TEST(wl_buffer_copy_tst)
+{
+	char buf[40];
+	struct wl_buffer b = {.head = 0, .tail = 0};
+
+	wl_buffer_put(&b, data, sizeof data);
+	wl_buffer_copy(&b, &buf, sizeof data);
+
+	assert(strcmp(buf, b.data) == 0);
+
+	/* wl_buffer_copy is not destructive */
+	assertf(strcmp(buf, b.data) == 0,
+		"Previous wl_buffer_copy modified data");
+	assert(b.tail == 0);
+
+	/* do overflow */
+	b.head = sizeof b.data - 10;
+	b.tail = b.head;
+	wl_buffer_put(&b, data, sizeof data);
+
+	memset(&buf, 0, sizeof buf);
+	wl_buffer_copy(&b, buf, sizeof data);
+	assert(strcmp(buf, data) == 0);
+}
+
+TEST(wl_buffer_put_iov_tst)
+{
+	struct wl_buffer b = {.head = 0, .tail = 0};
+	struct iovec iov[2];
+	int cnt = 0;
+	size_t len;
+
+	int p[2];
+	char buf1[] = "buffer1";
+	char buf2[] = "buffer2";
+
+	assert(pipe(p) != -1);
+
+	/* try empty buffer */
+	wl_buffer_put_iov(&b, iov, &cnt);
+	assertf(cnt == 1, "Count: %d", cnt);
+
+	write(p[1], buf1, sizeof buf1);
+	len = readv(p[0], iov, cnt);
+	assertf(len == sizeof buf1, "len: %lu, sizeof buf1: %lu",
+		len, sizeof buf1);
+	assert(strcmp(buf1, b.data) == 0);
+
+	b.head += len;
+	wl_buffer_put_iov(&b, iov, &cnt);
+	assertf(cnt == 1, "Count: %d", cnt);
+
+	write(p[1], buf2, sizeof buf2);
+	len = readv(p[0], iov, cnt);
+	assertf(len == sizeof buf2, "len: %lu, sizeof buf2: %lu",
+		len, sizeof buf2);
+	/* the contents should be "buffer1buffer2" */
+	assert(strcmp(b.data, buf1) == 0);
+	assert(strcmp(b.data + sizeof buf1, buf2) == 0);
+
+	/* set head 3 bytes from the end --> it should write only 3 bytes */
+	b.head = sizeof b.data - 3;
+	wl_buffer_put_iov(&b, iov, &cnt);
+	assertf(cnt == 1, "Count: %d", cnt);
+	write(p[1], buf1, sizeof buf1);
+	len = readv(p[0], iov, cnt);
+	assertf(len == 3, "len: %lu", len);
+
+	/* set tail != 0, it should fill both iovec structures */
+	b.tail = 5;
+	wl_buffer_put_iov(&b, iov, &cnt);
+	assertf(cnt == 2, "Count: %d", cnt);
+	/* in the pipe left 5 bytes {'f', 'e', 'r', '1', '\0'}*/
+	len = readv(p[0], iov, cnt);
+	assertf(len == 5, "len: %lu", len);
+	assert(strncmp(b.data + sizeof b.data - 3, "fer", 3) == 0);
+	assert(strcmp(b.data, "1") == 0);
+
+	close(p[0]);
+	close(p[1]);
+}
+
+TEST(wl_buffer_get_iov_tst)
+{
+	struct wl_buffer b = {.head = 0, .tail = 0};
+	struct wl_buffer tmp;
+	struct iovec iov[2];
+	int cnt = 0;
+	size_t index;
+	ssize_t len;
+
+	int p[2];
+
+	assert(pipe(p) != -1);
+
+	fill_buffer(&b);
+	index = sizeof b.data % sizeof data;
+
+	wl_buffer_get_iov(&b, iov, &cnt);
+	assert((len = writev(p[1], iov, cnt)) > 0);
+	assert(read(p[0], &tmp.data, sizeof b.data - index) == len);
+	assert(strcmp(tmp.data, b.data) == 0);
+
+	/* circulation */
+	b.tail = sizeof b.data - 10;
+	b.head = b.tail;
+	wl_buffer_put(&b, data, sizeof data);
+
+	wl_buffer_get_iov(&b, iov, &cnt);
+	assertf(cnt == 2, "cnt: %d", cnt);
+	assert((len = writev(p[1], iov, cnt)) > 0);
+	assert(read(p[0], &tmp.data, sizeof data) == len);
+	assert(strncmp(tmp.data, b.data + sizeof b.data - 10, 10) == 0);
+	assert(strcmp(tmp.data + 10, b.data) == 0);
+
+	close(p[0]);
+	close(p[1]);
+}
+
+TEST(wl_buffer_get_put_iov_tst)
+{
+	struct wl_buffer b1, b2;
+	struct iovec iov1[2], iov2[2];
+	int cnt1 = 0;
+	int cnt2 = 0;
+
+	int p[2];
+
+	assert(pipe(p) != -1);
+	memset(&b1, 0, sizeof b1);
+	memset(&b2, 0, sizeof b2);
+
+	fill_buffer(&b1);
+	wl_buffer_get_iov(&b1, iov1, &cnt1);
+	wl_buffer_put_iov(&b2, iov2, &cnt2);
+	assert((writev(p[1], iov1, cnt1) == readv(p[0], iov2, cnt2)) > 0);
+	assert(memcmp(b1.data, b2.data, sizeof b1.data) == 0);
+
+	/* try cycled buffer (head < tail) */
+	b1.head = 10;
+	b1.tail = sizeof b1.data - 10;
+	b2.head = b1.tail;
+	b2.tail = b1.head;
+	wl_buffer_get_iov(&b1, iov1, &cnt1);
+	wl_buffer_put_iov(&b2, iov2, &cnt2);
+	assertf(cnt1 == 2 && cnt2 == 2, "cnt1: %d, cnt2: %d", cnt1, cnt2);
+	assert((writev(p[1], iov1, cnt1) == readv(p[0], iov2, cnt2)) > 0);
+	assert(memcmp(b1.data, b2.data, sizeof b1.data) == 0);
+
+	close(p[0]);
+	close(p[1]);
+
+}
-- 
1.8.4.2



More information about the wayland-devel mailing list