1#!/bin/sh
2#
3# Copyright 1994-2018 Brad Lanam, Walnut Creek, CA
4# Copyright 2020 Brad Lanam Pleasant Hill CA
5#
6
7#
8# speed at the cost of maintainability...
9# File Descriptors:
10#    9 - $TSTRUNLOG
11#    8 - $MAINLOG
12#    7 - $TMPORDER
13#    5 - stdout (as 1 is directed to the log)
14#
15
16set -f # global
17
18DOPERL=T
19TESTORDER=test_order
20SUBDIR=F
21
22# this is a workaround for ksh93 on solaris
23if [ "$1" = -d ]; then
24  cd $2
25  shift
26  shift
27fi
28unset CDPATH
29
30if [ "$1" = -s ]; then
31  SUBDIR=T
32  shift
33  CC="$1"
34  DC="$2"
35  shelllist="$3"
36  _pthlist="$4"
37  TMPOUT="$5"
38  shift; shift; shift; shift; shift
39fi
40
41if [ $# -lt 1 ]; then
42  echo "Usage: $0 <test-dir> [<test-to-run> ...]"
43  exit 1
44fi
45
46unset GREP_OPTIONS
47unset ENV
48unalias sed > /dev/null 2>&1
49unalias grep > /dev/null 2>&1
50unalias ls > /dev/null 2>&1
51unalias rm > /dev/null 2>&1
52LC_ALL=C
53export LC_ALL
54
55# this is used for regression testing.
56getlistofshells () {
57
58  getpaths
59  echo "## PATH: $PATH" >&8
60  echo "## paths: $_pthlist" >&8
61
62  tshelllist=""
63  inodelist=""
64  for d in $_pthlist; do
65    for s in $tryshell ; do
66      rs=$d/$s
67      if [ -x $rs ]; then
68        while [ -h $rs -a $s != osh ]; do
69          ors=$rs
70          rs="`ls -l $rs | sed 's/.* //'`"
71          case $rs in
72            /*)
73              ;;
74            *)
75              rs="$d/$rs"
76              ;;
77          esac
78
79          # /etc/alternatives/xxx has some weird names w/dots.
80          # all ksh* are ksh
81          # anything not ksh/bash/zsh/osh is sh
82          # if the name is sh->bash or sh->ksh; don't follow symlink.
83          ts=`echo $rs | sed -e 's,.*[/\.],,' \
84              -e 's/ksh88/ksh/' -e 's/ksh93/ksh/' `
85          tts=`echo $s | sed -e 's/ksh88/ksh/' -e 's/ksh93/ksh/' `
86          if [ $ts != ksh -a $ts != bash -a $ts != zsh ]; then
87            ts=sh
88          fi
89          if [ $ts != ksh -a $tts != bash -a $tts != zsh ]; then
90            tts=sh
91          fi
92          if [ $ts != $tts ]; then
93            rs=$ors
94            break
95          fi
96
97          rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'`
98          rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'`
99          rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'`
100          rs=`echo $rs | sed 's,/[^/]*/\.\./,/,'`
101        done
102
103        inode=`ls -i ${rs} | sed -e 's/^ *//' -e 's/ .*//'`
104        inode=${inode}${s}   # append shell type also
105        found=F
106        for i in $inodelist; do
107          if [ "$inode" = "${i}" ]; then
108            found=T
109            break
110          fi
111        done
112        if [ $found = T ]; then
113          continue
114        fi
115
116        if [ -x $rs ]; then
117          cmd="$rs -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;getshelltype $rs echo\""
118          set `eval $cmd`
119          dispshell=$1
120          echo "  found: $rs ($dispshell)" >&8
121          case $dispshell in
122            *)
123              tshelllist="${tshelllist}
124$rs"
125              if [ "${inode}" != ${s} ]; then
126                inodelist="${inodelist}
127${inode}"
128              fi
129              ;;
130          esac
131        fi # if executable
132      fi  # if there is a file
133    done
134  done
135
136  tshelllist=`echo "$tshelllist" | sort -u`
137  systype=`uname -s`
138  shelllist=""
139  for s in $tshelllist; do
140    putsnonl "  check $s" >&8
141    putsnonl "   $s"
142    cmd="$s -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;chkshell echo $s\""
143    eval $cmd >&8 2>&1
144    rc=$?
145    cmd="$s -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;getshelltype $s echo\""
146    set `eval $cmd`
147    dispshell=$1
148    shift
149    shvers=$@
150    if [ $rc -eq 0 ]; then
151      echo " ok" >&8
152      shelllist="${shelllist} $s"
153      echo " [$dispshell $shvers] (ok)"
154    else
155      echo " ng" >&8
156      echo " : $chkmsg" >&8
157      echo " [$dispshell $shvers] (ng)"
158    fi
159  done
160}
161
162runshelltest () {
163  stag=""
164  if [ "$_MKCONFIG_SHELL" != "" ]; then
165    stag=".${scount}_${dispshell}"
166  fi
167  TSTRUNLOG=${_MKCONFIG_TSTRUNTMPDIR}/${tbase}.log${stag}
168  > $TSTRUNLOG
169  exec 9>>$TSTRUNLOG
170
171  echo "####" >&9
172  echo "# Test: $tbase $arg" >&9
173  if [ "$_MKCONFIG_SHELL" != "" ]; then
174    echo "## testing with ${_MKCONFIG_SHELL} " >&9
175  fi
176  echo "# $dt" >&9
177  echo "####" >&9
178
179  cd $_MKCONFIG_TSTRUNTMPDIR
180  if [ "$_MKCONFIG_SHELL" != "" ]; then
181    putsnonl " ${dispshell}"
182  fi
183  targ=$arg
184  if [ "$arg" != "" ]; then
185    targ="$_MKCONFIG_DIR/$arg"
186  fi
187  # dup stdout to 5; redirect stdout to 9; redirect stderr to new 1.
188  ${_MKCONFIG_SHELL} $_MKCONFIG_RUNTESTDIR/$tf "$stag" $targ 5>&1 >&9 2>&1
189  rc=$?
190  cd $_MKCONFIG_RUNTESTDIR
191
192  dt=`date`
193  echo "####" >&9
194  echo "# $dt" >&9
195  echo "# exit $rc" >&9
196  echo "####" >&9
197  exec 9>&-
198  if [ $rc -ne 0 -a "$_MKCONFIG_SHELL" != "" ]; then
199    putsnonl "*"
200  fi
201  return $rc
202}
203
204#
205# main
206#
207
208_MKCONFIG_RUNTOPDIR=`pwd`
209export _MKCONFIG_RUNTOPDIR
210mypath=`echo $0 | sed -e 's,/[^/]*$,,' -e 's,^\.,./.,'`
211if [ "$mypath" = runtests.sh ]; then
212  mypath=.
213fi
214_MKCONFIG_DIR=`(cd $mypath;pwd)`
215export _MKCONFIG_DIR
216. ${_MKCONFIG_DIR}/bin/shellfuncs.sh
217
218_MKC_ONCE=0
219export _MKC_ONCE
220_MKC_SH=1
221export _MKC_SH
222_MKC_PL=2
223export _MKC_PL
224_MKC_SH_PL=3
225export _MKC_SH_PL
226
227doshelltest $0 $@
228if [ $SUBDIR = F ]; then
229  mkconfigversion
230fi
231
232testdir=$1
233if [ ! -d $testdir ]; then
234  echo "## Unable to locate $testdir"
235  exit 1
236fi
237
238shift
239teststorun=$*
240
241cd $testdir
242if [ $? != 0 ]; then
243  echo "## Unable to cd to $testdir"
244  exit 1
245fi
246
247_MKCONFIG_RUNTESTDIR=`pwd`
248export _MKCONFIG_RUNTESTDIR
249MKC_FILES=${MKC_FILES:-mkc_files}
250export MKC_FILES
251
252if [ $SUBDIR = F ]; then
253  _MKCONFIG_RUNTMPDIR=$_MKCONFIG_RUNTOPDIR/${MKC_FILES}/_mkconfig_runtests
254  export _MKCONFIG_RUNTMPDIR
255
256  CC=${CC:-cc}
257  export CC
258  DC=${DC:-gdc}
259  export DC
260else
261  btestdir=`echo $testdir | sed 's,.*/,,'`
262  _MKCONFIG_RUNTMPDIR=$_MKCONFIG_RUNTOPDIR/${MKC_FILES}/_mkconfig_runtests/$btestdir
263  export _MKCONFIG_RUNTMPDIR
264fi
265d=`dirname $_MKCONFIG_RUNTMPDIR`
266test -d $d || mkdir -p $d
267
268TMPORDER=test_order.tmp
269> $TMPORDER
270if [ "$teststorun" = "" ]; then
271  if [ ! -f "$TESTORDER" ]; then
272    ls -1d *.d *.sh 2>/dev/null | sed -e 's/\.sh$//' -e 's/^/1/' >> $TMPORDER
273  else
274    sort -n $TESTORDER >> $TMPORDER
275  fi
276else
277  for t in $teststorun; do
278    echo "1 $t"
279  done >> $TMPORDER
280fi
281
282if [ $SUBDIR = F ]; then
283  test -d $_MKCONFIG_RUNTMPDIR && rm -rf "$_MKCONFIG_RUNTMPDIR"
284fi
285test -d $_MKCONFIG_RUNTMPDIR || mkdir $_MKCONFIG_RUNTMPDIR
286
287MAINLOG=${_MKCONFIG_RUNTMPDIR}/main.log
288if [ $SUBDIR = F ]; then
289  > $MAINLOG
290fi
291exec 8>>$MAINLOG
292
293if [ $SUBDIR = F ]; then
294  echo "## locating valid shells"
295  getlistofshells
296fi
297
298locateawkcmd
299echo "awk: $awkcmd" >&8
300locatepkgconfigcmd
301echo "pkg-config: $pkgconfigcmd" >&8
302
303export shelllist
304grc=0
305count=0
306fcount=0
307fpass=0
308lastpass=""
309# save stdin in fd 7
310exec 7<&0 < ${TMPORDER}
311while read tline; do
312  set $tline
313  pass=$1
314  tbase=$2
315  if [ "$lastpass" = "" ]; then
316    lastpass=$pass
317  fi
318  if [ $grc -ne 0 -a "$lastpass" != "$pass" ]; then
319    if [ $SUBDIR = F ]; then
320      echo "## stopping tests due to failures in $testdir/ pass $lastpass"
321    else
322      fpass=$lastpass
323    fi
324    echo "## stopping tests due to failures in $testdir/ pass $lastpass" >&8
325    break
326  fi
327
328  if [ -d "$tbase" ]; then
329    ocwd=`pwd`
330    cd $_MKCONFIG_DIR
331    TMPOUT=${_MKCONFIG_RUNTMPDIR}/${tbase}.out
332    ${_MKCONFIG_SHELL} ./runtests.sh -s "$CC" "$DC" "$shelllist" "$_pthlist" $TMPOUT $testdir/$tbase
333    retvals=`tail -1 $TMPOUT`
334    rm -f $TMPOUT > /dev/null 2>&1
335    set $retvals
336    retcount=$1
337    retfcount=$2
338    retfpass=$3
339    domath count "$count + $retcount"
340    domath fcount "$fcount + $retfcount"
341    rc=$retfcount
342    if [ $rc -ne 0 ]; then
343      grc=$rc
344      echo "## stopping tests due to failures in $testdir/$tbase/ pass $retfpass (pass $lastpass) "
345      echo "## stopping tests due to failures in $testdir/$tbase/ pass $retfpass (pass $lastpass)" >&8
346      break
347    fi
348    cd $ocwd
349    continue
350  fi
351
352  tprefix=`echo $tbase | sed 's/-.*//'`
353  if [ "${CC}" = "" -a "$tprefix" = c ]; then
354    continue
355  fi
356  if [ "${DC}" = "" -a "$tprefix" = d ]; then
357    continue
358  fi
359  tf="${tbase}.sh"
360  tconfig="${tbase}.config"
361  tconfh="${tbase}.ctmp"
362
363  ok=T
364  if [ ! -f ./$tf ]; then
365    echo "$tbase ... missing ... failed"
366    echo "$tbase ... missing ... failed" >&8
367    ok=F
368  elif [ ! -x ./$tf ]; then
369    echo "$tbase ... permission denied ... failed"
370    echo "$tbase ... permission denied ... failed" >&8
371    ok=F
372  fi
373  if [ $ok = F ]; then
374    domath fcount "$fcount + 1"
375    domath count "$count + 1"
376    continue
377  fi
378
379  dt=`date`
380  arg="mkconfig.sh"
381
382  scount=""
383  putsnonl "$tbase ..."
384  putsnonl "$tbase ..." >&8
385  _MKCONFIG_TSTRUNTMPDIR=$_MKCONFIG_RUNTMPDIR/${tbase}
386  export _MKCONFIG_TSTRUNTMPDIR
387  mkdir ${_MKCONFIG_TSTRUNTMPDIR}
388  if [ -f $tconfig ]; then
389    cp $tconfig $_MKCONFIG_TSTRUNTMPDIR/$tconfh
390  fi
391  tfdisp=`$_MKCONFIG_RUNTESTDIR/$tf -d`
392  putsnonl " ${tfdisp}"
393  putsnonl " ${tfdisp}" >&8
394  $_MKCONFIG_RUNTESTDIR/$tf -q
395  runshpl=$?
396
397  if [ $runshpl -eq $_MKC_SH -o $runshpl -eq $_MKC_SH_PL ]; then
398    putsnonl " ..."
399    putsnonl " ..." >&8
400    src=0
401    scount=1
402    for s in $shelllist; do
403      unset _shell
404      unset dispshell
405      cmd="$s -c \". $_MKCONFIG_DIR/bin/shellfuncs.sh;getshelltype $s echo\""
406      set `eval $cmd`
407      dispshell=$1
408      _MKCONFIG_SHELL=$s
409      export _MKCONFIG_SHELL
410
411      runshelltest
412      rc=$?
413      if [ $rc -ne 0 ]; then src=$rc; fi
414      domath scount "$scount + 1"
415
416      unset _shell
417      unset dispshell
418      unset _MKCONFIG_SHELL
419    done
420  else
421    runshelltest
422    src=$?
423  fi
424
425  if [ $src -eq 166 ]; then
426    echo " ... skipped"
427    echo " skipped" >&8
428  elif [ $src -ne 0 ]; then
429    src=1
430    grc=1
431    if [ $tbase = c-compiler -a $grc -ne 0 ]; then
432      CC=""
433      grc=0
434    fi
435    if [ $tbase = d-compiler -a $grc -ne 0 ]; then
436      DC=""
437      grc=0
438    fi
439    if [ $grc -eq 0 ]; then
440      echo " ... skipping $tprefix compiler tests"
441      echo " skipping $tprefix compiler tests" >&8
442    else
443      echo " ... failed"
444      echo " failed" >&8
445      domath fcount "$fcount + 1"
446    fi
447  else
448    echo " ... success"
449    echo " success" >&8
450  fi
451  domath count "$count + 1"
452
453  if [ $src -eq 0 -a "$MKC_CLEAN_RUN_TMP" = Y ]; then
454    test -d "$_MKCONFIG_TSTRUNTMPDIR" && rm -rf "$_MKCONFIG_TSTRUNTMPDIR"
455  fi
456
457  # for some reason, unixware can't handle this if it is split into
458  # multiple lines.
459  if [ "$DOPERL" = T -a \( $runshpl -eq $_MKC_PL -o $runshpl -eq $_MKC_SH_PL \) ]; then
460    _MKCONFIG_TSTRUNTMPDIR=$_MKCONFIG_RUNTMPDIR/${tbase}_pl
461    export _MKCONFIG_TSTRUNTMPDIR
462    mkdir ${_MKCONFIG_TSTRUNTMPDIR}
463    TSTRUNLOG=$_MKCONFIG_TSTRUNTMPDIR/${tbase}.log
464    > $TSTRUNLOG
465    exec 9>>$TSTRUNLOG
466
467    dt=`date`
468    echo "####" >&9
469    echo "# Test: $tf mkconfig.pl" >&9
470    echo "# $dt" >&9
471    echo "####" >&9
472    putsnonl "$tbase ..."
473    putsnonl "$tbase ..." >&8
474    putsnonl " ${tfdisp}"
475    putsnonl " ${tfdisp}" >&8
476    putsnonl " ... perl"
477    putsnonl " ... perl" >&8
478    echo "## Using mkconfig.pl " >&9
479    if [ -f $tconfig ]; then
480      cp $tconfig $_MKCONFIG_TSTRUNTMPDIR/$tconfh
481    fi
482
483    cd $_MKCONFIG_TSTRUNTMPDIR
484    # dup stdout to 5; redirect stdout to 9; redirect stderr to new 1.
485    $_MKCONFIG_RUNTESTDIR/$tf none $_MKCONFIG_DIR/mkconfig.pl 5>&1 >&9 2>&1
486    rc=$?
487    cd $_MKCONFIG_RUNTESTDIR
488
489    dt=`date`
490    echo "####" >&9
491    echo "# $dt" >&9
492    echo "# exit $rc" >&9
493    echo "####" >&9
494    exec 9>&-
495    if [ $rc -ne 0 ]; then
496      echo " ... failed"
497      echo " failed" >&8
498      domath fcount "$fcount + 1"
499      grc=1
500    else
501      echo " ... success"
502      echo " success" >&8
503    fi
504    domath count "$count + 1"
505
506    if [ $rc -eq 0 -a "$MKC_CLEAN_RUN_TMP" = Y ]; then
507      test -d "$_MKCONFIG_TSTRUNTMPDIR" && rm -rf "$_MKCONFIG_TSTRUNTMPDIR"
508    fi
509  fi
510
511  lastpass=$pass
512done
513# set std to saved fd 7; close 7
514exec <&7 7<&-
515test -f $TMPORDER && rm -f $TMPORDER
516
517if [ $count -eq 0 ]; then  # this can't be right...
518  $fcount = -1
519fi
520
521exec 8>&-
522
523if [ $SUBDIR = F ]; then
524  echo "$count tests $fcount failures"
525  if [ $fcount -eq 0 ]; then
526    if [ "$MKC_KEEP_RUN_TMP" = "" ]; then
527      (
528        cd $_MKCONFIG_RUNTMPDIR/../..
529        test -d "$_MKCONFIG_RUNTMPDIR" && rm -rf "$_MKCONFIG_RUNTMPDIR"
530        test -d "${MKC_FILES}" && rmdir "${MKC_FILES}" > /dev/null 2>&1
531      )
532    fi
533  fi
534else
535  echo "$count $fcount $fpass" > $TMPOUT
536fi
537
538exit $fcount
539