1/*- 2 * Copyright (c) 2007 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "test.h" 28__FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_compress_gzip.c 191183 2009-04-17 01:06:31Z kientzle $"); 29 30/* 31 * A basic exercise of gzip reading and writing. 32 * 33 * TODO: Add a reference file and make sure we can decompress that. 34 */ 35 36DEFINE_TEST(test_write_filter_gzip) 37{ 38 struct archive_entry *ae; 39 struct archive* a; 40 char *buff, *data; 41 size_t buffsize, datasize; 42 char path[16]; 43 size_t used1, used2; 44 int i, r, use_prog = 0; 45 46 buffsize = 2000000; 47 assert(NULL != (buff = (char *)malloc(buffsize))); 48 if (buff == NULL) 49 return; 50 51 datasize = 10000; 52 assert(NULL != (data = (char *)malloc(datasize))); 53 if (data == NULL) { 54 free(buff); 55 return; 56 } 57 memset(data, 0, datasize); 58 59 /* 60 * Write a 100 files and read them all back. 61 */ 62 assert((a = archive_write_new()) != NULL); 63 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 64 r = archive_write_add_filter_gzip(a); 65 if (r != ARCHIVE_OK) { 66 if (canGzip() && r == ARCHIVE_WARN) 67 use_prog = 1; 68 else { 69 skipping("gzip writing not supported on this platform"); 70 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 71 free(buff); 72 free(data); 73 return; 74 } 75 } 76 assertEqualIntA(a, ARCHIVE_OK, 77 archive_write_set_bytes_per_block(a, 10)); 78 assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0)); 79 assertEqualString("gzip", archive_filter_name(a, 0)); 80 assertEqualIntA(a, ARCHIVE_OK, 81 archive_write_open_memory(a, buff, buffsize, &used1)); 82 assert((ae = archive_entry_new()) != NULL); 83 archive_entry_set_filetype(ae, AE_IFREG); 84 archive_entry_set_size(ae, datasize); 85 for (i = 0; i < 100; i++) { 86 sprintf(path, "file%03d", i); 87 archive_entry_copy_pathname(ae, path); 88 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 89 assertA(datasize 90 == (size_t)archive_write_data(a, data, datasize)); 91 } 92 archive_entry_free(ae); 93 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 94 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 95 96 assert((a = archive_read_new()) != NULL); 97 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 98 r = archive_read_support_filter_gzip(a); 99 if (r == ARCHIVE_WARN) { 100 skipping("Can't verify gzip writing by reading back;" 101 " gzip reading not fully supported on this platform"); 102 } else { 103 assertEqualIntA(a, ARCHIVE_OK, 104 archive_read_open_memory(a, buff, used1)); 105 for (i = 0; i < 100; i++) { 106 sprintf(path, "file%03d", i); 107 if (!assertEqualInt(ARCHIVE_OK, 108 archive_read_next_header(a, &ae))) 109 break; 110 assertEqualString(path, archive_entry_pathname(ae)); 111 assertEqualInt((int)datasize, archive_entry_size(ae)); 112 } 113 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 114 } 115 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 116 117 /* 118 * Repeat the cycle again, this time setting some compression 119 * options. 120 */ 121 assert((a = archive_write_new()) != NULL); 122 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 123 assertEqualIntA(a, ARCHIVE_OK, 124 archive_write_set_bytes_per_block(a, 10)); 125 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 126 archive_write_add_filter_gzip(a)); 127 assertEqualIntA(a, ARCHIVE_FAILED, 128 archive_write_set_options(a, "gzip:nonexistent-option=0")); 129 assertEqualIntA(a, ARCHIVE_OK, 130 archive_write_set_options(a, "gzip:compression-level=1")); 131 assertEqualIntA(a, ARCHIVE_OK, 132 archive_write_set_filter_option(a, NULL, "compression-level", "9")); 133 assertEqualIntA(a, ARCHIVE_FAILED, 134 archive_write_set_filter_option(a, NULL, "compression-level", "abc")); 135 assertEqualIntA(a, ARCHIVE_FAILED, 136 archive_write_set_filter_option(a, NULL, "compression-level", "99")); 137 assertEqualIntA(a, ARCHIVE_OK, 138 archive_write_set_options(a, "gzip:compression-level=9")); 139 assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); 140 for (i = 0; i < 100; i++) { 141 sprintf(path, "file%03d", i); 142 assert((ae = archive_entry_new()) != NULL); 143 archive_entry_copy_pathname(ae, path); 144 archive_entry_set_size(ae, datasize); 145 archive_entry_set_filetype(ae, AE_IFREG); 146 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 147 assertA(datasize == (size_t)archive_write_data(a, data, datasize)); 148 archive_entry_free(ae); 149 } 150 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 151 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 152 153 /* Curiously, this test fails; the test data above compresses 154 * better at default compression than at level 9. */ 155 /* 156 failure("compression-level=9 wrote %d bytes, default wrote %d bytes", 157 (int)used2, (int)used1); 158 assert(used2 < used1); 159 */ 160 161 assert((a = archive_read_new()) != NULL); 162 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 163 r = archive_read_support_filter_gzip(a); 164 if (r != ARCHIVE_OK && !use_prog) { 165 skipping("gzip reading not fully supported on this platform"); 166 } else { 167 assertEqualIntA(a, ARCHIVE_OK, 168 archive_read_support_filter_all(a)); 169 assertEqualIntA(a, ARCHIVE_OK, 170 archive_read_open_memory(a, buff, used2)); 171 for (i = 0; i < 100; i++) { 172 sprintf(path, "file%03d", i); 173 if (!assertEqualInt(ARCHIVE_OK, 174 archive_read_next_header(a, &ae))) 175 break; 176 assertEqualString(path, archive_entry_pathname(ae)); 177 assertEqualInt((int)datasize, archive_entry_size(ae)); 178 } 179 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 180 } 181 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 182 183 /* 184 * Repeat again, with much lower compression. 185 */ 186 assert((a = archive_write_new()) != NULL); 187 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 188 assertEqualIntA(a, ARCHIVE_OK, 189 archive_write_set_bytes_per_block(a, 10)); 190 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 191 archive_write_add_filter_gzip(a)); 192 assertEqualIntA(a, ARCHIVE_OK, 193 archive_write_set_filter_option(a, NULL, "compression-level", "1")); 194 assertEqualIntA(a, ARCHIVE_OK, 195 archive_write_open_memory(a, buff, buffsize, &used2)); 196 for (i = 0; i < 100; i++) { 197 sprintf(path, "file%03d", i); 198 assert((ae = archive_entry_new()) != NULL); 199 archive_entry_copy_pathname(ae, path); 200 archive_entry_set_size(ae, datasize); 201 archive_entry_set_filetype(ae, AE_IFREG); 202 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 203 failure("Writing file %s", path); 204 assertEqualIntA(a, datasize, 205 (size_t)archive_write_data(a, data, datasize)); 206 archive_entry_free(ae); 207 } 208 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 209 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 210 211 /* Level 1 really does result in larger data. */ 212 failure("Compression-level=1 wrote %d bytes; default wrote %d bytes", 213 (int)used2, (int)used1); 214 assert(used2 > used1); 215 216 assert((a = archive_read_new()) != NULL); 217 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 218 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 219 r = archive_read_support_filter_gzip(a); 220 if (r == ARCHIVE_WARN) { 221 skipping("gzip reading not fully supported on this platform"); 222 } else { 223 assertEqualIntA(a, ARCHIVE_OK, 224 archive_read_open_memory(a, buff, used2)); 225 for (i = 0; i < 100; i++) { 226 sprintf(path, "file%03d", i); 227 if (!assertEqualInt(ARCHIVE_OK, 228 archive_read_next_header(a, &ae))) 229 break; 230 assertEqualString(path, archive_entry_pathname(ae)); 231 assertEqualInt((int)datasize, archive_entry_size(ae)); 232 } 233 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 234 } 235 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 236 237 /* 238 * Test various premature shutdown scenarios to make sure we 239 * don't crash or leak memory. 240 */ 241 assert((a = archive_write_new()) != NULL); 242 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 243 archive_write_add_filter_gzip(a)); 244 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 245 246 assert((a = archive_write_new()) != NULL); 247 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 248 archive_write_add_filter_gzip(a)); 249 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 250 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 251 252 assert((a = archive_write_new()) != NULL); 253 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 254 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 255 archive_write_add_filter_gzip(a)); 256 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 257 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 258 259 assert((a = archive_write_new()) != NULL); 260 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 261 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 262 archive_write_add_filter_gzip(a)); 263 assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); 264 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 265 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 266 267 /* 268 * Clean up. 269 */ 270 free(data); 271 free(buff); 272} 273