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