summaryrefslogtreecommitdiffstats
path: root/src/lib/test-iostream-temp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test-iostream-temp.c')
-rw-r--r--src/lib/test-iostream-temp.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/src/lib/test-iostream-temp.c b/src/lib/test-iostream-temp.c
new file mode 100644
index 0000000..cfb8658
--- /dev/null
+++ b/src/lib/test-iostream-temp.c
@@ -0,0 +1,150 @@
+/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "istream.h"
+#include "ostream.h"
+#include "iostream-temp.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+
+static void test_iostream_temp_create_sized_memory(void)
+{
+ struct ostream *output;
+
+ test_begin("iostream_temp_create_sized() memory");
+ output = iostream_temp_create_sized(".intentional-nonexistent-error/", 0, "test", 4);
+ test_assert(o_stream_send(output, "123", 3) == 3);
+ test_assert(output->offset == 3);
+ test_assert(o_stream_send(output, "4", 1) == 1);
+ test_assert(output->offset == 4);
+ test_assert(o_stream_get_fd(output) == -1);
+
+ /* now we'll try to switch to writing to a file, but it'll fail */
+ test_expect_error_string("safe_mkstemp");
+ test_assert(o_stream_send(output, "5", 1) == 1);
+ test_expect_no_more_errors();
+
+ test_assert(o_stream_get_fd(output) == -1);
+ o_stream_destroy(&output);
+ test_end();
+}
+
+static void test_iostream_temp_create_sized_disk(void)
+{
+ struct ostream *output;
+
+ test_begin("iostream_temp_create_sized() disk");
+ output = iostream_temp_create_sized(".", 0, "test", 4);
+ test_assert(o_stream_send(output, "123", 3) == 3);
+ test_assert(output->offset == 3);
+ test_assert(o_stream_send(output, "4", 1) == 1);
+ test_assert(output->offset == 4);
+ test_assert(o_stream_get_fd(output) == -1);
+ test_assert(o_stream_send(output, "5", 1) == 1);
+ test_assert(output->offset == 5);
+ test_assert(o_stream_get_fd(output) != -1);
+ o_stream_destroy(&output);
+ test_end();
+}
+
+static void test_iostream_temp_create_write_error(void)
+{
+ struct ostream *output;
+
+ test_begin("iostream_temp_create_sized() write error");
+ output = iostream_temp_create_sized(".", 0, "test", 1);
+
+ test_assert(o_stream_send(output, "123", 3) == 3);
+ test_assert(o_stream_get_fd(output) != -1);
+ test_assert(output->offset == 3);
+ test_assert(o_stream_temp_move_to_memory(output) == 0);
+ test_assert(o_stream_get_fd(output) == -1);
+ test_assert(o_stream_send(output, "45", 2) == 2);
+ test_assert(output->offset == 5);
+
+ const unsigned char *data;
+ size_t size;
+ struct istream *input = iostream_temp_finish(&output, 128);
+ test_assert(i_stream_read_bytes(input, &data, &size, 5) == 1 &&
+ memcmp(data, "12345", 5) == 0);
+ i_stream_destroy(&input);
+
+ test_end();
+}
+
+static void test_iostream_temp_istream(void)
+{
+ struct istream *input, *input2, *temp_input;
+ struct ostream *output;
+ int fd;
+
+ test_begin("iostream_temp istream");
+
+ fd = open(".temp.istream", O_RDWR | O_CREAT | O_TRUNC, 0600);
+ if (fd == -1)
+ i_fatal("create(.temp.istream) failed: %m");
+ test_assert(write(fd, "foobar", 6) == 6);
+ test_assert(lseek(fd, 0, SEEK_SET) == 0);
+
+ input = i_stream_create_fd_autoclose(&fd, 1024);
+ /* a working fd-dup */
+ output = iostream_temp_create_sized(".nonexistent/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 1);
+ test_assert(o_stream_send_istream(output, input) == OSTREAM_SEND_ISTREAM_RESULT_FINISHED);
+ test_assert(output->offset == 6);
+ temp_input = iostream_temp_finish(&output, 128);
+ test_assert(i_stream_read(temp_input) == 6);
+ i_stream_destroy(&temp_input);
+
+ /* non-working fd-dup: write data before sending istream */
+ i_stream_seek(input, 0);
+ output = iostream_temp_create_sized(".intentional-nonexistent-error/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 4);
+ test_assert(o_stream_send(output, "1234", 4) == 4);
+ test_assert(output->offset == 4);
+ test_expect_error_string("safe_mkstemp");
+ test_assert(o_stream_send_istream(output, input) == OSTREAM_SEND_ISTREAM_RESULT_FINISHED);
+ test_assert(output->offset == 10);
+ test_expect_no_more_errors();
+ o_stream_destroy(&output);
+
+ /* non-working fd-dup: write data after sending istream */
+ i_stream_seek(input, 0);
+ output = iostream_temp_create_sized(".intentional-nonexistent-error/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 4);
+ test_assert(o_stream_send_istream(output, input) == OSTREAM_SEND_ISTREAM_RESULT_FINISHED);
+ test_assert(output->offset == 6);
+ test_expect_error_string("safe_mkstemp");
+ test_assert(o_stream_send(output, "1", 1) == 1);
+ test_assert(output->offset == 7);
+ test_expect_no_more_errors();
+ o_stream_destroy(&output);
+
+ /* non-working fd-dup: send two istreams */
+ i_stream_seek(input, 0);
+ input2 = i_stream_create_limit(input, UOFF_T_MAX);
+ output = iostream_temp_create_sized(".intentional-nonexistent-error/",
+ IOSTREAM_TEMP_FLAG_TRY_FD_DUP, "test", 4);
+ test_assert(o_stream_send_istream(output, input) == OSTREAM_SEND_ISTREAM_RESULT_FINISHED);
+ test_assert(output->offset == 6);
+ test_expect_error_string("safe_mkstemp");
+ test_assert(o_stream_send_istream(output, input2) == OSTREAM_SEND_ISTREAM_RESULT_FINISHED);
+ test_assert(output->offset == 12);
+ test_expect_no_more_errors();
+ o_stream_destroy(&output);
+ i_stream_unref(&input2);
+
+ i_stream_destroy(&input);
+
+ i_unlink(".temp.istream");
+ test_end();
+}
+
+void test_iostream_temp(void)
+{
+ test_iostream_temp_create_sized_memory();
+ test_iostream_temp_create_sized_disk();
+ test_iostream_temp_create_write_error();
+ test_iostream_temp_istream();
+}