test_write_filter_gzip.c revision 337352
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	unsigned char *rbuff;
43	char path[16];
44	size_t used1, used2;
45	int i, r, use_prog = 0;
46
47	buffsize = 2000000;
48	assert(NULL != (buff = (char *)malloc(buffsize)));
49	if (buff == NULL)
50		return;
51
52	datasize = 10000;
53	assert(NULL != (data = (char *)malloc(datasize)));
54	if (data == NULL) {
55		free(buff);
56		return;
57	}
58	memset(data, 0, datasize);
59
60	/*
61	 * Write a 100 files and read them all back.
62	 * Use default compression level (6).
63	 */
64	assert((a = archive_write_new()) != NULL);
65	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
66	r = archive_write_add_filter_gzip(a);
67	if (r != ARCHIVE_OK) {
68		if (canGzip() && r == ARCHIVE_WARN)
69			use_prog = 1;
70		else {
71			skipping("gzip writing not supported on this platform");
72			assertEqualInt(ARCHIVE_OK, archive_write_free(a));
73			free(buff);
74			free(data);
75			return;
76		}
77	}
78	assertEqualIntA(a, ARCHIVE_OK,
79	    archive_write_set_bytes_per_block(a, 10));
80	assertEqualInt(ARCHIVE_FILTER_GZIP, archive_filter_code(a, 0));
81	assertEqualString("gzip", archive_filter_name(a, 0));
82	assertEqualIntA(a, ARCHIVE_OK,
83	    archive_write_open_memory(a, buff, buffsize, &used1));
84	assert((ae = archive_entry_new()) != NULL);
85	archive_entry_set_filetype(ae, AE_IFREG);
86	archive_entry_set_size(ae, datasize);
87	for (i = 0; i < 100; i++) {
88		sprintf(path, "file%03d", i);
89		archive_entry_copy_pathname(ae, path);
90		assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
91		assertA(datasize
92		    == (size_t)archive_write_data(a, data, datasize));
93	}
94	archive_entry_free(ae);
95	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
96	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
97
98	/* Basic gzip header tests */
99	rbuff = (unsigned char *)buff;
100	assertEqualInt(rbuff[0], 0x1f);
101	assertEqualInt(rbuff[1], 0x8b);
102	assertEqualInt(rbuff[2], 0x08);
103	assertEqualInt(rbuff[3], 0x00);
104	assertEqualInt(rbuff[8], 0); /* RFC 1952 flag for compression level 6 */
105
106	assert((a = archive_read_new()) != NULL);
107	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
108	r = archive_read_support_filter_gzip(a);
109	if (r == ARCHIVE_WARN) {
110		skipping("Can't verify gzip writing by reading back;"
111		    " gzip reading not fully supported on this platform");
112	} else {
113		assertEqualIntA(a, ARCHIVE_OK,
114		    archive_read_open_memory(a, buff, used1));
115		for (i = 0; i < 100; i++) {
116			sprintf(path, "file%03d", i);
117			if (!assertEqualInt(ARCHIVE_OK,
118				archive_read_next_header(a, &ae)))
119				break;
120			assertEqualString(path, archive_entry_pathname(ae));
121			assertEqualInt((int)datasize, archive_entry_size(ae));
122		}
123		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
124	}
125	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
126
127	/*
128	 * Repeat the cycle again, this time setting some compression
129	 * options. Compression level is 9.
130	 */
131	assert((a = archive_write_new()) != NULL);
132	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
133	assertEqualIntA(a, ARCHIVE_OK,
134	    archive_write_set_bytes_per_block(a, 10));
135	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
136	    archive_write_add_filter_gzip(a));
137	assertEqualIntA(a, ARCHIVE_FAILED,
138	    archive_write_set_options(a, "gzip:nonexistent-option=0"));
139	assertEqualIntA(a, ARCHIVE_OK,
140	    archive_write_set_options(a, "gzip:compression-level=1"));
141	assertEqualIntA(a, ARCHIVE_OK,
142	    archive_write_set_filter_option(a, NULL, "compression-level", "9"));
143	assertEqualIntA(a, ARCHIVE_FAILED,
144	    archive_write_set_filter_option(a, NULL, "compression-level", "abc"));
145	assertEqualIntA(a, ARCHIVE_FAILED,
146	    archive_write_set_filter_option(a, NULL, "compression-level", "99"));
147	assertEqualIntA(a, ARCHIVE_OK,
148	    archive_write_set_options(a, "gzip:compression-level=9"));
149	assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
150	for (i = 0; i < 100; i++) {
151		sprintf(path, "file%03d", i);
152		assert((ae = archive_entry_new()) != NULL);
153		archive_entry_copy_pathname(ae, path);
154		archive_entry_set_size(ae, datasize);
155		archive_entry_set_filetype(ae, AE_IFREG);
156		assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
157		assertA(datasize == (size_t)archive_write_data(a, data, datasize));
158		archive_entry_free(ae);
159	}
160	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
161	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
162
163	/* Basic gzip header tests */
164	rbuff = (unsigned char *)buff;
165	assertEqualInt(rbuff[0], 0x1f);
166	assertEqualInt(rbuff[1], 0x8b);
167	assertEqualInt(rbuff[2], 0x08);
168	assertEqualInt(rbuff[3], 0x00);
169	assertEqualInt(rbuff[8], 2); /* RFC 1952 flag for compression level 9 */
170
171	/* Curiously, this test fails; the test data above compresses
172	 * better at default compression than at level 9. */
173	/*
174	failure("compression-level=9 wrote %d bytes, default wrote %d bytes",
175	    (int)used2, (int)used1);
176	assert(used2 < used1);
177	*/
178
179	assert((a = archive_read_new()) != NULL);
180	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
181	r = archive_read_support_filter_gzip(a);
182	if (r != ARCHIVE_OK && !use_prog) {
183		skipping("gzip reading not fully supported on this platform");
184	} else {
185		assertEqualIntA(a, ARCHIVE_OK,
186		    archive_read_support_filter_all(a));
187		assertEqualIntA(a, ARCHIVE_OK,
188		    archive_read_open_memory(a, buff, used2));
189		for (i = 0; i < 100; i++) {
190			sprintf(path, "file%03d", i);
191			if (!assertEqualInt(ARCHIVE_OK,
192				archive_read_next_header(a, &ae)))
193				break;
194			assertEqualString(path, archive_entry_pathname(ae));
195			assertEqualInt((int)datasize, archive_entry_size(ae));
196		}
197		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
198	}
199	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
200
201	/*
202	 * Repeat again, with compression level 1
203	 */
204	assert((a = archive_write_new()) != NULL);
205	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
206	assertEqualIntA(a, ARCHIVE_OK,
207	    archive_write_set_bytes_per_block(a, 10));
208	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
209	    archive_write_add_filter_gzip(a));
210	assertEqualIntA(a, ARCHIVE_OK,
211	    archive_write_set_filter_option(a, NULL, "compression-level", "1"));
212	assertEqualIntA(a, ARCHIVE_OK,
213	    archive_write_open_memory(a, buff, buffsize, &used2));
214	for (i = 0; i < 100; i++) {
215		sprintf(path, "file%03d", i);
216		assert((ae = archive_entry_new()) != NULL);
217		archive_entry_copy_pathname(ae, path);
218		archive_entry_set_size(ae, datasize);
219		archive_entry_set_filetype(ae, AE_IFREG);
220		assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
221		failure("Writing file %s", path);
222		assertEqualIntA(a, datasize,
223		    (size_t)archive_write_data(a, data, datasize));
224		archive_entry_free(ae);
225	}
226	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
227	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
228
229	/* Level 1 really does result in larger data. */
230	failure("Compression-level=1 wrote %d bytes; default wrote %d bytes",
231	    (int)used2, (int)used1);
232	assert(used2 > used1);
233
234	/* Basic gzip header tests */
235	rbuff = (unsigned char *)buff;
236	assertEqualInt(rbuff[0], 0x1f);
237	assertEqualInt(rbuff[1], 0x8b);
238	assertEqualInt(rbuff[2], 0x08);
239	assertEqualInt(rbuff[3], 0x00);
240	assertEqualInt(rbuff[8], 4); /* RFC 1952 flag for compression level 1 */
241
242	assert((a = archive_read_new()) != NULL);
243	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
244	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
245	r = archive_read_support_filter_gzip(a);
246	if (r == ARCHIVE_WARN) {
247		skipping("gzip reading not fully supported on this platform");
248	} else {
249		assertEqualIntA(a, ARCHIVE_OK,
250		    archive_read_open_memory(a, buff, used2));
251		for (i = 0; i < 100; i++) {
252			sprintf(path, "file%03d", i);
253			if (!assertEqualInt(ARCHIVE_OK,
254				archive_read_next_header(a, &ae)))
255				break;
256			assertEqualString(path, archive_entry_pathname(ae));
257			assertEqualInt((int)datasize, archive_entry_size(ae));
258		}
259		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
260	}
261	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
262
263	/*
264	 * Test various premature shutdown scenarios to make sure we
265	 * don't crash or leak memory.
266	 */
267	assert((a = archive_write_new()) != NULL);
268	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
269	    archive_write_add_filter_gzip(a));
270	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
271
272	assert((a = archive_write_new()) != NULL);
273	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
274	    archive_write_add_filter_gzip(a));
275	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
276	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
277
278	assert((a = archive_write_new()) != NULL);
279	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
280	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
281	    archive_write_add_filter_gzip(a));
282	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
283	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
284
285	assert((a = archive_write_new()) != NULL);
286	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
287	assertEqualIntA(a, (use_prog)?ARCHIVE_WARN:ARCHIVE_OK,
288	    archive_write_add_filter_gzip(a));
289	assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
290	assertEqualInt(ARCHIVE_OK, archive_write_close(a));
291	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
292
293	/*
294	 * Clean up.
295	 */
296	free(data);
297	free(buff);
298}
299