bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen#include "lib.h"
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen#include "str.h"
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen#include "ostream.h"
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen#include "fs-test.h"
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen#include "test-common.h"
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainenstatic void test_fs_async_write(const char *test_name, struct fs *fs)
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen{
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct fs_file *file;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct test_fs_file *test_file;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct ostream *output;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen unsigned int i;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_begin(t_strdup_printf("%s: async write", test_name));
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen for (i = 0; i < 3; i++) {
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen file = fs_file_init(fs, "foo", FS_OPEN_MODE_REPLACE |
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen FS_OPEN_FLAG_ASYNC);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen output = fs_write_stream(file);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen o_stream_nsend_str(output, "12345");
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen if (i < 2) {
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_write_stream_finish(file, &output) == 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(output == NULL);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_write_stream_finish_async(file) == 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen }
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_file = test_fs_file_get(fs, "foo");
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_file->wait_async = FALSE;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen switch (i) {
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen case 0:
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_write_stream_finish_async(file) > 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(test_file->contents->used > 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen break;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen case 1:
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_file->io_failure = TRUE;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_write_stream_finish_async(file) < 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(test_file->contents->used == 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen break;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen case 2:
6d035effc27b2556393e6b26fbe1a846741cdb8eAki Tuomi fs_write_stream_abort_error(file, &output, "test");
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(test_file->contents->used == 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen break;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen }
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen fs_file_deinit(&file);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen }
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_end();
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen}
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainenstatic void test_fs_async_copy(const char *test_name, struct fs *fs)
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen{
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct fs_file *src, *dest;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct test_fs_file *test_file;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_begin(t_strdup_printf("%s: async copy", test_name));
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen src = fs_file_init(fs, "foo", FS_OPEN_MODE_REPLACE);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_write(src, "source", 6) == 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen dest = fs_file_init(fs, "bar", FS_OPEN_MODE_REPLACE |
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen FS_OPEN_FLAG_ASYNC);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_copy(src, dest) == -1 && errno == EAGAIN);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_file = test_fs_file_get(fs, "bar");
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_file->wait_async = FALSE;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(fs_copy_finish_async(dest) == 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_assert(test_file->contents->used > 0);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen fs_file_deinit(&dest);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen fs_file_deinit(&src);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_end();
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen}
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainenvoid test_fs_async(const char *test_name, enum fs_properties properties,
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen const char *driver, const char *args)
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen{
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct fs_settings fs_set;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct fs *fs;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen struct test_fs *test_fs;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen const char *error;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&fs_set);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen if (fs_init(driver, args, &fs_set, &fs, &error) < 0)
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen i_fatal("fs_init() failed: %s", error);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_fs = test_fs_get(fs);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_fs->properties = properties;
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_fs_async_write(test_name, fs);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen test_fs_async_copy(test_name, fs);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen fs_deinit(&fs);
b162e16ade1e0d9bfae62e366caf57a3132f5963Timo Sirainen}