bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen#include "test-lib.h"
3ab672903a7ed98263b89180261079870c964831Timo Sirainen#include "istream-private.h"
3ab672903a7ed98263b89180261079870c964831Timo Sirainen#include "istream-chain.h"
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainenstatic void test_istream_chain_basic(void)
3ab672903a7ed98263b89180261079870c964831Timo Sirainen{
3ab672903a7ed98263b89180261079870c964831Timo Sirainen struct istream *input, *test_input, *test_input2;
3ab672903a7ed98263b89180261079870c964831Timo Sirainen struct istream_chain *chain;
3ab672903a7ed98263b89180261079870c964831Timo Sirainen const unsigned char *data;
3ab672903a7ed98263b89180261079870c964831Timo Sirainen size_t size;
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_begin("istream chain");
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_input = test_istream_create("stream1");
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_input2 = test_istream_create("STREAM2");
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen input = i_stream_create_chain(&chain);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen /* no input */
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen /* stream1 input */
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_chain_append(chain, test_input);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 7);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen data = i_stream_get_data(input, &size);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(size == 7 && memcmp(data, "stream1", 7) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen data = i_stream_get_data(input, &size);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(size == 7 && memcmp(data, "stream1", 7) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen /* STREAM2 input */
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_chain_append(chain, test_input2);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 7);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen data = i_stream_get_data(input, &size);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(size == 14 && memcmp(data, "stream1STREAM2", 14) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen data = i_stream_get_data(input, &size);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(size == 14 && memcmp(data, "stream1STREAM2", 14) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen /* EOF */
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_chain_append_eof(chain);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == -1 &&
3ab672903a7ed98263b89180261079870c964831Timo Sirainen input->eof && input->stream_errno == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen data = i_stream_get_data(input, &size);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(size == 14 && memcmp(data, "stream1STREAM2", 14) == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_unref(&input);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
a05250bd599fca0cb8b761c4fd69f91bc1c3667eTimo Sirainen test_assert(test_input->eof && test_input->stream_errno == 0);
a05250bd599fca0cb8b761c4fd69f91bc1c3667eTimo Sirainen test_assert(test_input2->eof && test_input2->stream_errno == 0);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_unref(&test_input);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_unref(&test_input2);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_end();
3ab672903a7ed98263b89180261079870c964831Timo Sirainen}
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainenstatic void test_istream_chain_early_end(void)
3ab672903a7ed98263b89180261079870c964831Timo Sirainen{
3ab672903a7ed98263b89180261079870c964831Timo Sirainen struct istream *input, *test_input;
3ab672903a7ed98263b89180261079870c964831Timo Sirainen struct istream_chain *chain;
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_begin("istream chain early end");
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_input = test_istream_create("string");
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_istream_set_size(test_input, 3);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_istream_set_allow_eof(test_input, FALSE);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen input = i_stream_create_chain(&chain);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_chain_append(chain, test_input);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 3);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_istream_set_size(test_input, 5);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(i_stream_read(input) == 2);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen /* with current implementation we could skip less than 5 and have
3ab672903a7ed98263b89180261079870c964831Timo Sirainen v_offset<5, but I don't think that can work in all situations.
3ab672903a7ed98263b89180261079870c964831Timo Sirainen the normal case is anyway that we'll read everything up until some
3ab672903a7ed98263b89180261079870c964831Timo Sirainen point and skip over all the data up to there. */
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_skip(input, 5);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_unref(&input);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_assert(test_input->v_offset == 5);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen i_stream_unref(&test_input);
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_end();
3ab672903a7ed98263b89180261079870c964831Timo Sirainen}
3ab672903a7ed98263b89180261079870c964831Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainenstatic void test_istream_chain_accumulate(void)
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen{
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen struct istream *input;
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen struct istream *test_input, *test_input2, *test_input3, *test_input4,
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen *test_input5;
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen struct istream_chain *chain;
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen const unsigned char *data;
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen size_t size;
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
1d4f019ffe68c9faa20f71e1c06df0bbad54917eTimo Sirainen test_begin("istream chain accumulate");
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_input = test_istream_create("aaaaaaaaaaaaaaaaaaaa");
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_input2 = test_istream_create("bbbbbbbbbbbbbbbbbbbbbbbbb");
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_input3 = test_istream_create("cccccccccccccccccccccccccccccc");
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_input4 = test_istream_create("ddddddddddddddddddddddddd");
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_input5 = test_istream_create("eeeeeeeeeeeeeeeeeeee");
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen input = i_stream_create_chain(&chain);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* no input */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read(input) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* first stream */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_chain_append(chain, test_input);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read_data(input, &data, &size, 0) == 1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 20);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(memcmp(data, "aaaaaaaaaaaaaaaaaaaa", 20) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* partially skip */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_skip(input, 12);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* second stream */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_chain_append(chain, test_input2);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read_data(input, &data, &size, 10) == 1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 33);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(memcmp(data, "aaaaaaaa"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "bbbbbbbbbbbbbbbbbbbbbbbbb", 33) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* partially skip */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_skip(input, 12);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* third stream */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_chain_append(chain, test_input3);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read_data(input, &data, &size, 25) == 1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 51);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(memcmp(data, "bbbbbbbbbbbbbbbbbbbbb"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "cccccccccccccccccccccccccccccc", 51) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* partially skip */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_skip(input, 12);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* forth stream */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_chain_append(chain, test_input4);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read_data(input, &data, &size, 40) == 1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 64);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(memcmp(data, "bbbbbbbbb"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "cccccccccccccccccccccccccccccc"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "ddddddddddddddddddddddddd", 64) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* partially skip */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_skip(input, 6);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* fifth stream */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_chain_append(chain, test_input5);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read_data(input, &data, &size, 60) == 1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 78);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(memcmp(data, "bbb"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "cccccccccccccccccccccccccccccc"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "ddddddddddddddddddddddddd"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "eeeeeeeeeeeeeeeeeeee", 78) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* EOF */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_chain_append_eof(chain);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read(input) == -1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(input->eof && input->stream_errno == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read_data(input, &data, &size, 78) == -1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 78);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(memcmp(data, "bbb"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "cccccccccccccccccccccccccccccc"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "ddddddddddddddddddddddddd"
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen "eeeeeeeeeeeeeeeeeeee", 78) == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen /* skip rest */
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_skip(input, 78);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(i_stream_read(input) == -1);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(input->eof && input->stream_errno == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen data = i_stream_get_data(input, &size);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_assert(size == 0);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_unref(&input);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_unref(&test_input);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_unref(&test_input2);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen i_stream_unref(&test_input3);
1d4f019ffe68c9faa20f71e1c06df0bbad54917eTimo Sirainen i_stream_unref(&test_input4);
1d4f019ffe68c9faa20f71e1c06df0bbad54917eTimo Sirainen i_stream_unref(&test_input5);
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_end();
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen}
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen
3ab672903a7ed98263b89180261079870c964831Timo Sirainenvoid test_istream_chain(void)
3ab672903a7ed98263b89180261079870c964831Timo Sirainen{
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_istream_chain_basic();
3ab672903a7ed98263b89180261079870c964831Timo Sirainen test_istream_chain_early_end();
bac6427712674cd4b6146ef51f90c14eb9603db6Timo Sirainen test_istream_chain_accumulate();
3ab672903a7ed98263b89180261079870c964831Timo Sirainen}