1# 2# Copyright (c) 2016 Spectra Logic Corp 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 28atf_test_case bad_namespace 29bad_namespace_head() { 30 atf_set "descr" "Can't set attributes for nonexistent namespaces" 31} 32bad_namespace_body() { 33 check_fs 34 touch foo 35 atf_check -s not-exit:0 -e match:"Invalid argument" \ 36 setextattr badnamespace myattr X foo 37 atf_check -s not-exit:0 -e match:"Invalid argument" \ 38 lsextattr -q badnamespace foo 39} 40 41atf_test_case hex 42hex_head() { 43 atf_set "descr" "Set and get attribute values in hexadecimal" 44} 45hex_body() { 46 check_fs 47 touch foo 48 atf_check -s exit:0 -o empty setextattr user myattr XYZ foo 49 atf_check -s exit:0 -o inline:"58 59 5a\n" \ 50 getextattr -qx user myattr foo 51} 52 53atf_test_case hex_nonascii 54hex_nonascii_head() { 55 atf_set "descr" "Get binary attribute values in hexadecimal" 56} 57hex_nonascii_body() { 58 check_fs 59 touch foo 60 BINSTUFF=`echo $'\x20\x30\x40\x55\x66\x70\x81\xa2\xb3\xee\xff'` 61 atf_check -s exit:0 -o empty setextattr user myattr "$BINSTUFF" foo 62 getextattr user myattr foo 63 atf_check -s exit:0 -o inline:"20 30 40 55 66 70 81 a2 b3 ee ff\n" \ 64 getextattr -qx user myattr foo 65} 66 67atf_test_case long_name 68long_name_head() { 69 atf_set "descr" "A maximum length attribute name" 70} 71long_name_body() { 72 check_fs 73 # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208965 74 atf_expect_fail "BUG 208965 extattr(2) doesn't allow maxlen attr names" 75 76 ATTRNAME=`jot -b X -s "" 255 0` 77 touch foo 78 atf_check -s exit:0 -o empty setextattr user $ATTRNAME myvalue foo 79 atf_check -s exit:0 -o inline:"${ATTRNAME}\n" lsextattr -q user foo 80 atf_check -s exit:0 -o inline:"myvalue\n" \ 81 getextattr -q user ${ATTRNAME} foo 82 atf_check -s exit:0 -o empty rmextattr user ${ATTRNAME} foo 83 atf_check -s exit:0 -o empty lsextattr -q user foo 84} 85 86atf_test_case loud 87loud_head() { 88 atf_set "descr" "Loud (non -q) output for each command" 89} 90loud_body() { 91 check_fs 92 touch foo 93 # setextattr(8) and friends print hard tabs. Use printf to convert 94 # them to spaces before checking the output. 95 atf_check -s exit:0 -o empty setextattr user myattr myvalue foo 96 atf_check -s exit:0 -o inline:"foo myattr" \ 97 printf "%s %s" $(lsextattr user foo) 98 atf_check -s exit:0 -o inline:"foo myvalue" \ 99 printf "%s %s" $(getextattr user myattr foo) 100 atf_check -s exit:0 -o empty rmextattr user myattr foo 101 atf_check -s exit:0 -o inline:"foo" printf %s $(lsextattr user foo) 102} 103 104atf_test_case noattrs 105noattrs_head() { 106 atf_set "descr" "A file with no extended attributes" 107} 108noattrs_body() { 109 check_fs 110 touch foo 111 atf_check -s exit:0 -o empty lsextattr -q user foo 112} 113 114atf_test_case nonexistent_file 115nonexistent_file_head() { 116 atf_set "descr" "A file that does not exist" 117} 118nonexistent_file_body() { 119 check_fs 120 atf_check -s exit:1 -e match:"No such file or directory" \ 121 lsextattr user foo 122 atf_check -s exit:1 -e match:"No such file or directory" \ 123 setextattr user myattr myvalue foo 124 atf_check -s exit:1 -e match:"No such file or directory" \ 125 getextattr user myattr foo 126 atf_check -s exit:1 -e match:"No such file or directory" \ 127 rmextattr user myattr foo 128} 129 130atf_test_case null 131null_head() { 132 atf_set "descr" "NUL-terminate an attribute value" 133} 134null_body() { 135 check_fs 136 touch foo 137 atf_check -s exit:0 -o empty setextattr -n user myattr myvalue foo 138 atf_check -s exit:0 -o inline:"myvalue\0\n" getextattr -q user myattr foo 139} 140 141atf_test_case one_user_attr 142one_user_attr_head() { 143 atf_set "descr" "A file with one extended attribute" 144} 145one_user_attr_body() { 146 check_fs 147 touch foo 148 atf_check -s exit:0 -o empty setextattr user myattr myvalue foo 149 atf_check -s exit:0 -o inline:"myattr\n" lsextattr -q user foo 150 atf_check -s exit:0 -o inline:"myvalue\n" getextattr -q user myattr foo 151 atf_check -s exit:0 -o empty rmextattr user myattr foo 152 atf_check -s exit:0 -o empty lsextattr -q user foo 153} 154 155atf_test_case one_system_attr 156one_system_attr_head() { 157 atf_set "descr" "A file with one extended attribute" 158 atf_set "require.user" "root" 159} 160one_system_attr_body() { 161 check_fs 162 touch foo 163 atf_check -s exit:0 -o empty setextattr system myattr myvalue foo 164 atf_check -s exit:0 -o inline:"myattr\n" lsextattr -q system foo 165 atf_check -s exit:0 -o inline:"myvalue\n" getextattr -q system myattr foo 166 atf_check -s exit:0 -o empty rmextattr system myattr foo 167 atf_check -s exit:0 -o empty lsextattr -q system foo 168} 169 170atf_test_case stdin 171stdin_head() { 172 atf_set "descr" "Set attribute value from stdin" 173} 174stdin_body() { 175 check_fs 176 dd if=/dev/random of=infile bs=1k count=8 177 touch foo 178 setextattr -i user myattr foo < infile || atf_fail "setextattr failed" 179 atf_check -s exit:0 -o inline:"myattr\n" lsextattr -q user foo 180 getextattr -qq user myattr foo > outfile || atf_fail "getextattr failed" 181 atf_check -s exit:0 cmp -s infile outfile 182} 183 184atf_test_case stringify 185stringify_head() { 186 atf_set "descr" "Stringify the output of getextattr" 187} 188stringify_body() { 189 check_fs 190 touch foo 191 atf_check -s exit:0 -o empty setextattr user myattr "my value" foo 192 atf_check -s exit:0 -o inline:"\"my\\\040value\"\n" \ 193 getextattr -qs user myattr foo 194} 195 196atf_test_case symlink 197symlink_head() { 198 atf_set "descr" "A symlink to an ordinary file" 199} 200symlink_body() { 201 check_fs 202 touch foo 203 ln -s foo foolink 204 atf_check -s exit:0 -o empty setextattr user myattr myvalue foolink 205 atf_check -s exit:0 -o inline:"myvalue\n" \ 206 getextattr -q user myattr foolink 207 atf_check -s exit:0 -o inline:"myvalue\n" getextattr -q user myattr foo 208} 209 210atf_test_case symlink_nofollow 211symlink_nofollow_head() { 212 atf_set "descr" "Operating directly on a symlink" 213} 214symlink_nofollow_body() { 215 check_fs 216 touch foo 217 ln -s foo foolink 218 # Check that with -h we can operate directly on the link 219 atf_check -s exit:0 -o empty setextattr -h user myattr myvalue foolink 220 atf_check -s exit:0 -o inline:"myvalue\n" \ 221 getextattr -qh user myattr foolink 222 atf_check -s exit:1 -e match:"Attribute not found" \ 223 getextattr user myattr foolink 224 atf_check -s exit:1 -e match:"Attribute not found" \ 225 getextattr user myattr foo 226 227 # Check that with -h we cannot operate on the destination file 228 atf_check -s exit:0 -o empty setextattr user otherattr othervalue foo 229 atf_check -s exit:1 getextattr -qh user otherattr foolink 230} 231 232atf_test_case system_and_user_attrs 233system_and_user_attrs_head() { 234 atf_set "descr" "A file with both system and user extended attributes" 235 atf_set "require.user" "root" 236} 237system_and_user_attrs_body() { 238 check_fs 239 touch foo 240 atf_check -s exit:0 -o empty setextattr user userattr userval foo 241 atf_check -s exit:0 -o empty setextattr system sysattr sysval foo 242 atf_check -s exit:0 -o inline:"userattr\n" lsextattr -q user foo 243 atf_check -s exit:0 -o inline:"sysattr\n" lsextattr -q system foo 244 245 atf_check -s exit:0 -o inline:"userval\n" getextattr -q user userattr foo 246 atf_check -s exit:0 -o inline:"sysval\n" getextattr -q system sysattr foo 247 atf_check -s exit:0 -o empty rmextattr user userattr foo 248 atf_check -s exit:0 -o empty rmextattr system sysattr foo 249 atf_check -s exit:0 -o empty lsextattr -q user foo 250 atf_check -s exit:0 -o empty lsextattr -q system foo 251} 252 253atf_test_case two_files 254two_files_head() { 255 atf_set "descr" "Manipulate two files" 256} 257two_files_body() { 258 check_fs 259 touch foo bar 260 atf_check -s exit:0 -o empty setextattr user myattr myvalue foo bar 261 atf_check -s exit:0 -o inline:"foo\tmyattr\nbar\tmyattr\n" \ 262 lsextattr user foo bar 263 atf_check -s exit:0 \ 264 -o inline:"foo\tmyvalue\nbar\tmyvalue\n" \ 265 getextattr user myattr foo bar 266 atf_check -s exit:0 -o empty rmextattr user myattr foo bar 267 atf_check -s exit:0 -o empty lsextattr -q user foo bar 268} 269 270atf_test_case two_files_force 271two_files_force_head() { 272 atf_set "descr" "Manipulate two files. The first does not exist" 273} 274two_files_force_body() { 275 check_fs 276 touch bar 277 atf_check -s exit:1 -e match:"No such file or directory" \ 278 setextattr user myattr myvalue foo bar 279 atf_check -s exit:0 -e ignore setextattr -f user myattr myvalue foo bar 280 atf_check -s exit:1 -e match:"No such file or directory" \ 281 lsextattr user foo bar 282 atf_check -s exit:0 -e ignore -o inline:"bar\tmyattr\n" \ 283 lsextattr -f user foo bar 284 atf_check -s exit:1 -e match:"No such file or directory" \ 285 getextattr user myattr foo bar 286 atf_check -s exit:0 -e ignore \ 287 -o inline:"bar\tmyvalue\n" \ 288 getextattr -f user myattr foo bar 289 atf_check -s exit:1 -e match:"No such file or directory" \ 290 rmextattr user myattr foo bar 291 atf_check -s exit:0 -e ignore \ 292 rmextattr -f user myattr foo bar 293 atf_check -s exit:0 -o empty lsextattr -q user bar 294} 295 296atf_test_case two_user_attrs 297two_user_attrs_head() { 298 atf_set "descr" "A file with two extended attributes" 299} 300two_user_attrs_body() { 301 check_fs 302 touch foo 303 atf_check -s exit:0 -o empty setextattr user myattr1 myvalue1 foo 304 atf_check -s exit:0 -o empty setextattr user myattr2 myvalue2 foo 305 # lsextattr could return the attributes in any order, so we must be 306 # careful how we compare them. 307 raw_output=`lsextattr -q user foo` || atf_fail "lsextattr failed" 308 tabless_output=`printf "%s %s" ${raw_output}` 309 if [ "myattr1 myattr2" != "${tabless_output}" -a \ 310 "myattr2 myattr1" != "${tabless_output}" ]; then 311 atf_fail "lsextattr printed ${tabless_output}" 312 fi 313 atf_check -s exit:0 -o inline:"myvalue1\n" getextattr -q user myattr1 foo 314 atf_check -s exit:0 -o inline:"myvalue2\n" getextattr -q user myattr2 foo 315 atf_check -s exit:0 -o empty rmextattr user myattr2 foo 316 atf_check -s exit:0 -o empty rmextattr user myattr1 foo 317 atf_check -s exit:0 -o empty lsextattr -q user foo 318} 319 320atf_test_case unprivileged_user_cannot_set_system_attr 321unprivileged_user_cannot_set_system_attr_head() { 322 atf_set "descr" "Unprivileged users can't set system attributes" 323 atf_set "require.user" "unprivileged" 324} 325unprivileged_user_cannot_set_system_attr_body() { 326 check_fs 327 touch foo 328 atf_check -s exit:1 -e match:"Operation not permitted" \ 329 setextattr system myattr myvalue foo 330} 331 332 333atf_init_test_cases() { 334 atf_add_test_case bad_namespace 335 atf_add_test_case hex 336 atf_add_test_case hex_nonascii 337 atf_add_test_case long_name 338 atf_add_test_case loud 339 atf_add_test_case noattrs 340 atf_add_test_case nonexistent_file 341 atf_add_test_case null 342 atf_add_test_case symlink_nofollow 343 atf_add_test_case one_user_attr 344 atf_add_test_case one_system_attr 345 atf_add_test_case stdin 346 atf_add_test_case stringify 347 atf_add_test_case symlink 348 atf_add_test_case symlink_nofollow 349 atf_add_test_case system_and_user_attrs 350 atf_add_test_case two_files 351 atf_add_test_case two_files_force 352 atf_add_test_case two_user_attrs 353 atf_add_test_case unprivileged_user_cannot_set_system_attr 354} 355 356check_fs() { 357 case `df -T . | tail -n 1 | cut -wf 2` in 358 "ufs") 359 case `dumpfs . | head -1 | awk -F'[()]' '{print $2}'` in 360 "UFS1") atf_skip "UFS1 is not supported by this test";; 361 "UFS2") ;; # UFS2 is fine 362 esac ;; 363 "zfs") ;; # ZFS is fine 364 "tmpfs") atf_skip "tmpfs does not support extended attributes";; 365 esac 366} 367