summaryrefslogtreecommitdiffstats
path: root/src/lib/test-istream-chain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test-istream-chain.c')
-rw-r--r--src/lib/test-istream-chain.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/lib/test-istream-chain.c b/src/lib/test-istream-chain.c
new file mode 100644
index 0000000..cb72c64
--- /dev/null
+++ b/src/lib/test-istream-chain.c
@@ -0,0 +1,199 @@
+/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "istream-private.h"
+#include "istream-chain.h"
+
+static void test_istream_chain_basic(void)
+{
+ struct istream *input, *test_input, *test_input2;
+ struct istream_chain *chain;
+ const unsigned char *data;
+ size_t size;
+
+ test_begin("istream chain");
+
+ test_input = test_istream_create("stream1");
+ test_input2 = test_istream_create("STREAM2");
+
+ input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
+ /* no input */
+ test_assert(i_stream_read(input) == 0);
+ /* stream1 input */
+ i_stream_chain_append(chain, test_input);
+ test_assert(i_stream_read(input) == 7);
+ data = i_stream_get_data(input, &size);
+ test_assert(size == 7 && memcmp(data, "stream1", 7) == 0);
+ test_assert(i_stream_read(input) == 0);
+ data = i_stream_get_data(input, &size);
+ test_assert(size == 7 && memcmp(data, "stream1", 7) == 0);
+ /* STREAM2 input */
+ i_stream_chain_append(chain, test_input2);
+ test_assert(i_stream_read(input) == 7);
+ data = i_stream_get_data(input, &size);
+ test_assert(size == 14 && memcmp(data, "stream1STREAM2", 14) == 0);
+ test_assert(i_stream_read(input) == 0);
+ data = i_stream_get_data(input, &size);
+ test_assert(size == 14 && memcmp(data, "stream1STREAM2", 14) == 0);
+ /* EOF */
+ i_stream_chain_append_eof(chain);
+ test_assert(i_stream_read(input) == -1 &&
+ input->eof && input->stream_errno == 0);
+ data = i_stream_get_data(input, &size);
+ test_assert(size == 14 && memcmp(data, "stream1STREAM2", 14) == 0);
+
+ i_stream_unref(&input);
+
+ test_assert(test_input->eof && test_input->stream_errno == 0);
+ test_assert(test_input2->eof && test_input2->stream_errno == 0);
+
+ i_stream_unref(&test_input);
+ i_stream_unref(&test_input2);
+ test_end();
+}
+
+static void test_istream_chain_early_end(void)
+{
+ struct istream *input, *test_input;
+ struct istream_chain *chain;
+
+ test_begin("istream chain early end");
+
+ test_input = test_istream_create("string");
+ test_istream_set_size(test_input, 3);
+ test_istream_set_allow_eof(test_input, FALSE);
+
+ input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
+ i_stream_chain_append(chain, test_input);
+ test_assert(i_stream_read(input) == 3);
+ test_istream_set_size(test_input, 5);
+ test_assert(i_stream_read(input) == 2);
+ /* with current implementation we could skip less than 5 and have
+ v_offset<5, but I don't think that can work in all situations.
+ the normal case is anyway that we'll read everything up until some
+ point and skip over all the data up to there. */
+ i_stream_skip(input, 5);
+ i_stream_unref(&input);
+
+ test_assert(test_input->v_offset == 5);
+ i_stream_unref(&test_input);
+ test_end();
+}
+
+static void test_istream_chain_accumulate(void)
+{
+ struct istream *input, *tmp_istream;
+ struct istream *test_istreams[5];
+ struct istream_chain *chain;
+ const unsigned char *data;
+ size_t size;
+
+ test_begin("istream chain accumulate");
+
+ test_istreams[0] = test_istream_create("abcdefghijklmnopqrst");
+ test_istreams[1] = test_istream_create("ABCDEFGHIJKLMNOPQRSTUVWXY");
+ test_istreams[2] = test_istream_create("!\"#$%&'()*+,-./01234567890:;<=");
+ test_istreams[3] = test_istream_create("z1y2x3w4v5u6t7s8r9q0p.o,n");
+ test_istreams[4] = test_istream_create("aAbBcCdDeEfFgGhHiIjJ");
+
+ input = i_stream_create_chain(&chain, IO_BLOCK_SIZE);
+ /* no input */
+ test_assert(i_stream_read(input) == 0);
+
+ /* first stream */
+ i_stream_chain_append(chain, test_istreams[0]);
+ tmp_istream = test_istreams[0]; i_stream_unref(&tmp_istream);
+ test_assert(i_stream_read_data(input, &data, &size, 0) == 1);
+ test_assert(size == 20);
+ test_assert(memcmp(data, "abcdefghijklmnopqrst", 20) == 0);
+
+ /* partially skip */
+ i_stream_skip(input, 12);
+
+ /* second stream */
+ i_stream_chain_append(chain, test_istreams[1]);
+ tmp_istream = test_istreams[1]; i_stream_unref(&tmp_istream);
+ test_istream_set_size(test_istreams[1], 0);
+ test_assert(i_stream_read_data(input, &data, &size, 10) == 0);
+ test_assert(size == 8);
+ test_istream_set_size(test_istreams[1], 10);
+ test_assert(i_stream_read_data(input, &data, &size, 10) == 1);
+ test_assert(size == 18);
+ test_istream_set_allow_eof(test_istreams[1], FALSE);
+ test_assert(i_stream_read(input) == 0);
+ test_istream_set_size(test_istreams[1], 25);
+ test_istream_set_allow_eof(test_istreams[1], TRUE);
+ test_assert(i_stream_read_data(input, &data, &size, 30) == 1);
+ test_assert(size == 33);
+ test_assert(memcmp(data, "mnopqrst"
+ "ABCDEFGHIJKLMNOPQRSTUVWXY", 33) == 0);
+
+ /* partially skip */
+ i_stream_skip(input, 12);
+
+ /* third stream */
+ i_stream_chain_append(chain, test_istreams[2]);
+ tmp_istream = test_istreams[2]; i_stream_unref(&tmp_istream);
+ test_istream_set_size(test_istreams[2], 0);
+ test_assert(i_stream_read(input) == 0);
+ test_istream_set_size(test_istreams[2], 30);
+ test_assert(i_stream_read_data(input, &data, &size, 25) == 1);
+ test_assert(size == 51);
+ test_assert(memcmp(data, "EFGHIJKLMNOPQRSTUVWXY"
+ "!\"#$%&'()*+,-./01234567890:;<=", 51) == 0);
+ test_assert(i_stream_read(input) == 0);
+
+ /* partially skip */
+ i_stream_skip(input, 12);
+
+ /* forth stream */
+ i_stream_chain_append(chain, test_istreams[3]);
+ tmp_istream = test_istreams[3]; i_stream_unref(&tmp_istream);
+ test_assert(i_stream_read_data(input, &data, &size, 40) == 1);
+ test_assert(size == 64);
+ test_assert(memcmp(data, "QRSTUVWXY"
+ "!\"#$%&'()*+,-./01234567890:;<="
+ "z1y2x3w4v5u6t7s8r9q0p.o,n", 64) == 0);
+
+ /* partially skip */
+ i_stream_skip(input, 6);
+
+ /* fifth stream */
+ i_stream_chain_append(chain, test_istreams[4]);
+ tmp_istream = test_istreams[4]; i_stream_unref(&tmp_istream);
+ test_assert(i_stream_read_data(input, &data, &size, 60) == 1);
+ test_assert(size == 78);
+ test_assert(memcmp(data, "WXY"
+ "!\"#$%&'()*+,-./01234567890:;<="
+ "z1y2x3w4v5u6t7s8r9q0p.o,n"
+ "aAbBcCdDeEfFgGhHiIjJ", 78) == 0);
+
+ /* EOF */
+ i_stream_chain_append_eof(chain);
+ test_assert(i_stream_read(input) == -1);
+ test_assert(input->eof && input->stream_errno == 0);
+ test_assert(i_stream_read_data(input, &data, &size, 78) == -1);
+ test_assert(size == 78);
+ test_assert(memcmp(data, "WXY"
+ "!\"#$%&'()*+,-./01234567890:;<="
+ "z1y2x3w4v5u6t7s8r9q0p.o,n"
+ "aAbBcCdDeEfFgGhHiIjJ", 78) == 0);
+
+ /* skip rest */
+ i_stream_skip(input, 78);
+
+ test_assert(i_stream_read(input) == -1);
+ test_assert(input->eof && input->stream_errno == 0);
+ data = i_stream_get_data(input, &size);
+ test_assert(size == 0);
+
+ i_stream_unref(&input);
+ test_end();
+}
+
+void test_istream_chain(void)
+{
+ test_istream_chain_basic();
+ test_istream_chain_early_end();
+ test_istream_chain_accumulate();
+}