xref: /freebsd/bin/ln/tests/ln_test.sh (revision 8ce85300c792ecfcb9a307577e3af96ea9a4544c)
1670f1782SAlan Somers#
2e0afcbc8SDag-Erling Smørgrav# SPDX-License-Identifier: BSD-2-Clause
3e0afcbc8SDag-Erling Smørgrav#
4670f1782SAlan Somers# Copyright 2017 Shivansh Rai
5670f1782SAlan Somers# All rights reserved.
6670f1782SAlan Somers#
7670f1782SAlan Somers# Redistribution and use in source and binary forms, with or without
8670f1782SAlan Somers# modification, are permitted provided that the following conditions
9670f1782SAlan Somers# are met:
10670f1782SAlan Somers# 1. Redistributions of source code must retain the above copyright
11670f1782SAlan Somers#    notice, this list of conditions and the following disclaimer.
12670f1782SAlan Somers# 2. Redistributions in binary form must reproduce the above copyright
13670f1782SAlan Somers#    notice, this list of conditions and the following disclaimer in the
14670f1782SAlan Somers#    documentation and/or other materials provided with the distribution.
15670f1782SAlan Somers#
16670f1782SAlan Somers# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17670f1782SAlan Somers# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18670f1782SAlan Somers# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19670f1782SAlan Somers# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20670f1782SAlan Somers# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21670f1782SAlan Somers# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22670f1782SAlan Somers# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23670f1782SAlan Somers# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24670f1782SAlan Somers# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25670f1782SAlan Somers# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26670f1782SAlan Somers# SUCH DAMAGE.
27670f1782SAlan Somers#
28670f1782SAlan Somers
29e0afcbc8SDag-Erling Smørgravatf_check_same_file()
30670f1782SAlan Somers{
31e0afcbc8SDag-Erling Smørgrav	atf_check_equal "$(stat -f %d,%i "$1")" "$(stat -f %d,%i "$2")"
32e0afcbc8SDag-Erling Smørgrav}
33e0afcbc8SDag-Erling Smørgrav
34e0afcbc8SDag-Erling Smørgravatf_check_symlink_to()
35e0afcbc8SDag-Erling Smørgrav{
36e0afcbc8SDag-Erling Smørgrav	atf_check -o inline:"$1\n" readlink "$2"
37670f1782SAlan Somers}
38670f1782SAlan Somers
39670f1782SAlan Somersatf_test_case L_flag
40670f1782SAlan SomersL_flag_head()
41670f1782SAlan Somers{
42670f1782SAlan Somers	atf_set "descr" "Verify that when creating a hard link to a " \
43670f1782SAlan Somers			"symbolic link, '-L' option creates a hard" \
44670f1782SAlan Somers			"link to the target of the symbolic link"
45670f1782SAlan Somers}
46670f1782SAlan SomersL_flag_body()
47670f1782SAlan Somers{
48670f1782SAlan Somers	atf_check touch A
49670f1782SAlan Somers	atf_check ln -s A B
50670f1782SAlan Somers	atf_check ln -L B C
51e0afcbc8SDag-Erling Smørgrav	atf_check_same_file A C
52e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to A B
53670f1782SAlan Somers}
54670f1782SAlan Somers
55670f1782SAlan Somersatf_test_case P_flag
56670f1782SAlan SomersP_flag_head()
57670f1782SAlan Somers{
58670f1782SAlan Somers	atf_set "descr" "Verify that when creating a hard link to a " \
59670f1782SAlan Somers			"symbolic link, '-P' option creates a hard " \
60670f1782SAlan Somers			"link to the symbolic link itself"
61670f1782SAlan Somers}
62670f1782SAlan SomersP_flag_body()
63670f1782SAlan Somers{
64670f1782SAlan Somers	atf_check touch A
65670f1782SAlan Somers	atf_check ln -s A B
66670f1782SAlan Somers	atf_check ln -P B C
67e0afcbc8SDag-Erling Smørgrav	atf_check_same_file B C
68670f1782SAlan Somers}
69670f1782SAlan Somers
70670f1782SAlan Somersatf_test_case f_flag
71670f1782SAlan Somersf_flag_head()
72670f1782SAlan Somers{
73670f1782SAlan Somers	atf_set "descr" "Verify that if the target file already exists, " \
74670f1782SAlan Somers			"'-f' option unlinks it so that link may occur"
75670f1782SAlan Somers}
76670f1782SAlan Somersf_flag_body()
77670f1782SAlan Somers{
78670f1782SAlan Somers	atf_check touch A B
79670f1782SAlan Somers	atf_check ln -f A B
80e0afcbc8SDag-Erling Smørgrav	atf_check_same_file A B
81670f1782SAlan Somers}
82670f1782SAlan Somers
83670f1782SAlan Somersatf_test_case target_exists_hard
84670f1782SAlan Somerstarget_exists_hard_head()
85670f1782SAlan Somers{
86670f1782SAlan Somers	atf_set "descr" "Verify whether creating a hard link fails if the " \
87670f1782SAlan Somers			"target file already exists"
88670f1782SAlan Somers}
89670f1782SAlan Somerstarget_exists_hard_body()
90670f1782SAlan Somers{
91670f1782SAlan Somers	atf_check touch A B
92670f1782SAlan Somers	atf_check -s exit:1 -e inline:'ln: B: File exists\n' \
93670f1782SAlan Somers	    ln A B
94670f1782SAlan Somers}
95670f1782SAlan Somers
96670f1782SAlan Somersatf_test_case target_exists_symbolic
97670f1782SAlan Somerstarget_exists_symbolic_head()
98670f1782SAlan Somers{
99670f1782SAlan Somers	atf_set "descr" "Verify whether creating a symbolic link fails if " \
100670f1782SAlan Somers			"the target file already exists"
101670f1782SAlan Somers}
102670f1782SAlan Somerstarget_exists_symbolic_body()
103670f1782SAlan Somers{
104670f1782SAlan Somers	atf_check touch A B
105670f1782SAlan Somers	atf_check -s exit:1 -e inline:'ln: B: File exists\n' \
106670f1782SAlan Somers	    ln -s A B
107670f1782SAlan Somers}
108670f1782SAlan Somers
109670f1782SAlan Somersatf_test_case shf_flag_dir
110670f1782SAlan Somersshf_flag_dir_head() {
111670f1782SAlan Somers	atf_set "descr" "Verify that if the target directory is a symbolic " \
112670f1782SAlan Somers			"link, '-shf' option prevents following the link"
113670f1782SAlan Somers}
114670f1782SAlan Somersshf_flag_dir_body()
115670f1782SAlan Somers{
116670f1782SAlan Somers	atf_check mkdir -m 0777 A B
117670f1782SAlan Somers	atf_check ln -s A C
118670f1782SAlan Somers	atf_check ln -shf B C
119e0afcbc8SDag-Erling Smørgrav	atf_check test -L C
12007b98436SEnji Cooper	atf_check -o inline:'B\n' readlink C
121670f1782SAlan Somers}
122670f1782SAlan Somers
123670f1782SAlan Somersatf_test_case snf_flag_dir
124670f1782SAlan Somerssnf_flag_dir_head() {
125670f1782SAlan Somers	atf_set "descr" "Verify that if the target directory is a symbolic " \
126670f1782SAlan Somers			"link, '-snf' option prevents following the link"
127670f1782SAlan Somers}
128670f1782SAlan Somerssnf_flag_dir_body()
129670f1782SAlan Somers{
130670f1782SAlan Somers	atf_check mkdir -m 0777 A B
131670f1782SAlan Somers	atf_check ln -s A C
132670f1782SAlan Somers	atf_check ln -snf B C
133e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to B C
134670f1782SAlan Somers}
135670f1782SAlan Somers
136ed66391aSEnji Cooperatf_test_case sF_flag
137ed66391aSEnji CoopersF_flag_head()
138ed66391aSEnji Cooper{
139ed66391aSEnji Cooper	atf_set "descr" "Verify that if the target file already exists " \
140ed66391aSEnji Cooper			"and is a directory, then '-sF' option removes " \
141ed66391aSEnji Cooper			"it so that the link may occur"
142ed66391aSEnji Cooper}
143ed66391aSEnji CoopersF_flag_body()
144ed66391aSEnji Cooper{
145ed66391aSEnji Cooper	atf_check mkdir A B
146ed66391aSEnji Cooper	atf_check ln -sF A B
147e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to A B
148ed66391aSEnji Cooper}
149ed66391aSEnji Cooper
150670f1782SAlan Somersatf_test_case sf_flag
151670f1782SAlan Somerssf_flag_head()
152670f1782SAlan Somers{
153670f1782SAlan Somers	atf_set "descr" "Verify that if the target file already exists, " \
154670f1782SAlan Somers			"'-sf' option unlinks it and creates a symbolic link " \
155670f1782SAlan Somers			"to the source file"
156670f1782SAlan Somers}
157670f1782SAlan Somerssf_flag_body()
158670f1782SAlan Somers{
159670f1782SAlan Somers	atf_check touch A B
160670f1782SAlan Somers	atf_check ln -sf A B
161e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to A B
162670f1782SAlan Somers}
163670f1782SAlan Somers
1642ae8d346SDag-Erling Smørgravatf_test_case sfF_flag
1652ae8d346SDag-Erling SmørgravsfF_flag_head()
1662ae8d346SDag-Erling Smørgrav{
1672ae8d346SDag-Erling Smørgrav	atf_set "descr" "Verify that if the target file already exists " \
1682ae8d346SDag-Erling Smørgrav			"and is a symlink, then '-sfF' option removes " \
1692ae8d346SDag-Erling Smørgrav			"it so that the link may occur"
1702ae8d346SDag-Erling Smørgrav}
1712ae8d346SDag-Erling SmørgravsfF_flag_body()
1722ae8d346SDag-Erling Smørgrav{
173*8ce85300SDag-Erling Smørgrav	atf_check mkdir A B C D D/A
1742ae8d346SDag-Erling Smørgrav	atf_check ln -sF A C
1752ae8d346SDag-Erling Smørgrav	atf_check_symlink_to A C
1762ae8d346SDag-Erling Smørgrav	atf_check ln -sfF B C
1772ae8d346SDag-Erling Smørgrav	atf_check_symlink_to B C
178*8ce85300SDag-Erling Smørgrav	atf_check ln -sfF A D/
179*8ce85300SDag-Erling Smørgrav	atf_check_symlink_to A D/A
180*8ce85300SDag-Erling Smørgrav	atf_check ln -sfF ../A .
181*8ce85300SDag-Erling Smørgrav	atf_check_symlink_to ../A A
1822ae8d346SDag-Erling Smørgrav}
1832ae8d346SDag-Erling Smørgrav
184670f1782SAlan Somersatf_test_case s_flag
185670f1782SAlan Somerss_flag_head()
186670f1782SAlan Somers{
187670f1782SAlan Somers	atf_set "descr" "Verify that '-s' option creates a symbolic link"
188670f1782SAlan Somers}
189670f1782SAlan Somerss_flag_body()
190670f1782SAlan Somers{
191670f1782SAlan Somers	atf_check touch A
192670f1782SAlan Somers	atf_check ln -s A B
193e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to A B
194670f1782SAlan Somers}
195670f1782SAlan Somers
196670f1782SAlan Somersatf_test_case s_flag_broken
197670f1782SAlan Somerss_flag_broken_head()
198670f1782SAlan Somers{
199670f1782SAlan Somers	atf_set "descr" "Verify that if the source file does not exists, '-s' " \
200670f1782SAlan Somers			"option creates a broken symbolic link to the source file"
201670f1782SAlan Somers}
202670f1782SAlan Somerss_flag_broken_body()
203670f1782SAlan Somers{
204670f1782SAlan Somers	atf_check ln -s A B
205e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to A B
206670f1782SAlan Somers}
207670f1782SAlan Somers
208670f1782SAlan Somersatf_test_case sw_flag
209670f1782SAlan Somerssw_flag_head()
210670f1782SAlan Somers{
211670f1782SAlan Somers	atf_set "descr" "Verify that '-sw' option produces a warning if the " \
212670f1782SAlan Somers			"source of a symbolic link does not currently exist"
213670f1782SAlan Somers}
214670f1782SAlan Somerssw_flag_body()
215670f1782SAlan Somers{
216670f1782SAlan Somers	atf_check -s exit:0 -e inline:'ln: warning: A: No such file or directory\n' \
217670f1782SAlan Somers	    ln -sw A B
218e0afcbc8SDag-Erling Smørgrav	atf_check_symlink_to A B
219670f1782SAlan Somers}
220670f1782SAlan Somers
221bee7cf9eSDag-Erling Smørgravatf_test_case link_argc
222bee7cf9eSDag-Erling Smørgravlink_argc_head() {
223bee7cf9eSDag-Erling Smørgrav	atf_set "descr" "Verify that link(1) requires exactly two arguments"
224bee7cf9eSDag-Erling Smørgrav}
225bee7cf9eSDag-Erling Smørgravlink_argc_body() {
226bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"usage: link" \
227bee7cf9eSDag-Erling Smørgrav	    link foo
228bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"No such file" \
229bee7cf9eSDag-Erling Smørgrav	    link foo bar
230bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"No such file" \
231bee7cf9eSDag-Erling Smørgrav	    link -- foo bar
232bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"usage: link" \
233bee7cf9eSDag-Erling Smørgrav	    link foo bar baz
234bee7cf9eSDag-Erling Smørgrav}
235bee7cf9eSDag-Erling Smørgrav
236bee7cf9eSDag-Erling Smørgravatf_test_case link_basic
237bee7cf9eSDag-Erling Smørgravlink_basic_head() {
238bee7cf9eSDag-Erling Smørgrav	atf_set "descr" "Verify that link(1) creates a link"
239bee7cf9eSDag-Erling Smørgrav}
240bee7cf9eSDag-Erling Smørgravlink_basic_body() {
241bee7cf9eSDag-Erling Smørgrav	touch foo
242bee7cf9eSDag-Erling Smørgrav	atf_check link foo bar
243bee7cf9eSDag-Erling Smørgrav	atf_check_same_file foo bar
244bee7cf9eSDag-Erling Smørgrav	rm bar
245bee7cf9eSDag-Erling Smørgrav	ln -s foo bar
246bee7cf9eSDag-Erling Smørgrav	atf_check link bar baz
247bee7cf9eSDag-Erling Smørgrav	atf_check_same_file foo baz
248bee7cf9eSDag-Erling Smørgrav}
249bee7cf9eSDag-Erling Smørgrav
250bee7cf9eSDag-Erling Smørgravatf_test_case link_eexist
251bee7cf9eSDag-Erling Smørgravlink_eexist_head() {
252bee7cf9eSDag-Erling Smørgrav	atf_set "descr" "Verify that link(1) fails if the target exists"
253bee7cf9eSDag-Erling Smørgrav}
254bee7cf9eSDag-Erling Smørgravlink_eexist_body() {
255bee7cf9eSDag-Erling Smørgrav	touch foo bar
256bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"bar.*exists" \
257bee7cf9eSDag-Erling Smørgrav	    link foo bar
258bee7cf9eSDag-Erling Smørgrav	ln -s non-existent baz
259bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"baz.*exists" \
260bee7cf9eSDag-Erling Smørgrav	    link foo baz
261bee7cf9eSDag-Erling Smørgrav}
262bee7cf9eSDag-Erling Smørgrav
263bee7cf9eSDag-Erling Smørgravatf_test_case link_eisdir
264bee7cf9eSDag-Erling Smørgravlink_eisdir_head() {
265bee7cf9eSDag-Erling Smørgrav	atf_set "descr" "Verify that link(1) fails if the source is a directory"
266bee7cf9eSDag-Erling Smørgrav}
267bee7cf9eSDag-Erling Smørgravlink_eisdir_body() {
268bee7cf9eSDag-Erling Smørgrav	mkdir foo
269bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"foo.*directory" \
270bee7cf9eSDag-Erling Smørgrav	    link foo bar
271bee7cf9eSDag-Erling Smørgrav	ln -s foo bar
272bee7cf9eSDag-Erling Smørgrav	atf_check -s exit:1 -e match:"bar.*directory" \
273bee7cf9eSDag-Erling Smørgrav	    link bar baz
274bee7cf9eSDag-Erling Smørgrav}
275bee7cf9eSDag-Erling Smørgrav
276670f1782SAlan Somersatf_init_test_cases()
277670f1782SAlan Somers{
278670f1782SAlan Somers	atf_add_test_case L_flag
279670f1782SAlan Somers	atf_add_test_case P_flag
280670f1782SAlan Somers	atf_add_test_case f_flag
281670f1782SAlan Somers	atf_add_test_case target_exists_hard
282670f1782SAlan Somers	atf_add_test_case target_exists_symbolic
283670f1782SAlan Somers	atf_add_test_case shf_flag_dir
284670f1782SAlan Somers	atf_add_test_case snf_flag_dir
285ed66391aSEnji Cooper	atf_add_test_case sF_flag
286670f1782SAlan Somers	atf_add_test_case sf_flag
2872ae8d346SDag-Erling Smørgrav	atf_add_test_case sfF_flag
288670f1782SAlan Somers	atf_add_test_case s_flag
289670f1782SAlan Somers	atf_add_test_case s_flag_broken
290670f1782SAlan Somers	atf_add_test_case sw_flag
291bee7cf9eSDag-Erling Smørgrav	atf_add_test_case link_argc
292bee7cf9eSDag-Erling Smørgrav	atf_add_test_case link_basic
293bee7cf9eSDag-Erling Smørgrav	atf_add_test_case link_eexist
294bee7cf9eSDag-Erling Smørgrav	atf_add_test_case link_eisdir
295670f1782SAlan Somers}
296