tools_common.sh 13.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
#!/bin/sh
##
##  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
##
##  Use of this source code is governed by a BSD-style license
##  that can be found in the LICENSE file in the root of the source
##  tree. An additional intellectual property rights grant can be found
##  in the file PATENTS.  All contributing project authors may
##  be found in the AUTHORS file in the root of the source tree.
##
##  This file contains shell code shared by test scripts for libvpx tools.
12 13 14 15 16

# Use $VPX_TEST_TOOLS_COMMON_SH as a pseudo include guard.
if [ -z "${VPX_TEST_TOOLS_COMMON_SH}" ]; then
VPX_TEST_TOOLS_COMMON_SH=included

17
set -e
18
devnull='> /dev/null 2>&1'
19
VPX_TEST_PREFIX=""
20

21 22 23 24
elog() {
  echo "$@" 1>&2
}

25
vlog() {
26 27 28
  if [ "${VPX_TEST_VERBOSE_OUTPUT}" = "yes" ]; then
    echo "$@"
  fi
29 30
}

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
# Sets $VPX_TOOL_TEST to the name specified by positional parameter one.
test_begin() {
  VPX_TOOL_TEST="${1}"
}

# Clears the VPX_TOOL_TEST variable after confirming that $VPX_TOOL_TEST matches
# positional parameter one.
test_end() {
  if [ "$1" != "${VPX_TOOL_TEST}" ]; then
    echo "FAIL completed test mismatch!."
    echo "  completed test: ${1}"
    echo "  active test: ${VPX_TOOL_TEST}."
    return 1
  fi
  VPX_TOOL_TEST='<unset>'
}

# Echoes the target configuration being tested.
test_configuration_target() {
  vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk"
  # Find the TOOLCHAIN line, split it using ':=' as the field separator, and
  # print the last field to get the value. Then pipe the value to tr to consume
  # any leading/trailing spaces while allowing tr to echo the output to stdout.
  awk -F ':=' '/TOOLCHAIN/ { print $NF }' "${vpx_config_mk}" | tr -d ' '
}

# Trap function used for failure reports and tool output directory removal.
# When the contents of $VPX_TOOL_TEST do not match the string '<unset>', reports
# failure of test stored in $VPX_TOOL_TEST.
cleanup() {
  if [ -n "${VPX_TOOL_TEST}" ] && [ "${VPX_TOOL_TEST}" != '<unset>' ]; then
    echo "FAIL: $VPX_TOOL_TEST"
  fi
  if [ -n "${VPX_TEST_OUTPUT_DIR}" ] && [ -d "${VPX_TEST_OUTPUT_DIR}" ]; then
    rm -rf "${VPX_TEST_OUTPUT_DIR}"
  fi
}

# Echoes the git hash portion of the VERSION_STRING variable defined in
# $LIBVPX_CONFIG_PATH/config.mk to stdout, or the version number string when
# no git hash is contained in VERSION_STRING.
config_hash() {
  vpx_config_mk="${LIBVPX_CONFIG_PATH}/config.mk"
  # Find VERSION_STRING line, split it with "-g" and print the last field to
  # output the git hash to stdout.
  vpx_version=$(awk -F -g '/VERSION_STRING/ {print $NF}' "${vpx_config_mk}")
  # Handle two situations here:
  # 1. The default case: $vpx_version is a git hash, so echo it unchanged.
  # 2. When being run a non-dev tree, the -g portion is not present in the
  #    version string: It's only the version number.
  #    In this case $vpx_version is something like 'VERSION_STRING=v1.3.0', so
  #    we echo only what is after the '='.
  echo "${vpx_version##*=}"
}

# Echoes the short form of the current git hash.
current_hash() {
  if git --version > /dev/null 2>&1; then
    (cd "$(dirname "${0}")"
    git rev-parse --short HEAD)
  else
    # Return the config hash if git is unavailable: Fail silently, git hashes
    # are used only for warnings.
    config_hash
  fi
}

# Echoes warnings to stdout when git hash in vpx_config.h does not match the
# current git hash.
check_git_hashes() {
  hash_at_configure_time=$(config_hash)
  hash_now=$(current_hash)

  if [ "${hash_at_configure_time}" != "${hash_now}" ]; then
    echo "Warning: git hash has changed since last configure."
  fi
}

109 110 111 112 113 114 115 116 117 118 119
# $1 is the name of an environment variable containing a directory name to
# test.
test_env_var_dir() {
  local dir=$(eval echo "\${$1}")
  if [ ! -d "${dir}" ]; then
    elog "'${dir}': No such directory"
    elog "The $1 environment variable must be set to a valid directory."
    return 1
  fi
}

120 121 122 123
# This script requires that the LIBVPX_BIN_PATH, LIBVPX_CONFIG_PATH, and
# LIBVPX_TEST_DATA_PATH variables are in the environment: Confirm that
# the variables are set and that they all evaluate to directory paths.
verify_vpx_test_environment() {
124 125 126
  test_env_var_dir "LIBVPX_BIN_PATH" \
    && test_env_var_dir "LIBVPX_CONFIG_PATH" \
    && test_env_var_dir "LIBVPX_TEST_DATA_PATH"
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
}

# Greps vpx_config.h in LIBVPX_CONFIG_PATH for positional parameter one, which
# should be a LIBVPX preprocessor flag. Echoes yes to stdout when the feature
# is available.
vpx_config_option_enabled() {
  vpx_config_option="${1}"
  vpx_config_file="${LIBVPX_CONFIG_PATH}/vpx_config.h"
  config_line=$(grep "${vpx_config_option}" "${vpx_config_file}")
  if echo "${config_line}" | egrep -q '1$'; then
    echo yes
  fi
}

# Echoes yes when output of test_configuration_target() contains win32 or win64.
is_windows_target() {
  if test_configuration_target \
     | grep -q -e win32 -e win64 > /dev/null 2>&1; then
    echo yes
  fi
}

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
# Echoes path to $1 when it's executable and exists in ${LIBVPX_BIN_PATH}, or an
# empty string. Caller is responsible for testing the string once the function
# returns.
vpx_tool_path() {
  local readonly tool_name="$1"
  local tool_path="${LIBVPX_BIN_PATH}/${tool_name}${VPX_TEST_EXE_SUFFIX}"
  if [ ! -x "${tool_path}" ]; then
    # Try one directory up: when running via examples.sh the tool could be in
    # the parent directory of $LIBVPX_BIN_PATH.
    tool_path="${LIBVPX_BIN_PATH}/../${tool_name}${VPX_TEST_EXE_SUFFIX}"
  fi

  if [ ! -x "${tool_path}" ]; then
    tool_path=""
  fi
  echo "${tool_path}"
}

167 168 169
# Echoes yes to stdout when the file named by positional parameter one exists
# in LIBVPX_BIN_PATH, and is executable.
vpx_tool_available() {
170 171 172
  local tool_name="$1"
  local tool="${LIBVPX_BIN_PATH}/${tool_name}${VPX_TEST_EXE_SUFFIX}"
  [ -x "${tool}" ] && echo yes
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
}

# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
# CONFIG_VP8_DECODER.
vp8_decode_available() {
  [ "$(vpx_config_option_enabled CONFIG_VP8_DECODER)" = "yes" ] && echo yes
}

# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
# CONFIG_VP8_ENCODER.
vp8_encode_available() {
  [ "$(vpx_config_option_enabled CONFIG_VP8_ENCODER)" = "yes" ] && echo yes
}

# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
# CONFIG_VP9_DECODER.
vp9_decode_available() {
  [ "$(vpx_config_option_enabled CONFIG_VP9_DECODER)" = "yes" ] && echo yes
}

# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
# CONFIG_VP9_ENCODER.
vp9_encode_available() {
  [ "$(vpx_config_option_enabled CONFIG_VP9_ENCODER)" = "yes" ] && echo yes
}

# Echoes yes to stdout when vpx_config_option_enabled() reports yes for
# CONFIG_WEBM_IO.
webm_io_available() {
  [ "$(vpx_config_option_enabled CONFIG_WEBM_IO)" = "yes" ] && echo yes
}

205 206 207 208 209
# Filters strings from $1 using the filter specified by $2. Filter behavior
# depends on the presence of $3. When $3 is present, strings that match the
# filter are excluded. When $3 is omitted, strings matching the filter are
# included.
# The filtered result is echoed to stdout.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
filter_strings() {
  strings=${1}
  filter=${2}
  exclude=${3}

  if [ -n "${exclude}" ]; then
    # When positional parameter three exists the caller wants to remove strings.
    # Tell grep to invert matches using the -v argument.
    exclude='-v'
  else
    unset exclude
  fi

  if [ -n "${filter}" ]; then
    for s in ${strings}; do
      if echo "${s}" | egrep -q ${exclude} "${filter}" > /dev/null 2>&1; then
        filtered_strings="${filtered_strings} ${s}"
      fi
    done
  else
    filtered_strings="${strings}"
  fi
  echo "${filtered_strings}"
}

# Runs user test functions passed via positional parameters one and two.
# Functions in positional parameter one are treated as environment verification
# functions and are run unconditionally. Functions in positional parameter two
# are run according to the rules specified in vpx_test_usage().
run_tests() {
240 241 242 243 244
  local env_tests="verify_vpx_test_environment $1"
  local tests_to_filter="$2"
  local test_name="${VPX_TEST_NAME}"

  if [ -z "${test_name}" ]; then
245
    test_name="$(basename "${0%.*}")"
246
  fi
247 248 249 250 251 252 253 254 255 256 257

  if [ "${VPX_TEST_RUN_DISABLED_TESTS}" != "yes" ]; then
    # Filter out DISABLED tests.
    tests_to_filter=$(filter_strings "${tests_to_filter}" ^DISABLED exclude)
  fi

  if [ -n "${VPX_TEST_FILTER}" ]; then
    # Remove tests not matching the user's filter.
    tests_to_filter=$(filter_strings "${tests_to_filter}" ${VPX_TEST_FILTER})
  fi

258 259 260 261 262 263 264 265
  # User requested test listing: Dump test names and return.
  if [ "${VPX_TEST_LIST_TESTS}" = "yes" ]; then
    for test_name in $tests_to_filter; do
      echo ${test_name}
    done
    return
  fi

266 267 268
  # Don't bother with the environment tests if everything else was disabled.
  [ -z "${tests_to_filter}" ] && return

269
  # Combine environment and actual tests.
270
  local tests_to_run="${env_tests} ${tests_to_filter}"
271 272 273 274 275 276

  check_git_hashes

  # Run tests.
  for test in ${tests_to_run}; do
    test_begin "${test}"
277
    vlog "  RUN  ${test}"
278
    "${test}"
279
    vlog "  PASS ${test}"
280 281 282
    test_end "${test}"
  done

283 284
  local tested_config="$(test_configuration_target) @ $(current_hash)"
  echo "${test_name}: Done, all tests pass for ${tested_config}."
285 286 287 288 289 290 291 292 293 294 295
}

vpx_test_usage() {
cat << EOF
  Usage: ${0##*/} [arguments]
    --bin-path <path to libvpx binaries directory>
    --config-path <path to libvpx config directory>
    --filter <filter>: User test filter. Only tests matching filter are run.
    --run-disabled-tests: Run disabled tests.
    --help: Display this message and exit.
    --test-data-path <path to libvpx test data directory>
296
    --show-program-output: Shows output from all programs being tested.
297 298 299
    --prefix: Allows for a user specified prefix to be inserted before all test
              programs. Grants the ability, for example, to run test programs
              within valgrind.
300
    --list-tests: List all test names and exit without actually running tests.
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
    --verbose: Verbose output.

    When the --bin-path option is not specified the script attempts to use
    \$LIBVPX_BIN_PATH and then the current directory.

    When the --config-path option is not specified the script attempts to use
    \$LIBVPX_CONFIG_PATH and then the current directory.

    When the -test-data-path option is not specified the script attempts to use
    \$LIBVPX_TEST_DATA_PATH and then the current directory.
EOF
}

# Returns non-zero (failure) when required environment variables are empty
# strings.
vpx_test_check_environment() {
  if [ -z "${LIBVPX_BIN_PATH}" ] || \
     [ -z "${LIBVPX_CONFIG_PATH}" ] || \
     [ -z "${LIBVPX_TEST_DATA_PATH}" ]; then
    return 1
  fi
}

# Parse the command line.
while [ -n "$1" ]; do
  case "$1" in
    --bin-path)
      LIBVPX_BIN_PATH="$2"
      shift
      ;;
    --config-path)
      LIBVPX_CONFIG_PATH="$2"
      shift
      ;;
    --filter)
      VPX_TEST_FILTER="$2"
      shift
      ;;
    --run-disabled-tests)
      VPX_TEST_RUN_DISABLED_TESTS=yes
      ;;
    --help)
      vpx_test_usage
      exit
      ;;
    --test-data-path)
      LIBVPX_TEST_DATA_PATH="$2"
      shift
      ;;
350 351 352 353
    --prefix)
      VPX_TEST_PREFIX="$2"
      shift
      ;;
354 355 356
    --verbose)
      VPX_TEST_VERBOSE_OUTPUT=yes
      ;;
357 358 359
    --show-program-output)
      devnull=
      ;;
360 361 362
    --list-tests)
      VPX_TEST_LIST_TESTS=yes
      ;;
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
    *)
      vpx_test_usage
      exit 1
      ;;
  esac
  shift
done

# Handle running the tests from a build directory without arguments when running
# the tests on *nix/macosx.
LIBVPX_BIN_PATH="${LIBVPX_BIN_PATH:-.}"
LIBVPX_CONFIG_PATH="${LIBVPX_CONFIG_PATH:-.}"
LIBVPX_TEST_DATA_PATH="${LIBVPX_TEST_DATA_PATH:-.}"

# Create a temporary directory for output files, and a trap to clean it up.
if [ -n "${TMPDIR}" ]; then
  VPX_TEST_TEMP_ROOT="${TMPDIR}"
elif [ -n "${TEMPDIR}" ]; then
  VPX_TEST_TEMP_ROOT="${TEMPDIR}"
else
  VPX_TEST_TEMP_ROOT=/tmp
fi

386
VPX_TEST_OUTPUT_DIR="${VPX_TEST_TEMP_ROOT}/vpx_test_$$"
387 388 389 390 391 392 393 394

if ! mkdir -p "${VPX_TEST_OUTPUT_DIR}" || \
   [ ! -d "${VPX_TEST_OUTPUT_DIR}" ]; then
  echo "${0##*/}: Cannot create output directory, giving up."
  echo "${0##*/}:   VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}"
  exit 1
fi

395 396 397 398
if [ "$(is_windows_target)" = "yes" ]; then
  VPX_TEST_EXE_SUFFIX=".exe"
fi

399 400 401 402 403
# Variables shared by tests.
VP8_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp80-00-comprehensive-001.ivf"
VP9_IVF_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-09-subpixel-00.ivf"

VP9_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-00-quantizer-00.webm"
404
VP9_FPM_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-07-frame_parallel-1.webm"
405
VP9_LT_50_FRAMES_WEBM_FILE="${LIBVPX_TEST_DATA_PATH}/vp90-2-02-size-32x08.webm"
406 407 408 409 410

YUV_RAW_INPUT="${LIBVPX_TEST_DATA_PATH}/hantro_collage_w352h288.yuv"
YUV_RAW_INPUT_WIDTH=352
YUV_RAW_INPUT_HEIGHT=288

411
Y4M_NOSQ_PAR_INPUT="${LIBVPX_TEST_DATA_PATH}/park_joy_90p_8_420_a10-1.y4m"
412
Y4M_720P_INPUT="${LIBVPX_TEST_DATA_PATH}/niklas_1280_720_30.y4m"
413

414
# Setup a trap function to clean up after tests complete.
415 416
trap cleanup EXIT

417
vlog "$(basename "${0%.*}") test configuration:
418 419 420
  LIBVPX_BIN_PATH=${LIBVPX_BIN_PATH}
  LIBVPX_CONFIG_PATH=${LIBVPX_CONFIG_PATH}
  LIBVPX_TEST_DATA_PATH=${LIBVPX_TEST_DATA_PATH}
421 422 423 424
  VP8_IVF_FILE=${VP8_IVF_FILE}
  VP9_IVF_FILE=${VP9_IVF_FILE}
  VP9_WEBM_FILE=${VP9_WEBM_FILE}
  VPX_TEST_EXE_SUFFIX=${VPX_TEST_EXE_SUFFIX}
425
  VPX_TEST_FILTER=${VPX_TEST_FILTER}
426
  VPX_TEST_LIST_TESTS=${VPX_TEST_LIST_TESTS}
427
  VPX_TEST_OUTPUT_DIR=${VPX_TEST_OUTPUT_DIR}
428
  VPX_TEST_PREFIX=${VPX_TEST_PREFIX}
429
  VPX_TEST_RUN_DISABLED_TESTS=${VPX_TEST_RUN_DISABLED_TESTS}
430 431 432 433 434
  VPX_TEST_SHOW_PROGRAM_OUTPUT=${VPX_TEST_SHOW_PROGRAM_OUTPUT}
  VPX_TEST_TEMP_ROOT=${VPX_TEST_TEMP_ROOT}
  VPX_TEST_VERBOSE_OUTPUT=${VPX_TEST_VERBOSE_OUTPUT}
  YUV_RAW_INPUT=${YUV_RAW_INPUT}
  YUV_RAW_INPUT_WIDTH=${YUV_RAW_INPUT_WIDTH}
435 436
  YUV_RAW_INPUT_HEIGHT=${YUV_RAW_INPUT_HEIGHT}
  Y4M_NOSQ_PAR_INPUT=${Y4M_NOSQ_PAR_INPUT}"
437 438

fi  # End $VPX_TEST_TOOLS_COMMON_SH pseudo include guard.