]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
liblib unit tests are now split to separate files.
authorTimo Sirainen <tss@iki.fi>
Mon, 1 Jun 2009 05:11:17 +0000 (01:11 -0400)
committerTimo Sirainen <tss@iki.fi>
Mon, 1 Jun 2009 05:11:17 +0000 (01:11 -0400)
--HG--
branch : HEAD

17 files changed:
src/lib/Makefile.am
src/lib/test-aqueue.c [new file with mode: 0644]
src/lib/test-array.c [new file with mode: 0644]
src/lib/test-base64.c [new file with mode: 0644]
src/lib/test-bsearch-insert-pos.c [new file with mode: 0644]
src/lib/test-buffer.c [new file with mode: 0644]
src/lib/test-istream.c
src/lib/test-lib.c
src/lib/test-lib.h
src/lib/test-mempool-alloconly.c [new file with mode: 0644]
src/lib/test-network.c [new file with mode: 0644]
src/lib/test-primes.c [new file with mode: 0644]
src/lib/test-priorityq.c [new file with mode: 0644]
src/lib/test-seq-range-array.c [new file with mode: 0644]
src/lib/test-str-find.c [new file with mode: 0644]
src/lib/test-str-sanitize.c [new file with mode: 0644]
src/lib/test-utc-mktime.c [new file with mode: 0644]

index 0453b9a71ea827c35e948417941b412b022e46cd..eb40f1c446634f74e06cdd6e300f00692786e844 100644 (file)
@@ -210,7 +210,20 @@ test_libs = \
 
 test_lib_SOURCES = \
        test-lib.c \
-       test-istream.c
+       test-array.c \
+       test-aqueue.c \
+       test-base64.c \
+       test-bsearch-insert-pos.c \
+       test-buffer.c \
+       test-istream.c \
+       test-mempool-alloconly.c \
+       test-network.c \
+       test-primes.c \
+       test-priorityq.c \
+       test-seq-range-array.c \
+       test-str-find.c \
+       test-str-sanitize.c \
+       test-utc-mktime.c
 
 test_headers = \
        test-lib.h
diff --git a/src/lib/test-aqueue.c b/src/lib/test-aqueue.c
new file mode 100644 (file)
index 0000000..4064349
--- /dev/null
@@ -0,0 +1,71 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "array.h"
+#include "aqueue.h"
+
+static bool aqueue_is_ok(struct aqueue *aqueue, unsigned int deleted_n)
+{
+       const unsigned int *p;
+       unsigned int n, i, count;
+
+       count = aqueue_count(aqueue);
+       for (i = 0, n = 1; i < count; i++, n++) {
+               p = array_idx_i(aqueue->arr, aqueue_idx(aqueue, i));
+               if (i == deleted_n)
+                       n++;
+               if (*p != n)
+                       return FALSE;
+       }
+       return TRUE;
+}
+
+static const unsigned int aqueue_input[] = { 1, 2, 3, 4, 5, 6 };
+static const char *test_aqueue2(unsigned int initial_size)
+{
+       ARRAY_DEFINE(aqueue_array, unsigned int);
+       unsigned int i, j, k;
+       struct aqueue *aqueue;
+
+       for (i = 0; i < N_ELEMENTS(aqueue_input); i++) {
+               for (k = 0; k < N_ELEMENTS(aqueue_input); k++) {
+                       t_array_init(&aqueue_array, initial_size);
+                       aqueue = aqueue_init(&aqueue_array.arr);
+                       aqueue->head = aqueue->tail = initial_size - 1;
+                       for (j = 0; j < k; j++) {
+                               aqueue_append(aqueue, &aqueue_input[j]);
+                               if (aqueue_count(aqueue) != j + 1) {
+                                       return t_strdup_printf("Wrong count after append %u vs %u)",
+                                                              aqueue_count(aqueue), j + 1);
+                               }
+                               if (!aqueue_is_ok(aqueue, -1U))
+                                       return "Invalid data after append";
+                       }
+
+                       if (k != 0 && i < k) {
+                               aqueue_delete(aqueue, i);
+                               if (aqueue_count(aqueue) != k - 1)
+                                       return "Wrong count after delete";
+                               if (!aqueue_is_ok(aqueue, i))
+                                       return "Invalid data after delete";
+                       }
+               }
+       }
+       aqueue_clear(aqueue);
+       if (aqueue_count(aqueue) != 0)
+               return "aqueue_clear() broken";
+       return NULL;
+}
+
+void test_aqueue(void)
+{
+       unsigned int i;
+       const char *reason = NULL;
+
+       for (i = 1; i <= N_ELEMENTS(aqueue_input) + 1 && reason == NULL; i++) {
+               T_BEGIN {
+                       reason = test_aqueue2(i);
+               } T_END;
+       }
+       test_out_reason("aqueue", reason == NULL, reason);
+}
diff --git a/src/lib/test-array.c b/src/lib/test-array.c
new file mode 100644 (file)
index 0000000..419e35d
--- /dev/null
@@ -0,0 +1,30 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "array.h"
+
+static void test_array_reverse(void)
+{
+       ARRAY_DEFINE(intarr, int);
+       int input[] = { -1234567890, -272585721, 2724859223U, 824725652 };
+       const int *output;
+       unsigned int i, j;
+
+       test_begin("array reverse");
+       t_array_init(&intarr, 5);
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               array_clear(&intarr);
+               array_append(&intarr, input, i);
+               array_reverse(&intarr);
+
+               output = i == 0 ? NULL : array_idx(&intarr, 0);
+               for (j = 0; j < i; j++)
+                       test_assert(input[i-j-1] == output[j]);
+       }
+       test_end();
+}
+
+void test_array(void)
+{
+       test_array_reverse();
+}
diff --git a/src/lib/test-base64.c b/src/lib/test-base64.c
new file mode 100644 (file)
index 0000000..645c45c
--- /dev/null
@@ -0,0 +1,110 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str.h"
+#include "base64.h"
+
+#include <stdlib.h>
+
+static void test_base64_encode(void)
+{
+       static const char *input[] = {
+               "hello world",
+               "foo barits",
+               "just niin"
+       };
+       static const char *output[] = {
+               "aGVsbG8gd29ybGQ=",
+               "Zm9vIGJhcml0cw==",
+               "anVzdCBuaWlu"
+       };
+       string_t *str;
+       unsigned int i;
+
+       test_begin("base64_encode()");
+       str = t_str_new(256);
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               str_truncate(str, 0);
+               base64_encode(input[i], strlen(input[i]), str);
+               test_assert(strcmp(output[i], str_c(str)) == 0);
+       }
+       test_end();
+}
+
+struct test_base64_decode_output {
+       const char *text;
+       int ret;
+       unsigned int src_pos;
+};
+
+static void test_base64_decode(void)
+{
+       static const char *input[] = {
+               "\taGVsbG8gd29ybGQ=",
+               "\nZm9v\n \tIGJh  \t\ncml0cw==",
+               "  anVzdCBuaWlu  \n",
+               "aGVsb",
+               "aGVsb!!!!!",
+               "aGVs!!!!!"
+       };
+       static const struct test_base64_decode_output output[] = {
+               { "hello world", 0, -1 },
+               { "foo barits", 0, -1 },
+               { "just niin", 1, -1 },
+               { "hel", 1, 4 },
+               { "hel", -1, 4 },
+               { "hel", -1, 4 }
+       };
+       string_t *str;
+       unsigned int i;
+       size_t src_pos;
+       int ret;
+
+       test_begin("base64_decode()");
+       str = t_str_new(256);
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               str_truncate(str, 0);
+
+               src_pos = 0;
+               ret = base64_decode(input[i], strlen(input[i]), &src_pos, str);
+
+               test_assert(output[i].ret == ret &&
+                           strcmp(output[i].text, str_c(str)) == 0 &&
+                           (src_pos == output[i].src_pos ||
+                            (output[i].src_pos == (unsigned int)-1 &&
+                             src_pos == strlen(input[i]))));
+       }
+       test_end();
+}
+
+static void test_base64_random(void)
+{
+       string_t *str, *dest;
+       char buf[10];
+       unsigned int i, j, max;
+
+       str = t_str_new(256);
+       dest = t_str_new(256);
+
+       test_begin("base64 encode/decode with random input");
+       for (i = 0; i < 1000; i++) {
+               max = rand() % sizeof(buf);
+               for (j = 0; j < max; j++)
+                       buf[j] = rand();
+
+               str_truncate(str, 0);
+               str_truncate(dest, 0);
+               base64_encode(buf, max, str);
+               base64_decode(str_data(str), str_len(str), NULL, dest);
+               test_assert(str_len(dest) == max &&
+                           memcmp(buf, str_data(dest), max) == 0);
+       }
+       test_end();
+}
+
+void test_base64(void)
+{
+       test_base64_encode();
+       test_base64_decode();
+       test_base64_random();
+}
diff --git a/src/lib/test-bsearch-insert-pos.c b/src/lib/test-bsearch-insert-pos.c
new file mode 100644 (file)
index 0000000..548016f
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "bsearch-insert-pos.h"
+
+static int cmp_uint(const void *p1, const void *p2)
+{
+       const unsigned int *i1 = p1, *i2 = p2;
+
+       return *i1 - *i2;
+}
+
+void test_bsearch_insert_pos(void)
+{
+       static const unsigned int input[] = {
+               1, 5, 9, 15, 16, -1,
+               1, 5, 9, 15, 16, 17, -1,
+               -1
+       };
+       static const unsigned int max_key = 18;
+       const unsigned int *cur;
+       unsigned int key, len, i, idx;
+       bool success;
+
+       cur = input;
+       for (i = 0; cur[0] != -1U; i++) {
+               for (len = 0; cur[len] != -1U; len++) ;
+               for (key = 0; key < max_key; key++) {
+                       if (bsearch_insert_pos(&key, cur, len, sizeof(*cur),
+                                              cmp_uint, &idx))
+                               success = cur[idx] == key;
+                       else if (idx == 0)
+                               success = cur[0] > key;
+                       else if (idx == len)
+                               success = cur[len-1] < key;
+                       else {
+                               success = cur[idx-1] < key &&
+                                       cur[idx+1] > key;
+                       }
+                       if (!success)
+                               break;
+               }
+               cur += len + 1;
+
+               test_out(t_strdup_printf("bsearch_insert_pos(%d,%d)", i, key),
+                        success);
+       }
+}
diff --git a/src/lib/test-buffer.c b/src/lib/test-buffer.c
new file mode 100644 (file)
index 0000000..e20b95b
--- /dev/null
@@ -0,0 +1,135 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "buffer.h"
+
+#include <stdlib.h>
+
+void test_buffer(void)
+{
+#define BUF_TEST_SIZE (1024*2)
+#define BUF_TEST_COUNT 1000
+       buffer_t *buf;
+       unsigned char *p, testdata[BUF_TEST_SIZE], shadowbuf[BUF_TEST_SIZE];
+       unsigned int i, shadowbuf_size;
+       size_t pos, pos2, size;
+       int test = -1;
+       bool zero;
+
+       buf = buffer_create_dynamic(default_pool, 1);
+       for (i = 0; i < BUF_TEST_SIZE; i++)
+               testdata[i] = random();
+       memset(shadowbuf, 0, sizeof(shadowbuf));
+
+       srand(1);
+       shadowbuf_size = 0;
+       for (i = 0; i < BUF_TEST_COUNT; i++) {
+               if (buf->used == BUF_TEST_SIZE) {
+                       size = shadowbuf_size = rand() % (buf->used - 1);
+                       buffer_set_used_size(buf, size);
+                       memset(shadowbuf + shadowbuf_size, 0,
+                              BUF_TEST_SIZE - shadowbuf_size);
+                       i_assert(buf->used < BUF_TEST_SIZE);
+               }
+
+               test = rand() % 6;
+               zero = rand() % 10 == 0;
+               switch (test) {
+               case 0:
+                       pos = rand() % (BUF_TEST_SIZE-1);
+                       size = rand() % (BUF_TEST_SIZE - pos);
+                       if (!zero) {
+                               buffer_write(buf, pos, testdata, size);
+                               memcpy(shadowbuf + pos, testdata, size);
+                       } else {
+                               buffer_write_zero(buf, pos, size);
+                               memset(shadowbuf + pos, 0, size);
+                       }
+                       if (pos + size > shadowbuf_size)
+                               shadowbuf_size = pos + size;
+                       break;
+               case 1:
+                       size = rand() % (BUF_TEST_SIZE - buf->used);
+                       if (!zero) {
+                               buffer_append(buf, testdata, size);
+                               memcpy(shadowbuf + shadowbuf_size,
+                                      testdata, size);
+                       } else {
+                               buffer_append_zero(buf, size);
+                               memset(shadowbuf + shadowbuf_size, 0, size);
+                       }
+                       shadowbuf_size += size;
+                       break;
+               case 2:
+                       pos = rand() % (BUF_TEST_SIZE-1);
+                       size = rand() % (BUF_TEST_SIZE - I_MAX(buf->used, pos));
+                       if (!zero) {
+                               buffer_insert(buf, pos, testdata, size);
+                               memmove(shadowbuf + pos + size,
+                                       shadowbuf + pos,
+                                       BUF_TEST_SIZE - (pos + size));
+                               memcpy(shadowbuf + pos, testdata, size);
+                       } else {
+                               buffer_insert_zero(buf, pos, size);
+                               memmove(shadowbuf + pos + size,
+                                       shadowbuf + pos,
+                                       BUF_TEST_SIZE - (pos + size));
+                               memset(shadowbuf + pos, 0, size);
+                       }
+                       if (pos < shadowbuf_size)
+                               shadowbuf_size += size;
+                       else
+                               shadowbuf_size = pos + size;
+                       break;
+               case 3:
+                       pos = rand() % (BUF_TEST_SIZE-1);
+                       size = rand() % (BUF_TEST_SIZE - pos);
+                       buffer_delete(buf, pos, size);
+                       if (pos < shadowbuf_size) {
+                               if (pos + size > shadowbuf_size)
+                                       size = shadowbuf_size - pos;
+                               memmove(shadowbuf + pos,
+                                       shadowbuf + pos + size,
+                                       BUF_TEST_SIZE - (pos + size));
+
+                               shadowbuf_size -= size;
+                               memset(shadowbuf + shadowbuf_size, 0,
+                                      BUF_TEST_SIZE - shadowbuf_size);
+                       }
+                       break;
+               case 4:
+                       if (shadowbuf_size == 0)
+                               break;
+                       pos = rand() % (shadowbuf_size-1); /* dest */
+                       pos2 = rand() % (shadowbuf_size-1); /* source */
+                       size = rand() % (shadowbuf_size - I_MAX(pos, pos2));
+                       buffer_copy(buf, pos, buf, pos2, size);
+                       memmove(shadowbuf + pos,
+                               shadowbuf + pos2, size);
+                       if (pos > pos2 && pos + size > shadowbuf_size)
+                               shadowbuf_size = pos + size;
+                       break;
+               case 5:
+                       pos = rand() % (BUF_TEST_SIZE-1);
+                       size = rand() % (BUF_TEST_SIZE - pos);
+                       p = buffer_get_space_unsafe(buf, pos, size);
+                       memcpy(p, testdata, size);
+                       memcpy(shadowbuf + pos, testdata, size);
+                       if (pos + size > shadowbuf_size)
+                               shadowbuf_size = pos + size;
+                       break;
+               }
+               i_assert(shadowbuf_size <= BUF_TEST_SIZE);
+
+               if (buf->used != shadowbuf_size ||
+                   memcmp(buf->data, shadowbuf, buf->used) != 0)
+                       break;
+       }
+       if (i == BUF_TEST_COUNT)
+               test_out("buffer", TRUE);
+       else {
+               test_out_reason("buffer", FALSE,
+                       t_strdup_printf("round %u test %d failed", i, test));
+       }
+       buffer_free(&buf);
+}
index 838e062ebb1b21fbf832b8ea77224a18d7fc3396..415569b4cea32053e73a15af7d0389bdf2bc5929 100644 (file)
@@ -99,7 +99,7 @@ static void test_istream_crlf(void)
                test_istream_crlf_input(input[i], i);
 }
 
-void test_istreams(void)
+void test_istream(void)
 {
        test_istream_crlf();
 }
index ea19d241ee060c0e76f98e54b54bab147c4ad80c..21cd0bbb78cae4b1b45064e22d96ce6809181558 100644 (file)
 /* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
 
 #include "test-lib.h"
-#include "array.h"
-#include "str.h"
-#include "base64.h"
-#include "bsearch-insert-pos.h"
-#include "aqueue.h"
-#include "network.h"
-#include "primes.h"
-#include "priorityq.h"
-#include "seq-range-array.h"
-#include "str-find.h"
-#include "str-sanitize.h"
-#include "utc-mktime.h"
-
-#include <stdlib.h>
-#include <time.h>
-
-static void test_array(void)
-{
-       ARRAY_DEFINE(intarr, int);
-       int input[] = { -1234567890, -272585721, 2724859223U, 824725652 };
-       const int *output;
-       unsigned int i, j;
-       bool success = TRUE;
-
-       t_array_init(&intarr, 5);
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               array_clear(&intarr);
-               array_append(&intarr, input, i);
-               array_reverse(&intarr);
-
-               output = i == 0 ? NULL : array_idx(&intarr, 0);
-               for (j = 0; j < i; j++) {
-                       if (input[i-j-1] != output[j]) {
-                               success = FALSE;
-                               break;
-                       }
-               }
-       }
-       test_out("array_reverse()", success);
-}
-
-static void test_base64_encode(void)
-{
-       static const char *input[] = {
-               "hello world",
-               "foo barits",
-               "just niin"
-       };
-       static const char *output[] = {
-               "aGVsbG8gd29ybGQ=",
-               "Zm9vIGJhcml0cw==",
-               "anVzdCBuaWlu"
-       };
-       string_t *str, *dest;
-       unsigned int i, j, max;
-       char buf[10];
-       bool success;
-
-       str = t_str_new(256);
-       dest = t_str_new(256);
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               str_truncate(str, 0);
-               base64_encode(input[i], strlen(input[i]), str);
-               success = strcmp(output[i], str_c(str)) == 0;
-               test_out(t_strdup_printf("base64_encode(%d)", i), success);
-       }
-
-       for (i = 0; i < 1000; i++) {
-               max = rand() % sizeof(buf);
-               for (j = 0; j < max; j++)
-                       buf[j] = rand();
-
-               str_truncate(str, 0);
-               str_truncate(dest, 0);
-               base64_encode(buf, max, str);
-               base64_decode(str_data(str), str_len(str), NULL, dest);
-               if (str_len(dest) != max &&
-                   memcmp(buf, str_data(dest), max) != 0)
-                       break;
-       }
-       test_out("base64 random", success);
-}
-
-struct test_base64_decode_output {
-       const char *text;
-       int ret;
-       unsigned int src_pos;
-};
-
-static void test_base64_decode(void)
-{
-       static const char *input[] = {
-               "\taGVsbG8gd29ybGQ=",
-               "\nZm9v\n \tIGJh  \t\ncml0cw==",
-               "  anVzdCBuaWlu  \n",
-               "aGVsb",
-               "aGVsb!!!!!",
-               "aGVs!!!!!"
-       };
-       static const struct test_base64_decode_output output[] = {
-               { "hello world", 0, -1 },
-               { "foo barits", 0, -1 },
-               { "just niin", 1, -1 },
-               { "hel", 1, 4 },
-               { "hel", -1, 4 },
-               { "hel", -1, 4 }
-       };
-       string_t *str;
-       unsigned int i;
-       size_t src_pos;
-       int ret;
-       bool success;
-
-       str = t_str_new(256);
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               str_truncate(str, 0);
-
-               src_pos = 0;
-               ret = base64_decode(input[i], strlen(input[i]), &src_pos, str);
-
-               success = output[i].ret == ret &&
-                       strcmp(output[i].text, str_c(str)) == 0 &&
-                       (src_pos == output[i].src_pos ||
-                        (output[i].src_pos == (unsigned int)-1 &&
-                         src_pos == strlen(input[i])));
-               test_out(t_strdup_printf("base64_decode(%d)", i), success);
-       }
-}
-
-static int cmp_uint(const void *p1, const void *p2)
-{
-       const unsigned int *i1 = p1, *i2 = p2;
-
-       return *i1 - *i2;
-}
-
-static void test_bsearch_insert_pos(void)
-{
-       static const unsigned int input[] = {
-               1, 5, 9, 15, 16, -1,
-               1, 5, 9, 15, 16, 17, -1,
-               -1
-       };
-       static const unsigned int max_key = 18;
-       const unsigned int *cur;
-       unsigned int key, len, i, idx;
-       bool success;
-
-       cur = input;
-       for (i = 0; cur[0] != -1U; i++) {
-               for (len = 0; cur[len] != -1U; len++) ;
-               for (key = 0; key < max_key; key++) {
-                       if (bsearch_insert_pos(&key, cur, len, sizeof(*cur),
-                                              cmp_uint, &idx))
-                               success = cur[idx] == key;
-                       else if (idx == 0)
-                               success = cur[0] > key;
-                       else if (idx == len)
-                               success = cur[len-1] < key;
-                       else {
-                               success = cur[idx-1] < key &&
-                                       cur[idx+1] > key;
-                       }
-                       if (!success)
-                               break;
-               }
-               cur += len + 1;
-
-               test_out(t_strdup_printf("bsearch_insert_pos(%d,%d)", i, key),
-                        success);
-       }
-}
-
-static void test_buffer(void)
-{
-#define BUF_TEST_SIZE (1024*2)
-#define BUF_TEST_COUNT 1000
-       buffer_t *buf;
-       unsigned char *p, testdata[BUF_TEST_SIZE], shadowbuf[BUF_TEST_SIZE];
-       unsigned int i, shadowbuf_size;
-       size_t pos, pos2, size;
-       int test = -1;
-       bool zero;
-
-       buf = buffer_create_dynamic(default_pool, 1);
-       for (i = 0; i < BUF_TEST_SIZE; i++)
-               testdata[i] = random();
-       memset(shadowbuf, 0, sizeof(shadowbuf));
-
-       srand(1);
-       shadowbuf_size = 0;
-       for (i = 0; i < BUF_TEST_COUNT; i++) {
-               if (buf->used == BUF_TEST_SIZE) {
-                       size = shadowbuf_size = rand() % (buf->used - 1);
-                       buffer_set_used_size(buf, size);
-                       memset(shadowbuf + shadowbuf_size, 0,
-                              BUF_TEST_SIZE - shadowbuf_size);
-                       i_assert(buf->used < BUF_TEST_SIZE);
-               }
-
-               test = rand() % 6;
-               zero = rand() % 10 == 0;
-               switch (test) {
-               case 0:
-                       pos = rand() % (BUF_TEST_SIZE-1);
-                       size = rand() % (BUF_TEST_SIZE - pos);
-                       if (!zero) {
-                               buffer_write(buf, pos, testdata, size);
-                               memcpy(shadowbuf + pos, testdata, size);
-                       } else {
-                               buffer_write_zero(buf, pos, size);
-                               memset(shadowbuf + pos, 0, size);
-                       }
-                       if (pos + size > shadowbuf_size)
-                               shadowbuf_size = pos + size;
-                       break;
-               case 1:
-                       size = rand() % (BUF_TEST_SIZE - buf->used);
-                       if (!zero) {
-                               buffer_append(buf, testdata, size);
-                               memcpy(shadowbuf + shadowbuf_size,
-                                      testdata, size);
-                       } else {
-                               buffer_append_zero(buf, size);
-                               memset(shadowbuf + shadowbuf_size, 0, size);
-                       }
-                       shadowbuf_size += size;
-                       break;
-               case 2:
-                       pos = rand() % (BUF_TEST_SIZE-1);
-                       size = rand() % (BUF_TEST_SIZE - I_MAX(buf->used, pos));
-                       if (!zero) {
-                               buffer_insert(buf, pos, testdata, size);
-                               memmove(shadowbuf + pos + size,
-                                       shadowbuf + pos,
-                                       BUF_TEST_SIZE - (pos + size));
-                               memcpy(shadowbuf + pos, testdata, size);
-                       } else {
-                               buffer_insert_zero(buf, pos, size);
-                               memmove(shadowbuf + pos + size,
-                                       shadowbuf + pos,
-                                       BUF_TEST_SIZE - (pos + size));
-                               memset(shadowbuf + pos, 0, size);
-                       }
-                       if (pos < shadowbuf_size)
-                               shadowbuf_size += size;
-                       else
-                               shadowbuf_size = pos + size;
-                       break;
-               case 3:
-                       pos = rand() % (BUF_TEST_SIZE-1);
-                       size = rand() % (BUF_TEST_SIZE - pos);
-                       buffer_delete(buf, pos, size);
-                       if (pos < shadowbuf_size) {
-                               if (pos + size > shadowbuf_size)
-                                       size = shadowbuf_size - pos;
-                               memmove(shadowbuf + pos,
-                                       shadowbuf + pos + size,
-                                       BUF_TEST_SIZE - (pos + size));
-
-                               shadowbuf_size -= size;
-                               memset(shadowbuf + shadowbuf_size, 0,
-                                      BUF_TEST_SIZE - shadowbuf_size);
-                       }
-                       break;
-               case 4:
-                       if (shadowbuf_size == 0)
-                               break;
-                       pos = rand() % (shadowbuf_size-1); /* dest */
-                       pos2 = rand() % (shadowbuf_size-1); /* source */
-                       size = rand() % (shadowbuf_size - I_MAX(pos, pos2));
-                       buffer_copy(buf, pos, buf, pos2, size);
-                       memmove(shadowbuf + pos,
-                               shadowbuf + pos2, size);
-                       if (pos > pos2 && pos + size > shadowbuf_size)
-                               shadowbuf_size = pos + size;
-                       break;
-               case 5:
-                       pos = rand() % (BUF_TEST_SIZE-1);
-                       size = rand() % (BUF_TEST_SIZE - pos);
-                       p = buffer_get_space_unsafe(buf, pos, size);
-                       memcpy(p, testdata, size);
-                       memcpy(shadowbuf + pos, testdata, size);
-                       if (pos + size > shadowbuf_size)
-                               shadowbuf_size = pos + size;
-                       break;
-               }
-               i_assert(shadowbuf_size <= BUF_TEST_SIZE);
-
-               if (buf->used != shadowbuf_size ||
-                   memcmp(buf->data, shadowbuf, buf->used) != 0)
-                       break;
-       }
-       if (i == BUF_TEST_COUNT)
-               test_out("buffer", TRUE);
-       else {
-               test_out_reason("buffer", FALSE,
-                       t_strdup_printf("round %u test %d failed", i, test));
-       }
-       buffer_free(&buf);
-}
-
-static bool aqueue_is_ok(struct aqueue *aqueue, unsigned int deleted_n)
-{
-       const unsigned int *p;
-       unsigned int n, i, count;
-
-       count = aqueue_count(aqueue);
-       for (i = 0, n = 1; i < count; i++, n++) {
-               p = array_idx_i(aqueue->arr, aqueue_idx(aqueue, i));
-               if (i == deleted_n)
-                       n++;
-               if (*p != n)
-                       return FALSE;
-       }
-       return TRUE;
-}
-
-static const unsigned int aqueue_input[] = { 1, 2, 3, 4, 5, 6 };
-static const char *test_aqueue2(unsigned int initial_size)
-{
-       ARRAY_DEFINE(aqueue_array, unsigned int);
-       unsigned int i, j, k;
-       struct aqueue *aqueue;
-
-       for (i = 0; i < N_ELEMENTS(aqueue_input); i++) {
-               for (k = 0; k < N_ELEMENTS(aqueue_input); k++) {
-                       t_array_init(&aqueue_array, initial_size);
-                       aqueue = aqueue_init(&aqueue_array.arr);
-                       aqueue->head = aqueue->tail = initial_size - 1;
-                       for (j = 0; j < k; j++) {
-                               aqueue_append(aqueue, &aqueue_input[j]);
-                               if (aqueue_count(aqueue) != j + 1) {
-                                       return t_strdup_printf("Wrong count after append %u vs %u)",
-                                                              aqueue_count(aqueue), j + 1);
-                               }
-                               if (!aqueue_is_ok(aqueue, -1U))
-                                       return "Invalid data after append";
-                       }
-
-                       if (k != 0 && i < k) {
-                               aqueue_delete(aqueue, i);
-                               if (aqueue_count(aqueue) != k - 1)
-                                       return "Wrong count after delete";
-                               if (!aqueue_is_ok(aqueue, i))
-                                       return "Invalid data after delete";
-                       }
-               }
-       }
-       aqueue_clear(aqueue);
-       if (aqueue_count(aqueue) != 0)
-               return "aqueue_clear() broken";
-       return NULL;
-}
-
-static void test_aqueue(void)
-{
-       unsigned int i;
-       const char *reason = NULL;
-
-       for (i = 1; i <= N_ELEMENTS(aqueue_input) + 1 && reason == NULL; i++) {
-               T_BEGIN {
-                       reason = test_aqueue2(i);
-               } T_END;
-       }
-       test_out_reason("aqueue", reason == NULL, reason);
-}
-
-static bool mem_has_bytes(const void *mem, size_t size, uint8_t b)
-{
-       const uint8_t *bytes = mem;
-       unsigned int i;
-
-       for (i = 0; i < size; i++) {
-               if (bytes[i] != b)
-                       return FALSE;
-       }
-       return TRUE;
-}
-
-static void test_mempool_alloconly(void)
-{
-#define PMALLOC_MAX_COUNT 128
-       pool_t pool;
-       unsigned int i, j, k;
-       void *mem[PMALLOC_MAX_COUNT + 1];
-       bool success = TRUE;
-
-       for (i = 0; i < 64; i++) {
-               for (j = 1; j <= 128; j++) {
-                       pool = pool_alloconly_create(MEMPOOL_GROWING"test", i);
-                       mem[0] = p_malloc(pool, j);
-                       memset(mem[0], j, j);
-
-                       for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
-                               mem[k] = p_malloc(pool, k);
-                               memset(mem[k], k, k);
-                       }
-
-                       if (!mem_has_bytes(mem[0], j, j))
-                               success = FALSE;
-                       for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
-                               if (!mem_has_bytes(mem[k], k, k))
-                                       success = FALSE;
-                       }
-                       pool_unref(&pool);
-               }
-       }
-       test_out("mempool_alloconly", success);
-}
-
-struct test_net_is_in_network_input {
-       const char *ip;
-       const char *net;
-       unsigned int bits;
-       bool ret;
-};
-
-static void test_net_is_in_network(void)
-{
-       static struct test_net_is_in_network_input input[] = {
-               { "1.2.3.4", "1.2.3.4", 32, TRUE },
-               { "1.2.3.4", "1.2.3.3", 32, FALSE },
-               { "1.2.3.4", "1.2.3.5", 32, FALSE },
-               { "1.2.3.4", "1.2.2.4", 32, FALSE },
-               { "1.2.3.4", "1.1.3.4", 32, FALSE },
-               { "1.2.3.4", "0.2.3.4", 32, FALSE },
-               { "1.2.3.253", "1.2.3.254", 31, FALSE },
-               { "1.2.3.254", "1.2.3.254", 31, TRUE },
-               { "1.2.3.255", "1.2.3.254", 31, TRUE },
-               { "1.2.3.255", "1.2.3.0", 24, TRUE },
-               { "1.2.255.255", "1.2.254.0", 23, TRUE },
-               { "255.255.255.255", "128.0.0.0", 1, TRUE },
-               { "255.255.255.255", "127.0.0.0", 1, FALSE }
-#ifdef HAVE_IPV6
-               ,
-               { "1234:5678::abcf", "1234:5678::abce", 127, TRUE },
-               { "1234:5678::abcd", "1234:5678::abce", 127, FALSE },
-               { "123e::ffff", "123e::0", 15, TRUE },
-               { "123d::ffff", "123e::0", 15, FALSE }
-#endif
-       };
-       struct ip_addr ip, net_ip;
-       unsigned int i;
-       bool success;
-
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               net_addr2ip(input[i].ip, &ip);
-               net_addr2ip(input[i].net, &net_ip);
-               success = net_is_in_network(&ip, &net_ip, input[i].bits) ==
-                       input[i].ret;
-               test_out(t_strdup_printf("net_is_in_network(%u)", i), success);
-       }
-}
-
-struct pq_test_item {
-       struct priorityq_item item;
-       int num;
-};
-
-static int cmp_int(const void *p1, const void *p2)
-{
-       const struct pq_test_item *i1 = p1, *i2 = p2;
-
-       return i1->num - i2->num;
-}
-
-static void test_primes(void)
-{
-       unsigned int i, j, num;
-       bool success;
-
-       success = primes_closest(0) > 0;
-       for (num = 1; num < 1024; num++) {
-               if (primes_closest(num) < num)
-                       success = FALSE;
-       }
-       for (i = 10; i < 32; i++) {
-               num = (1 << i) - 100;
-               for (j = 0; j < 200; j++, num++) {
-                       if (primes_closest(num) < num)
-                               success = FALSE;
-               }
-       }
-       test_out("primes_closest()", success);
-}
-
-static void test_priorityq(void)
-{
-#define PQ_MAX_ITEMS 100
-       static const int input[] = {
-               1, 2, 3, 4, 5, 6, 7, 8, -1,
-               8, 7, 6, 5, 4, 3, 2, 1, -1,
-               8, 7, 5, 6, 1, 3, 4, 2, -1,
-               -1
-       };
-       static const int output[] = {
-               1, 2, 3, 4, 5, 6, 7, 8
-       };
-       struct pq_test_item *item, items[PQ_MAX_ITEMS];
-       unsigned int i, j;
-       struct priorityq *pq;
-       pool_t pool;
-       int prev;
-       bool success = TRUE;
-
-       pool = pool_alloconly_create("priorityq items", 1024);
-
-       /* simple tests with popping only */
-       for (i = 0; input[i] != -1; i++) {
-               p_clear(pool);
-               pq = priorityq_init(cmp_int, 1);
-               for (j = 0; input[i] != -1; i++, j++) {
-                       if (priorityq_count(pq) != j)
-                               success = FALSE;
-                       item = p_new(pool, struct pq_test_item, 1);
-                       item->num = input[i];
-                       priorityq_add(pq, &item->item);
-               }
-               for (j = 0; j < N_ELEMENTS(output); j++) {
-                       if (priorityq_count(pq) != N_ELEMENTS(output) - j)
-                               success = FALSE;
-
-                       item = (struct pq_test_item *)priorityq_peek(pq);
-                       if (output[j] != item->num)
-                               success = FALSE;
-                       item = (struct pq_test_item *)priorityq_pop(pq);
-                       if (output[j] != item->num)
-                               success = FALSE;
-               }
-               if (priorityq_count(pq) != 0)
-                       success = FALSE;
-               if (priorityq_peek(pq) != NULL || priorityq_pop(pq) != NULL)
-                       success = FALSE;
-               priorityq_deinit(&pq);
-       }
-       test_out("priorityq(1)", success);
-
-       /* randomized tests, remove elements */
-       success = TRUE;
-       for (i = 0; i < 100; i++) {
-               pq = priorityq_init(cmp_int, 1);
-               for (j = 0; j < PQ_MAX_ITEMS; j++) {
-                       items[j].num = rand();
-                       priorityq_add(pq, &items[j].item);
-               }
-               for (j = 0; j < PQ_MAX_ITEMS; j++) {
-                       if (rand() % 3 == 0) {
-                               priorityq_remove(pq, &items[j].item);
-                               items[j].num = -1;
-                       }
-               }
-               prev = 0;
-               while (priorityq_count(pq) > 0) {
-                       item = (struct pq_test_item *)priorityq_pop(pq);
-                       if (item->num < 0 || prev > item->num)
-                               success = FALSE;
-                       prev = item->num;
-                       item->num = -1;
-               }
-               for (j = 0; j < PQ_MAX_ITEMS; j++) {
-                       if (items[j].num != -1)
-                               success = FALSE;
-               }
-               priorityq_deinit(&pq);
-       }
-       test_out("priorityq(2)", success);
-       pool_unref(&pool);
-}
-
-static void test_seq_range_array_random(void)
-{
-#define SEQ_RANGE_TEST_BUFSIZE 20
-#define SEQ_RANGE_TEST_COUNT 10000
-       unsigned char shadowbuf[SEQ_RANGE_TEST_BUFSIZE];
-       ARRAY_TYPE(seq_range) range;
-       const struct seq_range *seqs;
-       uint32_t seq1, seq2;
-       unsigned int i, j, ret, ret2, count;
-       int test = -1;
-
-       ret = ret2 = 0;
-       i_array_init(&range, 1);
-       memset(shadowbuf, 0, sizeof(shadowbuf));
-       for (i = 0; i < SEQ_RANGE_TEST_COUNT; i++) {
-               seq1 = rand() % SEQ_RANGE_TEST_BUFSIZE;
-               seq2 = seq1 + rand() % (SEQ_RANGE_TEST_BUFSIZE - seq1);
-               test = rand() % 4;
-               switch (test) {
-               case 0:
-                       seq_range_array_add(&range, 0, seq1);
-                       shadowbuf[seq1] = 1;
-                       break;
-               case 1:
-                       seq_range_array_add_range(&range, seq1, seq2);
-                       memset(shadowbuf + seq1, 1, seq2 - seq1 + 1);
-                       break;
-               case 2:
-                       ret = seq_range_array_remove(&range, seq1) ? 1 : 0;
-                       ret2 = shadowbuf[seq1] != 0 ? 1 : 0;
-                       shadowbuf[seq1] = 0;
-                       break;
-               case 3:
-                       ret = seq_range_array_remove_range(&range, seq1, seq2);
-                       for (ret2 = 0; seq1 <= seq2; seq1++) {
-                               if (shadowbuf[seq1] != 0) {
-                                       ret2++;
-                                       shadowbuf[seq1] = 0;
-                               }
-                       }
-                       break;
-               }
-               if (ret != ret2)
-                       break;
-
-               seqs = array_get(&range, &count);
-               for (j = 0, seq1 = 0; j < count; j++) {
-                       if (j > 0 && seqs[j-1].seq2 >= seqs[j].seq1)
-                               goto fail;
-                       for (; seq1 < seqs[j].seq1; seq1++) {
-                               if (shadowbuf[seq1] != 0)
-                                       goto fail;
-                       }
-                       for (; seq1 <= seqs[j].seq2; seq1++) {
-                               if (shadowbuf[seq1] == 0)
-                                       goto fail;
-                       }
-               }
-               i_assert(seq1 <= SEQ_RANGE_TEST_BUFSIZE);
-               for (; seq1 < SEQ_RANGE_TEST_BUFSIZE; seq1++) {
-                       if (shadowbuf[seq1] != 0)
-                               goto fail;
-               }
-       }
-fail:
-       if (i == SEQ_RANGE_TEST_COUNT)
-               test_out("seq_range_array random", TRUE);
-       else {
-               test_out_reason("seq_range_array random", FALSE,
-                       t_strdup_printf("round %u test %d failed", i, test));
-       }
-}
-
-static void test_seq_range_array_invert(void)
-{
-       static const unsigned int input_min = 1, input_max = 5;
-       static const unsigned int input[] = {
-               1, 2, 3, 4, 5, -1U,
-               2, 3, 4, -1U,
-               1, 2, 4, 5, -1U,
-               1, 3, 5, -1U,
-               1, -1U,
-               5, -1U,
-               -1U
-       };
-       ARRAY_TYPE(seq_range) range = ARRAY_INIT;
-       unsigned int i, j, seq, start, num;
-       bool old_exists, success;
-
-       for (i = num = 0; input[i] != -1U; num++, i++) {
-               success = TRUE;
-               start = i;
-               for (; input[i] != -1U; i++) {
-                       seq_range_array_add(&range, 32, input[i]);
-                       for (j = start; j < i; j++) {
-                               if (!seq_range_exists(&range, input[j]))
-                                       success = FALSE;
-                       }
-               }
-
-               seq_range_array_invert(&range, input_min, input_max);
-               for (seq = input_min; seq <= input_max; seq++) {
-                       for (j = start; input[j] != -1U; j++) {
-                               if (input[j] == seq)
-                                       break;
-                       }
-                       old_exists = input[j] != -1U;
-                       if (seq_range_exists(&range, seq) == old_exists)
-                               success = FALSE;
-               }
-               test_out(t_strdup_printf("seq_range_array_invert(%u)", num),
-                        success);
-               array_free(&range);
-       }
-}
-
-static void test_seq_range_create(ARRAY_TYPE(seq_range) *array, uint8_t byte)
-{
-       unsigned int i;
-
-       array_clear(array);
-       for (i = 0; i < 8; i++) {
-               if ((byte & (1 << i)) != 0)
-                       seq_range_array_add(array, 0, i + 1);
-       }
-}
-
-static void test_seq_range_array_have_common(void)
-{
-       ARRAY_TYPE(seq_range) arr1, arr2;
-       unsigned int i, j;
-       bool ret1, ret2, success = TRUE;
-
-       t_array_init(&arr1, 8);
-       t_array_init(&arr2, 8);
-       for (i = 0; i < 256; i++) {
-               test_seq_range_create(&arr1, i);
-               for (j = 0; j < 256; j++) {
-                       test_seq_range_create(&arr2, j);
-                       ret1 = seq_range_array_have_common(&arr1, &arr2);
-                       ret2 = (i & j) != 0;
-                       if (ret1 != ret2)
-                               success = FALSE;
-               }
-       }
-       test_out("seq_range_array_have_common()", success);
-}
-
-static void test_seq_range_array(void)
-{
-       test_seq_range_array_invert();
-       test_seq_range_array_have_common();
-       test_seq_range_array_random();
-}
-
-static const char *str_find_text = "xababcd";
-
-static bool test_str_find_substring(const char *key, int expected_pos)
-{
-       const unsigned char *text = (const unsigned char *)str_find_text;
-       const unsigned int text_len = strlen(str_find_text);
-       struct str_find_context *ctx;
-       unsigned int i, j, pos, max, offset;
-       bool ret;
-
-       ctx = str_find_init(pool_datastack_create(), key);
-       /* divide text into every possible block combination and test that
-          it matches */
-       max = 1 << (text_len-1);
-       for (i = 0; i < max; i++) {
-               str_find_reset(ctx);
-               pos = 0; offset = 0; ret = FALSE;
-               for (j = 0; j < text_len; j++) {
-                       if ((i & (1 << j)) != 0) {
-                               if (str_find_more(ctx, text+pos, j-pos+1)) {
-                                       ret = TRUE;
-                                       break;
-                               }
-                               offset += j-pos + 1;
-                               pos = j + 1;
-                       }
-               }
-               if (pos != text_len && !ret) {
-                       if (str_find_more(ctx, text+pos, j-pos))
-                               ret = TRUE;
-               }
-               if (expected_pos < 0) {
-                       if (ret)
-                               return FALSE;
-               } else {
-                       if (!ret)
-                               return FALSE;
-
-                       pos = str_find_get_match_end_pos(ctx) +
-                               offset - strlen(key);
-                       if ((int)pos != expected_pos)
-                               return FALSE;
-               }
-       }
-       return TRUE;
-}
-
-struct str_find_input {
-       const char *str;
-       int pos;
-};
-static void test_str_find(void)
-{
-       static const char *fail_input[] = {
-               "xabc",
-               "xabd",
-               "abd"
-       };
-       unsigned int idx, len;
-       const char *key, *p;
-       unsigned int i;
-       bool success = TRUE;
-
-       for (idx = 0; idx < strlen(str_find_text); idx++) {
-               for (len = strlen(str_find_text)-idx; len > 0; len--) {
-                       /* we'll get a search key for all substrings of text */
-                       T_BEGIN {
-                               key = t_strndup(str_find_text + idx, len);
-                               p = strstr(str_find_text, key);
-                               success = test_str_find_substring(key, p - str_find_text);
-                       } T_END;
-                       if (!success)
-                               break;
-               }
-       }
-       for (i = 0; i < N_ELEMENTS(fail_input) && success; i++)
-               success = test_str_find_substring(fail_input[i], -1);
-       test_out("str_find()", success);
-}
-
-struct str_sanitize_input {
-       const char *str;
-       unsigned int max_len;
-};
-static void test_str_sanitize(void)
-{
-       static struct str_sanitize_input input[] = {
-               { NULL, 2 },
-               { "", 2 },
-               { "a", 2 },
-               { "ab", 2 },
-               { "abc", 2 },
-               { "abcd", 3 },
-               { "abcde", 4 }
-       };
-       static const char *output[] = {
-               NULL,
-               "",
-               "a",
-               "ab",
-               "...",
-               "...",
-               "a..."
-       };
-       const char *str;
-       unsigned int i;
-       bool success;
-
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               str = str_sanitize(input[i].str, input[i].max_len);
-               success = null_strcmp(output[i], str) == 0;
-               test_out(t_strdup_printf("str_sanitize(%d)", i), success);
-       }
-}
-
-struct test_message_date_output {
-       time_t time;
-       int tz_offset;
-       bool ret;
-};
-
-struct test_utc_mktime_input {
-       int year, month, day, hour, min, sec;
-};
-
-static void test_utc_mktime(void)
-{
-       static struct test_utc_mktime_input input[] = {
-#ifdef TIME_T_SIGNED
-               { 1969, 12, 31, 23, 59, 59 },
-               { 1901, 12, 13, 20, 45, 53 },
-#endif
-#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
-               { 2106, 2, 7, 6, 28, 15 },
-#endif
-               { 2007, 11, 7, 1, 7, 20 },
-               { 1970, 1, 1, 0, 0, 0 },
-               { 2038, 1, 19, 3, 14, 7 }
-       };
-       static time_t output[] = {
-#ifdef TIME_T_SIGNED
-               -1,
-               -2147483647,
-#endif
-#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
-               4294967295,
-#endif
-               1194397640,
-               0,
-               2147483647
-       };
-       struct tm tm;
-       unsigned int i;
-       time_t t;
-       bool success;
-
-       for (i = 0; i < N_ELEMENTS(input); i++) {
-               memset(&tm, 0, sizeof(tm));
-               tm.tm_year = input[i].year - 1900;
-               tm.tm_mon = input[i].month - 1;
-               tm.tm_mday = input[i].day;
-               tm.tm_hour = input[i].hour;
-               tm.tm_min = input[i].min;
-               tm.tm_sec = input[i].sec;
-
-               t = utc_mktime(&tm);
-               success = t == output[i];
-               test_out_reason(t_strdup_printf("utc_mktime(%d)", i), success,
-                               success ? NULL : t_strdup_printf("%ld != %ld",
-                                                    (long)t, (long)output[i]));
-       }
-}
 
 int main(void)
 {
        static void (*test_functions[])(void) = {
-               test_array,
                test_aqueue,
-               test_base64_encode,
-               test_base64_decode,
+               test_array,
+               test_base64,
                test_bsearch_insert_pos,
                test_buffer,
+               test_istream,
                test_mempool_alloconly,
-               test_net_is_in_network,
+               test_network,
                test_primes,
                test_priorityq,
                test_seq_range_array,
                test_str_find,
                test_str_sanitize,
                test_utc_mktime,
-
-               test_istreams
+               NULL
        };
        return test_run(test_functions);
 }
index 6941541862b60f6816bdae240de762275b9a94cf..97c1b9686a99a4cfc66f90456ae417db530e9930 100644 (file)
@@ -1,4 +1,22 @@
+#ifndef TEST_LIB
+#define TEST_LIB
+
 #include "lib.h"
 #include "test-common.h"
 
-void test_istreams(void);
+void test_aqueue(void);
+void test_array(void);
+void test_base64(void);
+void test_bsearch_insert_pos(void);
+void test_buffer(void);
+void test_istream(void);
+void test_mempool_alloconly(void);
+void test_network(void);
+void test_primes(void);
+void test_priorityq(void);
+void test_seq_range_array(void);
+void test_str_find(void);
+void test_str_sanitize(void);
+void test_utc_mktime(void);
+
+#endif
diff --git a/src/lib/test-mempool-alloconly.c b/src/lib/test-mempool-alloconly.c
new file mode 100644 (file)
index 0000000..a03015e
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+
+static bool mem_has_bytes(const void *mem, size_t size, uint8_t b)
+{
+       const uint8_t *bytes = mem;
+       unsigned int i;
+
+       for (i = 0; i < size; i++) {
+               if (bytes[i] != b)
+                       return FALSE;
+       }
+       return TRUE;
+}
+
+void test_mempool_alloconly(void)
+{
+#define PMALLOC_MAX_COUNT 128
+       pool_t pool;
+       unsigned int i, j, k;
+       void *mem[PMALLOC_MAX_COUNT + 1];
+       bool success = TRUE;
+
+       for (i = 0; i < 64; i++) {
+               for (j = 1; j <= 128; j++) {
+                       pool = pool_alloconly_create(MEMPOOL_GROWING"test", i);
+                       mem[0] = p_malloc(pool, j);
+                       memset(mem[0], j, j);
+
+                       for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
+                               mem[k] = p_malloc(pool, k);
+                               memset(mem[k], k, k);
+                       }
+
+                       if (!mem_has_bytes(mem[0], j, j))
+                               success = FALSE;
+                       for (k = 1; k <= PMALLOC_MAX_COUNT; k++) {
+                               if (!mem_has_bytes(mem[k], k, k))
+                                       success = FALSE;
+                       }
+                       pool_unref(&pool);
+               }
+       }
+       test_out("mempool_alloconly", success);
+}
diff --git a/src/lib/test-network.c b/src/lib/test-network.c
new file mode 100644 (file)
index 0000000..861b0d1
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "network.h"
+
+struct test_net_is_in_network_input {
+       const char *ip;
+       const char *net;
+       unsigned int bits;
+       bool ret;
+};
+
+static void test_net_is_in_network(void)
+{
+       static struct test_net_is_in_network_input input[] = {
+               { "1.2.3.4", "1.2.3.4", 32, TRUE },
+               { "1.2.3.4", "1.2.3.3", 32, FALSE },
+               { "1.2.3.4", "1.2.3.5", 32, FALSE },
+               { "1.2.3.4", "1.2.2.4", 32, FALSE },
+               { "1.2.3.4", "1.1.3.4", 32, FALSE },
+               { "1.2.3.4", "0.2.3.4", 32, FALSE },
+               { "1.2.3.253", "1.2.3.254", 31, FALSE },
+               { "1.2.3.254", "1.2.3.254", 31, TRUE },
+               { "1.2.3.255", "1.2.3.254", 31, TRUE },
+               { "1.2.3.255", "1.2.3.0", 24, TRUE },
+               { "1.2.255.255", "1.2.254.0", 23, TRUE },
+               { "255.255.255.255", "128.0.0.0", 1, TRUE },
+               { "255.255.255.255", "127.0.0.0", 1, FALSE }
+#ifdef HAVE_IPV6
+               ,
+               { "1234:5678::abcf", "1234:5678::abce", 127, TRUE },
+               { "1234:5678::abcd", "1234:5678::abce", 127, FALSE },
+               { "123e::ffff", "123e::0", 15, TRUE },
+               { "123d::ffff", "123e::0", 15, FALSE }
+#endif
+       };
+       struct ip_addr ip, net_ip;
+       unsigned int i;
+       bool success;
+
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               net_addr2ip(input[i].ip, &ip);
+               net_addr2ip(input[i].net, &net_ip);
+               success = net_is_in_network(&ip, &net_ip, input[i].bits) ==
+                       input[i].ret;
+               test_out(t_strdup_printf("net_is_in_network(%u)", i), success);
+       }
+}
+
+void test_network(void)
+{
+       test_net_is_in_network();
+}
diff --git a/src/lib/test-primes.c b/src/lib/test-primes.c
new file mode 100644 (file)
index 0000000..e4c05a1
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "primes.h"
+
+void test_primes(void)
+{
+       unsigned int i, j, num;
+       bool success;
+
+       success = primes_closest(0) > 0;
+       for (num = 1; num < 1024; num++) {
+               if (primes_closest(num) < num)
+                       success = FALSE;
+       }
+       for (i = 10; i < 32; i++) {
+               num = (1 << i) - 100;
+               for (j = 0; j < 200; j++, num++) {
+                       if (primes_closest(num) < num)
+                               success = FALSE;
+               }
+       }
+       test_out("primes_closest()", success);
+}
diff --git a/src/lib/test-priorityq.c b/src/lib/test-priorityq.c
new file mode 100644 (file)
index 0000000..686b7ac
--- /dev/null
@@ -0,0 +1,101 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "priorityq.h"
+
+#include <stdlib.h>
+
+struct pq_test_item {
+       struct priorityq_item item;
+       int num;
+};
+
+static int cmp_int(const void *p1, const void *p2)
+{
+       const struct pq_test_item *i1 = p1, *i2 = p2;
+
+       return i1->num - i2->num;
+}
+
+void test_priorityq(void)
+{
+#define PQ_MAX_ITEMS 100
+       static const int input[] = {
+               1, 2, 3, 4, 5, 6, 7, 8, -1,
+               8, 7, 6, 5, 4, 3, 2, 1, -1,
+               8, 7, 5, 6, 1, 3, 4, 2, -1,
+               -1
+       };
+       static const int output[] = {
+               1, 2, 3, 4, 5, 6, 7, 8
+       };
+       struct pq_test_item *item, items[PQ_MAX_ITEMS];
+       unsigned int i, j;
+       struct priorityq *pq;
+       pool_t pool;
+       int prev;
+       bool success = TRUE;
+
+       pool = pool_alloconly_create("priorityq items", 1024);
+
+       /* simple tests with popping only */
+       for (i = 0; input[i] != -1; i++) {
+               p_clear(pool);
+               pq = priorityq_init(cmp_int, 1);
+               for (j = 0; input[i] != -1; i++, j++) {
+                       if (priorityq_count(pq) != j)
+                               success = FALSE;
+                       item = p_new(pool, struct pq_test_item, 1);
+                       item->num = input[i];
+                       priorityq_add(pq, &item->item);
+               }
+               for (j = 0; j < N_ELEMENTS(output); j++) {
+                       if (priorityq_count(pq) != N_ELEMENTS(output) - j)
+                               success = FALSE;
+
+                       item = (struct pq_test_item *)priorityq_peek(pq);
+                       if (output[j] != item->num)
+                               success = FALSE;
+                       item = (struct pq_test_item *)priorityq_pop(pq);
+                       if (output[j] != item->num)
+                               success = FALSE;
+               }
+               if (priorityq_count(pq) != 0)
+                       success = FALSE;
+               if (priorityq_peek(pq) != NULL || priorityq_pop(pq) != NULL)
+                       success = FALSE;
+               priorityq_deinit(&pq);
+       }
+       test_out("priorityq(1)", success);
+
+       /* randomized tests, remove elements */
+       success = TRUE;
+       for (i = 0; i < 100; i++) {
+               pq = priorityq_init(cmp_int, 1);
+               for (j = 0; j < PQ_MAX_ITEMS; j++) {
+                       items[j].num = rand();
+                       priorityq_add(pq, &items[j].item);
+               }
+               for (j = 0; j < PQ_MAX_ITEMS; j++) {
+                       if (rand() % 3 == 0) {
+                               priorityq_remove(pq, &items[j].item);
+                               items[j].num = -1;
+                       }
+               }
+               prev = 0;
+               while (priorityq_count(pq) > 0) {
+                       item = (struct pq_test_item *)priorityq_pop(pq);
+                       if (item->num < 0 || prev > item->num)
+                               success = FALSE;
+                       prev = item->num;
+                       item->num = -1;
+               }
+               for (j = 0; j < PQ_MAX_ITEMS; j++) {
+                       if (items[j].num != -1)
+                               success = FALSE;
+               }
+               priorityq_deinit(&pq);
+       }
+       test_out("priorityq(2)", success);
+       pool_unref(&pool);
+}
diff --git a/src/lib/test-seq-range-array.c b/src/lib/test-seq-range-array.c
new file mode 100644 (file)
index 0000000..a6a022a
--- /dev/null
@@ -0,0 +1,162 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "array.h"
+#include "seq-range-array.h"
+
+#include <stdlib.h>
+
+static void test_seq_range_array_random(void)
+{
+#define SEQ_RANGE_TEST_BUFSIZE 20
+#define SEQ_RANGE_TEST_COUNT 10000
+       unsigned char shadowbuf[SEQ_RANGE_TEST_BUFSIZE];
+       ARRAY_TYPE(seq_range) range;
+       const struct seq_range *seqs;
+       uint32_t seq1, seq2;
+       unsigned int i, j, ret, ret2, count;
+       int test = -1;
+
+       ret = ret2 = 0;
+       i_array_init(&range, 1);
+       memset(shadowbuf, 0, sizeof(shadowbuf));
+       for (i = 0; i < SEQ_RANGE_TEST_COUNT; i++) {
+               seq1 = rand() % SEQ_RANGE_TEST_BUFSIZE;
+               seq2 = seq1 + rand() % (SEQ_RANGE_TEST_BUFSIZE - seq1);
+               test = rand() % 4;
+               switch (test) {
+               case 0:
+                       seq_range_array_add(&range, 0, seq1);
+                       shadowbuf[seq1] = 1;
+                       break;
+               case 1:
+                       seq_range_array_add_range(&range, seq1, seq2);
+                       memset(shadowbuf + seq1, 1, seq2 - seq1 + 1);
+                       break;
+               case 2:
+                       ret = seq_range_array_remove(&range, seq1) ? 1 : 0;
+                       ret2 = shadowbuf[seq1] != 0 ? 1 : 0;
+                       shadowbuf[seq1] = 0;
+                       break;
+               case 3:
+                       ret = seq_range_array_remove_range(&range, seq1, seq2);
+                       for (ret2 = 0; seq1 <= seq2; seq1++) {
+                               if (shadowbuf[seq1] != 0) {
+                                       ret2++;
+                                       shadowbuf[seq1] = 0;
+                               }
+                       }
+                       break;
+               }
+               if (ret != ret2)
+                       break;
+
+               seqs = array_get(&range, &count);
+               for (j = 0, seq1 = 0; j < count; j++) {
+                       if (j > 0 && seqs[j-1].seq2 >= seqs[j].seq1)
+                               goto fail;
+                       for (; seq1 < seqs[j].seq1; seq1++) {
+                               if (shadowbuf[seq1] != 0)
+                                       goto fail;
+                       }
+                       for (; seq1 <= seqs[j].seq2; seq1++) {
+                               if (shadowbuf[seq1] == 0)
+                                       goto fail;
+                       }
+               }
+               i_assert(seq1 <= SEQ_RANGE_TEST_BUFSIZE);
+               for (; seq1 < SEQ_RANGE_TEST_BUFSIZE; seq1++) {
+                       if (shadowbuf[seq1] != 0)
+                               goto fail;
+               }
+       }
+fail:
+       if (i == SEQ_RANGE_TEST_COUNT)
+               test_out("seq_range_array random", TRUE);
+       else {
+               test_out_reason("seq_range_array random", FALSE,
+                       t_strdup_printf("round %u test %d failed", i, test));
+       }
+}
+
+static void test_seq_range_array_invert(void)
+{
+       static const unsigned int input_min = 1, input_max = 5;
+       static const unsigned int input[] = {
+               1, 2, 3, 4, 5, -1U,
+               2, 3, 4, -1U,
+               1, 2, 4, 5, -1U,
+               1, 3, 5, -1U,
+               1, -1U,
+               5, -1U,
+               -1U
+       };
+       ARRAY_TYPE(seq_range) range = ARRAY_INIT;
+       unsigned int i, j, seq, start, num;
+       bool old_exists, success;
+
+       for (i = num = 0; input[i] != -1U; num++, i++) {
+               success = TRUE;
+               start = i;
+               for (; input[i] != -1U; i++) {
+                       seq_range_array_add(&range, 32, input[i]);
+                       for (j = start; j < i; j++) {
+                               if (!seq_range_exists(&range, input[j]))
+                                       success = FALSE;
+                       }
+               }
+
+               seq_range_array_invert(&range, input_min, input_max);
+               for (seq = input_min; seq <= input_max; seq++) {
+                       for (j = start; input[j] != -1U; j++) {
+                               if (input[j] == seq)
+                                       break;
+                       }
+                       old_exists = input[j] != -1U;
+                       if (seq_range_exists(&range, seq) == old_exists)
+                               success = FALSE;
+               }
+               test_out(t_strdup_printf("seq_range_array_invert(%u)", num),
+                        success);
+               array_free(&range);
+       }
+}
+
+static void test_seq_range_create(ARRAY_TYPE(seq_range) *array, uint8_t byte)
+{
+       unsigned int i;
+
+       array_clear(array);
+       for (i = 0; i < 8; i++) {
+               if ((byte & (1 << i)) != 0)
+                       seq_range_array_add(array, 0, i + 1);
+       }
+}
+
+static void test_seq_range_array_have_common(void)
+{
+       ARRAY_TYPE(seq_range) arr1, arr2;
+       unsigned int i, j;
+       bool ret1, ret2, success = TRUE;
+
+       t_array_init(&arr1, 8);
+       t_array_init(&arr2, 8);
+       for (i = 0; i < 256; i++) {
+               test_seq_range_create(&arr1, i);
+               for (j = 0; j < 256; j++) {
+                       test_seq_range_create(&arr2, j);
+                       ret1 = seq_range_array_have_common(&arr1, &arr2);
+                       ret2 = (i & j) != 0;
+                       if (ret1 != ret2)
+                               success = FALSE;
+               }
+       }
+       test_out("seq_range_array_have_common()", success);
+}
+
+void test_seq_range_array(void)
+{
+       test_seq_range_array_invert();
+       test_seq_range_array_have_common();
+       test_seq_range_array_random();
+}
diff --git a/src/lib/test-str-find.c b/src/lib/test-str-find.c
new file mode 100644 (file)
index 0000000..d3247d2
--- /dev/null
@@ -0,0 +1,85 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str-find.h"
+
+static const char *str_find_text = "xababcd";
+
+static bool test_str_find_substring(const char *key, int expected_pos)
+{
+       const unsigned char *text = (const unsigned char *)str_find_text;
+       const unsigned int text_len = strlen(str_find_text);
+       struct str_find_context *ctx;
+       unsigned int i, j, pos, max, offset;
+       bool ret;
+
+       ctx = str_find_init(pool_datastack_create(), key);
+       /* divide text into every possible block combination and test that
+          it matches */
+       max = 1 << (text_len-1);
+       for (i = 0; i < max; i++) {
+               str_find_reset(ctx);
+               pos = 0; offset = 0; ret = FALSE;
+               for (j = 0; j < text_len; j++) {
+                       if ((i & (1 << j)) != 0) {
+                               if (str_find_more(ctx, text+pos, j-pos+1)) {
+                                       ret = TRUE;
+                                       break;
+                               }
+                               offset += j-pos + 1;
+                               pos = j + 1;
+                       }
+               }
+               if (pos != text_len && !ret) {
+                       if (str_find_more(ctx, text+pos, j-pos))
+                               ret = TRUE;
+               }
+               if (expected_pos < 0) {
+                       if (ret)
+                               return FALSE;
+               } else {
+                       if (!ret)
+                               return FALSE;
+
+                       pos = str_find_get_match_end_pos(ctx) +
+                               offset - strlen(key);
+                       if ((int)pos != expected_pos)
+                               return FALSE;
+               }
+       }
+       return TRUE;
+}
+
+struct str_find_input {
+       const char *str;
+       int pos;
+};
+
+void test_str_find(void)
+{
+       static const char *fail_input[] = {
+               "xabc",
+               "xabd",
+               "abd"
+       };
+       unsigned int idx, len;
+       const char *key, *p;
+       unsigned int i;
+       bool success = TRUE;
+
+       for (idx = 0; idx < strlen(str_find_text); idx++) {
+               for (len = strlen(str_find_text)-idx; len > 0; len--) {
+                       /* we'll get a search key for all substrings of text */
+                       T_BEGIN {
+                               key = t_strndup(str_find_text + idx, len);
+                               p = strstr(str_find_text, key);
+                               success = test_str_find_substring(key, p - str_find_text);
+                       } T_END;
+                       if (!success)
+                               break;
+               }
+       }
+       for (i = 0; i < N_ELEMENTS(fail_input) && success; i++)
+               success = test_str_find_substring(fail_input[i], -1);
+       test_out("str_find()", success);
+}
diff --git a/src/lib/test-str-sanitize.c b/src/lib/test-str-sanitize.c
new file mode 100644 (file)
index 0000000..8a5033c
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str-sanitize.h"
+
+struct str_sanitize_input {
+       const char *str;
+       unsigned int max_len;
+};
+
+void test_str_sanitize(void)
+{
+       static struct str_sanitize_input input[] = {
+               { NULL, 2 },
+               { "", 2 },
+               { "a", 2 },
+               { "ab", 2 },
+               { "abc", 2 },
+               { "abcd", 3 },
+               { "abcde", 4 }
+       };
+       static const char *output[] = {
+               NULL,
+               "",
+               "a",
+               "ab",
+               "...",
+               "...",
+               "a..."
+       };
+       const char *str;
+       unsigned int i;
+       bool success;
+
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               str = str_sanitize(input[i].str, input[i].max_len);
+               success = null_strcmp(output[i], str) == 0;
+               test_out(t_strdup_printf("str_sanitize(%d)", i), success);
+       }
+}
diff --git a/src/lib/test-utc-mktime.c b/src/lib/test-utc-mktime.c
new file mode 100644 (file)
index 0000000..f4aafc0
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "utc-mktime.h"
+
+struct test_utc_mktime_input {
+       int year, month, day, hour, min, sec;
+};
+
+void test_utc_mktime(void)
+{
+       static struct test_utc_mktime_input input[] = {
+#ifdef TIME_T_SIGNED
+               { 1969, 12, 31, 23, 59, 59 },
+               { 1901, 12, 13, 20, 45, 53 },
+#endif
+#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
+               { 2106, 2, 7, 6, 28, 15 },
+#endif
+               { 2007, 11, 7, 1, 7, 20 },
+               { 1970, 1, 1, 0, 0, 0 },
+               { 2038, 1, 19, 3, 14, 7 }
+       };
+       static time_t output[] = {
+#ifdef TIME_T_SIGNED
+               -1,
+               -2147483647,
+#endif
+#if (TIME_T_MAX_BITS > 32 || !defined(TIME_T_SIGNED))
+               4294967295,
+#endif
+               1194397640,
+               0,
+               2147483647
+       };
+       struct tm tm;
+       unsigned int i;
+       time_t t;
+       bool success;
+
+       for (i = 0; i < N_ELEMENTS(input); i++) {
+               memset(&tm, 0, sizeof(tm));
+               tm.tm_year = input[i].year - 1900;
+               tm.tm_mon = input[i].month - 1;
+               tm.tm_mday = input[i].day;
+               tm.tm_hour = input[i].hour;
+               tm.tm_min = input[i].min;
+               tm.tm_sec = input[i].sec;
+
+               t = utc_mktime(&tm);
+               success = t == output[i];
+               test_out_reason(t_strdup_printf("utc_mktime(%d)", i), success,
+                               success ? NULL : t_strdup_printf("%ld != %ld",
+                                                    (long)t, (long)output[i]));
+       }
+}