summaryrefslogtreecommitdiffstats
path: root/src/lib/test-istream-try.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test-istream-try.c')
-rw-r--r--src/lib/test-istream-try.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/lib/test-istream-try.c b/src/lib/test-istream-try.c
new file mode 100644
index 0000000..888e00f
--- /dev/null
+++ b/src/lib/test-istream-try.c
@@ -0,0 +1,195 @@
+/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "istream-private.h"
+#include "istream-base64.h"
+#include "istream-try.h"
+
+#define MIN_FULL_SIZE 1
+
+static void test_istream_try_normal(void)
+{
+ bool finished = FALSE;
+
+ test_begin("istream try");
+ for (unsigned int test = 0; test <= 10; test++) {
+ struct istream *test_inputs[3], *try_input;
+
+ test_inputs[0] = test_istream_create("1");
+ test_inputs[1] = test_istream_create("2");
+ test_inputs[2] = NULL;
+ test_istream_set_size(test_inputs[0], 0);
+ test_istream_set_size(test_inputs[1], 0);
+ try_input = istream_try_create(test_inputs, MIN_FULL_SIZE);
+
+ /* nonblocking read */
+ test_assert_idx(i_stream_read(try_input) == 0, test);
+
+ switch (test) {
+ case 0:
+ /* stream 0 is available */
+ test_istream_set_size(test_inputs[0], 1);
+ test_assert_idx(i_stream_read(try_input) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+ break;
+ case 1:
+ /* stream 1 is available, but not used before 0 */
+ test_istream_set_size(test_inputs[1], 1);
+ test_assert_idx(i_stream_read(try_input) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+ /* continue failing stream 0 -> 1 is available */
+ test_inputs[0]->stream_errno = EINVAL;
+ test_assert_idx(i_stream_read(try_input) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 1, test);
+ break;
+ case 2:
+ /* both streams are available - stream 0 is read */
+ test_istream_set_size(test_inputs[0], 1);
+ test_istream_set_size(test_inputs[1], 1);
+ test_assert_idx(i_stream_read(try_input) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+ break;
+ case 3:
+ /* stream 0 fails */
+ test_inputs[0]->stream_errno = EINVAL;
+ test_assert_idx(i_stream_read(try_input) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+ /* continue making stream 1 available */
+ test_istream_set_size(test_inputs[1], 1);
+ test_assert_idx(i_stream_read(try_input) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 1, test);
+ break;
+ case 4:
+ /* stream 1 fails */
+ test_inputs[1]->stream_errno = EINVAL;
+ test_assert_idx(i_stream_read(try_input) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+ break;
+ case 5:
+ /* stream 0 fails, stream 1 is available */
+ test_inputs[0]->stream_errno = EINVAL;
+ test_istream_set_size(test_inputs[1], 1);
+ test_assert_idx(i_stream_read(try_input) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 0, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 1, test);
+ break;
+ case 6:
+ /* stream 0 is available, stream 1 fails */
+ test_inputs[1]->stream_errno = EINVAL;
+ test_istream_set_size(test_inputs[0], 1);
+ test_assert_idx(i_stream_read(try_input) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[0]) == 1, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+ break;
+ case 7:
+ /* both streams fail */
+ test_inputs[0]->stream_errno = EINVAL;
+ test_inputs[1]->stream_errno = EINVAL;
+ test_assert_idx(i_stream_read(try_input) == -1, test);
+ test_assert_idx(try_input->stream_errno == EINVAL, test);
+ break;
+ case 8:
+ /* stream 0 fails with EINVAL, stream 1 with EIO */
+ test_inputs[0]->stream_errno = EINVAL;
+ test_inputs[1]->stream_errno = EIO;
+ test_assert_idx(i_stream_read(try_input) == -1, test);
+ test_assert_idx(try_input->stream_errno == EIO, test);
+ break;
+ case 9:
+ /* stream 0 fails with EIO, stream 1 with EINVAL */
+ test_inputs[0]->stream_errno = EIO;
+ test_inputs[1]->stream_errno = EINVAL;
+ test_assert_idx(i_stream_read(try_input) == -1, test);
+ test_assert_idx(try_input->stream_errno == EIO, test);
+ break;
+ case 10:
+ /* stream 0 fails with EIO, stream 1 would work.. */
+ test_inputs[0]->stream_errno = EIO;
+ test_istream_set_size(test_inputs[1], 1);
+ test_assert_idx(i_stream_read(try_input) == -1, test);
+ test_assert_idx(try_input->stream_errno == EIO, test);
+ test_assert_idx(i_stream_get_data_size(test_inputs[1]) == 0, test);
+
+ finished = TRUE;
+ break;
+ }
+
+ test_assert_idx(test_inputs[0]->v_offset == 0, test);
+ test_assert_idx(test_inputs[1]->v_offset == 0, test);
+
+ i_stream_unref(&test_inputs[0]);
+ i_stream_unref(&test_inputs[1]);
+ i_stream_unref(&try_input);
+ }
+ i_assert(finished);
+ test_end();
+}
+
+static void test_istream_try_empty(void)
+{
+ test_begin("istream try empty stream");
+ struct istream *test_inputs[] = {
+ test_istream_create(""),
+ test_istream_create(""),
+ NULL
+ };
+ struct istream *try_input =
+ istream_try_create(test_inputs, MIN_FULL_SIZE);
+ test_assert(i_stream_read(try_input) == -1);
+ test_assert(try_input->eof);
+ test_assert(try_input->stream_errno == 0);
+ i_stream_unref(&test_inputs[0]);
+ i_stream_unref(&test_inputs[1]);
+ i_stream_unref(&try_input);
+ test_end();
+}
+
+static void test_istream_try_buffer_full(void)
+{
+ const char *test_strings[] = { "Zm9v", "YmFy" };
+ struct istream *test_inputs[3], *try_input, *input, *input2;
+
+ test_begin("istream try buffer full");
+
+ for (unsigned int i = 0; i < 2; i++) {
+ input = test_istream_create(test_strings[i]);
+ test_istream_set_size(input, 1);
+ test_istream_set_max_buffer_size(input, 1);
+ input2 = i_stream_create_base64_decoder(input);
+ i_stream_unref(&input);
+ test_inputs[i] = input2;
+ };
+ test_inputs[2] = NULL;
+
+ try_input = istream_try_create(test_inputs, MIN_FULL_SIZE);
+
+ test_assert(i_stream_read(try_input) == 0);
+ test_assert(try_input->real_stream->parent != NULL);
+ test_assert(i_stream_get_data_size(test_inputs[0]) == 0);
+ test_assert(i_stream_get_data_size(test_inputs[1]) == 0);
+
+ test_istream_set_size(test_inputs[0], 2);
+ test_assert(i_stream_read(try_input) == 1);
+ test_assert(i_stream_get_data_size(test_inputs[0]) == 1);
+ test_assert(i_stream_get_data_size(test_inputs[1]) == 0);
+
+ i_stream_unref(&test_inputs[0]);
+ i_stream_unref(&test_inputs[1]);
+ i_stream_unref(&try_input);
+
+ test_end();
+}
+
+void test_istream_try(void)
+{
+ test_istream_try_normal();
+ test_istream_try_empty();
+ test_istream_try_buffer_full();
+}