1# 2# Copyright (c) 2017 Dell EMC 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 F_flag 29F_flag_head() 30{ 31 atf_set "descr" "Verify the output format for -F" 32} 33F_flag_body() 34{ 35 # TODO: socket, whiteout file 36 atf_check touch a 37 atf_check mkdir b 38 atf_check install -m 0777 /dev/null c 39 atf_check ln -s a d 40 atf_check mkfifo f 41 42 atf_check -o match:'.* a' stat -Fn a 43 atf_check -o match:'.* b/' stat -Fn b 44 atf_check -o match:'.* c\*' stat -Fn c 45 atf_check -o match:'.* d@' stat -Fn d 46 atf_check -o match:'.* f\|' stat -Fn f 47} 48 49atf_test_case l_flag 50l_flag_head() 51{ 52 atf_set "descr" "Verify the output format for -l" 53} 54l_flag_body() 55{ 56 atf_check touch a 57 atf_check ln a b 58 atf_check ln -s a c 59 atf_check mkdir d 60 61 paths="a b c d" 62 63 ls_out=ls.output 64 stat_out=stat.output 65 66 # NOTE: 67 # - Even though stat -l claims to be equivalent to `ls -lT`, the 68 # whitespace is a bit more liberal in the `ls -lT` output. 69 # - `ls -ldT` is used to not recursively list the contents of 70 # directories. 71 for path in $paths; do 72 atf_check -o save:$ls_out ls -ldT $path 73 cat $ls_out 74 atf_check -o save:$stat_out stat -l $path 75 cat $stat_out 76 echo "Comparing normalized whitespace" 77 atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $ls_out 78 atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $stat_out 79 atf_check cmp $ls_out $stat_out 80 done 81} 82 83atf_test_case n_flag 84n_flag_head() 85{ 86 atf_set "descr" "Verify that -n suppresses newline output for lines" 87} 88n_flag_body() 89{ 90 atf_check touch a b 91 atf_check -o inline:"$(stat a | tr -d '\n')" stat -n a 92 atf_check -o inline:"$(stat a b | tr -d '\n')" stat -n a b 93} 94 95atf_test_case q_flag 96q_flag_head() 97{ 98 atf_set "descr" "Verify that -q suppresses error messages from l?stat(2)" 99} 100q_flag_body() 101{ 102 ln -s nonexistent broken-link 103 104 atf_check -s exit:1 stat -q nonexistent 105 atf_check -s exit:1 stat -q nonexistent 106 atf_check -o not-empty stat -q broken-link 107 atf_check -o not-empty stat -qL broken-link 108} 109 110atf_test_case r_flag 111r_flag_head() 112{ 113 atf_set "descr" "Verify that -r displays output in 'raw mode'" 114} 115r_flag_body() 116{ 117 atf_check touch a 118 # TODO: add more thorough checks. 119 atf_check -o not-empty stat -r a 120} 121 122atf_test_case s_flag 123s_flag_head() 124{ 125 atf_set "descr" "Verify the output format for -s" 126} 127s_flag_body() 128{ 129 atf_check touch a 130 atf_check ln a b 131 atf_check ln -s a c 132 atf_check mkdir d 133 134 paths="a b c d" 135 136 # The order/name of each of the fields is specified by stat(1) manpage. 137 fields="st_dev st_ino st_mode st_nlink" 138 fields="$fields st_uid st_gid st_rdev st_size" 139 fields="$fields st_uid st_gid st_mode" 140 fields="$fields st_atime st_mtime st_ctime st_birthtime" 141 fields="$fields st_blksize st_blocks st_flags" 142 143 # NOTE: the following... 144 # - ... relies on set -eu to ensure that the fields are set, as 145 # documented, in stat(1). 146 # - ... uses a subshell to ensure that the eval'ed variables don't 147 # pollute the next iteration's behavior. 148 for path in $paths; do 149 ( 150 set -eu 151 eval $(stat -s $path) 152 for field in $fields; do 153 eval "$field=\$$field" 154 done 155 ) || atf_fail 'One or more fields not set by stat(1)' 156 done 157} 158 159atf_test_case t_flag 160t_flag_head() 161{ 162 atf_set "descr" "Verify the output format for -t" 163} 164 165t_flag_body() 166{ 167 atf_check touch foo 168 atf_check touch -d 1970-01-01T00:00:42 foo 169 atf_check -o inline:'42\n' \ 170 stat -t '%s' -f '%a' foo 171 atf_check -o inline:'1970-01-01 00:00:42\n' \ 172 stat -t '%F %H:%M:%S' -f '%Sa' foo 173} 174 175x_output_date() 176{ 177 local date_format='%a %b %e %H:%M:%S %Y' 178 179 stat -t "$date_format" "$@" 180} 181 182x_output() 183{ 184 local path=$1; shift 185 186 local atime_s=$(x_output_date -f '%Sa' $path) 187 local btime_s=$(x_output_date -f '%SB' $path) 188 local ctime_s=$(x_output_date -f '%Sc' $path) 189 local devid=$(stat -f '%Hd,%Ld' $path) 190 local file_type_s=$(stat -f '%HT' $path) 191 local gid=$(stat -f '%5g' $path) 192 local groupname=$(stat -f '%8Sg' $path) 193 local inode=$(stat -f '%i' $path) 194 local mode=$(stat -f '%Mp%Lp' $path) 195 local mode_s=$(stat -f '%Sp' $path) 196 local mtime_s=$(x_output_date -f '%Sm' $path) 197 local nlink=$(stat -f '%l' $path) 198 local size_a=$(stat -f '%-11z' $path) 199 local uid=$(stat -f '%5u' $path) 200 local username=$(stat -f '%8Su' $path) 201 202 cat <<EOF 203 File: "$path" 204 Size: $size_a FileType: $file_type_s 205 Mode: ($mode/$mode_s) Uid: ($uid/$username) Gid: ($gid/$groupname) 206Device: $devid Inode: $inode Links: $nlink 207Access: $atime_s 208Modify: $mtime_s 209Change: $ctime_s 210 Birth: $btime_s 211EOF 212} 213 214atf_test_case x_flag 215x_flag_head() 216{ 217 atf_set "descr" "Verify the output format for -x" 218} 219x_flag_body() 220{ 221 atf_check touch a 222 atf_check ln a b 223 atf_check ln -s a c 224 atf_check mkdir d 225 226 paths="a b c d" 227 228 for path in $paths; do 229 atf_check -o "inline:$(x_output $path)\n" stat -x $path 230 done 231} 232 233atf_init_test_cases() 234{ 235 atf_add_test_case F_flag 236 #atf_add_test_case H_flag 237 #atf_add_test_case L_flag 238 #atf_add_test_case f_flag 239 atf_add_test_case l_flag 240 atf_add_test_case n_flag 241 atf_add_test_case q_flag 242 atf_add_test_case r_flag 243 atf_add_test_case s_flag 244 atf_add_test_case t_flag 245 atf_add_test_case x_flag 246} 247