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