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

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to