bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainenstatic void test_compression_handler(const struct compression_handler *handler)
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen unsigned char output_sha1[SHA1_RESULTLEN], input_sha1[SHA1_RESULTLEN];
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen unsigned int i;
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen test_begin(t_strdup_printf("compression handler %s", handler->name));
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* write compressed data */
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen fd = open(path, O_TRUNC | O_CREAT | O_RDWR, 0600);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen file_output = o_stream_create_fd_file(fd, 0, FALSE);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen output = handler->create_ostream(file_output, 1);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* 1) write lots of easily compressible data */
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen for (i = 0; i < 1024*1024*4 / sizeof(buf); i++) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen test_assert(o_stream_send(output, buf, sizeof(buf)) == sizeof(buf));
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* 2) write uncompressible data */
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen for (i = 0; i < 1024*128 / sizeof(buf); i++) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen test_assert(o_stream_send(output, buf, sizeof(buf)) == sizeof(buf));
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* 3) write semi-compressible data */
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen for (i = 0; i < sizeof(buf); i++) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen for (i = 0; i < 1024*128 / sizeof(buf); i++) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen test_assert(o_stream_send(output, buf, sizeof(buf)) == sizeof(buf));
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* read and uncompress the data */
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi file_input = i_stream_create_fd(fd, IO_BLOCK_SIZE);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen input = handler->create_istream(file_input, FALSE);
3858a7a5da361c35f1e6e50c8e3214dc0cf379d6Phil Carmody while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen test_assert(memcmp(input_sha1, output_sha1, sizeof(input_sha1)) == 0);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen unsigned int i;
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen for (i = 0; compression_handlers[i].name != NULL; i++) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen if (compression_handlers[i].create_istream != NULL)
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen test_compression_handler(&compression_handlers[i]);
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainenstatic void test_gz(const char *str1, const char *str2)
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen const struct compression_handler *gz = compression_lookup_handler("gz");
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen return; /* not compiled in */
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen /* write concated output */
8e8b9d01d454fc3dc81dbe3fd1cca772d1d2c381Timo Sirainen o_stream_set_finish_via_child(buf_output, FALSE);
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen /* read concated input */
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen test_input = test_istream_create_data(buf->data, buf->used);
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen test_istream_set_allow_eof(test_input, FALSE);
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen test_assert(size == strlen(str1)+strlen(str2) &&
e7f31dfdcf5c51983bc4a489d69714f763128c18Timo Sirainen memcmp(data+strlen(str1), str2, strlen(str2)) == 0);
b317602a1dd7588710bd004404cd68cf2d699361Timo Sirainen const struct compression_handler *gz = compression_lookup_handler("gz");
b317602a1dd7588710bd004404cd68cf2d699361Timo Sirainen return; /* not compiled in */
d827cffa4b59591ab2a5a710237e34839ed6a952Timo Sirainen /* max buffer size smaller than gz header */
d827cffa4b59591ab2a5a710237e34839ed6a952Timo Sirainen file_input = test_istream_create_data(gz_input, sizeof(gz_input));
d827cffa4b59591ab2a5a710237e34839ed6a952Timo Sirainen test_istream_set_max_buffer_size(file_input, i);
b317602a1dd7588710bd004404cd68cf2d699361Timo Sirainen input = gz->create_istream(file_input, FALSE);
d827cffa4b59591ab2a5a710237e34839ed6a952Timo Sirainen test_assert_idx(i_stream_read(input) == 0, i);
d827cffa4b59591ab2a5a710237e34839ed6a952Timo Sirainen /* max buffer size is exactly the gz header */
d827cffa4b59591ab2a5a710237e34839ed6a952Timo Sirainen file_input = test_istream_create_data(gz_input, sizeof(gz_input));
b317602a1dd7588710bd004404cd68cf2d699361Timo Sirainen input = gz->create_istream(file_input, FALSE);
697a4fbe2d9cd776b8ceecb0c907a7ad55d3153eTimo Sirainenstatic void test_uncompress_file(const char *path)
697a4fbe2d9cd776b8ceecb0c907a7ad55d3153eTimo Sirainen handler = compression_lookup_handler_from_ext(path);
697a4fbe2d9cd776b8ceecb0c907a7ad55d3153eTimo Sirainen i_fatal("Can't detect compression algorithm from path %s", path);
697a4fbe2d9cd776b8ceecb0c907a7ad55d3153eTimo Sirainen i_fatal("Support not compiled in for %s", handler->name);
697a4fbe2d9cd776b8ceecb0c907a7ad55d3153eTimo Sirainen file_input = i_stream_create_file(path, IO_BLOCK_SIZE);
00bcc83b18793b9ec5e5d264480a88bf78b10b33Timo Sirainen input = handler->create_istream(file_input, TRUE);
697a4fbe2d9cd776b8ceecb0c907a7ad55d3153eTimo Sirainen while (i_stream_read_more(input, &data, &size) > 0) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainenstatic void test_compress_file(const char *in_path, const char *out_path)
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen unsigned char output_sha1[SHA1_RESULTLEN], input_sha1[SHA1_RESULTLEN];
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen handler = compression_lookup_handler_from_ext(out_path);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen i_fatal("Can't detect compression algorithm from path %s", out_path);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen i_fatal("Support not compiled in for %s", handler->name);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* write the compressed output file */
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen fd_out = open(out_path, O_TRUNC | O_CREAT | O_RDWR, 0600);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen file_output = o_stream_create_fd_file(fd_out, 0, FALSE);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen output = handler->create_ostream(file_output, 1);
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen input = i_stream_create_fd_autoclose(&fd_in, IO_BLOCK_SIZE);
3858a7a5da361c35f1e6e50c8e3214dc0cf379d6Phil Carmody while (i_stream_read_more(input, &data, &size) > 0) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen /* verify that we can read the compressed file */
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi file_input = i_stream_create_fd(fd_out, IO_BLOCK_SIZE);
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen input = handler->create_istream(file_input, FALSE);
3858a7a5da361c35f1e6e50c8e3214dc0cf379d6Phil Carmody while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen if (memcmp(input_sha1, output_sha1, sizeof(input_sha1)) != 0)
443fd76b8dfbb708bf2eab8bf5fe7440cc90eb13Timo Sirainen i_fatal("Decompression couldn't get the original input");
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {