Blame tests/functions.sh

Packit Service 087331
#!/bin/bash
Packit Service 087331
# SPDX-License-Identifier: GPL-2.0
Packit Service 087331
#
Packit Service 087331
# ima-evm-utils tests bash functions
Packit Service 087331
#
Packit Service 087331
# Copyright (C) 2020 Vitaly Chikunov <vt@altlinux.org>
Packit Service 087331
#
Packit Service 087331
# This program is free software; you can redistribute it and/or modify
Packit Service 087331
# it under the terms of the GNU General Public License as published by
Packit Service 087331
# the Free Software Foundation; either version 2, or (at your option)
Packit Service 087331
# any later version.
Packit Service 087331
#
Packit Service 087331
# This program is distributed in the hope that it will be useful,
Packit Service 087331
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 087331
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 087331
# GNU General Public License for more details.
Packit Service 087331
Packit Service 087331
# Tests accounting
Packit Service 087331
declare -i testspass=0 testsfail=0 testsskip=0
Packit Service 087331
Packit Service 087331
# Exit codes (compatible with automake)
Packit Service 087331
declare -r OK=0
Packit Service 087331
declare -r FAIL=1
Packit Service 087331
declare -r HARDFAIL=99 # hard failure no matter testing mode
Packit Service 087331
declare -r SKIP=77
Packit Service 087331
Packit Service 087331
# You can set env VERBOSE=1 to see more output from evmctl
Packit Service 087331
VERBOSE=${VERBOSE:-0}
Packit Service 087331
V=vvvv
Packit Service 087331
V=${V:0:$VERBOSE}
Packit Service 087331
V=${V:+-$V}
Packit Service 087331
Packit Service 087331
# Exit if env FAILEARLY is defined.
Packit Service 087331
# Used in expect_{pass,fail}.
Packit Service 087331
exit_early() {
Packit Service 087331
  if [ "$FAILEARLY" ]; then
Packit Service 087331
    exit "$1"
Packit Service 087331
  fi
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Require particular executables to be present
Packit Service 087331
_require() {
Packit Service 087331
  ret=
Packit Service 087331
  for i; do
Packit Service 087331
    if ! type $i; then
Packit Service 087331
      echo "$i is required for test"
Packit Service 087331
      ret=1
Packit Service 087331
    fi
Packit Service 087331
  done
Packit Service 087331
  [ $ret ] && exit "$HARDFAIL"
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Non-TTY output is never colored
Packit Service 087331
if [ -t 1 ]; then
Packit Service 087331
     RED=$'\e[1;31m'
Packit Service 087331
   GREEN=$'\e[1;32m'
Packit Service 087331
  YELLOW=$'\e[1;33m'
Packit Service 087331
    BLUE=$'\e[1;34m'
Packit Service 087331
    CYAN=$'\e[1;36m'
Packit Service 087331
    NORM=$'\e[m'
Packit Service 087331
  export RED GREEN YELLOW BLUE CYAN NORM
Packit Service 087331
fi
Packit Service 087331
Packit Service 087331
# Test mode determined by TFAIL variable:
Packit Service 087331
#   undefined: to success testing
Packit Service 087331
#   defined: failure testing
Packit Service 087331
TFAIL=
Packit Service 087331
TMODE=+ # mode character to prepend running command in log
Packit Service 087331
declare -i TNESTED=0 # just for sanity checking
Packit Service 087331
Packit Service 087331
# Run positive test (one that should pass) and account its result
Packit Service 087331
expect_pass() {
Packit Service 087331
  local -i ret
Packit Service 087331
Packit Service 087331
  if [ $TNESTED -gt 0 ]; then
Packit Service 087331
    echo $RED"expect_pass should not be run nested"$NORM
Packit Service 087331
    testsfail+=1
Packit Service 087331
    exit "$HARDFAIL"
Packit Service 087331
  fi
Packit Service 087331
  TFAIL=
Packit Service 087331
  TMODE=+
Packit Service 087331
  TNESTED+=1
Packit Service 087331
  [ "$VERBOSE" -gt 1 ] && echo "____ START positive test: $*"
Packit Service 087331
  "$@"
Packit Service 087331
  ret=$?
Packit Service 087331
  [ "$VERBOSE" -gt 1 ] && echo "^^^^ STOP ($ret) positive test: $*"
Packit Service 087331
  TNESTED+=-1
Packit Service 087331
  case $ret in
Packit Service 087331
    0)  testspass+=1 ;;
Packit Service 087331
    77) testsskip+=1 ;;
Packit Service 087331
    99) testsfail+=1; exit_early 1 ;;
Packit Service 087331
    *)  testsfail+=1; exit_early 2 ;;
Packit Service 087331
  esac
Packit Service 087331
  return $ret
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Eval negative test (one that should fail) and account its result
Packit Service 087331
expect_fail() {
Packit Service 087331
  local ret
Packit Service 087331
Packit Service 087331
  if [ $TNESTED -gt 0 ]; then
Packit Service 087331
    echo $RED"expect_fail should not be run nested"$NORM
Packit Service 087331
    testsfail+=1
Packit Service 087331
    exit "$HARDFAIL"
Packit Service 087331
  fi
Packit Service 087331
Packit Service 087331
  TFAIL=yes
Packit Service 087331
  TMODE=-
Packit Service 087331
  TNESTED+=1
Packit Service 087331
  [ "$VERBOSE" -gt 1 ] && echo "____ START negative test: $*"
Packit Service 087331
  "$@"
Packit Service 087331
  ret=$?
Packit Service 087331
  [ "$VERBOSE" -gt 1 ] && echo "^^^^ STOP ($ret) negative test: $*"
Packit Service 087331
  TNESTED+=-1
Packit Service 087331
  case $ret in
Packit Service 087331
    0)  testsfail+=1; exit_early 3 ;;
Packit Service 087331
    77) testsskip+=1 ;;
Packit Service 087331
    99) testsfail+=1; exit_early 4 ;;
Packit Service 087331
    *)  testspass+=1 ;;
Packit Service 087331
  esac
Packit Service 087331
  # Restore defaults (as in positive tests)
Packit Service 087331
  # for tests to run without wrappers
Packit Service 087331
  TFAIL=
Packit Service 087331
  TMODE=+
Packit Service 087331
  return $ret
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# return true if current test is positive
Packit Service 087331
_test_expected_to_pass() {
Packit Service 087331
  [ ! $TFAIL ]
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# return true if current test is negative
Packit Service 087331
_test_expected_to_fail() {
Packit Service 087331
  [ $TFAIL ]
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Show blank line and color following text to red
Packit Service 087331
# if it's real error (ie we are in expect_pass mode).
Packit Service 087331
color_red_on_failure() {
Packit Service 087331
  if _test_expected_to_pass; then
Packit Service 087331
    echo "$RED"
Packit Service 087331
    COLOR_RESTORE=true
Packit Service 087331
  fi
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# For hard errors
Packit Service 087331
color_red() {
Packit Service 087331
  echo "$RED"
Packit Service 087331
  COLOR_RESTORE=true
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
color_restore() {
Packit Service 087331
  [ $COLOR_RESTORE ] && echo "$NORM"
Packit Service 087331
  COLOR_RESTORE=
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
ADD_DEL=
Packit Service 087331
ADD_TEXT_FOR=
Packit Service 087331
# _evmctl_run should be run as `_evmctl_run ... || return'
Packit Service 087331
_evmctl_run() {
Packit Service 087331
  local op=$1 out=$1-$$.out
Packit Service 087331
  local text_for=${FOR:+for $ADD_TEXT_FOR}
Packit Service 087331
  # Additional parameters:
Packit Service 087331
  # ADD_DEL: additional files to rm on failure
Packit Service 087331
  # ADD_TEXT_FOR: append to text as 'for $ADD_TEXT_FOR'
Packit Service 087331
Packit Service 087331
  cmd="evmctl $V $EVMCTL_ENGINE $*"
Packit Service 087331
  echo $YELLOW$TMODE "$cmd"$NORM
Packit Service 087331
  $cmd >"$out" 2>&1
Packit Service 087331
  ret=$?
Packit Service 087331
Packit Service 087331
  # Shell special and signal exit codes (except 255)
Packit Service 087331
  if [ $ret -ge 126 ] && [ $ret -lt 255 ]; then
Packit Service 087331
    color_red
Packit Service 087331
    echo "evmctl $op failed hard with ($ret) $text_for"
Packit Service 087331
    sed 's/^/  /' "$out"
Packit Service 087331
    color_restore
Packit Service 087331
    rm "$out" $ADD_DEL
Packit Service 087331
    ADD_DEL=
Packit Service 087331
    ADD_TEXT_FOR=
Packit Service 087331
    return "$HARDFAIL"
Packit Service 087331
  elif [ $ret -gt 0 ]; then
Packit Service 087331
    color_red_on_failure
Packit Service 087331
    echo "evmctl $op failed" ${TFAIL:+properly} "with ($ret) $text_for"
Packit Service 087331
    # Show evmctl output only in verbose mode or if real failure.
Packit Service 087331
    if _test_expected_to_pass || [ "$VERBOSE" ]; then
Packit Service 087331
      sed 's/^/  /' "$out"
Packit Service 087331
    fi
Packit Service 087331
    color_restore
Packit Service 087331
    rm "$out" $ADD_DEL
Packit Service 087331
    ADD_DEL=
Packit Service 087331
    ADD_TEXT_FOR=
Packit Service 087331
    return "$FAIL"
Packit Service 087331
  elif _test_expected_to_fail; then
Packit Service 087331
    color_red
Packit Service 087331
    echo "evmctl $op wrongly succeeded $text_for"
Packit Service 087331
    sed 's/^/  /' "$out"
Packit Service 087331
    color_restore
Packit Service 087331
  else
Packit Service 087331
    [ "$VERBOSE" ] && sed 's/^/  /' "$out"
Packit Service 087331
  fi
Packit Service 087331
  rm "$out"
Packit Service 087331
  ADD_DEL=
Packit Service 087331
  ADD_TEXT_FOR=
Packit Service 087331
  return "$OK"
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Extract xattr $attr from $file into $out file skipping $pref'ix
Packit Service 087331
_extract_xattr() {
Packit Service 087331
  local file=$1 attr=$2 out=$3 pref=$4
Packit Service 087331
Packit Service 087331
  getfattr -n "$attr" -e hex "$file" \
Packit Service 087331
    | grep "^$attr=" \
Packit Service 087331
    | sed "s/^$attr=$pref//" \
Packit Service 087331
    | xxd -r -p > "$out"
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Test if xattr $attr in $file matches $prefix
Packit Service 087331
# Show error and fail otherwise.
Packit Service 087331
_test_xattr() {
Packit Service 087331
  local file=$1 attr=$2 prefix=$3
Packit Service 087331
  local text_for=${ADD_TEXT_FOR:+ for $ADD_TEXT_FOR}
Packit Service 087331
Packit Service 087331
  if ! getfattr -n "$attr" -e hex "$file" | egrep -qx "$attr=$prefix"; then
Packit Service 087331
    color_red_on_failure
Packit Service 087331
    echo "Did not find expected hash$text_for:"
Packit Service 087331
    echo "    $attr=$prefix"
Packit Service 087331
    echo ""
Packit Service 087331
    echo "Actual output below:"
Packit Service 087331
    getfattr -n "$attr" -e hex "$file" | sed 's/^/    /'
Packit Service 087331
    color_restore
Packit Service 087331
    rm "$file"
Packit Service 087331
    ADD_TEXT_FOR=
Packit Service 087331
    return "$FAIL"
Packit Service 087331
  fi
Packit Service 087331
  ADD_TEXT_FOR=
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Try to enable gost-engine if needed.
Packit Service 087331
_enable_gost_engine() {
Packit Service 087331
  # Do not enable if it's already working (enabled by user)
Packit Service 087331
  if ! openssl md_gost12_256 /dev/null >/dev/null 2>&1 \
Packit Service 087331
    && openssl engine gost >/dev/null 2>&1; then
Packit Service 087331
    export EVMCTL_ENGINE="--engine gost"
Packit Service 087331
    export OPENSSL_ENGINE="-engine gost"
Packit Service 087331
  fi
Packit Service 087331
}
Packit Service 087331
Packit Service 087331
# Show test stats and exit into automake test system
Packit Service 087331
# with proper exit code (same as ours).
Packit Service 087331
_report_exit() {
Packit Service 087331
  if [ $testsfail -gt 0 ]; then
Packit Service 087331
    echo "================================="
Packit Service 087331
    echo " Run with FAILEARLY=1 $0 $*"
Packit Service 087331
    echo " To stop after first failure"
Packit Service 087331
    echo "================================="
Packit Service 087331
  fi
Packit Service 087331
  [ $testspass -gt 0 ] && echo -n "$GREEN" || echo -n "$NORM"
Packit Service 087331
  echo -n "PASS: $testspass"
Packit Service 087331
  [ $testsskip -gt 0 ] && echo -n "$YELLOW" || echo -n "$NORM"
Packit Service 087331
  echo -n " SKIP: $testsskip"
Packit Service 087331
  [ $testsfail -gt 0 ] && echo -n "$RED" || echo -n "$NORM"
Packit Service 087331
  echo " FAIL: $testsfail"
Packit Service 087331
  echo "$NORM"
Packit Service 087331
  if [ $testsfail -gt 0 ]; then
Packit Service 087331
    exit "$FAIL"
Packit Service 087331
  elif [ $testspass -gt 0 ]; then
Packit Service 087331
    exit "$OK"
Packit Service 087331
  else
Packit Service 087331
    exit "$SKIP"
Packit Service 087331
  fi
Packit Service 087331
}
Packit Service 087331