Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test.sh 4.61 KiB
#!/usr/bin/env bash

# Defaults
LOGFILE=test.log
MODULENAME=testversions
EPICS_BASE=${EPICS_BASE:-/epics/base-7.0.5}
REQUIRE_VER=${E3_REQUIRE_VERSION:-3.4.1}

if which ack &>/dev/null; then
  __SEARCH_COMMAND__="ack --passthru"
else
  echo "ack is not installed; defaulting to grep, but note that the log will be missing the IOC log" >&2
  __SEARCH_COMMAND__="grep -P"
fi

function usage {
  echo "Usage:"
  echo "  bash test.sh [-b <EPICS_BASE>] [-r <REQUIRE_VER>] [-h] testfile"
  exit 0
}

function show_header {
  echo "Testing require version loader"
  echo "============================================================"
  echo -e "EPICS base:          \033[34m${EPICS_BASE}\033[0m"
  echo -e "Require version:     \033[34m${REQUIRE_VER}\033[0m"
  echo "============================================================"
}

function install_vers {
  for ver in "$@"; do
    echo "=========================================="
    echo "Installing local version version '$ver'"
    echo "=========================================="
    make -C test clean cellinstall __DEBUG_VERSION="$ver" __EPICS_BASE_LOCATION="$EPICS_BASE" __REQUIRE_VERSION="$REQUIRE_VER" E3_NO_TEST=true
  done
}

function clean_vers {
  rm -rf test/cellMods
}

function test_require {
  if [ "$#" -lt "3" ]; then
    usage
    return
  fi

  required=$1
  shift
  expected=$1
  shift
  args=("$@")

  if [ "$required" = "-" ]; then
    req_str="$MODULENAME"
  else
    req_str="$MODULENAME,$required"
  fi

  echo "============================================================"
  echo "Running test case:"
  echo "Requested: $required"
  echo "Expected:  $expected"
  echo "Installed: ${args[*]}"
  echo "============================================================"

  required=${required//+/\\+}
  expected=${expected//+/\\+}

  clean_vers

  install_vers "${args[@]}"

  echo "=========================================="
  echo "Running iocsh.bash -l cellMods -r $req_str"
  echo "=========================================="

  iocsh_args="-l test/cellMods -c 'var requireDebug 1' -r $req_str"

  if [ "$expected" = "-" ]; then
    search_string="Module $MODULENAME (not available|version $required not available|version $required not available \(but other versions are available\))"
  else
    search_string="^Loaded $MODULENAME version $expected\$"
  fi

  echo "SEARCH STRING: $search_string"

  # The funny sed command here is from https://unix.stackexchange.com/a/235016/445931
  # The reason this is needed is because the "Starting iocInit" message seems to be threaded
  # differently than the regular flow of output and sometimes will separate the strings that
  # we are looking for. If we simply cut it out then we seem to be able to more consistently
  # get meaningful tests.
  echo exit | eval iocsh.bash "$iocsh_args" |
    sed -e '1 h; 2,$ H; $! d; g' -e 's/Starting iocInit\niocRun: All initialization complete\n//' |
    $__SEARCH_COMMAND__ "${search_string}"
}

function format_output {
  result=$1
  shift
  requested=$1
  shift
  expected=$1
  shift
  versions=$*

  if [ "$result" = "0" ]; then
    result_str="\033[32mpassed\033[0m"
  else
    result_str="\033[31mfailed\033[0m"
  fi

  printf "Test: %b\n" "$result_str"
  printf "requested: %-20s     expected: %-20s\n" "$requested" "$expected"
  printf "Given versions: %s\n" "$versions"
  printf "============================================================\n"
}

while getopts "hb:r:c:" opt; do
  case $opt in
    b)
      EPICS_BASE="$OPTARG"
      ;;
    r)
      REQUIRE_VER="$OPTARG"
      ;;
    c)
      COMMAND="$OPTARG"
      ;;
    h)
      HELP=true
      ;;
    *)
      usage
      exit 1
      ;;
  esac
done
shift $((OPTIND - 1))
TESTFILE=$1

if [ "$HELP" = true ]; then
  usage
  exit 0
fi

rm -f "$LOGFILE"

ENV_SRC="$EPICS_BASE/require/$REQUIRE_VER/bin/setE3Env.bash"
if [ ! -f "$ENV_SRC" ]; then
  echo "setE3Env.bash not found at location $ENV_SRC" >&2
  exit 1
fi
# shellcheck disable=SC1090
source "$ENV_SRC" &>/dev/null

show_header

# TODO: Fix these silly shellcheck disables here.
failed_tests=0
if [ -n "$COMMAND" ]; then
  # shellcheck disable=2086
  test_require $COMMAND &>>"$LOGFILE"
  result=$?
  [ "$result" = 0 ] || ((failed_tests++))
  # shellcheck disable=2086
  format_output $result $COMMAND
fi

if [ -f "$TESTFILE" ]; then
  while read -r line; do
    # shellcheck disable=2086
    test_require $line &>>"$LOGFILE"
    result=$?
    [ "$result" = 0 ] || ((failed_tests++))
    # shellcheck disable=2086
    format_output $result $line
  done < <(sed -e 's/[[:space:]]*#.*//; /^[[:space:]]*$/d' "$TESTFILE")
fi

if [ ! "$failed_tests" = 0 ]; then
  echo -e "\033[31mFailing tests: $failed_tests\033[0m\n" >&2
  cat test.log
  exit 1
fi