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 22unalias -a 23#set -o xtrace 24 25if [[ -z "$TMPDIR" ]]; then 26 TMPDIR="/tmp" 27fi 28 29 30ctf_arg0=$(basename $0) 31ctf_root=$(cd $(dirname $0) && echo $PWD) 32ctf_tests= 33ctf_cc="gcc" 34ctf_cxx="g++" 35ctf_as="gas" 36ctf_convert="ctfconvert" 37ctf_merge="ctfmerge" 38ctf_debugflags="-gdwarf-2 " 39ctf_mach32="-m32" 40ctf_mach64="-m64" 41ctf_temp="$TMPDIR/ctftest.$$.o" 42ctf_makefile="Makefile.ctftest" 43ctf_nerrs=0 44ctf_cc_type= 45ctf_cc_vers= 46 47usage() 48{ 49 typeset msg="$*" 50 [[ -z "$msg" ]] || echo "$msg" >&2 51 cat <<USAGE >&2 52Usage: $ctf_arg0 [-a as] [-c cc] [-C CC] [-g flags] [-m ctfmerge] [-t ctfconvert] 53 54 Runs the CTF test suite 55 56 -a assembler Use the specified assembler, defaults to 'as' 57 -c compiler Use the specified C compiler, defaults to 'gcc' 58 -C compiler Use the specified C++ compiler, defaults to 'g++' 59 -g flags Use flags to generate debug info. Defaults to 60 "-gdwarf-2". 61 -m ctfmerge Use the specified ctfmerge, defaults to 62 'ctfmerge' 63 -t ctfconvert Use the specified ctfconvert, defaults to 64 'ctfconvert' 65USAGE 66 exit 2 67} 68 69 70test_fail() 71{ 72 typeset msg="$*" 73 [[ -z "$msg" ]] && msg="failed" 74 echo "TEST FAILED: $msg" >&2 75 ((ctf_nerrs++)) 76} 77 78warn() 79{ 80 typeset msg="$*" 81 echo "$ctf_arg0: $msg" >&2 82} 83 84fatal() 85{ 86 typeset msg="$*" 87 [[ -z "$msg" ]] && msg="failed" 88 echo "$ctf_arg0: $msg" >&2 89 rm -f "$ctf_temp" 90 exit 1 91} 92 93# 94# Attempt to try and figure out what class and version of compiler we 95# are dealing with so we can try and skip known failures due to existing 96# bugs in the compiler. 97# 98determine_compiler() 99{ 100 typeset name=$($ctf_cc --version | awk '{ print $1; exit; }') 101 typeset version 102 103 if [[ "$name" == "gcc" ]]; then 104 version=$($ctf_cc --version | awk '{ print $NF; exit; }') 105 elif [[ "$name" == "clang" ]]; then 106 version=$($ctf_cc --version | awk '{ print $NF; exit; }') 107 else 108 warn "failed to parse compiler name from $ctf_cc, will " \ 109 "not make any assumptions about expected failures" 110 name="unknown" 111 version="unknown" 112 fi 113 114 ctf_cc_type="$name" 115 ctf_cc_version="$version" 116} 117 118announce() 119{ 120 cat << EOF 121Beginning CTF tests with the following settings: 122cc: $(which $ctf_cc) 123detected: $ctf_cc_type $ctf_cc_version 124CC: $(which $ctf_cxx) 125as: $(which $ctf_as) 126ctfconvert: $(which $ctf_convert) 127ctfmerge: $(which $ctf_merge) 12832-bit CFLAGS: $ctf_32cflags 12964-bit CFLAGS: $ctf_64cflags 130 131EOF 132} 133 134run_one() 135{ 136 typeset source=$1 checker=$2 flags=$3 137 138 if ! "$ctf_cc" $flags -o "$ctf_temp" -c "$source"; then 139 test_fail "failed to compile $source with flags: $flags" 140 return 141 fi 142 143 if ! "$ctf_convert" "$ctf_temp"; then 144 test_fail "failed to convert CTF in $source" 145 return 146 fi 147 148 if ! "$checker" "$ctf_temp"; then 149 test_fail "check for $source, $checker, failed" 150 return 151 fi 152 153 rm -f "$ctf_temp" 154 echo "TEST PASSED: $source $flags" 155} 156 157# 158# Perform a more complex build. The Makefile present will drive the 159# building of the artifacts and the running of the tests based on the 160# variables that we pass to it. 161# 162run_dir() 163{ 164 typeset dir outdir check32 check64 flags32 flags64 165 166 dir=$1 167 outdir="$TMPDIR/ctftest.$$-$(basename $d)" 168 check32=$2 169 flags32=$3 170 check64=$4 171 flags64=$5 172 173 if ! mkdir $outdir; then 174 fatal "failed to make temporary directory '$outdir'" 175 fi 176 177 if ! make -C $dir -f Makefile.ctftest \ 178 BUILDDIR="$outdir" \ 179 CC="$ctf_cc" \ 180 CFLAGS32="$ctf_mach32" \ 181 CFLAGS64="$ctf_mach64" \ 182 DEBUGFLAGS="$ctf_debugflags" \ 183 CTFCONVERT="$ctf_convert" \ 184 CTFMERGE="$ctf_merge" \ 185 build 1>/dev/null; then 186 rm -rf $outdir 187 test_fail "failed to build $dir" 188 return 189 fi 190 191 if ! make -C $dir -f Makefile.ctftest \ 192 BUILDDIR="$outdir" \ 193 CHECK32="$check32" \ 194 CHECK64="$check64" \ 195 run-test 1>/dev/null; then 196 rm -rf $outdir 197 test_fail "failed to run tests for $dir" 198 return 199 fi 200 201 rm -rf $outdir 202 echo "TEST PASSED: $dir (dir)" 203} 204 205# 206# Find all of the tests that exist and then try to run them all. Tests 207# may either be a single file or a directory. 208# 209run_tests() 210{ 211 typeset t base check 212 ctf_tests=$(ls "$ctf_root"/*.c) 213 for t in $ctf_tests; do 214 base=$(basename "$t" .c) 215 check=$(echo "$base" | sed s/test-/check-/) 216 if [[ -f "$ctf_root/$check" ]]; then 217 run_one $t "$ctf_root/$check" "$ctf_32cflags" 218 run_one $t "$ctf_root/$check" "$ctf_64cflags" 219 elif [[ -f "$ctf_root/$check-32" && \ 220 -f "$ctf_root/$check-64" ]]; then 221 run_one $t "$ctf_root/$check-32" "$ctf_32cflags" 222 run_one $t "$ctf_root/$check-64" "$ctf_64cflags" 223 else 224 test_fail "missing checker for $t" 225 fi 226 done 227 228 for d in $(find "$ctf_root" -maxdepth 1 -type d -name 'test-*'); do 229 [[ ! -f "$d/$ctf_makefile" ]] && continue 230 base=$(basename "$d") 231 check=$(echo "$base" | sed s/test-/check-/) 232 if [[ -f "$ctf_root/$check" ]]; then 233 run_dir $d "$ctf_root/$check" "$ctf_32cflags" \ 234 "$ctf_root/$check" "$ctf_64cflags" 235 elif [[ -f "$ctf_root/$check-32" && \ 236 -f "$ctf_root/$check-64" ]]; then 237 run_dir $d "$ctf_root/$check-32" "$ctf_32cflags" \ 238 "$ctf_root/$check-64" "$ctf_64cflags" 239 else 240 test_fail "missing checker for $t" 241 fi 242 done 243 244 outdir="$TMPDIR/ctftest.$$" 245 246 for f in $(find "$ctf_root" -maxdepth 1 -type f -name 'ctftest-*'); do 247 if ! mkdir $outdir; then 248 fatal "failed to make temporary directory '$outdir'" 249 fi 250 251 echo "Running $f in $outdir" 252 253 (cd $outdir && $f) 254 255 if [[ $? -ne 0 ]]; then 256 test_fail "$f failed" 257 else 258 echo "TEST PASSED: $f" 259 fi 260 261 rm -rf $outdir 262 done 263} 264 265while getopts ":a:C:c:g:m:t:" c $@; do 266 case "$c" in 267 a) 268 ctf_as=$OPTARG 269 ;; 270 C) 271 ctf_cxx=$OPTARG 272 ;; 273 c) 274 ctf_cc=$OPTARG 275 ;; 276 g) 277 ctf_debugflags=$OPTARG 278 ;; 279 m) 280 ctf_merge=$OPTARG 281 ;; 282 t) 283 ctf_convert=$OPTARG 284 ;; 285 :) 286 usage "option requires an argument -- $OPTARG" 287 ;; 288 *) 289 usage "invalid option -- $OPTARG" 290 ;; 291 esac 292done 293 294ctf_32cflags="$ctf_mach32 $ctf_debugflags" 295ctf_64cflags="$ctf_mach64 $ctf_debugflags" 296 297determine_compiler 298 299export ctf_as ctf_cc ctf_cxx ctf_debugflags ctf_merge ctf_convert 300export ctf_cc_type ctf_cc_version 301 302announce 303 304run_tests 305 306if [[ $ctf_nerrs -ne 0 ]]; then 307 if [[ $ctf_nerrs -eq 1 ]]; then 308 printf "\n%s: %u test failed\n" "$ctf_arg0" "$ctf_nerrs" 309 else 310 printf "\n%s: %u tests failed\n" "$ctf_arg0" "$ctf_nerrs" 311 fi 312 exit 1 313else 314 printf "\n%s: All tests passed successfully\n" "$ctf_arg0" 315 exit 0 316fi 317