xref: /freebsd/contrib/netbsd-tests/usr.sbin/mtree/t_mtree.sh (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1# $NetBSD: t_mtree.sh,v 1.7 2017/01/14 20:45:16 christos Exp $
2#
3# Copyright (c) 2009, 2012 The NetBSD Foundation, Inc.
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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27
28# Postprocess mtree output, canonicalising portions that
29# are expected to differ from one run to another.
30#
31
32h_postprocess()
33{
34	sed -e '
35		/^#	   user: /s/:.*/: x/
36		/^#	machine: /s/:.*/: x/
37		/^#	   tree: /s/:.*/: x/
38		/^#	   date: /s/:.*/: x/
39		' \
40	    -e '/type=dir/s/ size=[0-9]*//'
41}
42
43h_check()
44{
45        diff -Nru "$1" "$2" || atf_fail "files $1 and $2 differ"
46}
47
48
49atf_test_case mtree_create
50atf_test_case netbsd6_create
51create_head()
52{
53	atf_set "descr" "Create a specfile describing a directory tree"
54}
55
56create_setup()
57{
58	# create some directories
59	rm -fr create
60	mkdir -p create/a/1 create/a/2 create/b
61	# create some files
62	for file in create/top.file.1 \
63		    create/a/a.file.1 \
64		    create/a/a.file.2 \
65		    create/a/1/a1.file.1 \
66		    create/b/b.file.1 \
67		    create/b/b.file.2
68	do
69		echo "$file" >$file
70	done
71	# hard link to file in same dir
72	ln create/b/b.file.1 create/b/b.hardlink.1
73	# hard link to file in another dir
74	ln create/b/b.file.2 create/a/a.hardlink.b2
75	# symlink to file
76	ln -s a.file.1 create/a.symlink.1
77	# symlink to dir
78	ln -s b create/top.symlink.b
79	# dangling symlink
80	ln -s nonexistent create/top.dangling
81}
82
83create_body()
84{
85	create_setup
86
87	# run mtree and check output
88	( cd create && mtree -F ${FLAVOR} -c -k type,nlink,link,size,sha256 ) >output.raw \
89	|| atf_fail "mtree exit status $?"
90	h_postprocess <output.raw >output
91	h_check "$(atf_get_srcdir)/${FLAVOR}_d_create.out" output
92}
93
94mtree_create_head()
95{
96	FLAVOR=mtree create_head
97}
98netbsd6_create_head()
99{
100	FLAVOR=netbsd6 create_head
101}
102
103mtree_create_body()
104{
105	FLAVOR=mtree create_body
106}
107netbsd6_create_body()
108{
109	FLAVOR=netbsd6 create_body
110}
111
112
113atf_test_case mtree_check
114atf_test_case netbsd6_check
115check_head()
116{
117	atf_set "descr" "Check a directory tree against a specfile"
118}
119
120check_body()
121{
122	# we use the same directory tree and specfile as in the "create" test
123	create_setup
124
125	# run mtree and check output
126	( cd create && mtree -F ${FLAVOR}  ) <"$(atf_get_srcdir)/${FLAVOR}_d_create.out" >output \
127	|| atf_fail "mtree exit status $?"
128	h_check /dev/null output
129}
130
131mtree_check_head()
132{
133	FLAVOR=mtree check_head
134}
135netbsd6_check_head()
136{
137	FLAVOR=netbsd6 check_head
138}
139
140mtree_check_body()
141{
142	FLAVOR=mtree check_body
143}
144netbsd6_check_body()
145{
146	FLAVOR=netbsd6 check_body
147}
148
149
150atf_test_case mtree_convert_C
151atf_test_case netbsd6_convert_C
152convert_C_head()
153{
154	atf_set "descr" "Convert a specfile to mtree -C format, unsorted"
155}
156
157convert_C_body()
158{
159	mtree -F ${FLAVOR} -C -K all <"$(atf_get_srcdir)/d_convert.in" >output
160	h_check "$(atf_get_srcdir)/d_convert_C.out" output
161}
162
163mtree_convert_C_head()
164{
165	FLAVOR=mtree convert_C_head
166}
167netbsd6_convert_C_head()
168{
169	FLAVOR=netbsd6 convert_C_head
170}
171
172mtree_convert_C_body()
173{
174	FLAVOR=mtree convert_C_body
175}
176netbsd6_convert_C_body()
177{
178	FLAVOR=netbsd6 convert_C_body
179}
180
181
182atf_test_case mtree_convert_C_S
183atf_test_case netbsd6_convert_C_S
184convert_C_S_head()
185{
186	atf_set "descr" "Convert a specfile to mtree -C format, sorted"
187}
188
189convert_C_S_body()
190{
191	mtree -F ${FLAVOR} -C -S -K all <"$(atf_get_srcdir)/d_convert.in" >output
192	h_check "$(atf_get_srcdir)/d_convert_C_S.out" output
193}
194
195mtree_convert_C_S_head()
196{
197	FLAVOR=mtree convert_C_S_head
198}
199netbsd6_convert_C_S_head()
200{
201	FLAVOR=netbsd6 convert_C_S_head
202}
203
204mtree_convert_C_S_body()
205{
206	FLAVOR=mtree convert_C_S_body
207}
208netbsd6_convert_C_S_body()
209{
210	FLAVOR=netbsd6 convert_C_S_body
211}
212
213
214atf_test_case mtree_convert_D
215atf_test_case netbsd6_convert_D
216convert_D_head()
217{
218	atf_set "descr" "Convert a specfile to mtree -D format, unsorted"
219}
220
221convert_D_body()
222{
223	mtree -F ${FLAVOR} -D -K all <"$(atf_get_srcdir)/d_convert.in" >output
224	h_check "$(atf_get_srcdir)/d_convert_D.out" output
225}
226
227mtree_convert_D_head()
228{
229	FLAVOR=mtree convert_D_head
230}
231netbsd6_convert_D_head()
232{
233	FLAVOR=netbsd6 convert_D_head
234}
235
236mtree_convert_D_body()
237{
238	FLAVOR=mtree convert_D_body
239}
240netbsd6_convert_D_body()
241{
242	FLAVOR=netbsd6 convert_D_body
243}
244
245
246atf_test_case mtree_convert_D_S
247atf_test_case netbsd6_convert_D_S
248convert_D_S_head()
249{
250	atf_set "descr" "Convert a specfile to mtree -D format, sorted"
251}
252
253convert_D_S_body()
254{
255	mtree -F ${FLAVOR} -D -S -K all <"$(atf_get_srcdir)/d_convert.in" >output
256	h_check "$(atf_get_srcdir)/d_convert_D_S.out" output
257}
258
259mtree_convert_D_S_head()
260{
261	FLAVOR=mtree convert_D_S_head
262}
263netbsd6_convert_D_S_head()
264{
265	FLAVOR=netbsd6 convert_D_S_head
266}
267
268mtree_convert_D_S_body()
269{
270	FLAVOR=mtree convert_D_S_body
271}
272netbsd6_convert_D_S_body()
273{
274	FLAVOR=netbsd6 convert_D_S_body
275}
276
277
278atf_test_case mtree_ignore
279atf_test_case netbs6_ignore
280ignore_head()
281{
282	atf_set "descr" "Test that -d ignores symlinks (PR bin/41061)"
283}
284
285ignore_body()
286{
287	# Kyua 0.11 and above point TMPDIR to our work directory and atf-check
288	# generates a temporary file, which confuses mtree.  Put the mtree files
289	# into a subdirectory.
290	#
291	# See https://github.com/jmmv/kyua/issues/133 for details.
292	mkdir root && cd root
293
294	mkdir newdir
295	mtree -F ${FLAVOR} -c | mtree -F ${FLAVOR} -Ck uid,gid,mode > mtree.spec
296	ln -s newdir otherdir
297
298	# This yields "extra: otherdir" even with -d.
299	# (PR bin/41061)
300	atf_check -s ignore -o empty -e empty -x "mtree -F ${FLAVOR} -d < mtree.spec"
301
302	# Delete the symlink and re-verify.
303	#
304	rm otherdir
305	atf_check -s ignore -o empty -e empty -x "mtree -F ${FLAVOR} -d < mtree.spec"
306}
307
308mtree_ignore_head()
309{
310	FLAVOR=mtree ignore_head
311}
312netbsd6_ignore_head()
313{
314	FLAVOR=netbsd6 ignore_head
315}
316
317mtree_ignore_body()
318{
319	FLAVOR=mtree ignore_body
320}
321netbsd6_ignore_body()
322{
323	# Kyua 0.11 and above point TMPDIR to our work directory and atf-check
324	# generates a temporary file, which confuses mtree.  Put the mtree files
325	# into a subdirectory.
326	#
327	# See https://github.com/jmmv/kyua/issues/133 for details.
328	mkdir root && cd root
329
330	FLAVOR=netbsd6 ignore_body
331}
332
333
334atf_test_case mtree_merge
335atf_test_case netbsd6_merge
336merge_head()
337{
338	atf_set "descr" "Merge records of different type"
339}
340
341merge_body()
342{
343	mtree -F ${FLAVOR} -C -M -K all <"$(atf_get_srcdir)/d_merge.in" >output
344	h_check "$(atf_get_srcdir)/d_merge_C_M.out" output
345	# same again, with sorting
346	mtree -F ${FLAVOR} -C -M -S -K all <"$(atf_get_srcdir)/d_merge.in" >output
347	h_check "$(atf_get_srcdir)/d_merge_C_M_S.out" output
348}
349
350mtree_merge_head()
351{
352	FLAVOR=mtree merge_head
353}
354netbsd6_merge_head()
355{
356	FLAVOR=netbsd6 merge_head
357}
358
359mtree_merge_body()
360{
361	FLAVOR=mtree merge_body
362}
363netbsd6_merge_body()
364{
365	FLAVOR=netbsd6 merge_body
366}
367
368
369atf_test_case mtree_nonemptydir
370atf_test_case netbsd6_nonemptydir
371nonemptydir_head()
372{
373	atf_set "descr" "Test that new non-empty " \
374			"directories are recorded (PR bin/25693)"
375}
376
377nonemptydir_body()
378{
379	mkdir testdir
380	cd testdir
381
382	mtree -F ${FLAVOR} -c > mtree.spec
383
384	if [ ! -f mtree.spec ]; then
385		atf_fail "mtree failed"
386	fi
387
388	touch bar
389	atf_check -s ignore -o save:output -x "mtree -F ${FLAVOR} -f mtree.spec"
390
391	if [ ! -n "$(egrep "extra: bar" output)" ]; then
392		atf_fail "mtree did not record changes (PR bin/25693)"
393	fi
394}
395
396mtree_nonemptydir_head()
397{
398	FLAVOR=mtree nonemptydir_head
399}
400netbsd6_nonemptydir_head()
401{
402	FLAVOR=netbsd6 nonemptydir_head
403}
404
405mtree_nonemptydir_body()
406{
407	FLAVOR=mtree nonemptydir_body
408}
409netbsd6_nonemptydir_body()
410{
411	FLAVOR=netbsd6 nonemptydir_body
412}
413
414atf_test_case mtree_specspec_type
415mtree_specspec_type_head()
416{
417	atf_set "descr" "Test that spec comparisons detect type changes"
418}
419
420mtree_specspec_type_body()
421{
422	mkdir testdir
423
424	touch testdir/bar
425	mtree -c -p testdir > mtree1.spec
426
427	if [ ! -f mtree1.spec ]; then
428		atf_fail "mtree failed"
429	fi
430
431	rm -f testdir/bar
432	ln -s foo testdir/bar
433	# uid change is expected to be ignored as done in -C
434	chown -h operator testdir/bar
435	mtree -c -p testdir > mtree2.spec
436
437	if [ ! -f mtree2.spec ]; then
438		atf_fail "mtree failed"
439	fi
440
441	atf_check -s ignore -o save:output \
442	    -x "mtree -f mtree1.spec -f mtree2.spec"
443
444	if ! cut -f 3 output | egrep -q "bar file" || \
445	    ! cut -f 3 output | egrep -q "bar link"; then
446		atf_fail "mtree did not detect type change"
447	fi
448}
449
450atf_init_test_cases()
451{
452	atf_add_test_case mtree_create
453	atf_add_test_case mtree_check
454	atf_add_test_case mtree_convert_C
455	atf_add_test_case mtree_convert_C_S
456	atf_add_test_case mtree_convert_D
457	atf_add_test_case mtree_convert_D_S
458	atf_add_test_case mtree_ignore
459	atf_add_test_case mtree_merge
460	atf_add_test_case mtree_nonemptydir
461	atf_add_test_case mtree_specspec_type
462
463	atf_add_test_case netbsd6_create
464	atf_add_test_case netbsd6_check
465	atf_add_test_case netbsd6_convert_C
466	atf_add_test_case netbsd6_convert_C_S
467	atf_add_test_case netbsd6_convert_D
468	atf_add_test_case netbsd6_convert_D_S
469	atf_add_test_case netbsd6_ignore
470	atf_add_test_case netbsd6_merge
471	atf_add_test_case netbsd6_nonemptydir
472}
473