test_write_format_tar_sparse.c revision 358088
1/*-
2 * Copyright (c) 2003-2010 Tim Kientzle
3 * Copyright (c) 2012 Michihiro NAKAJIMA
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
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#include "test.h"
27__FBSDID("$FreeBSD$");
28
29static char buff[1000000];
30
31static void
32test_1(void)
33{
34	struct archive_entry *ae;
35	struct archive *a;
36	size_t used;
37	size_t blocksize;
38	int64_t offset, length;
39	char *buff2;
40	size_t buff2_size = 0x13000;
41	char buff3[1024];
42	long i;
43
44	assert((buff2 = malloc(buff2_size)) != NULL);
45	/* Repeat the following for a variety of odd blocksizes. */
46	for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) {
47		/* Create a new archive in memory. */
48		assert((a = archive_write_new()) != NULL);
49		assertEqualIntA(a, ARCHIVE_OK,
50		    archive_write_set_format_pax(a));
51		assertEqualIntA(a, ARCHIVE_OK,
52		    archive_write_add_filter_none(a));
53		assertEqualIntA(a, ARCHIVE_OK,
54		    archive_write_set_bytes_per_block(a, (int)blocksize));
55		assertEqualIntA(a, ARCHIVE_OK,
56		    archive_write_set_bytes_in_last_block(a, (int)blocksize));
57		assertEqualInt(blocksize,
58		    archive_write_get_bytes_in_last_block(a));
59		assertEqualIntA(a, ARCHIVE_OK,
60		    archive_write_open_memory(a, buff, sizeof(buff), &used));
61		assertEqualInt(blocksize,
62		    archive_write_get_bytes_in_last_block(a));
63
64		/*
65		 * Write a file to it.
66		 */
67		assert((ae = archive_entry_new()) != NULL);
68		archive_entry_set_mtime(ae, 1, 10);
69		assertEqualInt(1, archive_entry_mtime(ae));
70		assertEqualInt(10, archive_entry_mtime_nsec(ae));
71		archive_entry_copy_pathname(ae, "file");
72		assertEqualString("file", archive_entry_pathname(ae));
73		archive_entry_set_mode(ae, S_IFREG | 0755);
74		assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
75		archive_entry_set_size(ae, 0x81000);
76		archive_entry_sparse_add_entry(ae, 0x10000, 0x1000);
77		archive_entry_sparse_add_entry(ae, 0x80000, 0x1000);
78
79		assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
80		archive_entry_free(ae);
81		memset(buff2, 'a', buff2_size);
82		for (i = 0; i < 0x81000;) {
83			size_t ws = buff2_size;
84			if (i + ws > 0x81000)
85				ws = 0x81000 - i;
86			assertEqualInt(ws,
87				archive_write_data(a, buff2, ws));
88			i += (long)ws;
89		}
90
91		/* Close out the archive. */
92		assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
93		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
94
95		/* This calculation gives "the smallest multiple of
96		 * the block size that is at least 11264 bytes". */
97		failure("blocksize=%zu", blocksize);
98		assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used);
99
100		/*
101		 * Now, read the data back.
102		 */
103		assert((a = archive_read_new()) != NULL);
104		assertEqualIntA(a, ARCHIVE_OK,
105		    archive_read_support_format_all(a));
106		assertEqualIntA(a, ARCHIVE_OK,
107		    archive_read_support_filter_all(a));
108		assertEqualIntA(a, ARCHIVE_OK,
109		    archive_read_open_memory(a, buff, used));
110
111		assertEqualIntA(a, ARCHIVE_OK,
112		    archive_read_next_header(a, &ae));
113
114		assertEqualInt(1, archive_entry_mtime(ae));
115		assertEqualInt(10, archive_entry_mtime_nsec(ae));
116		assertEqualInt(0, archive_entry_atime(ae));
117		assertEqualInt(0, archive_entry_ctime(ae));
118		assertEqualString("file", archive_entry_pathname(ae));
119		assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
120		assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
121		assertEqualInt(0x81000, archive_entry_size(ae));
122		/* Verify sparse information. */
123		assertEqualInt(2, archive_entry_sparse_reset(ae));
124		assertEqualInt(0,
125			archive_entry_sparse_next(ae, &offset, &length));
126		assertEqualInt(0x10000, offset);
127		assertEqualInt(0x1000, length);
128		assertEqualInt(0,
129			archive_entry_sparse_next(ae, &offset, &length));
130		assertEqualInt(0x80000, offset);
131		assertEqualInt(0x1000, length);
132		/* Verify file contents. */
133		memset(buff3, 0, sizeof(buff3));
134		for (i = 0; i < 0x10000; i += 1024) {
135			assertEqualInt(1024, archive_read_data(a, buff2, 1024));
136			failure("Read data(0x%lx - 0x%lx) should be all zero",
137			    i, i + 1024);
138			assertEqualMem(buff2, buff3, 1024);
139		}
140		memset(buff3, 'a', sizeof(buff3));
141		for (i = 0x10000; i < 0x11000; i += 1024) {
142			assertEqualInt(1024, archive_read_data(a, buff2, 1024));
143			failure("Read data(0x%lx - 0x%lx) should be all 'a'",
144			    i, i + 1024);
145			assertEqualMem(buff2, buff3, 1024);
146		}
147		memset(buff3, 0, sizeof(buff3));
148		for (i = 0x11000; i < 0x80000; i += 1024) {
149			assertEqualInt(1024, archive_read_data(a, buff2, 1024));
150			failure("Read data(0x%lx - 0x%lx) should be all zero",
151			    i, i + 1024);
152			assertEqualMem(buff2, buff3, 1024);
153		}
154		memset(buff3, 'a', sizeof(buff3));
155		for (i = 0x80000; i < 0x81000; i += 1024) {
156			assertEqualInt(1024, archive_read_data(a, buff2, 1024));
157			failure("Read data(0x%lx - 0x%lx) should be all 'a'",
158			    i, i + 1024);
159			assertEqualMem(buff2, buff3, 1024);
160		}
161
162		/* Verify the end of the archive. */
163		assertEqualIntA(a, ARCHIVE_EOF,
164		    archive_read_next_header(a, &ae));
165		assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
166		assertEqualInt(ARCHIVE_OK, archive_read_free(a));
167	}
168	free(buff2);
169}
170
171/*
172 * Test for the case the full bytes of sparse file data is not written.
173 */
174static void
175test_2(void)
176{
177	struct archive_entry *ae;
178	struct archive *a;
179	size_t used;
180	size_t blocksize = 20 * 512;
181	int64_t offset, length;
182	char *buff2;
183	size_t buff2_size = 0x11000;
184	char buff3[1024];
185	long i;
186
187	assert((buff2 = malloc(buff2_size)) != NULL);
188	/* Create a new archive in memory. */
189	assert((a = archive_write_new()) != NULL);
190	assertEqualIntA(a, ARCHIVE_OK,
191	    archive_write_set_format_pax(a));
192	assertEqualIntA(a, ARCHIVE_OK,
193	    archive_write_add_filter_none(a));
194	assertEqualIntA(a, ARCHIVE_OK,
195	    archive_write_set_bytes_per_block(a, (int)blocksize));
196	assertEqualIntA(a, ARCHIVE_OK,
197	    archive_write_set_bytes_in_last_block(a, (int)blocksize));
198	assertEqualInt(blocksize,
199	    archive_write_get_bytes_in_last_block(a));
200	assertEqualIntA(a, ARCHIVE_OK,
201	    archive_write_open_memory(a, buff, sizeof(buff), &used));
202	assertEqualInt(blocksize,
203	    archive_write_get_bytes_in_last_block(a));
204
205	/*
206	 * Write a file to it.
207	 */
208	assert((ae = archive_entry_new()) != NULL);
209	archive_entry_set_mtime(ae, 1, 10);
210	assertEqualInt(1, archive_entry_mtime(ae));
211	assertEqualInt(10, archive_entry_mtime_nsec(ae));
212	archive_entry_copy_pathname(ae, "file");
213	assertEqualString("file", archive_entry_pathname(ae));
214	archive_entry_set_mode(ae, S_IFREG | 0755);
215	assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
216	archive_entry_set_size(ae, 0x81000);
217	archive_entry_sparse_add_entry(ae, 0x10000, 0x1000);
218	archive_entry_sparse_add_entry(ae, 0x80000, 0x1000);
219
220	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
221	archive_entry_free(ae);
222	memset(buff2, 'a', buff2_size);
223	/* Write bytes less than it should be. */
224	assertEqualInt(buff2_size, archive_write_data(a, buff2, buff2_size));
225
226	/* Close out the archive. */
227	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
228	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
229
230	/* This calculation gives "the smallest multiple of
231	 * the block size that is at least 11264 bytes". */
232	failure("blocksize=%zu", blocksize);
233	assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used);
234
235	/*
236	 * Now, read the data back.
237	 */
238	assert((a = archive_read_new()) != NULL);
239	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
240	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
241	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
242
243	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
244
245	assertEqualInt(1, archive_entry_mtime(ae));
246	assertEqualInt(10, archive_entry_mtime_nsec(ae));
247	assertEqualInt(0, archive_entry_atime(ae));
248	assertEqualInt(0, archive_entry_ctime(ae));
249	assertEqualString("file", archive_entry_pathname(ae));
250	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
251	assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
252	assertEqualInt(0x81000, archive_entry_size(ae));
253	/* Verify sparse information. */
254	assertEqualInt(2, archive_entry_sparse_reset(ae));
255	assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length));
256	assertEqualInt(0x10000, offset);
257	assertEqualInt(0x1000, length);
258	assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length));
259	assertEqualInt(0x80000, offset);
260	assertEqualInt(0x1000, length);
261	/* Verify file contents. */
262	memset(buff3, 0, sizeof(buff3));
263	for (i = 0; i < 0x10000; i += 1024) {
264		assertEqualInt(1024, archive_read_data(a, buff2, 1024));
265		failure("Read data(0x%lx - 0x%lx) should be all zero",
266		    i, i + 1024);
267		assertEqualMem(buff2, buff3, 1024);
268	}
269	memset(buff3, 'a', sizeof(buff3));
270	for (i = 0x10000; i < 0x11000; i += 1024) {
271		assertEqualInt(1024, archive_read_data(a, buff2, 1024));
272		failure("Read data(0x%lx - 0x%lx) should be all 'a'",
273		    i, i + 1024);
274		assertEqualMem(buff2, buff3, 1024);
275	}
276	memset(buff3, 0, sizeof(buff3));
277	for (i = 0x11000; i < 0x80000; i += 1024) {
278		assertEqualInt(1024, archive_read_data(a, buff2, 1024));
279		failure("Read data(0x%lx - 0x%lx) should be all zero",
280		    i, i + 1024);
281		assertEqualMem(buff2, buff3, 1024);
282	}
283	memset(buff3, 0, sizeof(buff3));
284	for (i = 0x80000; i < 0x81000; i += 1024) {
285		assertEqualInt(1024, archive_read_data(a, buff2, 1024));
286		failure("Read data(0x%lx - 0x%lx) should be all 'a'",
287		    i, i + 1024);
288		assertEqualMem(buff2, buff3, 1024);
289	}
290
291	/* Verify the end of the archive. */
292	assertEqualIntA(a, ARCHIVE_EOF,
293	    archive_read_next_header(a, &ae));
294	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
295	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
296	free(buff2);
297}
298
299DEFINE_TEST(test_write_format_tar_sparse)
300{
301	/* Test1: archiving sparse files. */
302	test_1();
303	/* Test2: incompletely archiving sparse files. */
304	test_2();
305}
306