test-ostream-file.c revision e6e5e9c0309a48a1301577829fcebc5a83886705
10139N/A/* Copyright (c) 2009-2016 Dovecot authors, see the included COPYING file */
10139N/A
10139N/A#include "test-lib.h"
18537N/A#include "str.h"
10139N/A#include "safe-mkstemp.h"
10139N/A#include "randgen.h"
10139N/A#include "istream.h"
20307N/A#include "ostream.h"
10139N/A
17180N/A#include <fcntl.h>
18603N/A#include <unistd.h>
17180N/A
15153N/A#define MAX_BUFSIZE 256
10139N/A
15308N/Astatic void test_ostream_file_random_once(void)
10139N/A{
20332N/A struct ostream *output;
20332N/A string_t *path = t_str_new(128);
10139N/A char buf[MAX_BUFSIZE*4], buf2[MAX_BUFSIZE*4], randbuf[MAX_BUFSIZE];
18616N/A unsigned int i, offset, size;
10139N/A ssize_t ret;
20332N/A int fd;
12773N/A
15153N/A memset(buf, 0, sizeof(buf));
15153N/A fd = safe_mkstemp(path, 0600, (uid_t)-1, (gid_t)-1);
12773N/A if (fd == -1)
13633N/A i_fatal("safe_mkstemp(%s) failed: %m", str_c(path));
13992N/A i_unlink(str_c(path));
15555N/A output = o_stream_create_fd(fd, MAX_BUFSIZE, FALSE);
15428N/A o_stream_cork(output);
20307N/A
18719N/A size = (rand() % MAX_BUFSIZE) + 1;
20196N/A random_fill_weak(randbuf, size);
20196N/A memcpy(buf, randbuf, size);
10139N/A test_assert(o_stream_send(output, buf, size) > 0);
10139N/A
10139N/A for (i = 0; i < 10; i++) {
10139N/A offset = rand() % (MAX_BUFSIZE*3);
10139N/A size = (rand() % MAX_BUFSIZE) + 1;
10139N/A random_fill_weak(randbuf, size);
10139N/A memcpy(buf + offset, randbuf, size);
10139N/A test_assert(o_stream_pwrite(output, randbuf, size, offset) == 0);
10139N/A if (rand() % 10 == 0)
10139N/A test_assert(o_stream_flush(output) > 0);
10139N/A }
10139N/A
10139N/A test_assert(o_stream_flush(output) > 0);
10139N/A o_stream_uncork(output);
10139N/A ret = pread(fd, buf2, sizeof(buf2), 0);
10139N/A if (ret < 0)
10139N/A i_fatal("pread() failed: %m");
10139N/A else {
10139N/A i_assert(ret > 0);
10139N/A test_assert(memcmp(buf, buf2, ret) == 0);
10139N/A }
10139N/A o_stream_unref(&output);
10139N/A i_close_fd(&fd);
10139N/A}
10139N/A
10139N/Astatic void test_ostream_file_random(void)
10139N/A{
10139N/A unsigned int i;
15153N/A
15153N/A test_begin("ostream pwrite random");
15153N/A for (i = 0; i < 100; i++) T_BEGIN {
15153N/A test_ostream_file_random_once();
15153N/A } T_END;
13551N/A test_end();
15428N/A}
20332N/A
20196N/Astatic void test_ostream_file_send_istream_file(void)
10139N/A{
10139N/A struct istream *input, *input2;
10139N/A struct ostream *output;
10139N/A char buf[10];
10139N/A int fd;
10139N/A
10139N/A test_begin("ostream file send istream file");
10139N/A
10139N/A /* temp file istream */
10139N/A fd = open(".temp.istream", O_RDWR | O_CREAT | O_TRUNC, 0600);
10139N/A if (fd == -1)
10139N/A i_fatal("creat(.temp.istream) failed: %m");
10139N/A test_assert(write(fd, "1234567890", 10) == 10);
10139N/A test_assert(lseek(fd, 0, SEEK_SET) == 0);
10139N/A input = i_stream_create_fd(fd, 1024, TRUE);
12773N/A
12773N/A /* temp file ostream */
12773N/A fd = open(".temp.ostream", O_RDWR | O_CREAT | O_TRUNC, 0600);
12773N/A if (fd == -1)
12773N/A i_fatal("creat(.temp.ostream) failed: %m");
15724N/A output = o_stream_create_fd(fd, 0, TRUE);
15724N/A
15724N/A /* test that writing works between two files */
15724N/A i_stream_seek(input, 3);
15724N/A input2 = i_stream_create_limit(input, 4);
15724N/A test_assert(o_stream_send_istream(output, input2) > 0);
15724N/A test_assert(output->offset == 4);
15724N/A test_assert(pread(fd, buf, sizeof(buf), 0) == 4 &&
10826N/A memcmp(buf, "4567", 4) == 0);
15724N/A i_stream_unref(&input2);
10826N/A
15724N/A /* test that writing works within the same file */
10139N/A i_stream_destroy(&input);
10139N/A
10139N/A input = i_stream_create_fd(fd, 1024, FALSE);
10139N/A /* forwards: 4567 -> 4677 */
10139N/A o_stream_seek(output, 1);
10139N/A i_stream_seek(input, 2);
10139N/A input2 = i_stream_create_limit(input, 2);
10139N/A test_assert(o_stream_send_istream(output, input2) > 0);
10139N/A test_assert(output->offset == 3);
10139N/A test_assert(pread(fd, buf, sizeof(buf), 0) == 4 &&
10139N/A memcmp(buf, "4677", 4) == 0);
10139N/A i_stream_destroy(&input2);
10139N/A i_stream_destroy(&input);
10139N/A
10139N/A /* backwards: 1234 -> 11234 */
10139N/A memcpy(buf, "1234", 4);
10139N/A test_assert(pwrite(fd, buf, 4, 0) == 4);
10139N/A input = i_stream_create_fd(fd, 1024, FALSE);
10139N/A o_stream_seek(output, 1);
10139N/A test_assert(o_stream_send_istream(output, input) > 0);
10139N/A test_assert(output->offset == 5);
10139N/A test_assert(pread(fd, buf, sizeof(buf), 0) == 5 &&
10139N/A memcmp(buf, "11234", 5) == 0);
10139N/A i_stream_destroy(&input);
10139N/A
10139N/A o_stream_destroy(&output);
10139N/A
10139N/A i_unlink(".temp.istream");
10914N/A i_unlink(".temp.ostream");
10139N/A test_end();
10139N/A}
10139N/A
10139N/Avoid test_ostream_file(void)
10139N/A{
20332N/A test_ostream_file_random();
20332N/A test_ostream_file_send_istream_file();
20196N/A}
20196N/A