bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include "test-lib.h"
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include "istream.h"
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include "ostream.h"
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include "buffer.h"
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include "ioloop.h"
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include "iostream-proxy.h"
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include <unistd.h>
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include <sys/types.h>
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi#include <sys/socket.h>
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomistatic
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainenvoid completed(enum iostream_proxy_side side ATTR_UNUSED,
987c15a5980f53225e60f79325c14cb2acddaabbTimo Sirainen enum iostream_proxy_status status ATTR_UNUSED, int *u0)
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi{
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_assert(*u0 > 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi if (--*u0 == 0)
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi io_loop_stop(current_ioloop);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi}
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomistatic
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomivoid test_iostream_proxy_simple(void)
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi{
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi size_t bytes;
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_begin("iostream_proxy");
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi int sfdl[2];
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi int sfdr[2];
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi int counter;
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sfdl) == 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sfdr) == 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi fd_set_nonblock(sfdl[0], TRUE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi fd_set_nonblock(sfdl[1], TRUE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi fd_set_nonblock(sfdr[0], TRUE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi fd_set_nonblock(sfdr[1], TRUE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi struct ioloop *ioloop = io_loop_create();
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi struct istream *left_in = i_stream_create_fd(sfdl[1], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi struct ostream *left_out = o_stream_create_fd(sfdl[1], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi struct istream *right_in = i_stream_create_fd(sfdr[1], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi struct ostream *right_out = o_stream_create_fd(sfdr[1], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi struct iostream_proxy *proxy;
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi proxy = iostream_proxy_create(left_in, left_out, right_in, right_out);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_unref(&left_in);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi o_stream_unref(&left_out);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_unref(&right_in);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi o_stream_unref(&right_out);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi iostream_proxy_set_completion_callback(proxy, completed, &counter);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi iostream_proxy_start(proxy);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi left_in = i_stream_create_fd(sfdl[0], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi left_out = o_stream_create_fd(sfdl[0], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi right_in = i_stream_create_fd(sfdr[0], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi right_out = o_stream_create_fd(sfdr[0], IO_BLOCK_SIZE);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(proxy != NULL);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(o_stream_send_str(left_out, "hello, world") > 0);
c34bdea0d736047ba7bbc835baf4126ea78d5da7Aki Tuomi test_assert(o_stream_flush(left_out) > 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi o_stream_unref(&left_out);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(shutdown(sfdl[0], SHUT_WR) == 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi counter = 1;
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi io_loop_run(ioloop);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_read(right_in);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(strcmp((const char*)i_stream_get_data(right_in, &bytes), "hello, world") == 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_skip(right_in, bytes);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(o_stream_send_str(right_out, "hello, world") > 0);
c34bdea0d736047ba7bbc835baf4126ea78d5da7Aki Tuomi test_assert(o_stream_flush(right_out) > 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi o_stream_unref(&right_out);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(shutdown(sfdr[0], SHUT_WR) == 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi counter = 1;
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi io_loop_run(ioloop);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_read(left_in);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_assert(strcmp((const char*)i_stream_get_data(left_in, &bytes), "hello, world") == 0);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_skip(left_in, bytes);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi iostream_proxy_unref(&proxy);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi io_loop_destroy(&ioloop);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_unref(&left_in);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi i_stream_unref(&right_in);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi /* close fd */
c31803dcbdf3d4e3b836134a2a04ee2cd5251ce5Aki Tuomi i_close_fd(&sfdl[0]);
c31803dcbdf3d4e3b836134a2a04ee2cd5251ce5Aki Tuomi i_close_fd(&sfdl[1]);
c31803dcbdf3d4e3b836134a2a04ee2cd5251ce5Aki Tuomi i_close_fd(&sfdr[0]);
c31803dcbdf3d4e3b836134a2a04ee2cd5251ce5Aki Tuomi i_close_fd(&sfdr[1]);
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_end();
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi}
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomivoid test_iostream_proxy(void)
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi{
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi T_BEGIN {
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi test_iostream_proxy_simple();
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi } T_END;
f7060b8499ed07205734cf7af94ad5405fa687b5Aki Tuomi}