xref: /freebsd/usr.bin/xinstall/tests/install_test.sh (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
1#
2# Copyright (c) 2016 Jilles Tjoelker
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# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24# SUCH DAMAGE.
25#
26#
27
28atf_test_case copy_to_empty
29copy_to_empty_body() {
30	printf 'test\n123\r456\r\n789\0z' >testf
31	atf_check -s not-exit:0 -e match:"empty string" \
32	    install testf ""
33}
34
35atf_test_case copy_to_nonexistent_dir
36copy_to_nonexistent_dir_body() {
37	local dir="/nonexistent"
38
39	printf 'test\n123\r456\r\n789\0z' >testf
40	atf_check -s not-exit:0 -e match:$dir": No such file or directory" \
41	    install testf $dir/testf
42}
43
44copy_to_nonexistent_with_opts() {
45	printf 'test\n123\r456\r\n789\0z' >testf
46	atf_check install "$@" testf copyf
47	cmp testf copyf || atf_fail "bad copy"
48	[ ! testf -nt copyf ] || atf_fail "bad timestamp"
49	[ ! -e copyf.bak ] || atf_fail "no backup expected"
50}
51
52atf_test_case copy_to_nonexistent
53copy_to_nonexistent_body() {
54	copy_to_nonexistent_with_opts
55}
56
57atf_test_case copy_to_nonexistent_safe
58copy_to_nonexistent_safe_body() {
59	copy_to_nonexistent_with_opts -S
60}
61
62atf_test_case copy_to_nonexistent_comparing
63copy_to_nonexistent_comparing_body() {
64	copy_to_nonexistent_with_opts -C
65}
66
67atf_test_case copy_to_nonexistent_safe_comparing
68copy_to_nonexistent_safe_comparing_body() {
69	copy_to_nonexistent_with_opts -S -C
70}
71
72atf_test_case copy_to_nonexistent_backup
73copy_to_nonexistent_backup_body() {
74	copy_to_nonexistent_with_opts -b -B.bak
75}
76
77atf_test_case copy_to_nonexistent_backup_safe
78copy_to_nonexistent_backup_safe_body() {
79	copy_to_nonexistent_with_opts -b -B.bak -S
80}
81
82atf_test_case copy_to_nonexistent_preserving
83copy_to_nonexistent_preserving_body() {
84	copy_to_nonexistent_with_opts -p
85	[ ! testf -ot copyf ] || atf_fail "bad timestamp 2"
86}
87
88copy_self_with_opts() {
89	printf 'test\n123\r456\r\n789\0z' >testf
90	printf 'test\n123\r456\r\n789\0z' >testf2
91	atf_check -s not-exit:0 -o empty -e match:. install "$@" testf testf
92	cmp testf testf2 || atf_fail "file changed after self-copy attempt"
93}
94
95atf_test_case copy_self
96copy_self_body() {
97	copy_self_with_opts
98}
99
100atf_test_case copy_self_safe
101copy_self_safe_body() {
102	copy_self_with_opts -S
103}
104
105atf_test_case copy_self_comparing
106copy_self_comparing_body() {
107	copy_self_with_opts -C
108}
109
110atf_test_case copy_self_safe_comparing
111copy_self_safe_comparing_body() {
112	copy_self_with_opts -S -C
113}
114
115overwrite_with_opts() {
116	printf 'test\n123\r456\r\n789\0z' >testf
117	printf 'test\n123\r456\r\n789\0w' >otherf
118	atf_check install "$@" testf otherf
119	cmp testf otherf || atf_fail "bad overwrite"
120	[ ! testf -nt otherf ] || atf_fail "bad timestamp"
121}
122
123atf_test_case overwrite
124overwrite_body() {
125	overwrite_with_opts
126}
127
128atf_test_case overwrite_safe
129overwrite_safe_body() {
130	overwrite_with_opts -S
131}
132
133atf_test_case overwrite_comparing
134overwrite_comparing_body() {
135	overwrite_with_opts -C
136}
137
138atf_test_case overwrite_safe_comparing
139overwrite_safe_comparing_body() {
140	overwrite_with_opts -S -C
141}
142
143overwrite_eq_with_opts() {
144	printf 'test\n123\r456\r\n789\0z' >testf
145	printf 'test\n123\r456\r\n789\0z' >otherf
146	atf_check install "$@" testf otherf
147	cmp testf otherf || atf_fail "bad overwrite"
148	[ ! testf -nt otherf ] || atf_fail "bad timestamp"
149}
150
151atf_test_case overwrite_eq
152overwrite_eq_body() {
153	overwrite_eq_with_opts
154}
155
156atf_test_case overwrite_eq_safe
157overwrite_eq_safe_body() {
158	overwrite_eq_with_opts -S
159}
160
161atf_test_case overwrite_eq_comparing
162overwrite_eq_comparing_body() {
163	overwrite_eq_with_opts -C
164}
165
166atf_test_case overwrite_eq_safe_comparing
167overwrite_eq_safe_comparing_body() {
168	overwrite_eq_with_opts -S -C
169}
170
171overwrite_backup_with_opts() {
172	printf 'test\n123\r456\r\n789\0z' >testf
173	printf 'test\n123\r456\r\n789\0w' >otherf
174	printf 'test\n123\r456\r\n789\0w' >otherf2
175	atf_check install -b -B.bak "$@" testf otherf
176	cmp testf otherf || atf_fail "bad overwrite"
177	[ ! testf -nt otherf ] || atf_fail "bad timestamp"
178	cmp otherf.bak otherf2 || atf_fail "bad backup"
179}
180
181atf_test_case overwrite_backup
182overwrite_backup_body() {
183	overwrite_backup_with_opts
184}
185
186atf_test_case overwrite_backup_safe
187overwrite_backup_safe_body() {
188	overwrite_backup_with_opts -S
189}
190
191atf_test_case overwrite_backup_comparing
192overwrite_backup_comparing_body() {
193	overwrite_backup_with_opts -C
194}
195
196atf_test_case overwrite_backup_safe_comparing
197overwrite_backup_safe_comparing_body() {
198	overwrite_backup_with_opts -S -C
199}
200
201setup_stripbin() {
202	cat <<\STRIPBIN >stripbin
203#!/bin/sh
204[ "$1" = "-o" ] && dst="$2" && shift 2
205[ "$1" = "--" ] && shift
206[ -z "$dst" ] && dst="$1"
207STRIPBIN
208	[ "$1" = "true" ] && cmd="cat" || cmd="tr z @"
209	echo $cmd '<"$1" >"$1.new" && mv -- "$1.new" "$dst"' >>stripbin
210	chmod 755 stripbin
211	export STRIPBIN="$PWD/stripbin"
212}
213
214strip_changing_with_opts() {
215	setup_stripbin
216	printf 'test\n123\r456\r\n789\0z' >testf
217	atf_check install -s "$@" testf copyf
218	[ ! testf -nt copyf ] || atf_fail "bad timestamp"
219	printf 'test\n123\r456\r\n789\0@' >otherf
220	cmp otherf copyf || atf_fail "bad stripped copy"
221}
222
223atf_test_case strip_changing
224strip_changing_body() {
225	strip_changing_with_opts
226}
227
228atf_test_case strip_changing_comparing
229strip_changing_comparing_body() {
230	strip_changing_with_opts -C
231}
232
233strip_changing_overwrite_with_opts() {
234	setup_stripbin
235	printf 'test\n123\r456\r\n789\0z' >testf
236	printf 'test\n123\r456\r\n789\0w' >copyf
237	atf_check install -s "$@" testf copyf
238	[ ! testf -nt copyf ] || atf_fail "bad timestamp"
239	printf 'test\n123\r456\r\n789\0@' >otherf
240	cmp otherf copyf || atf_fail "bad stripped copy"
241}
242
243atf_test_case strip_changing_overwrite
244strip_changing_overwrite_body() {
245	strip_changing_overwrite_with_opts
246}
247
248atf_test_case strip_changing_overwrite_comparing
249strip_changing_overwrite_comparing_body() {
250	strip_changing_overwrite_with_opts -C
251}
252
253strip_changing_overwrite_eq_with_opts() {
254	setup_stripbin
255	printf 'test\n123\r456\r\n789\0z' >testf
256	printf 'test\n123\r456\r\n789\0@' >copyf
257	atf_check install -s "$@" testf copyf
258	[ ! testf -nt copyf ] || atf_fail "bad timestamp"
259	printf 'test\n123\r456\r\n789\0@' >otherf
260	cmp otherf copyf || atf_fail "bad stripped copy"
261}
262
263atf_test_case strip_changing_overwrite_eq
264strip_changing_overwrite_eq_body() {
265	strip_changing_overwrite_eq_with_opts
266}
267
268atf_test_case strip_changing_overwrite_eq_comparing
269strip_changing_overwrite_eq_comparing_body() {
270	strip_changing_overwrite_eq_with_opts -C
271}
272
273atf_test_case strip_noop
274strip_noop_body() {
275	setup_stripbin true
276	printf 'test\n123\r456\r\n789\0z' >testf
277	atf_check install -s testf copyf
278	[ ! testf -nt copyf ] || atf_fail "bad timestamp"
279	printf 'test\n123\r456\r\n789\0z' >otherf
280	cmp otherf copyf || atf_fail "bad stripped copy"
281}
282
283atf_test_case hard_link
284hard_link_body() {
285	printf 'test\n123\r456\r\n789\0z' >testf
286	atf_check install -l h testf copyf
287	[ testf -ef copyf ] || atf_fail "not same file"
288	[ ! -L copyf ] || atf_fail "copy is symlink"
289}
290
291atf_test_case symbolic_link
292symbolic_link_body() {
293	printf 'test\n123\r456\r\n789\0z' >testf
294	atf_check install -l s testf copyf
295	[ testf -ef copyf ] || atf_fail "not same file"
296	[ -L copyf ] || atf_fail "copy is not symlink"
297}
298
299atf_test_case symbolic_link_absolute
300symbolic_link_absolute_body() {
301	printf 'test\n123\r456\r\n789\0z' >testf
302	atf_check install -l sa testf copyf
303	[ testf -ef copyf ] || atf_fail "not same file"
304	[ -L copyf ] || atf_fail "copy is not symlink"
305	copyf_path=$(readlink copyf)
306	testf_path="$(pwd -P)/testf"
307	if [ "$copyf_path" != "$testf_path" ]; then
308		atf_fail "unexpected symlink contents ('$copyf_path' != '$testf_path')"
309	fi
310}
311
312atf_test_case symbolic_link_relative
313symbolic_link_relative_body() {
314	printf 'test\n123\r456\r\n789\0z' >testf
315	atf_check install -l sr testf copyf
316	[ testf -ef copyf ] || atf_fail "not same file"
317	[ -L copyf ] || atf_fail "copy is not symlink"
318	copyf_path=$(readlink copyf)
319	testf_path="testf"
320	if [ "$copyf_path" != "$testf_path" ]; then
321		atf_fail "unexpected symlink contents ('$copyf_path' != '$testf_path')"
322	fi
323}
324
325atf_test_case symbolic_link_relative_absolute_source_and_dest1
326symbolic_link_relative_absolute_source_and_dest1_head() {
327	atf_set "descr" "Verify -l rs with absolute paths (.../copyf -> .../a/b/c/testf)"
328}
329symbolic_link_relative_absolute_source_and_dest1_body() {
330	src_path=a/b/c/testf
331	src_path_prefixed=$PWD/$src_path
332	dest_path=$PWD/copyf
333
334	atf_check mkdir -p a/b/c
335	atf_check touch $src_path
336	atf_check install -l sr $src_path_prefixed $dest_path
337	[ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
338	[ -L $dest_path ] || atf_fail "copy is not symlink"
339	dest_path_relative=$(readlink $dest_path)
340	src_path_relative="$src_path"
341	if [ "$src_path_relative" != "$dest_path_relative" ]; then
342		atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
343	fi
344}
345
346atf_test_case symbolic_link_relative_absolute_source_and_dest1_double_slash
347symbolic_link_relative_absolute_source_and_dest1_double_slash_head() {
348	atf_set "descr" "Verify -l rs with absolute paths (.../copyf -> .../a/b/c/testf), using double-slashes"
349}
350symbolic_link_relative_absolute_source_and_dest1_double_slash_body() {
351	src_path=a//b//c//testf
352	src_path_prefixed=$PWD/$src_path
353	dest_path=$PWD/copyf
354
355	atf_check mkdir -p a/b/c
356	atf_check touch $src_path
357	atf_check install -l sr $src_path_prefixed $dest_path
358	[ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
359	[ -L $dest_path ] || atf_fail "copy is not symlink"
360	dest_path_relative=$(readlink $dest_path)
361	src_path_relative="$(echo $src_path | sed -e 's,//,/,g')"
362	if [ "$src_path_relative" != "$dest_path_relative" ]; then
363		atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
364	fi
365}
366
367atf_test_case symbolic_link_relative_absolute_source_and_dest2
368symbolic_link_relative_absolute_source_and_dest2_head() {
369	atf_set "descr" "Verify -l rs with absolute paths (.../a/b/c/copyf -> .../testf)"
370}
371symbolic_link_relative_absolute_source_and_dest2_body() {
372	src_path=testf
373	src_path_prefixed=$PWD/$src_path
374	dest_path=$PWD/a/b/c/copyf
375
376	atf_check mkdir -p a/b/c
377	atf_check touch $src_path
378	atf_check install -l sr $src_path_prefixed $dest_path
379	[ $src_path_prefixed -ef $dest_path ] || atf_fail "not same file"
380	[ -L $dest_path ] || atf_fail "copy is not symlink"
381	dest_path_relative=$(readlink $dest_path)
382	src_path_relative="../../../$src_path"
383	if [ "$src_path_relative" != "$dest_path_relative" ]; then
384		atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
385	fi
386}
387
388atf_test_case mkdir_simple
389mkdir_simple_body() {
390	atf_check install -d dir1/dir2
391	[ -d dir1 ] || atf_fail "dir1 missing"
392	[ -d dir1/dir2 ] || atf_fail "dir2 missing"
393	atf_check install -d dir1/dir2/dir3
394	[ -d dir1/dir2/dir3 ] || atf_fail "dir3 missing"
395	atf_check install -d dir1
396	atf_check install -d dir1/dir2/dir3
397}
398
399atf_test_case symbolic_link_relative_absolute_common
400symbolic_link_relative_absolute_common_head() {
401	atf_set "descr" "Verify -l rs with absolute paths having common components"
402}
403symbolic_link_relative_absolute_common_body() {
404	filename=foo.so
405	src_path=lib
406	src_path_prefixed=$PWD/$src_path
407	dest_path=$PWD/libexec/
408	src_file=$src_path_prefixed/$filename
409	dest_file=$dest_path/$filename
410
411	atf_check mkdir $src_path_prefixed $dest_path
412	atf_check touch $src_file
413	atf_check install -l sr $src_file $dest_path
414
415	dest_path_relative=$(readlink $dest_file)
416	src_path_relative="../lib/$filename"
417	if [ "$src_path_relative" != "$dest_path_relative" ]; then
418		atf_fail "unexpected symlink contents ('$src_path_relative' != '$dest_path_relative')"
419	fi
420}
421
422atf_test_case set_owner_group_mode
423set_owner_group_mode_head() {
424	atf_set "require.user" "root"
425}
426set_owner_group_mode_body() {
427	local fu=65531 fg=65531
428	local cu=65532 cg=65532
429	local u="$(id -u)"
430	local g="$(id -g)"
431	local m=0755 cm=4444
432	printf "test" >testf
433	atf_check chown "$fu:$fg" testf
434	atf_check chmod "$m" testf
435
436	atf_check install testf testc
437	atf_check_equal "$u:$g:10$m" "$(stat -f"%u:%g:%p" testc)"
438
439	atf_check install -o "$cu" testf testc
440	atf_check_equal "$cu:$g:10$m" "$(stat -f"%u:%g:%p" testc)"
441
442	atf_check install -g "$cg" testf testc
443	atf_check_equal "$u:$cg:10$m" "$(stat -f"%u:%g:%p" testc)"
444
445	atf_check install -o "$cu" -g "$cg" testf testc
446	atf_check_equal "$cu:$cg:10$m" "$(stat -f"%u:%g:%p" testc)"
447
448	atf_check install -m "$cm" testf testc
449	atf_check_equal "$u:$g:10$cm" "$(stat -f"%u:%g:%p" testc)"
450
451	atf_check install -o "$cu" -m "$cm" testf testc
452	atf_check_equal "$cu:$g:10$cm" "$(stat -f"%u:%g:%p" testc)"
453
454	atf_check install -g "$cg" -m "$cm" testf testc
455	atf_check_equal "$u:$cg:10$cm" "$(stat -f"%u:%g:%p" testc)"
456
457	atf_check install -o "$cu" -g "$cg" -m "$cm" testf testc
458	atf_check_equal "$cu:$cg:10$cm" "$(stat -f"%u:%g:%p" testc)"
459}
460
461atf_test_case set_owner_group_mode_unpriv
462set_owner_group_mode_unpriv_head() {
463	atf_set "require.user" "root"
464}
465set_owner_group_mode_unpriv_body() {
466	local fu=65531 fg=65531
467	local cu=65532 cg=65532
468	local u="$(id -u)"
469	local g="$(id -g)"
470	local m=0755 cm=4444 cM=0444
471	printf "test" >testf
472	atf_check chown "$fu:$fg" testf
473	atf_check chmod "$m" testf
474
475	atf_check install -U testf testc
476	atf_check_equal "$u:$g:10$m" "$(stat -f"%u:%g:%p" testc)"
477
478	atf_check install -U -o "$cu" testf testc
479	atf_check_equal "$u:$g:10$m" "$(stat -f"%u:%g:%p" testc)"
480
481	atf_check install -U -g "$cg" testf testc
482	atf_check_equal "$u:$g:10$m" "$(stat -f"%u:%g:%p" testc)"
483
484	atf_check install -U -o "$cu" -g "$cg" testf testc
485	atf_check_equal "$u:$g:10$m" "$(stat -f"%u:%g:%p" testc)"
486
487	atf_check install -U -m "$cm" testf testc
488	atf_check_equal "$u:$g:10$cM" "$(stat -f"%u:%g:%p" testc)"
489
490	atf_check install -U -o "$cu" -m "$cm" testf testc
491	atf_check_equal "$u:$g:10$cM" "$(stat -f"%u:%g:%p" testc)"
492
493	atf_check install -U -g "$cg" -m "$cm" testf testc
494	atf_check_equal "$u:$g:10$cM" "$(stat -f"%u:%g:%p" testc)"
495
496	atf_check install -U -o "$cu" -g "$cg" -m "$cm" testf testc
497	atf_check_equal "$u:$g:10$cM" "$(stat -f"%u:%g:%p" testc)"
498}
499
500atf_test_case set_optional_exec
501set_optional_exec_head() {
502	atf_set "require.user" "unprivileged"
503}
504set_optional_exec_body()
505{
506	echo "abc" > testfile.src
507
508	atf_check install -d -m ug+rX testdir
509	atf_check test -x testdir
510
511	atf_check install -m ug+rX testfile.src testfile
512	atf_check test ! -x testfile
513}
514
515atf_init_test_cases() {
516	atf_add_test_case copy_to_empty
517	atf_add_test_case copy_to_nonexistent
518	atf_add_test_case copy_to_nonexistent_dir
519	atf_add_test_case copy_to_nonexistent_safe
520	atf_add_test_case copy_to_nonexistent_comparing
521	atf_add_test_case copy_to_nonexistent_safe_comparing
522	atf_add_test_case copy_to_nonexistent_backup
523	atf_add_test_case copy_to_nonexistent_backup_safe
524	atf_add_test_case copy_to_nonexistent_preserving
525	atf_add_test_case copy_self
526	atf_add_test_case copy_self_safe
527	atf_add_test_case copy_self_comparing
528	atf_add_test_case copy_self_safe_comparing
529	atf_add_test_case overwrite
530	atf_add_test_case overwrite_safe
531	atf_add_test_case overwrite_comparing
532	atf_add_test_case overwrite_safe_comparing
533	atf_add_test_case overwrite_eq
534	atf_add_test_case overwrite_eq_safe
535	atf_add_test_case overwrite_eq_comparing
536	atf_add_test_case overwrite_eq_safe_comparing
537	atf_add_test_case overwrite_backup
538	atf_add_test_case overwrite_backup_safe
539	atf_add_test_case overwrite_backup_comparing
540	atf_add_test_case overwrite_backup_safe_comparing
541	atf_add_test_case strip_changing
542	atf_add_test_case strip_changing_comparing
543	atf_add_test_case strip_changing_overwrite
544	atf_add_test_case strip_changing_overwrite_comparing
545	atf_add_test_case strip_changing_overwrite_eq
546	atf_add_test_case strip_changing_overwrite_eq_comparing
547	atf_add_test_case strip_noop
548	atf_add_test_case hard_link
549	atf_add_test_case symbolic_link
550	atf_add_test_case symbolic_link_absolute
551	atf_add_test_case symbolic_link_relative
552	atf_add_test_case symbolic_link_relative_absolute_source_and_dest1
553	atf_add_test_case symbolic_link_relative_absolute_source_and_dest1_double_slash
554	atf_add_test_case symbolic_link_relative_absolute_source_and_dest2
555	atf_add_test_case symbolic_link_relative_absolute_common
556	atf_add_test_case mkdir_simple
557	atf_add_test_case set_owner_group_mode
558	atf_add_test_case set_owner_group_mode_unpriv
559	atf_add_test_case set_optional_exec
560}
561