1 /*- 2 * Copyright (c) 2014 Michihiro NAKAJIMA 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 29 /* 30 * A basic exercise of lz4 reading and writing. 31 */ 32 33 DEFINE_TEST(test_write_filter_lz4) 34 { 35 struct archive_entry *ae; 36 struct archive* a; 37 char *buff, *data; 38 size_t buffsize, datasize; 39 char path[16]; 40 size_t used1, used2; 41 int i, r, use_prog = 0, filecount; 42 43 assert((a = archive_write_new()) != NULL); 44 r = archive_write_add_filter_lz4(a); 45 if (archive_liblz4_version() == NULL) { 46 if (!canLz4()) { 47 skipping("lz4 writing not supported on this platform"); 48 assertEqualInt(ARCHIVE_WARN, r); 49 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 50 return; 51 } else { 52 assertEqualInt(ARCHIVE_WARN, r); 53 use_prog = 1; 54 } 55 } else { 56 assertEqualInt(ARCHIVE_OK, r); 57 } 58 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 59 60 buffsize = 2000000; 61 assert(NULL != (buff = (char *)malloc(buffsize))); 62 63 datasize = 10000; 64 assert(NULL != (data = (char *)calloc(datasize, 1))); 65 filecount = 10; 66 67 /* 68 * Write a filecount files and read them all back. 69 */ 70 assert((a = archive_write_new()) != NULL); 71 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 72 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 73 archive_write_add_filter_lz4(a)); 74 assertEqualIntA(a, ARCHIVE_OK, 75 archive_write_set_bytes_per_block(a, 1024)); 76 assertEqualIntA(a, ARCHIVE_OK, 77 archive_write_set_bytes_in_last_block(a, 1024)); 78 assertEqualInt(ARCHIVE_FILTER_LZ4, archive_filter_code(a, 0)); 79 assertEqualString("lz4", 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 < filecount; i++) { 86 snprintf(path, sizeof(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_lz4(a); 99 if (r == ARCHIVE_WARN) { 100 skipping("Can't verify lz4 writing by reading back;" 101 " lz4 reading not fully supported on this platform"); 102 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 103 return; 104 } 105 106 assertEqualIntA(a, ARCHIVE_OK, 107 archive_read_open_memory(a, buff, used1)); 108 for (i = 0; i < filecount; i++) { 109 snprintf(path, sizeof(path), "file%03d", i); 110 if (!assertEqualInt(ARCHIVE_OK, 111 archive_read_next_header(a, &ae))) 112 break; 113 assertEqualString(path, archive_entry_pathname(ae)); 114 assertEqualInt((int)datasize, archive_entry_size(ae)); 115 } 116 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 117 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 118 119 /* 120 * Repeat the cycle again, this time setting some compression 121 * options. 122 */ 123 assert((a = archive_write_new()) != NULL); 124 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 125 assertEqualIntA(a, ARCHIVE_OK, 126 archive_write_set_bytes_per_block(a, 10)); 127 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 128 archive_write_add_filter_lz4(a)); 129 assertEqualIntA(a, ARCHIVE_FAILED, 130 archive_write_set_options(a, "lz4:nonexistent-option=0")); 131 assertEqualIntA(a, ARCHIVE_OK, 132 archive_write_set_options(a, "lz4:compression-level=1")); 133 assertEqualIntA(a, ARCHIVE_OK, 134 archive_write_set_filter_option(a, NULL, "compression-level", "9")); 135 assertEqualIntA(a, ARCHIVE_FAILED, 136 archive_write_set_filter_option(a, NULL, "compression-level", "abc")); 137 assertEqualIntA(a, ARCHIVE_FAILED, 138 archive_write_set_filter_option(a, NULL, "compression-level", "99")); 139 assertEqualIntA(a, ARCHIVE_OK, 140 archive_write_set_options(a, "lz4:compression-level=9")); 141 assertEqualIntA(a, ARCHIVE_OK, 142 archive_write_open_memory(a, buff, buffsize, &used2)); 143 for (i = 0; i < filecount; i++) { 144 snprintf(path, sizeof(path), "file%03d", i); 145 assert((ae = archive_entry_new()) != NULL); 146 archive_entry_copy_pathname(ae, path); 147 archive_entry_set_size(ae, datasize); 148 archive_entry_set_filetype(ae, AE_IFREG); 149 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 150 assertA(datasize == (size_t)archive_write_data( 151 a, data, datasize)); 152 archive_entry_free(ae); 153 } 154 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 155 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 156 157 failure("compression-level=9 wrote %d bytes, default wrote %d bytes", 158 (int)used2, (int)used1); 159 assert(used2 < used1); 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_lz4(a); 164 if (r != ARCHIVE_OK && !use_prog) { 165 skipping("lz4 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 < filecount; i++) { 172 snprintf(path, sizeof(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_lz4(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 < filecount; i++) { 197 snprintf(path, sizeof(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 #if 0 212 failure("Compression-level=1 wrote %d bytes; default wrote %d bytes", 213 (int)used2, (int)used1); 214 assert(used2 > used1); 215 #endif 216 217 assert((a = archive_read_new()) != NULL); 218 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 219 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 220 r = archive_read_support_filter_lz4(a); 221 if (r == ARCHIVE_WARN) { 222 skipping("lz4 reading not fully supported on this platform"); 223 } else { 224 assertEqualIntA(a, ARCHIVE_OK, 225 archive_read_open_memory(a, buff, used2)); 226 for (i = 0; i < filecount; i++) { 227 snprintf(path, sizeof(path), "file%03d", i); 228 if (!assertEqualInt(ARCHIVE_OK, 229 archive_read_next_header(a, &ae))) 230 break; 231 assertEqualString(path, archive_entry_pathname(ae)); 232 assertEqualInt((int)datasize, archive_entry_size(ae)); 233 } 234 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 235 } 236 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 237 238 /* 239 * Test various premature shutdown scenarios to make sure we 240 * don't crash or leak memory. 241 */ 242 assert((a = archive_write_new()) != NULL); 243 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 244 archive_write_add_filter_lz4(a)); 245 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 246 247 assert((a = archive_write_new()) != NULL); 248 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 249 archive_write_add_filter_lz4(a)); 250 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 251 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 252 253 assert((a = archive_write_new()) != NULL); 254 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 255 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 256 archive_write_add_filter_lz4(a)); 257 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 258 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 259 260 assert((a = archive_write_new()) != NULL); 261 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 262 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 263 archive_write_add_filter_lz4(a)); 264 assertEqualIntA(a, ARCHIVE_OK, 265 archive_write_open_memory(a, buff, buffsize, &used2)); 266 assertEqualInt(ARCHIVE_OK, archive_write_close(a)); 267 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 268 269 /* 270 * Clean up. 271 */ 272 free(data); 273 free(buff); 274 } 275 276 static void 277 test_options(const char *options) 278 { 279 struct archive_entry *ae; 280 struct archive* a; 281 char *buff, *data; 282 size_t buffsize, datasize; 283 char path[16]; 284 size_t used1; 285 int i, r, use_prog = 0, filecount; 286 287 assert((a = archive_write_new()) != NULL); 288 r = archive_write_add_filter_lz4(a); 289 if (archive_liblz4_version() == NULL) { 290 if (!canLz4()) { 291 skipping("lz4 writing not supported on this platform"); 292 assertEqualInt(ARCHIVE_WARN, r); 293 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 294 return; 295 } else { 296 assertEqualInt(ARCHIVE_WARN, r); 297 use_prog = 1; 298 } 299 } else { 300 assertEqualInt(ARCHIVE_OK, r); 301 } 302 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 303 304 buffsize = 2000000; 305 assert(NULL != (buff = (char *)malloc(buffsize))); 306 307 datasize = 10000; 308 assert(NULL != (data = (char *)calloc(datasize, 1))); 309 filecount = 10; 310 311 /* 312 * Write a filecount files and read them all back. 313 */ 314 assert((a = archive_write_new()) != NULL); 315 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); 316 assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK, 317 archive_write_add_filter_lz4(a)); 318 assertEqualIntA(a, ARCHIVE_OK, 319 archive_write_set_options(a, options)); 320 assertEqualIntA(a, ARCHIVE_OK, 321 archive_write_set_bytes_per_block(a, 1024)); 322 assertEqualIntA(a, ARCHIVE_OK, 323 archive_write_set_bytes_in_last_block(a, 1024)); 324 assertEqualInt(ARCHIVE_FILTER_LZ4, archive_filter_code(a, 0)); 325 assertEqualString("lz4", archive_filter_name(a, 0)); 326 assertEqualIntA(a, ARCHIVE_OK, 327 archive_write_open_memory(a, buff, buffsize, &used1)); 328 assert((ae = archive_entry_new()) != NULL); 329 archive_entry_set_filetype(ae, AE_IFREG); 330 archive_entry_set_size(ae, datasize); 331 for (i = 0; i < filecount; i++) { 332 snprintf(path, sizeof(path), "file%03d", i); 333 archive_entry_copy_pathname(ae, path); 334 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 335 assertA(datasize 336 == (size_t)archive_write_data(a, data, datasize)); 337 } 338 archive_entry_free(ae); 339 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 340 assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 341 342 assert((a = archive_read_new()) != NULL); 343 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 344 r = archive_read_support_filter_lz4(a); 345 if (r == ARCHIVE_WARN) { 346 skipping("Can't verify lz4 writing by reading back;" 347 " lz4 reading not fully supported on this platform"); 348 } else { 349 assertEqualIntA(a, ARCHIVE_OK, 350 archive_read_open_memory(a, buff, used1)); 351 for (i = 0; i < filecount; i++) { 352 snprintf(path, sizeof(path), "file%03d", i); 353 if (!assertEqualInt(ARCHIVE_OK, 354 archive_read_next_header(a, &ae))) 355 break; 356 assertEqualString(path, archive_entry_pathname(ae)); 357 assertEqualInt((int)datasize, archive_entry_size(ae)); 358 } 359 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 360 } 361 assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 362 363 /* 364 * Clean up. 365 */ 366 free(data); 367 free(buff); 368 } 369 370 DEFINE_TEST(test_write_filter_lz4_disable_stream_checksum) 371 { 372 test_options("lz4:!stream-checksum"); 373 } 374 375 DEFINE_TEST(test_write_filter_lz4_enable_block_checksum) 376 { 377 test_options("lz4:block-checksum"); 378 } 379 380 DEFINE_TEST(test_write_filter_lz4_block_size_4) 381 { 382 test_options("lz4:block-size=4"); 383 } 384 385 DEFINE_TEST(test_write_filter_lz4_block_size_5) 386 { 387 test_options("lz4:block-size=5"); 388 } 389 390 DEFINE_TEST(test_write_filter_lz4_block_size_6) 391 { 392 test_options("lz4:block-size=6"); 393 } 394 395 DEFINE_TEST(test_write_filter_lz4_block_dependence) 396 { 397 test_options("lz4:block-dependence"); 398 } 399 400 /* 401 * TODO: Figure out how to correctly handle this. 402 * 403 * This option simply fails on some versions of the LZ4 libraries. 404 */ 405 /* 406 XXXDEFINE_TEST(test_write_filter_lz4_block_dependence_hc) 407 { 408 test_options("lz4:block-dependence,lz4:compression-level=9"); 409 } 410 */ 411