summaryrefslogtreecommitdiffstats
path: root/src/lib/test-istream-tee.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test-istream-tee.c')
-rw-r--r--src/lib/test-istream-tee.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/lib/test-istream-tee.c b/src/lib/test-istream-tee.c
new file mode 100644
index 0000000..53e9a0c
--- /dev/null
+++ b/src/lib/test-istream-tee.c
@@ -0,0 +1,139 @@
+/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str.h"
+#include "istream-private.h"
+#include "istream-tee.h"
+
+
+#define TEST_BUF_SIZE I_STREAM_MIN_SIZE
+#define TEST_STR_LEN (TEST_BUF_SIZE*3)
+#define CHILD_COUNT 5
+
+static void test_istream_tee_tailing(const char *str)
+{
+ struct istream *test_input, *child_input[CHILD_COUNT];
+ struct tee_istream *tee;
+ unsigned int i, len, delta;
+
+ test_input = test_istream_create(str);
+ test_istream_set_max_buffer_size(test_input, TEST_BUF_SIZE);
+
+ test_begin("istream tee tailing");
+ tee = tee_i_stream_create(test_input);
+ for (i = 0; i < CHILD_COUNT; i++)
+ child_input[i] = tee_i_stream_create_child(tee);
+
+ test_istream_set_allow_eof(test_input, FALSE);
+ delta = 1;
+ for (len = 1; len < TEST_BUF_SIZE; len += delta) {
+ test_istream_set_size(test_input, len);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert_idx(i_stream_read(child_input[i]) == (int)delta, len);
+ test_assert_idx(!tee_i_stream_child_is_waiting(child_input[i]), len);
+ test_assert_idx(i_stream_read(child_input[i]) == 0, len);
+ test_assert_idx(!tee_i_stream_child_is_waiting(child_input[i]), len);
+ }
+ delta = i_rand_limit(32); /* may stand still */
+ if(delta > TEST_BUF_SIZE - len)
+ delta = 1;
+ }
+
+ test_istream_set_size(test_input, len);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert(i_stream_read(child_input[i]) == (int)delta);
+ test_assert(i_stream_read(child_input[i]) == -2);
+ test_assert(!tee_i_stream_child_is_waiting(child_input[i]));
+ }
+
+ delta = 1;
+ while ((len += delta) <= TEST_STR_LEN) {
+ unsigned int lagger = i_rand_limit(CHILD_COUNT);
+ test_istream_set_size(test_input, len);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert(i_stream_read(child_input[i]) == -2);
+ test_assert(!tee_i_stream_child_is_waiting(child_input[i]));
+ }
+ for (i = 0; i < CHILD_COUNT; i++) {
+ if (i == lagger)
+ continue;
+ i_stream_skip(child_input[i], delta);
+ test_assert(i_stream_read(child_input[i]) == 0);
+ test_assert(tee_i_stream_child_is_waiting(child_input[i]));
+ }
+ i_stream_skip(child_input[lagger], delta);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert(i_stream_read(child_input[i]) == (int)delta);
+ test_assert(i_stream_read(child_input[i]) == -2);
+ test_assert(!tee_i_stream_child_is_waiting(child_input[i]));
+ }
+ delta = i_rand_minmax(1, 31); /* mustn't stand still */
+ if(delta > TEST_STR_LEN - len)
+ delta = 1;
+ }
+
+ for (i = 0; i < CHILD_COUNT-1; i++) {
+ i_stream_skip(child_input[i], 1);
+ test_assert(i_stream_read(child_input[i]) == 0);
+ test_assert(tee_i_stream_child_is_waiting(child_input[i]));
+ }
+ i_stream_skip(child_input[i], 1);
+ test_assert(i_stream_read(child_input[i]) == 0);
+ test_assert(!tee_i_stream_child_is_waiting(child_input[i]));
+
+ test_istream_set_allow_eof(test_input, TRUE);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert(i_stream_read(child_input[i]) == -1);
+ i_stream_unref(&child_input[i]);
+ }
+ i_stream_unref(&test_input);
+
+ test_end();
+}
+
+static void test_istream_tee_blocks(const char *str)
+{
+ struct istream *test_input, *child_input[CHILD_COUNT];
+ struct tee_istream *tee;
+ unsigned int i, j;
+
+ test_input = test_istream_create(str);
+ test_istream_set_max_buffer_size(test_input, TEST_BUF_SIZE);
+
+ test_begin("istream tee blocks");
+ tee = tee_i_stream_create(test_input);
+ for (i = 0; i < CHILD_COUNT; i++)
+ child_input[i] = tee_i_stream_create_child(tee);
+
+ test_istream_set_allow_eof(test_input, FALSE);
+ for (j = 1; j <= 3; j++) {
+ test_istream_set_size(test_input, TEST_BUF_SIZE*j);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert(i_stream_read(child_input[i]) == TEST_BUF_SIZE);
+ i_stream_skip(child_input[i], TEST_BUF_SIZE);
+ }
+ }
+ test_istream_set_allow_eof(test_input, TRUE);
+ for (i = 0; i < CHILD_COUNT; i++) {
+ test_assert(i_stream_read(child_input[i]) == -1);
+ i_stream_unref(&child_input[i]);
+ }
+ i_stream_unref(&test_input);
+
+ test_end();
+}
+
+void test_istream_tee(void)
+{
+ string_t *str;
+ unsigned int i;
+
+ str = str_new(default_pool, TEST_STR_LEN);
+ for (i = 0; i < TEST_STR_LEN; i++)
+ str_append_c(str, 'a' + i%26);
+
+ test_istream_tee_tailing(str_c(str));
+ test_istream_tee_blocks(str_c(str));
+
+ str_free(&str);
+}