1 #!/usr/bin/ksh 2 # 3 # 4 # This file and its contents are supplied under the terms of the 5 # Common Development and Distribution License ("CDDL"), version 1.0. 6 # You may only use this file in accordance with the terms of version 7 # 1.0 of the CDDL. 8 # 9 # A full copy of the text of the CDDL should have accompanied this 10 # source. A copy of the CDDL is also available via the Internet at 11 # http://www.illumos.org/license/CDDL. 12 # 13 14 # 15 # Copyright (c) 2019, Joyent, Inc. 16 # 17 18 # 19 # Run all of the various CTF tests 20 # 21 22 unalias -a 23 #set -o xtrace 24 25 if [[ -z "$TMPDIR" ]]; then 26 TMPDIR="/tmp" 27 fi 28 29 ctf_arg0=$(basename $0) 30 ctf_root=$(cd $(dirname $0) && echo $PWD) 31 ctf_tests= 32 ctf_compiler="gcc" 33 ctf_convert="ctfconvert" 34 ctf_merge="ctfmerge" 35 ctf_debugflags="-gdwarf-2 " 36 ctf_mach32="-m32" 37 ctf_mach64="-m64" 38 ctf_32cflags="$ctf_mach32 $ctf_debugflags" 39 ctf_64cflags="$ctf_mach64 $ctf_debugflags" 40 ctf_temp="$TMPDIR/ctftest.$$.o" 41 ctf_makefile="Makefile.ctftest" 42 ctf_nerrs=0 43 44 usage() 45 { 46 typeset msg="$*" 47 [[ -z "$msg" ]] || echo "$msg" >&2 48 cat <<USAGE >&2 49 Usage: $ctf_arg0 [-c compiler] [-g flags] [-m ctfmerge] [-t ctfconvert] 50 51 Runs the CTF test suite 52 53 -c compiler Use the specified compiler, defaults to 'gcc' 54 on path. 55 -g flags Use flags to generate debug info. Defaults to 56 "-gdwarf-2". 57 -m ctfmerge Use the specified ctfmerge, defaults to 58 'ctfmerge' on path. 59 -t ctfconvert Use the specified ctfconvert, defaults to 60 'ctfconvert' on path. 61 USAGE 62 exit 2 63 } 64 65 66 test_fail() 67 { 68 typeset msg="$*" 69 [[ -z "$msg" ]] && msg="failed" 70 echo "TEST FAILED: $msg" >&2 71 ((ctf_nerrs++)) 72 } 73 74 fatal() 75 { 76 typeset msg="$*" 77 [[ -z "$msg" ]] && msg="failed" 78 echo "$ctf_arg0: $msg" >&2 79 rm -f "$ctf_tmp32" "$ctf_temp64" 80 exit 1 81 } 82 83 check_env() 84 { 85 if which "$1" 2>/dev/null >/dev/null; then 86 return 87 fi 88 89 [[ -f "$1" ]] || fatal "failed to find tool $1" 90 } 91 92 announce() 93 { 94 cat << EOF 95 Beginning CTF tests with the following settings: 96 COMPILER: $(which $ctf_compiler) 97 CTFCONVERT: $(which $ctf_convert) 98 CTFMERGE: $(which $ctf_merge) 99 32-bit CFLAGS: $ctf_32cflags 100 64-bit CFLAGS: $ctf_64cflags 101 102 EOF 103 } 104 105 run_one() 106 { 107 typeset source=$1 checker=$2 flags=$3 108 109 if ! "$ctf_compiler" $flags -o "$ctf_temp" -c "$source"; then 110 test_fail "failed to compile $source with flags: $flags" 111 return 112 fi 113 114 if ! "$ctf_convert" "$ctf_temp"; then 115 test_fail "failed to convert CTF in $source" 116 return 117 fi 118 119 if ! "$checker" "$ctf_temp"; then 120 test_fail "check for $source, $checker, failed" 121 return 122 fi 123 124 echo "TEST PASSED: $source $flags" 125 } 126 127 # 128 # Perform a more complex build. The Makefile present will drive the 129 # building of the artifacts and the running of the tests based on the 130 # variables that we pass to it. 131 # 132 run_dir() 133 { 134 typeset dir outdir check32 check64 flags32 flags64 135 136 dir=$1 137 outdir="$TMPDIR/ctftest.$$-$(basename $d)" 138 check32=$2 139 flags32=$3 140 check64=$4 141 flags64=$5 142 143 if ! mkdir $outdir; then 144 fatal "failed to make temporary directory '$outdir'" 145 fi 146 147 if ! make -C $dir -f Makefile.ctftest \ 148 BUILDDIR="$outdir" \ 149 CC="$ctf_compiler" \ 150 CFLAGS32="$ctf_mach32" \ 151 CFLAGS64="$ctf_mach64" \ 152 DEBUGFLAGS="$ctf_debugflags" \ 153 CTFCONVERT="$ctf_convert" \ 154 CTFMERGE="$ctf_merge" \ 155 build 1>/dev/null; then 156 rm -rf $outdir 157 test_fail "failed to build $dir" 158 return 159 fi 160 161 if ! make -C $dir -f Makefile.ctftest \ 162 BUILDDIR="$outdir" \ 163 CHECK32="$check32" \ 164 CHECK64="$check64" \ 165 run-test 1>/dev/null; then 166 rm -rf $outdir 167 test_fail "failed to run tests for $dir" 168 return 169 fi 170 171 rm -rf $outdir 172 echo "TEST PASSED: $dir (dir)" 173 } 174 175 # 176 # Find all of the tests that exist and then try to run them all. Tests 177 # may either be a single file or a directory. 178 # 179 run_tests() 180 { 181 typeset t base check 182 ctf_tests=$(ls "$ctf_root"/*.c) 183 for t in $ctf_tests; do 184 base=$(basename "$t" .c) 185 check=$(echo "$base" | sed s/test-/check-/) 186 if [[ -f "$ctf_root/$check" ]]; then 187 run_one $t "$ctf_root/$check" "$ctf_32cflags" 188 run_one $t "$ctf_root/$check" "$ctf_64cflags" 189 elif [[ -f "$ctf_root/$check-32" && \ 190 -f "$ctf_root/$check-64" ]]; then 191 run_one $t "$ctf_root/$check-32" "$ctf_32cflags" 192 run_one $t "$ctf_root/$check-64" "$ctf_64cflags" 193 else 194 test_fail "missing checker for $t" 195 fi 196 done 197 198 for d in $(find "$ctf_root" -maxdepth 1 -type d -name 'test-*'); do 199 [[ ! -f "$d/$ctf_makefile" ]] && continue 200 base=$(basename "$d") 201 check=$(echo "$base" | sed s/test-/check-/) 202 if [[ -f "$ctf_root/$check" ]]; then 203 run_dir $d "$ctf_root/$check" "$ctf_32cflags" \ 204 "$ctf_root/$check" "$ctf_64cflags" 205 elif [[ -f "$ctf_root/$check-32" && \ 206 -f "$ctf_root/$check-64" ]]; then 207 run_dir $d "$ctf_root/$check-32" "$ctf_32cflags" \ 208 "$ctf_root/$check-64" "$ctf_64cflags" 209 else 210 test_fail "missing checker for $t" 211 fi 212 done 213 } 214 215 while getopts ":c:g:m:t:" c $@; do 216 case "$c" in 217 c) 218 ctf_compiler=$OPTARG 219 ;; 220 g) 221 ctf_debugflags=$OPTARG 222 ;; 223 m) 224 ctf_merge=$OPTARG 225 ;; 226 t) 227 ctf_convert=$OPTARG 228 ;; 229 :) 230 usage "option requires an argument -- $OPTARG" 231 ;; 232 *) 233 usage "invalid option -- $OPTARG" 234 ;; 235 esac 236 done 237 238 ctf_32cflags="$ctf_mach32 $ctf_debugflags" 239 ctf_64cflags="$ctf_mach64 $ctf_debugflags" 240 241 check_env "$ctf_compiler" 242 check_env "$ctf_convert" 243 check_env "$ctf_merge" 244 announce 245 246 run_tests 247 248 if [[ $ctf_nerrs -ne 0 ]]; then 249 if [[ $ctf_nerrs -eq 1 ]]; then 250 printf "\n%s: %u test failed\n" "$ctf_arg0" "$ctf_nerrs" 251 else 252 printf "\n%s: %u tests failed\n" "$ctf_arg0" "$ctf_nerrs" 253 fi 254 else 255 printf "\n%s: All tests passed successfully\n" "$ctf_arg0" 256 exit 0 257 fi