1# $NetBSD: t_mtree.sh,v 1.7 2017/01/14 20:45:16 christos Exp $ 2# 3# Copyright (c) 2009, 2012 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28# Postprocess mtree output, canonicalising portions that 29# are expected to differ from one run to another. 30# 31 32h_postprocess() 33{ 34 sed -e ' 35 /^# user: /s/:.*/: x/ 36 /^# machine: /s/:.*/: x/ 37 /^# tree: /s/:.*/: x/ 38 /^# date: /s/:.*/: x/ 39 ' \ 40 -e '/type=dir/s/ size=[0-9]*//' 41} 42 43h_check() 44{ 45 diff -Nru "$1" "$2" || atf_fail "files $1 and $2 differ" 46} 47 48 49atf_test_case mtree_create 50atf_test_case netbsd6_create 51create_head() 52{ 53 atf_set "descr" "Create a specfile describing a directory tree" 54} 55 56create_setup() 57{ 58 # create some directories 59 rm -fr create 60 mkdir -p create/a/1 create/a/2 create/b 61 # create some files 62 for file in create/top.file.1 \ 63 create/a/a.file.1 \ 64 create/a/a.file.2 \ 65 create/a/1/a1.file.1 \ 66 create/b/b.file.1 \ 67 create/b/b.file.2 68 do 69 echo "$file" >$file 70 done 71 # hard link to file in same dir 72 ln create/b/b.file.1 create/b/b.hardlink.1 73 # hard link to file in another dir 74 ln create/b/b.file.2 create/a/a.hardlink.b2 75 # symlink to file 76 ln -s a.file.1 create/a.symlink.1 77 # symlink to dir 78 ln -s b create/top.symlink.b 79 # dangling symlink 80 ln -s nonexistent create/top.dangling 81} 82 83create_body() 84{ 85 create_setup 86 87 # run mtree and check output 88 ( cd create && mtree -F ${FLAVOR} -c -k type,nlink,link,size,sha256 ) >output.raw \ 89 || atf_fail "mtree exit status $?" 90 h_postprocess <output.raw >output 91 h_check "$(atf_get_srcdir)/${FLAVOR}_d_create.out" output 92} 93 94mtree_create_head() 95{ 96 FLAVOR=mtree create_head 97} 98netbsd6_create_head() 99{ 100 FLAVOR=netbsd6 create_head 101} 102 103mtree_create_body() 104{ 105 FLAVOR=mtree create_body 106} 107netbsd6_create_body() 108{ 109 FLAVOR=netbsd6 create_body 110} 111 112 113atf_test_case mtree_check 114atf_test_case netbsd6_check 115check_head() 116{ 117 atf_set "descr" "Check a directory tree against a specfile" 118} 119 120check_body() 121{ 122 # we use the same directory tree and specfile as in the "create" test 123 create_setup 124 125 # run mtree and check output 126 ( cd create && mtree -F ${FLAVOR} ) <"$(atf_get_srcdir)/${FLAVOR}_d_create.out" >output \ 127 || atf_fail "mtree exit status $?" 128 h_check /dev/null output 129} 130 131mtree_check_head() 132{ 133 FLAVOR=mtree check_head 134} 135netbsd6_check_head() 136{ 137 FLAVOR=netbsd6 check_head 138} 139 140mtree_check_body() 141{ 142 FLAVOR=mtree check_body 143} 144netbsd6_check_body() 145{ 146 FLAVOR=netbsd6 check_body 147} 148 149 150atf_test_case mtree_convert_C 151atf_test_case netbsd6_convert_C 152convert_C_head() 153{ 154 atf_set "descr" "Convert a specfile to mtree -C format, unsorted" 155} 156 157convert_C_body() 158{ 159 mtree -F ${FLAVOR} -C -K all <"$(atf_get_srcdir)/d_convert.in" >output 160 h_check "$(atf_get_srcdir)/d_convert_C.out" output 161} 162 163mtree_convert_C_head() 164{ 165 FLAVOR=mtree convert_C_head 166} 167netbsd6_convert_C_head() 168{ 169 FLAVOR=netbsd6 convert_C_head 170} 171 172mtree_convert_C_body() 173{ 174 FLAVOR=mtree convert_C_body 175} 176netbsd6_convert_C_body() 177{ 178 FLAVOR=netbsd6 convert_C_body 179} 180 181 182atf_test_case mtree_convert_C_S 183atf_test_case netbsd6_convert_C_S 184convert_C_S_head() 185{ 186 atf_set "descr" "Convert a specfile to mtree -C format, sorted" 187} 188 189convert_C_S_body() 190{ 191 mtree -F ${FLAVOR} -C -S -K all <"$(atf_get_srcdir)/d_convert.in" >output 192 h_check "$(atf_get_srcdir)/d_convert_C_S.out" output 193} 194 195mtree_convert_C_S_head() 196{ 197 FLAVOR=mtree convert_C_S_head 198} 199netbsd6_convert_C_S_head() 200{ 201 FLAVOR=netbsd6 convert_C_S_head 202} 203 204mtree_convert_C_S_body() 205{ 206 FLAVOR=mtree convert_C_S_body 207} 208netbsd6_convert_C_S_body() 209{ 210 FLAVOR=netbsd6 convert_C_S_body 211} 212 213 214atf_test_case mtree_convert_D 215atf_test_case netbsd6_convert_D 216convert_D_head() 217{ 218 atf_set "descr" "Convert a specfile to mtree -D format, unsorted" 219} 220 221convert_D_body() 222{ 223 mtree -F ${FLAVOR} -D -K all <"$(atf_get_srcdir)/d_convert.in" >output 224 h_check "$(atf_get_srcdir)/d_convert_D.out" output 225} 226 227mtree_convert_D_head() 228{ 229 FLAVOR=mtree convert_D_head 230} 231netbsd6_convert_D_head() 232{ 233 FLAVOR=netbsd6 convert_D_head 234} 235 236mtree_convert_D_body() 237{ 238 FLAVOR=mtree convert_D_body 239} 240netbsd6_convert_D_body() 241{ 242 FLAVOR=netbsd6 convert_D_body 243} 244 245 246atf_test_case mtree_convert_D_S 247atf_test_case netbsd6_convert_D_S 248convert_D_S_head() 249{ 250 atf_set "descr" "Convert a specfile to mtree -D format, sorted" 251} 252 253convert_D_S_body() 254{ 255 mtree -F ${FLAVOR} -D -S -K all <"$(atf_get_srcdir)/d_convert.in" >output 256 h_check "$(atf_get_srcdir)/d_convert_D_S.out" output 257} 258 259mtree_convert_D_S_head() 260{ 261 FLAVOR=mtree convert_D_S_head 262} 263netbsd6_convert_D_S_head() 264{ 265 FLAVOR=netbsd6 convert_D_S_head 266} 267 268mtree_convert_D_S_body() 269{ 270 FLAVOR=mtree convert_D_S_body 271} 272netbsd6_convert_D_S_body() 273{ 274 FLAVOR=netbsd6 convert_D_S_body 275} 276 277 278atf_test_case mtree_ignore 279atf_test_case netbs6_ignore 280ignore_head() 281{ 282 atf_set "descr" "Test that -d ignores symlinks (PR bin/41061)" 283} 284 285ignore_body() 286{ 287 # Kyua 0.11 and above point TMPDIR to our work directory and atf-check 288 # generates a temporary file, which confuses mtree. Put the mtree files 289 # into a subdirectory. 290 # 291 # See https://github.com/jmmv/kyua/issues/133 for details. 292 mkdir root && cd root 293 294 mkdir newdir 295 mtree -F ${FLAVOR} -c | mtree -F ${FLAVOR} -Ck uid,gid,mode > mtree.spec 296 ln -s newdir otherdir 297 298 # This yields "extra: otherdir" even with -d. 299 # (PR bin/41061) 300 atf_check -s ignore -o empty -e empty -x "mtree -F ${FLAVOR} -d < mtree.spec" 301 302 # Delete the symlink and re-verify. 303 # 304 rm otherdir 305 atf_check -s ignore -o empty -e empty -x "mtree -F ${FLAVOR} -d < mtree.spec" 306} 307 308mtree_ignore_head() 309{ 310 FLAVOR=mtree ignore_head 311} 312netbsd6_ignore_head() 313{ 314 FLAVOR=netbsd6 ignore_head 315} 316 317mtree_ignore_body() 318{ 319 FLAVOR=mtree ignore_body 320} 321netbsd6_ignore_body() 322{ 323 # Kyua 0.11 and above point TMPDIR to our work directory and atf-check 324 # generates a temporary file, which confuses mtree. Put the mtree files 325 # into a subdirectory. 326 # 327 # See https://github.com/jmmv/kyua/issues/133 for details. 328 mkdir root && cd root 329 330 FLAVOR=netbsd6 ignore_body 331} 332 333 334atf_test_case mtree_merge 335atf_test_case netbsd6_merge 336merge_head() 337{ 338 atf_set "descr" "Merge records of different type" 339} 340 341merge_body() 342{ 343 mtree -F ${FLAVOR} -C -M -K all <"$(atf_get_srcdir)/d_merge.in" >output 344 h_check "$(atf_get_srcdir)/d_merge_C_M.out" output 345 # same again, with sorting 346 mtree -F ${FLAVOR} -C -M -S -K all <"$(atf_get_srcdir)/d_merge.in" >output 347 h_check "$(atf_get_srcdir)/d_merge_C_M_S.out" output 348} 349 350mtree_merge_head() 351{ 352 FLAVOR=mtree merge_head 353} 354netbsd6_merge_head() 355{ 356 FLAVOR=netbsd6 merge_head 357} 358 359mtree_merge_body() 360{ 361 FLAVOR=mtree merge_body 362} 363netbsd6_merge_body() 364{ 365 FLAVOR=netbsd6 merge_body 366} 367 368 369atf_test_case mtree_nonemptydir 370atf_test_case netbsd6_nonemptydir 371nonemptydir_head() 372{ 373 atf_set "descr" "Test that new non-empty " \ 374 "directories are recorded (PR bin/25693)" 375} 376 377nonemptydir_body() 378{ 379 mkdir testdir 380 cd testdir 381 382 mtree -F ${FLAVOR} -c > mtree.spec 383 384 if [ ! -f mtree.spec ]; then 385 atf_fail "mtree failed" 386 fi 387 388 touch bar 389 atf_check -s ignore -o save:output -x "mtree -F ${FLAVOR} -f mtree.spec" 390 391 if [ ! -n "$(egrep "extra: bar" output)" ]; then 392 atf_fail "mtree did not record changes (PR bin/25693)" 393 fi 394} 395 396mtree_nonemptydir_head() 397{ 398 FLAVOR=mtree nonemptydir_head 399} 400netbsd6_nonemptydir_head() 401{ 402 FLAVOR=netbsd6 nonemptydir_head 403} 404 405mtree_nonemptydir_body() 406{ 407 FLAVOR=mtree nonemptydir_body 408} 409netbsd6_nonemptydir_body() 410{ 411 FLAVOR=netbsd6 nonemptydir_body 412} 413 414atf_test_case mtree_specspec_type 415mtree_specspec_type_head() 416{ 417 atf_set "descr" "Test that spec comparisons detect type changes" 418} 419 420mtree_specspec_type_body() 421{ 422 mkdir testdir 423 424 touch testdir/bar 425 mtree -c -p testdir > mtree1.spec 426 427 if [ ! -f mtree1.spec ]; then 428 atf_fail "mtree failed" 429 fi 430 431 rm -f testdir/bar 432 ln -s foo testdir/bar 433 # uid change is expected to be ignored as done in -C 434 chown -h operator testdir/bar 435 mtree -c -p testdir > mtree2.spec 436 437 if [ ! -f mtree2.spec ]; then 438 atf_fail "mtree failed" 439 fi 440 441 atf_check -s ignore -o save:output \ 442 -x "mtree -f mtree1.spec -f mtree2.spec" 443 444 if ! cut -f 3 output | egrep -q "bar file" || \ 445 ! cut -f 3 output | egrep -q "bar link"; then 446 atf_fail "mtree did not detect type change" 447 fi 448} 449 450atf_init_test_cases() 451{ 452 atf_add_test_case mtree_create 453 atf_add_test_case mtree_check 454 atf_add_test_case mtree_convert_C 455 atf_add_test_case mtree_convert_C_S 456 atf_add_test_case mtree_convert_D 457 atf_add_test_case mtree_convert_D_S 458 atf_add_test_case mtree_ignore 459 atf_add_test_case mtree_merge 460 atf_add_test_case mtree_nonemptydir 461 atf_add_test_case mtree_specspec_type 462 463 atf_add_test_case netbsd6_create 464 atf_add_test_case netbsd6_check 465 atf_add_test_case netbsd6_convert_C 466 atf_add_test_case netbsd6_convert_C_S 467 atf_add_test_case netbsd6_convert_D 468 atf_add_test_case netbsd6_convert_D_S 469 atf_add_test_case netbsd6_ignore 470 atf_add_test_case netbsd6_merge 471 atf_add_test_case netbsd6_nonemptydir 472} 473