1#!/bin/sh 2# 3# Copyright (c) 2011-2015 Dmitry V. Levin <ldv@altlinux.org> 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 3. The name of the author may not be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28ME_="${0##*/}" 29 30warn_() { printf >&2 '%s\n' "$*"; } 31fail_() { warn_ "$ME_: failed test: $*"; exit 1; } 32skip_() { warn_ "$ME_: skipped test: $*"; exit 77; } 33framework_failure_() { warn_ "$ME_: framework failure: $*"; exit 99; } 34framework_skip_() { warn_ "$ME_: framework skip: $*"; exit 77; } 35 36check_prog() 37{ 38 type "$@" > /dev/null 2>&1 || 39 framework_skip_ "$* is not available" 40} 41 42dump_log_and_fail_with() 43{ 44 cat < "$LOG" 45 fail_ "$*" 46} 47 48run_prog() 49{ 50 if [ $# -eq 0 ]; then 51 set -- "./${ME_%.test}" 52 fi 53 args="$*" 54 "$@" || { 55 if [ $? -eq 77 ]; then 56 skip_ "$args exited with code 77" 57 else 58 fail_ "$args failed" 59 fi 60 } 61} 62 63 64run_prog_skip_if_failed() 65{ 66 args="$*" 67 "$@" || framework_skip_ "$args failed" 68} 69 70run_strace() 71{ 72 > "$LOG" || fail_ "failed to write $LOG" 73 args="$*" 74 $STRACE -o "$LOG" "$@" || 75 dump_log_and_fail_with "$STRACE $args failed" 76} 77 78run_strace_merge() 79{ 80 rm -f -- "$LOG".[0-9]* 81 run_strace -ff -tt "$@" 82 "$srcdir"/../strace-log-merge "$LOG" > "$LOG" || 83 dump_log_and_fail_with 'strace-log-merge failed' 84 rm -f -- "$LOG".[0-9]* 85} 86 87check_gawk() 88{ 89 check_prog gawk 90 check_prog grep 91 92 local program="$1"; shift 93 if grep '^@include[[:space:]]' < "$program" > /dev/null; then 94 gawk '@include "/dev/null"' < /dev/null || 95 framework_skip_ 'gawk does not support @include' 96 fi 97} 98 99# Usage: [FILE_TO_CHECK [AWK_PROGRAM [ERROR_MESSAGE [EXTRA_AWK_OPTIONS...]]]] 100# Check whether AWK_PROGRAM matches FILE_TO_CHECK using gawk. 101# If it doesn't, dump FILE_TO_CHECK and fail with ERROR_MESSAGE. 102match_awk() 103{ 104 local output program error 105 if [ $# -eq 0 ]; then 106 output="$LOG" 107 else 108 output="$1"; shift 109 fi 110 if [ $# -eq 0 ]; then 111 program="$srcdir/${ME_%.test}.awk" 112 else 113 program="$1"; shift 114 fi 115 if [ $# -eq 0 ]; then 116 error="$STRACE $args output mismatch" 117 else 118 error="$1"; shift 119 fi 120 121 check_gawk "$program" 122 123 AWKPATH="$srcdir" gawk -f "$program" "$@" < "$output" || { 124 cat < "$output" 125 fail_ "$error" 126 } 127} 128 129# Usage: [FILE_TO_CHECK [FILE_TO_COMPATE_WITH [ERROR_MESSAGE]]] 130# Check whether FILE_TO_CHECK differs from FILE_TO_COMPATE_WITH. 131# If it does, dump the difference and fail with ERROR_MESSAGE. 132match_diff() 133{ 134 local output expected error 135 if [ $# -eq 0 ]; then 136 output="$LOG" 137 else 138 output="$1"; shift 139 fi 140 if [ $# -eq 0 ]; then 141 expected="$srcdir/${ME_%.test}.expected" 142 else 143 expected="$1"; shift 144 fi 145 if [ $# -eq 0 ]; then 146 error="$STRACE $args output mismatch" 147 else 148 error="$1"; shift 149 fi 150 151 check_prog diff 152 153 diff -- "$expected" "$output" || 154 fail_ "$error" 155} 156 157# Usage: [FILE_TO_CHECK [FILE_WITH_PATTERNS [ERROR_MESSAGE]]] 158# Check whether all patterns listed in FILE_WITH_PATTERNS 159# match FILE_TO_CHECK using egrep. 160# If at least one of these patterns does not match, 161# dump both files and fail with ERROR_MESSAGE. 162match_grep() 163{ 164 local output patterns error pattern failed= 165 if [ $# -eq 0 ]; then 166 output="$LOG" 167 else 168 output="$1"; shift 169 fi 170 if [ $# -eq 0 ]; then 171 patterns="$srcdir/${ME_%.test}.expected" 172 else 173 patterns="$1"; shift 174 fi 175 if [ $# -eq 0 ]; then 176 error="$STRACE $args output mismatch" 177 else 178 error="$1"; shift 179 fi 180 181 check_prog wc 182 check_prog grep 183 184 while read -r pattern; do 185 LC_ALL=C grep -E -x -e "$pattern" < "$output" > /dev/null || { 186 test -n "$failed" || { 187 echo 'Failed patterns of expected output:' 188 failed=1 189 } 190 printf '%s\n' "$pattern" 191 } 192 done < "$patterns" 193 test -z "$failed" || { 194 echo 'Actual output:' 195 cat < "$output" 196 fail_ "$error" 197 } 198} 199 200check_prog cat 201check_prog rm 202 203LOG="$ME_.tmp" 204rm -f "$LOG" 205 206: "${STRACE:=../strace}" 207: "${TIMEOUT_DURATION:=60}" 208: "${SLEEP_A_BIT:=sleep 1}" 209 210[ -z "${VERBOSE-}" ] || 211 set -x 212