xref: /freebsd/usr.sbin/makefs/tests/makefs_cd9660_tests.sh (revision e2afbc45258f2fa4bdcf126e959ac660e76fc802)
1#
2# Copyright 2015 EMC Corp.
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 are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10#   notice, this list of conditions and the following disclaimer.
11# * 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27# A note on specs:
28# - A copy of the ISO-9660 spec can be found here:
29#   https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
30# - Any references to `rockridge` are referring to the `Rock Ridge` extensions
31#   of the ISO-9660 spec. A copy of the draft `IEEE-P1282` spec can be found
32#   here:
33#   http://www.ymi.com/ymi/sites/default/files/pdf/Rockridge.pdf
34
35MAKEFS="makefs -t cd9660"
36MOUNT="mount_cd9660"
37
38. "$(dirname "$0")/makefs_tests_common.sh"
39
40common_cleanup()
41{
42	if ! test_md_device=$(cat $TEST_MD_DEVICE_FILE); then
43		echo "$TEST_MD_DEVICE_FILE could not be opened; has an md(4) device been attached?"
44		return
45	fi
46
47	umount -f /dev/$test_md_device || :
48	mdconfig -d -u $test_md_device || :
49}
50
51check_base_iso9660_image_contents()
52{
53	# Symlinks are treated like files when rockridge support isn't
54	# specified, and directories cannot contain a '.'.
55	check_image_contents "$@" -X c -X .g -X _g
56
57	atf_check -e empty -o empty -s exit:0 test -L $TEST_INPUTS_DIR/c
58	atf_check -e empty -o empty -s exit:0 test -f $TEST_MOUNT_DIR/c
59}
60
61atf_test_case D_flag cleanup
62D_flag_body()
63{
64	atf_skip "makefs crashes with SIGBUS with dupe mtree entries; see FreeBSD bug # 192839"
65
66	create_test_inputs
67
68	atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \
69	    mtree -cp $TEST_INPUTS_DIR
70	atf_check -e empty -o not-empty -s exit:0 \
71	    $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR
72
73	atf_check -e empty -o empty -s exit:0 \
74	    cp $TEST_SPEC_FILE spec2.mtree
75	atf_check -e empty -o save:dupe_$TEST_SPEC_FILE -s exit:0 \
76	    cat $TEST_SPEC_FILE spec2.mtree
77
78	atf_check -e empty -o not-empty -s not-exit:0 \
79	    $MAKEFS -F dupe_$TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR
80	atf_check -e empty -o not-empty -s exit:0 \
81	    $MAKEFS -D -F dupe_$TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR
82}
83D_flag_cleanup()
84{
85	common_cleanup
86}
87
88atf_test_case F_flag cleanup
89F_flag_body()
90{
91	create_test_inputs
92
93	atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \
94	    mtree -cp $TEST_INPUTS_DIR
95
96	atf_check -e empty -o empty -s exit:0 \
97	    $MAKEFS -F $TEST_SPEC_FILE -M 1m $TEST_IMAGE $TEST_INPUTS_DIR
98
99	mount_image
100	check_base_iso9660_image_contents
101}
102F_flag_cleanup()
103{
104	common_cleanup
105}
106
107atf_test_case from_mtree_spec_file cleanup
108from_mtree_spec_file_body()
109{
110	create_test_inputs
111
112	atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \
113	    mtree -c -k "$DEFAULT_MTREE_KEYWORDS" -p $TEST_INPUTS_DIR
114	cd $TEST_INPUTS_DIR
115	atf_check -e empty -o empty -s exit:0 \
116	    $MAKEFS $TEST_IMAGE $TEST_SPEC_FILE
117	cd -
118
119	mount_image
120	check_base_iso9660_image_contents
121}
122from_mtree_spec_file_cleanup()
123{
124	common_cleanup
125}
126
127atf_test_case from_multiple_dirs cleanup
128from_multiple_dirs_body()
129{
130	test_inputs_dir2=$TMPDIR/inputs2
131
132	create_test_inputs
133
134	atf_check -e empty -o empty -s exit:0 mkdir -p $test_inputs_dir2
135	atf_check -e empty -o empty -s exit:0 \
136	    touch $test_inputs_dir2/multiple_dirs_test_file
137
138	atf_check -e empty -o empty -s exit:0 \
139	    $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR $test_inputs_dir2
140
141	mount_image
142	check_base_iso9660_image_contents -d $test_inputs_dir2
143}
144from_multiple_dirs_cleanup()
145{
146	common_cleanup
147}
148
149atf_test_case from_single_dir cleanup
150from_single_dir_body()
151{
152	create_test_inputs
153
154	atf_check -e empty -o empty -s exit:0 \
155	    $MAKEFS $TEST_IMAGE $TEST_INPUTS_DIR
156
157	mount_image
158	check_base_iso9660_image_contents
159}
160from_single_dir_cleanup()
161{
162	common_cleanup
163}
164
165atf_test_case o_flag_allow_deep_trees cleanup
166o_flag_allow_deep_trees_body()
167{
168	create_test_inputs
169
170	# Make sure the "more than 8 levels deep" requirement is met.
171	atf_check -e empty -o empty -s exit:0 \
172	    mkdir -p $TEST_INPUTS_DIR/a/b/c/d/e/f/g/h/i/j
173
174	atf_check -e empty -o empty -s exit:0 \
175	    $MAKEFS -o allow-deep-trees $TEST_IMAGE $TEST_INPUTS_DIR
176
177	mount_image
178	check_base_iso9660_image_contents
179}
180o_flag_allow_deep_trees_cleanup()
181{
182	common_cleanup
183}
184
185atf_test_case o_flag_allow_max_name cleanup
186o_flag_allow_max_name_body()
187{
188	atf_expect_fail "-o allow-max-name doesn't appear to be implemented on FreeBSD's copy of makefs [yet]"
189
190	create_test_inputs
191
192	long_path=$TEST_INPUTS_DIR/$(jot -s '' -b 0 37)
193
194	# Make sure the "37 char name" limit requirement is met.
195	atf_check -e empty -o empty -s exit:0 touch $long_path
196
197	atf_check -e empty -o empty -s exit:0 \
198	    $MAKEFS -o allow-max-name $TEST_IMAGE $TEST_INPUTS_DIR
199
200	mount_image
201	check_base_iso9660_image_contents
202}
203o_flag_allow_max_name_cleanup()
204{
205	common_cleanup
206}
207
208atf_test_case o_flag_isolevel_1 cleanup
209o_flag_isolevel_1_body()
210{
211	atf_expect_fail "this testcase needs work; the filenames generated seem incorrect/corrupt"
212
213	create_test_inputs
214
215	atf_check -e empty -o empty -s exit:0 \
216	    $MAKEFS -o isolevel=1 $TEST_IMAGE $TEST_INPUTS_DIR
217
218	mount_image
219	check_base_iso9660_image_contents
220}
221o_flag_isolevel_1_cleanup()
222{
223	common_cleanup
224}
225
226atf_test_case o_flag_isolevel_2 cleanup
227o_flag_isolevel_2_body()
228{
229	create_test_inputs
230
231	atf_check -e empty -o empty -s exit:0 \
232	    $MAKEFS -o isolevel=2 $TEST_IMAGE $TEST_INPUTS_DIR
233
234	mount_image
235	check_base_iso9660_image_contents
236}
237o_flag_isolevel_2_cleanup()
238{
239	common_cleanup
240}
241
242atf_test_case o_flag_isolevel_3 cleanup
243o_flag_isolevel_3_body()
244{
245	create_test_inputs
246
247	# XXX: isolevel=3 isn't implemented yet. See FreeBSD bug # 203645
248	if true; then
249	atf_check -e match:'makefs: ISO Level 3 is greater than 2\.' -o empty -s not-exit:0 \
250	    $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR
251	else
252	atf_check -e empty -o empty -s exit:0 \
253	    $MAKEFS -o isolevel=3 $TEST_IMAGE $TEST_INPUTS_DIR
254
255	mount_image
256	check_base_iso9660_image_contents
257	fi
258}
259o_flag_isolevel_3_cleanup()
260{
261	common_cleanup
262}
263
264atf_test_case o_flag_preparer
265o_flag_preparer_head()
266{
267	atf_set "require.progs" "strings"
268}
269o_flag_preparer_body()
270{
271	create_test_dirs
272
273	preparer='My Very First ISO'
274	preparer_uppercase="$(echo $preparer | tr '[[:lower:]]' '[[:upper:]]')"
275
276	atf_check -e empty -o empty -s exit:0 touch $TEST_INPUTS_DIR/dummy_file
277	atf_check -e empty -o empty -s exit:0 \
278	    $MAKEFS -o preparer="$preparer" $TEST_IMAGE $TEST_INPUTS_DIR
279	atf_check -e empty -o match:"$preparer_uppercase" -s exit:0 \
280	    strings $TEST_IMAGE
281}
282
283atf_test_case o_flag_publisher
284o_flag_publisher_head()
285{
286	atf_set "require.progs" "strings"
287}
288o_flag_publisher_body()
289{
290	create_test_dirs
291
292	publisher='My Super Awesome Publishing Company LTD'
293	publisher_uppercase="$(echo $publisher | tr '[[:lower:]]' '[[:upper:]]')"
294
295	atf_check -e empty -o empty -s exit:0 touch $TEST_INPUTS_DIR/dummy_file
296	atf_check -e empty -o empty -s exit:0 \
297	    $MAKEFS -o publisher="$publisher" $TEST_IMAGE $TEST_INPUTS_DIR
298	atf_check -e empty -o match:"$publisher_uppercase" -s exit:0 \
299	    strings $TEST_IMAGE
300}
301
302atf_test_case o_flag_rockridge cleanup
303o_flag_rockridge_body()
304{
305	create_test_dirs
306
307	# Make sure the "more than 8 levels deep" requirement is met.
308	atf_check -e empty -o empty -s exit:0 \
309	    mkdir -p $TEST_INPUTS_DIR/a/b/c/d/e/f/g/h/i/j
310
311	# Make sure the "pathname larger than 255 chars" requirement is met.
312	#
313	# $long_path's needs to be nested in a directory, as creating it
314	# outright as a 256 char filename via touch will fail with ENAMETOOLONG
315	long_path=$TEST_INPUTS_DIR/$(jot -s '/' -b "$(jot -s '' -b 0 64)" 4)
316	atf_check -e empty -o empty -s exit:0 mkdir -p "$(dirname $long_path)"
317	atf_check -e empty -o empty -s exit:0 touch "$long_path"
318
319	atf_check -e empty -o empty -s exit:0 \
320	    $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
321
322	mount_image
323	check_image_contents -X .rr_moved
324
325	# .rr_moved is a special directory created when you have deep directory
326	# trees with rock ridge extensions on
327	atf_check -e empty -o empty -s exit:0 \
328	    test -d $TEST_MOUNT_DIR/.rr_moved
329}
330o_flag_rockridge_cleanup()
331{
332	common_cleanup
333}
334
335atf_test_case o_flag_rockridge_dev_nodes cleanup
336o_flag_rockridge_dev_nodes_head()
337{
338	atf_set "descr" "Functional tests to ensure that dev nodes are handled properly with rockridge extensions (NetBSD kern/48852; FreeBSD bug 203648)"
339}
340o_flag_rockridge_dev_nodes_body()
341{
342	create_test_dirs
343
344	(tar -cvf - -C /dev null && touch .tar_ok) | \
345	atf_check -e not-empty -o empty -s exit:0 tar -xvf - -C "$TEST_INPUTS_DIR"
346
347	atf_check -e empty -o empty -s exit:0 test -c $TEST_INPUTS_DIR/null
348	atf_check -e empty -o empty -s exit:0 test -f .tar_ok
349
350	atf_check -e empty -o empty -s exit:0 \
351	    $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
352
353	mount_image
354	check_image_contents
355}
356o_flag_rockridge_dev_nodes_cleanup()
357{
358	common_cleanup
359}
360
361atf_test_case T_flag_dir cleanup
362T_flag_dir_body()
363{
364	timestamp=1742574909
365	create_test_dirs
366
367	mkdir -p $TEST_INPUTS_DIR/dir1
368	atf_check -e empty -o empty -s exit:0 \
369	    $MAKEFS -T $timestamp -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
370
371	mount_image
372	eval $(stat -s  $TEST_MOUNT_DIR/dir1)
373	atf_check_equal $st_atime $timestamp
374	atf_check_equal $st_mtime $timestamp
375	atf_check_equal $st_ctime $timestamp
376}
377
378T_flag_dir_cleanup()
379{
380	common_cleanup
381}
382
383atf_test_case T_flag_F_flag cleanup
384T_flag_F_flag_body()
385{
386	atf_expect_fail "-F doesn't take precedence over -T"
387	timestamp_F=1742574909
388	timestamp_T=1742574910
389	create_test_dirs
390	mkdir -p $TEST_INPUTS_DIR/dir1
391
392	atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \
393	    mtree -c -k "type,time" -p $TEST_INPUTS_DIR
394	change_mtree_timestamp $TEST_SPEC_FILE $timestamp_F
395	atf_check -e empty -o not-empty -s exit:0 \
396	    $MAKEFS -F $TEST_SPEC_FILE -T $timestamp_T -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
397
398	mount_image
399	eval $(stat -s  $TEST_MOUNT_DIR/dir1)
400	atf_check_equal $st_atime $timestamp_F
401	atf_check_equal $st_mtime $timestamp_F
402	atf_check_equal $st_ctime $timestamp_F
403}
404
405T_flag_F_flag_cleanup()
406{
407	common_cleanup
408}
409
410atf_test_case T_flag_mtree cleanup
411T_flag_mtree_body()
412{
413	timestamp=1742574909
414	create_test_dirs
415	mkdir -p $TEST_INPUTS_DIR/dir1
416
417	atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \
418	    mtree -c -k "type" -p $TEST_INPUTS_DIR
419	atf_check -e empty -o empty -s exit:0 \
420	    $MAKEFS -T $timestamp -o rockridge $TEST_IMAGE $TEST_SPEC_FILE
421
422	mount_image
423	eval $(stat -s  $TEST_MOUNT_DIR/dir1)
424	atf_check_equal $st_atime $timestamp
425	atf_check_equal $st_mtime $timestamp
426	atf_check_equal $st_ctime $timestamp
427}
428
429T_flag_mtree_cleanup()
430{
431	common_cleanup
432}
433
434atf_test_case duplicate_names cleanup
435duplicate_names_head()
436{
437	atf_set "descr" "Ensure shortened directory names are unique (PR283238)"
438}
439duplicate_names_body()
440{
441	create_test_dirs
442
443	# Create three directories which are identical in the first 31 characters.
444	dir_prefix="this_directory_name_is_31_chars"
445	mkdir -p $TEST_INPUTS_DIR/${dir_prefix}1
446	mkdir -p $TEST_INPUTS_DIR/${dir_prefix}2
447	mkdir -p $TEST_INPUTS_DIR/${dir_prefix}3
448
449	atf_check -e empty -o empty -s exit:0 \
450	    $MAKEFS -o rockridge $TEST_IMAGE $TEST_INPUTS_DIR
451
452	# Disable Rock Ridge extensions to read the plain ISO Level 2 names.
453	mount_image -r
454
455	# The specific way the short names are made unique is not important.
456	# We verify only that there are three unique names and that the unique
457	# part is at the end of the name.
458	atf_check_equal $(ls -1 $TEST_MOUNT_DIR | sort | uniq | wc -l) 3
459	atf_check_equal $(ls -1 $TEST_MOUNT_DIR | cut -c -29 | sort | uniq | wc -l) 1
460}
461duplicate_names_cleanup()
462{
463	common_cleanup
464}
465
466atf_init_test_cases()
467{
468	atf_add_test_case D_flag
469	atf_add_test_case F_flag
470
471	atf_add_test_case from_mtree_spec_file
472	atf_add_test_case from_multiple_dirs
473	atf_add_test_case from_single_dir
474
475	atf_add_test_case o_flag_allow_deep_trees
476	atf_add_test_case o_flag_allow_max_name
477	atf_add_test_case o_flag_isolevel_1
478	atf_add_test_case o_flag_isolevel_2
479	atf_add_test_case o_flag_isolevel_3
480	atf_add_test_case o_flag_preparer
481	atf_add_test_case o_flag_publisher
482	atf_add_test_case o_flag_rockridge
483	atf_add_test_case o_flag_rockridge_dev_nodes
484	atf_add_test_case T_flag_dir
485	atf_add_test_case T_flag_F_flag
486	atf_add_test_case T_flag_mtree
487
488	atf_add_test_case duplicate_names
489}
490