test-compression.c revision 8e8b9d01d454fc3dc81dbe3fd1cca772d1d2c381
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2014-2017 Dovecot authors, see the included COPYING file */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainenstatic void test_compression_handler(const struct compression_handler *handler)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const unsigned char *data;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned char output_sha1[SHA1_RESULTLEN], input_sha1[SHA1_RESULTLEN];
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int i;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_begin(t_strdup_printf("compression handler %s", handler->name));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* write compressed data */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen fd = open(path, O_TRUNC | O_CREAT | O_RDWR, 0600);
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen file_output = o_stream_create_fd_file(fd, 0, FALSE);
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen output = handler->create_ostream(file_output, 1);
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen /* 1) write lots of easily compressible data */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < 1024*1024*4 / sizeof(buf); i++) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_assert(o_stream_send(output, buf, sizeof(buf)) == sizeof(buf));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* 2) write uncompressible data */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < 1024*128 / sizeof(buf); i++) {
9eef11df882f9c14d164f42cb438f32fe724041cTimo Sirainen test_assert(o_stream_send(output, buf, sizeof(buf)) == sizeof(buf));
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen /* 3) write semi-compressible data */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen for (i = 0; i < sizeof(buf); i++) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen for (i = 0; i < 1024*128 / sizeof(buf); i++) {
6abf66a3731d52889517bd644595c540e3a9b3ecTimo Sirainen test_assert(o_stream_send(output, buf, sizeof(buf)) == sizeof(buf));
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen /* read and uncompress the data */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen file_input = i_stream_create_fd(fd, IO_BLOCK_SIZE);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen input = handler->create_istream(file_input, FALSE);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_assert(memcmp(input_sha1, output_sha1, sizeof(input_sha1)) == 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void test_compression(void)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen unsigned int i;
47255691575e06a1c95ce78ff0a1b502199de3abTimo Sirainen for (i = 0; compression_handlers[i].name != NULL; i++) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen if (compression_handlers[i].create_istream != NULL)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_compression_handler(&compression_handlers[i]);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void test_gz(const char *str1, const char *str2)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const struct compression_handler *gz = compression_lookup_handler("gz");
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen buffer_t *buf = buffer_create_dynamic(pool_datastack_create(), 512);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return; /* not compiled in */
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen /* write concated output */
d9b9687bf8cae9cfb070b1b7aadefa683220269fTimo Sirainen o_stream_set_finish_via_child(buf_output, FALSE);
31d32d39dd09be0625a6d92ee715155f5d679515Timo Sirainen /* read concated input */
31d32d39dd09be0625a6d92ee715155f5d679515Timo Sirainen const unsigned char *data;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_input = test_istream_create_data(buf->data, buf->used);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_istream_set_allow_eof(test_input, FALSE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_assert(size == strlen(str1)+strlen(str2) &&
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen memcmp(data+strlen(str1), str2, strlen(str2)) == 0);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void test_gz_concat(void)
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainenstatic void test_gz_no_concat(void)
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen const struct compression_handler *gz = compression_lookup_handler("gz");
ec0cc8fa647794e44a1afaa448f495a713048dc4Timo Sirainen static const unsigned char gz_input[] = {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen return; /* not compiled in */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* max buffer size smaller than gz header */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen file_input = test_istream_create_data(gz_input, sizeof(gz_input));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_istream_set_max_buffer_size(file_input, i);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen input = gz->create_istream(file_input, FALSE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen test_assert_idx(i_stream_read(input) == 0, i);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen /* max buffer size is exactly the gz header */
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen file_input = test_istream_create_data(gz_input, sizeof(gz_input));
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen input = gz->create_istream(file_input, FALSE);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void test_uncompress_file(const char *path)
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen const unsigned char *data;
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen handler = compression_lookup_handler_from_ext(path);
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainen i_fatal("Can't detect compression algorithm from path %s", path);
efeb13303798b47d2c4295468d233c1bcfd79c94Timo Sirainen i_fatal("Support not compiled in for %s", handler->name);
307ec6c2c319e3335ddb1a7aca2d2884fe17fae0Timo Sirainen file_input = i_stream_create_file(path, IO_BLOCK_SIZE);
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen input = handler->create_istream(file_input, TRUE);
975a784c2e02ecdcb56efb7a1db5e4769c7756d8Timo Sirainen while (i_stream_read_more(input, &data, &size) > 0) {
7bd5b1c64cc987715bdaf8cc4907c3c37d5d7b29Timo Sirainenstatic void test_compress_file(const char *in_path, const char *out_path)
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen unsigned char output_sha1[SHA1_RESULTLEN], input_sha1[SHA1_RESULTLEN];
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen const unsigned char *data;
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen handler = compression_lookup_handler_from_ext(out_path);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen i_fatal("Can't detect compression algorithm from path %s", out_path);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen i_fatal("Support not compiled in for %s", handler->name);
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* write the compressed output file */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen fd_out = open(out_path, O_TRUNC | O_CREAT | O_RDWR, 0600);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen file_output = o_stream_create_fd_file(fd_out, 0, FALSE);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen output = handler->create_ostream(file_output, 1);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen input = i_stream_create_fd_autoclose(&fd_in, IO_BLOCK_SIZE);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen while (i_stream_read_more(input, &data, &size) > 0) {
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen /* verify that we can read the compressed file */
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen file_input = i_stream_create_fd(fd_out, IO_BLOCK_SIZE);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen input = handler->create_istream(file_input, FALSE);
55d33f807765482eb47374aaaced1fe714e0b256Timo Sirainen while ((ret = i_stream_read_more(input, &data, &size)) > 0) {
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen if (memcmp(input_sha1, output_sha1, sizeof(input_sha1)) != 0)
5e32f3d9e2c58b6db53cc3b063c9ee73949207caTimo Sirainen i_fatal("Decompression couldn't get the original input");
41e51b972f02e8b16c19fab9160294ea0a07c343Timo Sirainen static void (*const test_functions[])(void) = {