1228753Smm/*-
2228753Smm * Copyright (c) 2007 Tim Kientzle
3228753Smm * All rights reserved.
4228753Smm *
5228753Smm * Redistribution and use in source and binary forms, with or without
6228753Smm * modification, are permitted provided that the following conditions
7228753Smm * are met:
8228753Smm * 1. Redistributions of source code must retain the above copyright
9228753Smm *    notice, this list of conditions and the following disclaimer
10228753Smm *    in this position and unchanged.
11228753Smm * 2. Redistributions in binary form must reproduce the above copyright
12228753Smm *    notice, this list of conditions and the following disclaimer in the
13228753Smm *    documentation and/or other materials provided with the distribution.
14228753Smm *
15228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25228753Smm */
26228753Smm
27228753Smm#include "test.h"
28229592Smm__FBSDID("$FreeBSD$");
29228753Smm
30228753Smm/*
31228753Smm * A basic exercise of gzip reading and writing.
32228753Smm *
33228753Smm * TODO: Add a reference file and make sure we can decompress that.
34228753Smm */
35228753Smm
36228753SmmDEFINE_TEST(test_write_compress_gzip)
37228753Smm{
38228753Smm	struct archive_entry *ae;
39228753Smm	struct archive* a;
40228753Smm	char *buff, *data;
41228753Smm	size_t buffsize, datasize;
42228753Smm	char path[16];
43228753Smm	size_t used1, used2;
44228753Smm	int i, r;
45228753Smm
46228753Smm	buffsize = 2000000;
47228753Smm	assert(NULL != (buff = (char *)malloc(buffsize)));
48228753Smm
49228753Smm	datasize = 10000;
50228753Smm	assert(NULL != (data = (char *)malloc(datasize)));
51228753Smm	memset(data, 0, datasize);
52228753Smm
53228753Smm	/*
54228753Smm	 * Write a 100 files and read them all back.
55228753Smm	 */
56228753Smm	assert((a = archive_write_new()) != NULL);
57228753Smm	assertA(0 == archive_write_set_format_ustar(a));
58228753Smm	r = archive_write_set_compression_gzip(a);
59228753Smm	if (r == ARCHIVE_FATAL) {
60228753Smm		skipping("gzip writing not supported on this platform");
61228753Smm		assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
62228753Smm		return;
63228753Smm	}
64228753Smm	assertEqualIntA(a, ARCHIVE_OK,
65228753Smm	    archive_write_set_bytes_per_block(a, 10));
66228753Smm	assertEqualInt(ARCHIVE_COMPRESSION_GZIP, archive_compression(a));
67228753Smm	assertEqualString("gzip", archive_compression_name(a));
68228753Smm	assertA(0 == archive_write_open_memory(a, buff, buffsize, &used1));
69228753Smm	assertEqualInt(ARCHIVE_COMPRESSION_GZIP, archive_compression(a));
70228753Smm	assertEqualString("gzip", archive_compression_name(a));
71228753Smm	assert((ae = archive_entry_new()) != NULL);
72228753Smm	archive_entry_set_filetype(ae, AE_IFREG);
73228753Smm	archive_entry_set_size(ae, datasize);
74228753Smm	for (i = 0; i < 100; i++) {
75228753Smm		sprintf(path, "file%03d", i);
76228753Smm		archive_entry_copy_pathname(ae, path);
77228753Smm		assertA(0 == archive_write_header(a, ae));
78228753Smm		assertA(datasize
79228753Smm		    == (size_t)archive_write_data(a, data, datasize));
80228753Smm	}
81228753Smm	archive_entry_free(ae);
82228753Smm	archive_write_close(a);
83228753Smm	assert(0 == archive_write_finish(a));
84228753Smm
85228753Smm	assert((a = archive_read_new()) != NULL);
86228753Smm	assertA(0 == archive_read_support_format_all(a));
87228753Smm	r = archive_read_support_compression_gzip(a);
88228753Smm	if (r == ARCHIVE_WARN) {
89228753Smm		skipping("Can't verify gzip writing by reading back;"
90228753Smm		    " gzip reading not fully supported on this platform");
91228753Smm	} else {
92228753Smm		assertEqualIntA(a, ARCHIVE_OK,
93228753Smm		    archive_read_support_compression_all(a));
94228753Smm		assertEqualIntA(a, ARCHIVE_OK,
95228753Smm		    archive_read_open_memory(a, buff, used1));
96228753Smm		for (i = 0; i < 100; i++) {
97228753Smm			sprintf(path, "file%03d", i);
98228753Smm			if (!assertEqualInt(ARCHIVE_OK,
99228753Smm				archive_read_next_header(a, &ae)))
100228753Smm				break;
101228753Smm			assertEqualString(path, archive_entry_pathname(ae));
102228753Smm			assertEqualInt((int)datasize, archive_entry_size(ae));
103228753Smm		}
104228753Smm		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
105228753Smm	}
106228753Smm	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
107228753Smm
108228753Smm	/*
109228753Smm	 * Repeat the cycle again, this time setting some compression
110228753Smm	 * options.
111228753Smm	 */
112228753Smm	assert((a = archive_write_new()) != NULL);
113228753Smm	assertA(0 == archive_write_set_format_ustar(a));
114228753Smm	assertEqualIntA(a, ARCHIVE_OK,
115228753Smm	    archive_write_set_bytes_per_block(a, 10));
116228753Smm	assertA(0 == archive_write_set_compression_gzip(a));
117228753Smm	assertEqualIntA(a, ARCHIVE_WARN,
118228753Smm	    archive_write_set_compressor_options(a, "nonexistent-option=0"));
119228753Smm	assertEqualIntA(a, ARCHIVE_WARN,
120228753Smm	    archive_write_set_compressor_options(a, "compression-level=abc"));
121228753Smm	assertEqualIntA(a, ARCHIVE_WARN,
122228753Smm	    archive_write_set_compressor_options(a, "compression-level=99"));
123228753Smm	assertEqualIntA(a, ARCHIVE_OK,
124228753Smm	    archive_write_set_compressor_options(a, "compression-level=9"));
125228753Smm	assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
126228753Smm	for (i = 0; i < 100; i++) {
127228753Smm		sprintf(path, "file%03d", i);
128228753Smm		assert((ae = archive_entry_new()) != NULL);
129228753Smm		archive_entry_copy_pathname(ae, path);
130228753Smm		archive_entry_set_size(ae, datasize);
131228753Smm		archive_entry_set_filetype(ae, AE_IFREG);
132228753Smm		assertA(0 == archive_write_header(a, ae));
133228753Smm		assertA(datasize == (size_t)archive_write_data(a, data, datasize));
134228753Smm		archive_entry_free(ae);
135228753Smm	}
136228753Smm	archive_write_close(a);
137228753Smm	assert(0 == archive_write_finish(a));
138228753Smm
139228753Smm	/* Curiously, this test fails; the test data above compresses
140228753Smm	 * better at default compression than at level 9. */
141228753Smm	/*
142228753Smm	failure("compression-level=9 wrote %d bytes, default wrote %d bytes",
143228753Smm	    (int)used2, (int)used1);
144228753Smm	assert(used2 < used1);
145228753Smm	*/
146228753Smm
147228753Smm	assert((a = archive_read_new()) != NULL);
148228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
149228753Smm	r = archive_read_support_compression_gzip(a);
150228753Smm	if (r == ARCHIVE_WARN) {
151228753Smm		skipping("gzip reading not fully supported on this platform");
152228753Smm	} else {
153228753Smm		assertEqualIntA(a, ARCHIVE_OK,
154228753Smm		    archive_read_support_compression_all(a));
155228753Smm		assertEqualIntA(a, ARCHIVE_OK,
156228753Smm		    archive_read_open_memory(a, buff, used2));
157228753Smm		for (i = 0; i < 100; i++) {
158228753Smm			sprintf(path, "file%03d", i);
159228753Smm			if (!assertEqualInt(ARCHIVE_OK,
160228753Smm				archive_read_next_header(a, &ae)))
161228753Smm				break;
162228753Smm			assertEqualString(path, archive_entry_pathname(ae));
163228753Smm			assertEqualInt((int)datasize, archive_entry_size(ae));
164228753Smm		}
165228753Smm		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
166228753Smm	}
167228753Smm	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
168228753Smm
169228753Smm	/*
170228753Smm	 * Repeat again, with much lower compression.
171228753Smm	 */
172228753Smm	assert((a = archive_write_new()) != NULL);
173228753Smm	assertA(0 == archive_write_set_format_ustar(a));
174228753Smm	assertEqualIntA(a, ARCHIVE_OK,
175228753Smm	    archive_write_set_bytes_per_block(a, 10));
176228753Smm	assertA(0 == archive_write_set_compression_gzip(a));
177228753Smm	assertEqualIntA(a, ARCHIVE_OK,
178228753Smm	    archive_write_set_compressor_options(a, "compression-level=0"));
179228753Smm	assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
180228753Smm	for (i = 0; i < 100; i++) {
181228753Smm		sprintf(path, "file%03d", i);
182228753Smm		assert((ae = archive_entry_new()) != NULL);
183228753Smm		archive_entry_copy_pathname(ae, path);
184228753Smm		archive_entry_set_size(ae, datasize);
185228753Smm		archive_entry_set_filetype(ae, AE_IFREG);
186228753Smm		assertA(0 == archive_write_header(a, ae));
187228753Smm		failure("Writing file %s", path);
188228753Smm		assertEqualIntA(a, datasize,
189228753Smm		    (size_t)archive_write_data(a, data, datasize));
190228753Smm		archive_entry_free(ae);
191228753Smm	}
192228753Smm	archive_write_close(a);
193228753Smm	assert(0 == archive_write_finish(a));
194228753Smm
195228753Smm	/* Level 0 really does result in larger data. */
196228753Smm	failure("Compression-level=0 wrote %d bytes; default wrote %d bytes",
197228753Smm	    (int)used2, (int)used1);
198228753Smm	assert(used2 > used1);
199228753Smm
200228753Smm	assert((a = archive_read_new()) != NULL);
201228753Smm	assertA(0 == archive_read_support_format_all(a));
202228753Smm	assertA(0 == archive_read_support_compression_all(a));
203228753Smm	r = archive_read_support_compression_gzip(a);
204228753Smm	if (r == ARCHIVE_WARN) {
205228753Smm		skipping("gzip reading not fully supported on this platform");
206228753Smm	} else {
207228753Smm		assertEqualIntA(a, ARCHIVE_OK,
208228753Smm		    archive_read_open_memory(a, buff, used2));
209228753Smm		for (i = 0; i < 100; i++) {
210228753Smm			sprintf(path, "file%03d", i);
211228753Smm			if (!assertEqualInt(ARCHIVE_OK,
212228753Smm				archive_read_next_header(a, &ae)))
213228753Smm				break;
214228753Smm			assertEqualString(path, archive_entry_pathname(ae));
215228753Smm			assertEqualInt((int)datasize, archive_entry_size(ae));
216228753Smm		}
217228753Smm		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
218228753Smm	}
219228753Smm	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
220228753Smm
221228753Smm	/*
222228753Smm	 * Test various premature shutdown scenarios to make sure we
223228753Smm	 * don't crash or leak memory.
224228753Smm	 */
225228753Smm	assert((a = archive_write_new()) != NULL);
226228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
227228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
228228753Smm
229228753Smm	assert((a = archive_write_new()) != NULL);
230228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
231228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
232228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
233228753Smm
234228753Smm	assert((a = archive_write_new()) != NULL);
235228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
236228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
237228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
238228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
239228753Smm
240228753Smm	assert((a = archive_write_new()) != NULL);
241228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
242228753Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_gzip(a));
243228753Smm	assertA(0 == archive_write_open_memory(a, buff, buffsize, &used2));
244228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
245228753Smm	assertEqualInt(ARCHIVE_OK, archive_write_finish(a));
246228753Smm
247228753Smm	/*
248228753Smm	 * Clean up.
249228753Smm	 */
250228753Smm	free(data);
251228753Smm	free(buff);
252228753Smm}
253