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