Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/fs/tarfs/tarfs_test.sh
39537 views
1
#!/bin/sh
2
#-
3
# SPDX-License-Identifier: BSD-2-Clause
4
#
5
# Copyright (c) 2023-2024 Klara, Inc.
6
#
7
# Redistribution and use in source and binary forms, with or without
8
# modification, are permitted provided that the following conditions
9
# are met:
10
# 1. Redistributions of source code must retain the above copyright
11
# notice, this list of conditions and the following disclaimer.
12
# 2. Redistributions in binary form must reproduce the above copyright
13
# notice, this list of conditions and the following disclaimer in the
14
# documentation and/or other materials provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
# SUCH DAMAGE.
27
#
28
29
mnt="$(realpath ${TMPDIR:-/tmp})/mnt"
30
31
# expected SHA256 checksum of file contained in test tarball
32
sum=4da2143234486307bb44eaa610375301781a577d1172f362b88bb4b1643dee62
33
34
tar() {
35
if [ -n "${TARFS_USE_GNU_TAR}" ] ; then
36
gtar --posix --absolute-names "$@"
37
else
38
bsdtar "$@"
39
fi
40
}
41
42
mktar() {
43
"$(atf_get_srcdir)"/mktar ${TARFS_USE_GNU_TAR+-g} "$@"
44
}
45
46
tarsum() {
47
"$(atf_get_srcdir)"/tarsum
48
}
49
50
tarfs_setup() {
51
mkdir "${mnt}"
52
}
53
54
tarfs_cleanup() {
55
umount -f "${mnt}" 2>/dev/null || true
56
}
57
58
atf_test_case tarfs_basic cleanup
59
tarfs_basic_head() {
60
atf_set "descr" "Basic function test"
61
atf_set "require.user" "root"
62
atf_set "require.kmods" "tarfs"
63
}
64
tarfs_basic_body() {
65
tarfs_setup
66
local tarball="${PWD}/tarfs_test.tar.zst"
67
mktar "${tarball}"
68
atf_check mount -rt tarfs "${tarball}" "${mnt}"
69
atf_check -o match:"^${tarball} on ${mnt} \(tarfs," mount
70
atf_check_equal "$(stat -f%d,%i "${mnt}"/sparse_file)" "$(stat -f%d,%i "${mnt}"/hard_link)"
71
atf_check_equal "$(stat -f%d,%i "${mnt}"/sparse_file)" "$(stat -L -f%d,%i "${mnt}"/short_link)"
72
atf_check_equal "$(stat -f%d,%i "${mnt}"/sparse_file)" "$(stat -L -f%d,%i "${mnt}"/long_link)"
73
atf_check -o inline:"${sum}\n" sha256 -q "${mnt}"/sparse_file
74
atf_check -o inline:"2,40755\n" stat -f%l,%p "${mnt}"/directory
75
atf_check -o inline:"1,100644\n" stat -f%l,%p "${mnt}"/file
76
atf_check -o inline:"2,100644\n" stat -f%l,%p "${mnt}"/hard_link
77
atf_check -o inline:"1,120755\n" stat -f%l,%p "${mnt}"/long_link
78
atf_check -o inline:"1,120755\n" stat -f%l,%p "${mnt}"/short_link
79
atf_check -o inline:"2,100644\n" stat -f%l,%p "${mnt}"/sparse_file
80
atf_check -o inline:"3,40755\n" stat -f%l,%p "${mnt}"
81
}
82
tarfs_basic_cleanup() {
83
tarfs_cleanup
84
}
85
86
atf_test_case tarfs_basic_gnu cleanup
87
tarfs_basic_gnu_head() {
88
atf_set "descr" "Basic function test using GNU tar"
89
atf_set "require.user" "root"
90
atf_set "require.kmods" "tarfs"
91
atf_set "require.progs" "gtar"
92
}
93
tarfs_basic_gnu_body() {
94
TARFS_USE_GNU_TAR=true
95
tarfs_basic_body
96
}
97
tarfs_basic_gnu_cleanup() {
98
tarfs_basic_cleanup
99
}
100
101
atf_test_case tarfs_notdir_device cleanup
102
tarfs_notdir_device_head() {
103
atf_set "descr" "Regression test for PR 269519 and 269561"
104
atf_set "require.user" "root"
105
atf_set "require.kmods" "tarfs"
106
}
107
tarfs_notdir_device_body() {
108
tarfs_setup
109
atf_check mknod d b 0xdead 0xbeef
110
tar -cf tarfs_notdir.tar d
111
rm d
112
mkdir d
113
echo "boom" >d/f
114
tar -rf tarfs_notdir.tar d/f
115
atf_check -s not-exit:0 -e match:"Invalid" \
116
mount -rt tarfs tarfs_notdir.tar "${mnt}"
117
}
118
tarfs_notdir_device_cleanup() {
119
tarfs_cleanup
120
}
121
122
atf_test_case tarfs_notdir_device_gnu cleanup
123
tarfs_notdir_device_gnu_head() {
124
atf_set "descr" "Regression test for PR 269519 and 269561 using GNU tar"
125
atf_set "require.user" "root"
126
atf_set "require.kmods" "tarfs"
127
atf_set "require.progs" "gtar"
128
}
129
tarfs_notdir_device_gnu_body() {
130
TARFS_USE_GNU_TAR=true
131
tarfs_notdir_device_body
132
}
133
tarfs_notdir_device_gnu_cleanup() {
134
tarfs_notdir_device_cleanup
135
}
136
137
atf_test_case tarfs_notdir_dot cleanup
138
tarfs_notdir_dot_head() {
139
atf_set "descr" "Regression test for PR 269519 and 269561"
140
atf_set "require.user" "root"
141
atf_set "require.kmods" "tarfs"
142
}
143
tarfs_notdir_dot_body() {
144
tarfs_setup
145
echo "hello" >d
146
tar -cf tarfs_notdir.tar d
147
rm d
148
mkdir d
149
echo "world" >d/f
150
tar -rf tarfs_notdir.tar d/./f
151
atf_check -s not-exit:0 -e match:"Invalid" \
152
mount -rt tarfs tarfs_notdir.tar "${mnt}"
153
}
154
tarfs_notdir_dot_cleanup() {
155
tarfs_cleanup
156
}
157
158
atf_test_case tarfs_notdir_dot_gnu cleanup
159
tarfs_notdir_dot_gnu_head() {
160
atf_set "descr" "Regression test for PR 269519 and 269561 using GNU tar"
161
atf_set "require.user" "root"
162
atf_set "require.kmods" "tarfs"
163
atf_set "require.progs" "gtar"
164
}
165
tarfs_notdir_dot_gnu_body() {
166
TARFS_USE_GNU_TAR=true
167
tarfs_notdir_dot_body
168
}
169
tarfs_notdir_dot_gnu_cleanup() {
170
tarfs_notdir_dot_cleanup
171
}
172
173
atf_test_case tarfs_notdir_dotdot cleanup
174
tarfs_notdir_dotdot_head() {
175
atf_set "descr" "Regression test for PR 269519 and 269561"
176
atf_set "require.user" "root"
177
atf_set "require.kmods" "tarfs"
178
}
179
tarfs_notdir_dotdot_body() {
180
tarfs_setup
181
echo "hello" >d
182
tar -cf tarfs_notdir.tar d
183
rm d
184
mkdir d
185
echo "world" >f
186
tar -rf tarfs_notdir.tar d/../f
187
atf_check -s not-exit:0 -e match:"Invalid" \
188
mount -rt tarfs tarfs_notdir.tar "${mnt}"
189
}
190
tarfs_notdir_dotdot_cleanup() {
191
tarfs_cleanup
192
}
193
194
atf_test_case tarfs_notdir_dotdot_gnu cleanup
195
tarfs_notdir_dotdot_gnu_head() {
196
atf_set "descr" "Regression test for PR 269519 and 269561 using GNU tar"
197
atf_set "require.user" "root"
198
atf_set "require.kmods" "tarfs"
199
atf_set "require.progs" "gtar"
200
}
201
tarfs_notdir_dotdot_gnu_body() {
202
TARFS_USE_GNU_TAR=true
203
tarfs_notdir_dotdot_body
204
}
205
tarfs_notdir_dotdot_gnu_cleanup() {
206
tarfs_notdir_dotdot_cleanup
207
}
208
209
atf_test_case tarfs_notdir_file cleanup
210
tarfs_notdir_file_head() {
211
atf_set "descr" "Regression test for PR 269519 and 269561"
212
atf_set "require.user" "root"
213
atf_set "require.kmods" "tarfs"
214
}
215
tarfs_notdir_file_body() {
216
tarfs_setup
217
echo "hello" >d
218
tar -cf tarfs_notdir.tar d
219
rm d
220
mkdir d
221
echo "world" >d/f
222
tar -rf tarfs_notdir.tar d/f
223
atf_check -s not-exit:0 -e match:"Invalid" \
224
mount -rt tarfs tarfs_notdir.tar "${mnt}"
225
}
226
tarfs_notdir_file_cleanup() {
227
tarfs_cleanup
228
}
229
230
atf_test_case tarfs_notdir_file_gnu cleanup
231
tarfs_notdir_file_gnu_head() {
232
atf_set "descr" "Regression test for PR 269519 and 269561 using GNU tar"
233
atf_set "require.user" "root"
234
atf_set "require.kmods" "tarfs"
235
atf_set "require.progs" "gtar"
236
}
237
tarfs_notdir_file_gnu_body() {
238
TARFS_USE_GNU_TAR=true
239
tarfs_notdir_file_body
240
}
241
tarfs_notdir_file_gnu_cleanup() {
242
tarfs_notdir_file_cleanup
243
}
244
245
atf_test_case tarfs_emptylink cleanup
246
tarfs_emptylink_head() {
247
atf_set "descr" "Regression test for PR 277360: empty link target"
248
atf_set "require.user" "root"
249
atf_set "require.kmods" "tarfs"
250
}
251
tarfs_emptylink_body() {
252
tarfs_setup
253
touch z
254
ln -f z hard
255
ln -fs z soft
256
tar -cf - z hard soft | dd bs=512 skip=1 | tr z '\0' | \
257
tarsum >> tarfs_emptylink.tar
258
atf_check -s not-exit:0 -e match:"Invalid" \
259
mount -rt tarfs tarfs_emptylink.tar "${mnt}"
260
}
261
tarfs_emptylink_cleanup() {
262
tarfs_cleanup
263
}
264
265
atf_test_case tarfs_linktodir cleanup
266
tarfs_linktodir_head() {
267
atf_set "descr" "Regression test for PR 277360: link to directory"
268
atf_set "require.user" "root"
269
atf_set "require.kmods" "tarfs"
270
}
271
tarfs_linktodir_body() {
272
tarfs_setup
273
mkdir d
274
tar -cf - d | dd bs=512 count=1 > tarfs_linktodir.tar
275
rmdir d
276
touch d
277
ln -f d link
278
tar -cf - d link | dd bs=512 skip=1 >> tarfs_linktodir.tar
279
atf_check -s not-exit:0 -e match:"Invalid" \
280
mount -rt tarfs tarfs_linktodir.tar "${mnt}"
281
}
282
tarfs_linktodir_cleanup() {
283
tarfs_cleanup
284
}
285
286
atf_test_case tarfs_linktononexistent cleanup
287
tarfs_linktononexistent_head() {
288
atf_set "descr" "Regression test for PR 277360: link to nonexistent target"
289
atf_set "require.user" "root"
290
atf_set "require.kmods" "tarfs"
291
}
292
tarfs_linktononexistent_body() {
293
tarfs_setup
294
touch f
295
ln -f f link
296
tar -cf - f link | dd bs=512 skip=1 >> tarfs_linktononexistent.tar
297
atf_check -s not-exit:0 -e match:"Invalid" \
298
mount -rt tarfs tarfs_linktononexistent.tar "${mnt}"
299
}
300
tarfs_linktononexistent_cleanup() {
301
tarfs_cleanup
302
}
303
304
atf_test_case tarfs_checksum cleanup
305
tarfs_checksum_head() {
306
atf_set "descr" "Verify that the checksum covers header padding"
307
atf_set "require.user" "root"
308
atf_set "require.kmods" "tarfs"
309
}
310
tarfs_checksum_body() {
311
tarfs_setup
312
touch f
313
tar -cf tarfs_checksum.tar f
314
truncate -s 500 tarfs_checksum.tar
315
printf "\1\1\1\1\1\1\1\1\1\1\1\1" >> tarfs_checksum.tar
316
dd if=/dev/zero bs=512 count=2 >> tarfs_checksum.tar
317
hexdump -C tarfs_checksum.tar
318
atf_check -s not-exit:0 -e match:"Invalid" \
319
mount -rt tarfs tarfs_checksum.tar "${mnt}"
320
}
321
tarfs_checksum_cleanup() {
322
tarfs_cleanup
323
}
324
325
atf_test_case tarfs_long_names cleanup
326
tarfs_long_names_head() {
327
atf_set "descr" "Verify that tarfs supports long file names"
328
atf_set "require.user" "root"
329
atf_set "require.kmods" "tarfs"
330
}
331
tarfs_long_names_body() {
332
tarfs_setup
333
local a b c d e
334
a="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
335
b="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
336
c="cccccccccccccccccccccccccccccccccccccccc"
337
d="dddddddddddddddddddddddddddddddddddddddd"
338
e="eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
339
mkdir -p "${a}"
340
touch "${a}/${b}_${c}_${d}_${e}_foo"
341
ln "${a}/${b}_${c}_${d}_${e}_foo" "${a}/${b}_${c}_${d}_${e}_bar"
342
ln -s "${b}_${c}_${d}_${e}_bar" "${a}/${b}_${c}_${d}_${e}_baz"
343
tar -cf tarfs_long_names.tar "${a}"
344
atf_check mount -rt tarfs tarfs_long_names.tar "${mnt}"
345
}
346
tarfs_long_names_cleanup() {
347
tarfs_cleanup
348
}
349
350
atf_test_case tarfs_long_paths cleanup
351
tarfs_long_paths_head() {
352
atf_set "descr" "Verify that tarfs supports long paths"
353
atf_set "require.user" "root"
354
atf_set "require.kmods" "tarfs"
355
}
356
tarfs_long_paths_body() {
357
tarfs_setup
358
local a b c d e
359
a="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
360
b="bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
361
c="cccccccccccccccccccccccccccccccccccccccc"
362
d="dddddddddddddddddddddddddddddddddddddddd"
363
e="eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
364
mkdir -p "${a}/${b}/${c}/${d}/${e}"
365
touch "${a}/${b}/${c}/${d}/${e}/foo"
366
ln "${a}/${b}/${c}/${d}/${e}/foo" "${a}/${b}/${c}/${d}/${e}/bar"
367
ln -s "${b}/${c}/${d}/${e}/bar" "${a}/baz"
368
tar -cf tarfs_long_paths.tar "${a}"
369
atf_check mount -rt tarfs tarfs_long_paths.tar "${mnt}"
370
}
371
tarfs_long_paths_cleanup() {
372
tarfs_cleanup
373
}
374
375
atf_test_case tarfs_git_archive cleanup
376
tarfs_git_archive_head() {
377
atf_set "descr" "Verify that tarfs supports archives created by git"
378
atf_set "require.user" "root"
379
atf_set "require.kmods" "tarfs"
380
atf_set "require.progs" "git"
381
}
382
tarfs_git_archive_body() {
383
tarfs_setup
384
mkdir foo
385
echo "Hello, world!" >foo/bar
386
git -C foo init --initial-branch=tarfs
387
git -C foo config user.name "File System"
388
git -C foo config user.email fs@freebsd.org
389
git -C foo add bar
390
git -C foo commit -m bar
391
git -C foo archive --output=../tarfs_git_archive.tar HEAD
392
atf_check mount -rt tarfs tarfs_git_archive.tar "${mnt}"
393
atf_check -o file:foo/bar cat "${mnt}"/bar
394
}
395
tarfs_git_archive_cleanup() {
396
tarfs_cleanup
397
}
398
399
atf_init_test_cases() {
400
atf_add_test_case tarfs_basic
401
atf_add_test_case tarfs_basic_gnu
402
atf_add_test_case tarfs_notdir_device
403
atf_add_test_case tarfs_notdir_device_gnu
404
atf_add_test_case tarfs_notdir_dot
405
atf_add_test_case tarfs_notdir_dot_gnu
406
atf_add_test_case tarfs_notdir_dotdot
407
atf_add_test_case tarfs_notdir_dotdot_gnu
408
atf_add_test_case tarfs_notdir_file
409
atf_add_test_case tarfs_notdir_file_gnu
410
atf_add_test_case tarfs_emptylink
411
atf_add_test_case tarfs_linktodir
412
atf_add_test_case tarfs_linktononexistent
413
atf_add_test_case tarfs_checksum
414
atf_add_test_case tarfs_long_names
415
atf_add_test_case tarfs_long_paths
416
atf_add_test_case tarfs_git_archive
417
}
418
419