daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa/* Copyright (c) 2017-2018 Dovecot authors, see the included COPYING file */
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
b51057b860560bf3ee454c03a121af3d5d34f482Eugen Kuksa#include "test-lib.h"
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa#include "buffer.h"
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa#include "str.h"
28001d576e67ba46ed481c5695f1e0827ff26007Eugen Kuksa#include "randgen.h"
b51057b860560bf3ee454c03a121af3d5d34f482Eugen Kuksa#include "istream.h"
b51057b860560bf3ee454c03a121af3d5d34f482Eugen Kuksa#include "ostream.h"
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
b1fe9054ad7c7192fe4c474363247dad15963e99Eugen Kuksa#define MAX_BUFSIZE 256
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksastatic void test_ostream_buffer_random_once(void)
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa{
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa buffer_t *buffer;
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa struct ostream *output;
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa char buf[MAX_BUFSIZE*4], randbuf[MAX_BUFSIZE];
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa unsigned int i, offset, size;
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa buffer = buffer_create_dynamic(default_pool, 8);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa memset(buf, 0, sizeof(buf));
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa output = o_stream_create_buffer(buffer);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa o_stream_cork(output);
366ce8d807067a97613cb23d49105d8a093c5015Eugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa size = i_rand_minmax(1, MAX_BUFSIZE);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa random_fill(randbuf, size);
366ce8d807067a97613cb23d49105d8a093c5015Eugen Kuksa memcpy(buf, randbuf, size);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_send(output, buf, size) > 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa for (i = 0; i < 10; i++) {
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa offset = i_rand_limit(MAX_BUFSIZE * 3);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa size = i_rand_minmax(1, MAX_BUFSIZE);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa random_fill(randbuf, size);
366ce8d807067a97613cb23d49105d8a093c5015Eugen Kuksa memcpy(buf + offset, randbuf, size);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_pwrite(output, randbuf, size, offset) == 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa if (i_rand_limit(10) == 0)
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_flush(output) > 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa }
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa o_stream_uncork(output);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_finish(output) > 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa i_assert(buffer->used <= MAX_BUFSIZE*4);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(memcmp(buf, buffer->data, buffer->used) == 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa o_stream_unref(&output);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa buffer_free(&buffer);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa}
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksastatic void test_ostream_buffer_random(void)
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa{
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa unsigned int i;
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_begin("ostream buffer pwrite random");
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa for (i = 0; i < 100; i++) T_BEGIN {
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_ostream_buffer_random_once();
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa } T_END;
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa test_end();
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa}
923d69139038e74c0936e826bbfdc8717fbbc7b3Eugen Kuksa
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksastatic void test_ostream_buffer_size(void)
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa{
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa struct ostream *output;
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa string_t *str = t_str_new(64);
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa test_begin("ostream buffer size/available");
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa output = o_stream_create_buffer(str);
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa test_assert(o_stream_get_buffer_used_size(output) == 0);
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa test_assert(o_stream_get_buffer_avail_size(output) == (size_t)-1);
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa /* test shrinking sink's max buffer size */
5efadb4662f2a63d5f5f1a5b303ab7c3371069a8Eugen Kuksa o_stream_set_max_buffer_size(output, 10);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_used_size(output) == 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_avail_size(output) == 10);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa /* partial send */
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa const char *partial_input = "01234567890123456789";
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa ssize_t ret = o_stream_send_str(output, partial_input);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(ret == 10);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_used_size(output) == 10);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_avail_size(output) == 0);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa /* increase max buffer size so that it can hold the whole message */
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa o_stream_set_max_buffer_size(output, 100);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_used_size(output) == 10);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_avail_size(output) == 90);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
28001d576e67ba46ed481c5695f1e0827ff26007Eugen Kuksa /* send the rest */
28001d576e67ba46ed481c5695f1e0827ff26007Eugen Kuksa ret += o_stream_send_str(output, partial_input + ret);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(ret == (ssize_t)strlen(partial_input));
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(output->offset == str_len(str));
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_used_size(output) == 20);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_assert(o_stream_get_buffer_avail_size(output) == 80);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa /* check buffered data */
284432981d641cf3d679841f75acbcf039d83062Eugen Kuksa test_assert(strcmp(str_c(str), partial_input) == 0);
284432981d641cf3d679841f75acbcf039d83062Eugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa o_stream_unref(&output);
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_end();
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa}
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksavoid test_ostream_buffer(void)
923d69139038e74c0936e826bbfdc8717fbbc7b3Eugen Kuksa{
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_ostream_buffer_random();
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa test_ostream_buffer_size();
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa}
daf3e28fff47a65b53d6fb65155301763b9f166eEugen Kuksa