]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added unit tests for istream-seekable istream-concat.
authorTimo Sirainen <tss@iki.fi>
Mon, 26 Oct 2009 21:07:57 +0000 (17:07 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 26 Oct 2009 21:07:57 +0000 (17:07 -0400)
--HG--
branch : HEAD

src/lib/Makefile.am
src/lib/test-istream-concat.c [new file with mode: 0644]
src/lib/test-istream-seekable.c [new file with mode: 0644]
src/lib/test-lib.c
src/lib/test-lib.h

index 9e88563e0820d5e303f80dded8600e921818a26c..9b1e8953e72696e1e592929312767c20a765dc0a 100644 (file)
@@ -221,7 +221,9 @@ test_lib_SOURCES = \
        test-bsearch-insert-pos.c \
        test-buffer.c \
        test-hex-binary.c \
+       test-istream-concat.c \
        test-istream-crlf.c \
+       test-istream-seekable.c \
        test-istream-tee.c \
        test-mempool-alloconly.c \
        test-network.c \
diff --git a/src/lib/test-istream-concat.c b/src/lib/test-istream-concat.c
new file mode 100644 (file)
index 0000000..a6877e1
--- /dev/null
@@ -0,0 +1,110 @@
+/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "istream-internal.h"
+#include "istream-concat.h"
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static void test_istream_concat_one(unsigned int buffer_size)
+{
+       static const char *input_string = "xyz";
+#define STREAM_COUNT 5
+#define STREAM_BYTES 3
+       struct istream *streams[STREAM_COUNT+1];
+       struct istream *input;
+       const unsigned char *data;
+       size_t size;
+       unsigned int i, j;
+
+       for (i = 0; i < STREAM_COUNT; i++) {
+               streams[i] = test_istream_create(input_string);
+               test_istream_set_allow_eof(streams[i], TRUE);
+               test_istream_set_size(streams[i], 0);
+       }
+       streams[i] = NULL;
+
+       input = i_stream_create_concat(streams);
+       for (i = 0; i/STREAM_BYTES < STREAM_COUNT; i++) {
+               test_istream_set_size(streams[i/STREAM_BYTES], (i%STREAM_BYTES) + 1);
+               test_assert(i_stream_read(input) == 1);
+               if (i < buffer_size) {
+                       data = i_stream_get_data(input, &size);
+                       test_assert(size == i+1);
+               } else {
+                       i_stream_skip(input, 1);
+                       data = i_stream_get_data(input, &size);
+                       test_assert(size == buffer_size);
+               }
+               for (j = 0; j < size; j++) {
+                       test_assert(data[j] == input_string[(input->v_offset + j) % STREAM_BYTES]);
+               }
+       }
+       i_stream_unref(&input);
+}
+
+static void test_istream_concat_random(void)
+{
+       struct istream **streams, *input;
+       const unsigned char *data;
+       unsigned char *w_data;
+       size_t size;
+       unsigned int i, j, offset, stream_count, data_len;
+
+       srand(1234);
+       stream_count = (rand() % 10) + 2;
+       streams = t_new(struct istream *, stream_count + 1);
+       for (i = 0, offset = 0; i < stream_count; i++) {
+               data_len = rand() % 100 + 1;
+               w_data = t_malloc(data_len);
+               for (j = 0; j < data_len; j++)
+                       w_data[j] = offset++;
+               streams[i] = test_istream_create_data(w_data, data_len);
+               test_istream_set_allow_eof(streams[i], TRUE);
+       }
+       streams[i] = NULL;
+
+       input = i_stream_create_concat(streams);
+       for (i = 0; i < 100; i++) {
+               if (rand() % 3 == 0) {
+                       i_stream_seek(input, rand() % offset);
+               } else {
+                       ssize_t ret = i_stream_read(input);
+                       if (input->v_offset + size == offset)
+                               test_assert(ret < 0);
+                       else {
+                               test_assert(ret > 0);
+                               test_assert(input->v_offset + ret <= offset);
+                               i_stream_skip(input, rand() % ret);
+
+                               data = i_stream_get_data(input, &size);
+                               for (j = 0; j < size; j++) {
+                                       test_assert(data[j] == (input->v_offset + j) % 256);
+                               }
+                       }
+               }
+               (void)i_stream_get_data(input, &size);
+       }
+       for (i = 0; i < stream_count; i++)
+               i_stream_unref(&streams[i]);
+       i_stream_unref(&input);
+}
+
+void test_istream_concat(void)
+{
+       unsigned int i;
+
+       test_begin("istream concat");
+       for (i = 1; i < STREAM_BYTES*STREAM_COUNT; i++) {
+               test_istream_concat_one(i);
+       }
+       test_end();
+
+       test_begin("istream concat random");
+       for (i = 0; i < 100; i++) T_BEGIN {
+               test_istream_concat_random();
+       } T_END;
+       test_end();
+}
diff --git a/src/lib/test-istream-seekable.c b/src/lib/test-istream-seekable.c
new file mode 100644 (file)
index 0000000..b10517e
--- /dev/null
@@ -0,0 +1,139 @@
+/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "istream-internal.h"
+#include "istream-seekable.h"
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static int fd_callback(const char **path_r, void *context ATTR_UNUSED)
+{
+       int fd;
+
+       *path_r = "test-lib.tmp";
+       fd = open(*path_r, O_RDWR | O_CREAT | O_TRUNC, 0600);
+       if (fd == -1)
+               i_error("creat(%s) failed: %m", *path_r);
+       else
+               unlink(*path_r);
+       return fd;
+}
+
+static void test_istream_seekable_one(unsigned int buffer_size)
+{
+       static const char *input_string = "xyz";
+#define STREAM_COUNT 5
+#define STREAM_BYTES 3
+       struct istream *streams[STREAM_COUNT+1];
+       struct istream *input;
+       const unsigned char *data;
+       size_t size;
+       unsigned int i, j;
+
+       for (i = 0; i < STREAM_COUNT; i++) {
+               streams[i] = test_istream_create(input_string);
+               streams[i]->seekable = FALSE;
+               test_istream_set_allow_eof(streams[i], TRUE);
+               test_istream_set_size(streams[i], 0);
+       }
+       streams[i] = NULL;
+
+       input = i_stream_create_seekable(streams, buffer_size, fd_callback, NULL);
+       for (i = 0; i/STREAM_BYTES < STREAM_COUNT; i++) {
+               test_istream_set_size(streams[i/STREAM_BYTES], (i%STREAM_BYTES) + 1);
+               if (i < buffer_size) {
+                       test_assert(i_stream_read(input) == 1);
+                       data = i_stream_get_data(input, &size);
+                       test_assert(size == i+1);
+               } else {
+                       test_assert(i_stream_read(input) == -2);
+                       i_stream_skip(input, 1);
+                       test_assert(i_stream_read(input) == 1);
+                       data = i_stream_get_data(input, &size);
+                       test_assert(size == buffer_size);
+               }
+               for (j = 0; j < size; j++) {
+                       test_assert(data[j] == input_string[(input->v_offset + j) % STREAM_BYTES]);
+               }
+       }
+       for (i = 0; i < STREAM_COUNT; i++)
+               i_stream_unref(&streams[i]);
+       i_stream_unref(&input);
+}
+
+static void test_istream_seekable_random(void)
+{
+       struct istream **streams, *input;
+       const unsigned char *data;
+       unsigned char *w_data;
+       size_t size;
+       unsigned int i, j, offset, stream_count, data_len, buffer_size;
+
+       stream_count = (rand() % 10) + 2;
+       streams = t_new(struct istream *, stream_count + 1);
+       for (i = 0, offset = 0; i < stream_count; i++) {
+               data_len = rand() % 100 + 1;
+               w_data = t_malloc(data_len);
+               for (j = 0; j < data_len; j++)
+                       w_data[j] = offset++;
+               streams[i] = test_istream_create_data(w_data, data_len);
+               streams[i]->seekable = FALSE;
+               test_istream_set_allow_eof(streams[i], TRUE);
+       }
+       streams[i] = NULL;
+
+       buffer_size = (rand() % 100) + 1; size = 0;
+       input = i_stream_create_seekable(streams, buffer_size, fd_callback, NULL);
+
+       /* first read it through */
+       while (i_stream_read(input) > 0) {
+               (void)i_stream_get_data(input, &size);
+               i_stream_skip(input, size);
+       }
+
+       i_stream_seek(input, 0);
+       for (i = 0; i < 100; i++) {
+               if (rand() % 3 == 0) {
+                       i_stream_seek(input, rand() % offset);
+               } else {
+                       ssize_t ret = i_stream_read(input);
+                       if (input->v_offset + size == offset)
+                               test_assert(ret < 0);
+                       else if (ret == -2) {
+                               data = i_stream_get_data(input, &size);
+                               test_assert(size == buffer_size);
+                       } else {
+                               test_assert(ret > 0);
+                               test_assert(input->v_offset + ret <= offset);
+                               i_stream_skip(input, rand() % ret);
+
+                               data = i_stream_get_data(input, &size);
+                               for (j = 0; j < size; j++) {
+                                       test_assert(data[j] == (input->v_offset + j) % 256);
+                               }
+                       }
+               }
+               (void)i_stream_get_data(input, &size);
+       }
+       for (i = 0; i < stream_count; i++)
+               i_stream_unref(&streams[i]);
+       i_stream_unref(&input);
+}
+
+void test_istream_seekable(void)
+{
+       unsigned int i;
+
+       test_begin("istream seekable");
+       for (i = 1; i <= STREAM_BYTES*STREAM_COUNT; i++)
+               test_istream_seekable_one(i);
+       test_end();
+
+       test_begin("istream seekable random");
+       for (i = 0; i < 100; i++) T_BEGIN {
+               test_istream_seekable_random();
+       } T_END;
+       test_end();
+}
index a8c2f03c12011b2d16d4330613649c0c14be610e..0d44e76d609a9859e6f8f72c8f1e7fd521c5af7d 100644 (file)
@@ -11,7 +11,9 @@ int main(void)
                test_bsearch_insert_pos,
                test_buffer,
                test_hex_binary,
+               test_istream_concat,
                test_istream_crlf,
+               test_istream_seekable,
                test_istream_tee,
                test_mempool_alloconly,
                test_network,
index 6536dd58296be612cb398dcd66801972870ba9ee..6505af6502520a02576de06a5334a3dfa29efd24 100644 (file)
@@ -10,7 +10,9 @@ void test_base64(void);
 void test_bsearch_insert_pos(void);
 void test_buffer(void);
 void test_hex_binary(void);
+void test_istream_concat(void);
 void test_istream_crlf(void);
+void test_istream_seekable(void);
 void test_istream_tee(void);
 void test_mempool_alloconly(void);
 void test_network(void);