bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "test-lib.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "istream.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "ostream.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "buffer.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "str.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "ioloop.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "iostream-pump.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "istream-failure-at.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include "ostream-failure-at.h"
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include <unistd.h>
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include <sys/types.h>
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi#include <sys/socket.h>
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomiunsigned char data[] = "hello, world";
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
39435f00a35a276d329283179b3e7e0351482939Timo Sirainenvoid completed(enum iostream_pump_status status, int *u0)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi /* to somehow discern between error and success .. */
39435f00a35a276d329283179b3e7e0351482939Timo Sirainen (*u0) -= (status == IOSTREAM_PUMP_STATUS_INPUT_EOF ? 1 : 2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi io_loop_stop(current_ioloop);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid failed(int *u0)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi *u0 = -1; /* ensure failure */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi io_loop_stop(current_ioloop);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistruct nonblock_ctx {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi uoff_t pos, max_size;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi};
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic void pump_nonblocking_timeout(struct nonblock_ctx *ctx)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi switch (ctx->pos % 4) {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi case 0:
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi break;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi case 1:
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi /* allow more input */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi if (ctx->pos/4 == ctx->max_size+1)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_istream_set_allow_eof(ctx->in, TRUE);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi else
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_istream_set_size(ctx->in, ctx->pos/4);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi i_stream_set_input_pending(ctx->in, TRUE);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi break;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi case 2:
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi break;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi case 3: {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi /* allow more output. give always one byte less than the
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi input size so there's something in internal buffer. */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi size_t size = ctx->pos/4;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi if (size > 0)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_ostream_set_max_output_size(ctx->out, size-1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi break;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi }
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi }
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi ctx->pos++;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomiconst char *run_pump(struct istream *in, struct ostream *out, int *counter, buffer_t *out_buffer)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct iostream_pump *pump;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ioloop *ioloop = io_loop_create();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi io_loop_set_current(ioloop);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct nonblock_ctx ctx = { in, out, 0, 0 };
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct timeout *to2 = NULL;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi if (!in->blocking) {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(i_stream_get_size(in, TRUE, &ctx.max_size) > 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_istream_set_size(in, 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_istream_set_allow_eof(in, FALSE);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_ostream_set_max_output_size(out, 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi to2 = timeout_add_short(0, pump_nonblocking_timeout, &ctx);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi }
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi pump = iostream_pump_create(in, out);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi i_stream_unref(&in);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi o_stream_unref(&out);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi iostream_pump_set_completion_callback(pump, completed, counter);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi iostream_pump_start(pump);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi alarm(5);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct timeout *to = timeout_add(3000, failed, counter);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi io_loop_run(current_ioloop);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi timeout_remove(&to);
0d1b8b6bec79746c5d89d57dd8c1688946bd9237Josef 'Jeff' Sipek timeout_remove(&to2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi alarm(0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(*counter == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi if (!ctx.in->blocking && ctx.in->stream_errno != 0 &&
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi ctx.out->stream_errno == 0) {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi /* input failed, finish flushing output */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_ostream_set_max_output_size(ctx.out, (size_t)-1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(o_stream_flush(ctx.out) > 0);
84b746f56209d4a85af73cd26850e75f519ae0b0Timo Sirainen } else {
84b746f56209d4a85af73cd26850e75f519ae0b0Timo Sirainen test_assert(o_stream_flush(ctx.out) != 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi }
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi const char *ret = t_strdup(str_c(out_buffer));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi iostream_pump_unref(&pump);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi io_loop_destroy(&ioloop);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi return ret;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_setup(bool block, struct istream **in_r,
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream **out_r, buffer_t **out_buffer_r)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
c147bff818798a979d93537f72f5c1f68f5d5ba8Aki Tuomi *out_buffer_r = t_buffer_create(128);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi *in_r = test_istream_create_data(data, sizeof(data));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi (*in_r)->blocking = block;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi if (block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi *out_r = test_ostream_create(*out_buffer_r);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi else
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi *out_r = test_ostream_create_nonblocking(*out_buffer_r, 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_simple(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin(t_strdup_printf("iostream_pump (%sblocking)", block ? "" : "non-"));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in, &out, &buffer);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 1;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), "hello, world") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_failure_start_read(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin(t_strdup_printf("iostream_pump failure start-read (%sblocking)", block ? "" : "non-"));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in_2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in_2, &out, &buffer);
a4985564b81d51caaddd38376792432428fd449bStephan Bosch struct istream *in = i_stream_create_failure_at(in_2, 0, EIO, "test pump fail");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi i_stream_unref(&in_2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), "") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_failure_mid_read(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin(t_strdup_printf("iostream_pump failure mid-read (%sblocking)", block ? "" : "non-"));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in_2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in_2, &out, &buffer);
a4985564b81d51caaddd38376792432428fd449bStephan Bosch struct istream *in = i_stream_create_failure_at(in_2, 4, EIO, "test pump fail");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi i_stream_unref(&in_2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), "hell") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_failure_end_read(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin(t_strdup_printf("iostream_pump failure mid-read (%sblocking)", block ? "" : "non-"));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in_2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in_2, &out, &buffer);
a4985564b81d51caaddd38376792432428fd449bStephan Bosch struct istream *in = i_stream_create_failure_at_eof(in_2, EIO, "test pump fail");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi i_stream_unref(&in_2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), "hello, world") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_failure_start_write(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin(t_strdup_printf("iostream_pump failure start-write (%sblocking)", block ? "" : "non-"));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out_2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in, &out_2, &buffer);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out = o_stream_create_failure_at(out_2, 0, "test pump fail");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi o_stream_unref(&out_2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), "") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_failure_mid_write(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin(t_strdup_printf("iostream_pump failure mid-write (%sblocking)", block ? "" : "non-"));
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out_2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in, &out_2, &buffer);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out = o_stream_create_failure_at(out_2, 4, "test pump fail");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi o_stream_unref(&out_2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi /* "hel" because the last byte is only in internal buffer */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), block ? "" : "hel") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomistatic
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump_failure_end_write(bool block)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi if (!block) {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi /* we'll get flushes constantly */
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi return;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi }
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_begin("iostream_pump failure end-write (blocking)");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi int counter;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct istream *in;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out_2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi buffer_t *buffer;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_setup(block, &in, &out_2, &buffer);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi struct ostream *out = o_stream_create_failure_at_flush(out_2, "test pump fail");
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi o_stream_unref(&out_2);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi counter = 2;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_assert(strcmp(run_pump(in, out, &counter, buffer), "hello, world") == 0);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_end();
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomivoid test_iostream_pump(void)
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi{
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi T_BEGIN {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi for(int i = 0; i < 2; i++) {
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_simple(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_failure_start_read(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_failure_mid_read(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_failure_end_read(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_failure_start_write(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_failure_mid_write(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi test_iostream_pump_failure_end_write(i < 1);
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi }
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi } T_END;
4d9181518769b1f78d8078f7fae899fd0b95907fAki Tuomi}