summary refs log tree commit diff stats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile2
-rw-r--r--tests/test-iov.c153
2 files changed, 155 insertions, 0 deletions
diff --git a/tests/Makefile b/tests/Makefile
index ab7f667009..7340bc5044 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -13,6 +13,7 @@ check-unit-y += tests/test-qmp-commands$(EXESUF)
 check-unit-y += tests/test-string-input-visitor$(EXESUF)
 check-unit-y += tests/test-string-output-visitor$(EXESUF)
 check-unit-y += tests/test-coroutine$(EXESUF)
+check-unit-y += tests/test-iov$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -47,6 +48,7 @@ tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o $(tools-obj-y)
 tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o $(tools-obj-y)
 tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) $(tools-obj-y)
 tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y)
+tests/test-iov$(EXESUF): tests/test-iov.o iov.o
 
 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
diff --git a/tests/test-iov.c b/tests/test-iov.c
new file mode 100644
index 0000000000..5f82296a86
--- /dev/null
+++ b/tests/test-iov.c
@@ -0,0 +1,153 @@
+#include <glib.h>
+#include "qemu-common.h"
+#include "iov.h"
+
+/* create a randomly-sized iovec with random vectors */
+static void iov_random(struct iovec **iovp, unsigned *iov_cntp)
+{
+     unsigned niov = g_test_rand_int_range(3,8);
+     struct iovec *iov = g_malloc(niov * sizeof(*iov));
+     unsigned i;
+     for (i = 0; i < niov; ++i) {
+         iov[i].iov_len = g_test_rand_int_range(5,20);
+         iov[i].iov_base = g_malloc(iov[i].iov_len);
+     }
+     *iovp = iov;
+     *iov_cntp = niov;
+}
+
+static void iov_free(struct iovec *iov, unsigned niov)
+{
+    unsigned i;
+    for (i = 0; i < niov; ++i) {
+        g_free(iov[i].iov_base);
+    }
+    g_free(iov);
+}
+
+static void test_iov_bytes(struct iovec *iov, unsigned niov,
+                           size_t offset, size_t bytes)
+{
+    unsigned i;
+    size_t j, o;
+    unsigned char *b;
+    o = 0;
+
+    /* we walk over all elements, */
+    for (i = 0; i < niov; ++i) {
+        b = iov[i].iov_base;
+        /* over each char of each element, */
+        for (j = 0; j < iov[i].iov_len; ++j) {
+            /* counting each of them and
+             * verifying that the ones within [offset,offset+bytes)
+             * range are equal to the position number (o) */
+            if (o >= offset && o < offset + bytes) {
+                g_assert(b[j] == (o & 255));
+            } else {
+                g_assert(b[j] == 0xff);
+            }
+            ++o;
+        }
+    }
+}
+
+static void test_to_from_buf_1(void)
+{
+     unsigned niov;
+     struct iovec *iov;
+     size_t sz;
+     unsigned char *ibuf, *obuf;
+     unsigned i, j, n;
+
+     iov_random(&iov, &niov);
+
+     sz = iov_size(iov, niov);
+
+     ibuf = g_malloc(sz + 8) + 4;
+     memcpy(ibuf-4, "aaaa", 4); memcpy(ibuf + sz, "bbbb", 4);
+     obuf = g_malloc(sz + 8) + 4;
+     memcpy(obuf-4, "xxxx", 4); memcpy(obuf + sz, "yyyy", 4);
+
+     /* fill in ibuf with 0123456... */
+     for (i = 0; i < sz; ++i) {
+         ibuf[i] = i & 255;
+     }
+
+     for (i = 0; i <= sz; ++i) {
+
+         /* Test from/to buf for offset(i) in [0..sz] up to the end of buffer.
+          * For last iteration with offset == sz, the procedure should
+          * skip whole vector and process exactly 0 bytes */
+
+         /* first set bytes [i..sz) to some "random" value */
+         n = iov_memset(iov, niov, 0, 0xff, -1);
+         g_assert(n == sz);
+
+         /* next copy bytes [i..sz) from ibuf to iovec */
+         n = iov_from_buf(iov, niov, i, ibuf + i, -1);
+         g_assert(n == sz - i);
+
+         /* clear part of obuf */
+         memset(obuf + i, 0, sz - i);
+         /* and set this part of obuf to values from iovec */
+         n = iov_to_buf(iov, niov, i, obuf + i, -1);
+         g_assert(n == sz - i);
+
+         /* now compare resulting buffers */
+         g_assert(memcmp(ibuf, obuf, sz) == 0);
+
+         /* test just one char */
+         n = iov_to_buf(iov, niov, i, obuf + i, 1);
+         g_assert(n == (i < sz));
+         if (n) {
+             g_assert(obuf[i] == (i & 255));
+         }
+
+         for (j = i; j <= sz; ++j) {
+             /* now test num of bytes cap up to byte no. j,
+              * with j in [i..sz]. */
+
+             /* clear iovec */
+             n = iov_memset(iov, niov, 0, 0xff, -1);
+             g_assert(n == sz);
+
+             /* copy bytes [i..j) from ibuf to iovec */
+             n = iov_from_buf(iov, niov, i, ibuf + i, j - i);
+             g_assert(n == j - i);
+
+             /* clear part of obuf */
+             memset(obuf + i, 0, j - i);
+
+             /* copy bytes [i..j) from iovec to obuf */
+             n = iov_to_buf(iov, niov, i, obuf + i, j - i);
+             g_assert(n == j - i);
+
+             /* verify result */
+             g_assert(memcmp(ibuf, obuf, sz) == 0);
+
+             /* now actually check if the iovec contains the right data */
+             test_iov_bytes(iov, niov, i, j - i);
+         }
+    }
+    g_assert(!memcmp(ibuf-4, "aaaa", 4) && !memcmp(ibuf+sz, "bbbb", 4));
+    g_free(ibuf-4);
+    g_assert(!memcmp(obuf-4, "xxxx", 4) && !memcmp(obuf+sz, "yyyy", 4));
+    g_free(obuf-4);
+    iov_free(iov, niov);
+}
+
+static void test_to_from_buf(void)
+{
+    int x;
+    for (x = 0; x < 4; ++x) {
+        test_to_from_buf_1();
+    }
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+    g_test_rand_int();
+    g_test_add_func("/basic/iov/from-to-buf", test_to_from_buf);
+    return g_test_run();
+}