#!/usr/bin/env bash
#
# Copyright © 2016-2017 Inria. All rights reserved.
# See COPYING in top-level directory.
#
# This script needs a test file as argument
# The syntax of this file is the following
# test1:
# testset: machine1 machine2 # subfolders where tests be run
# command: ./test1 param1 # command to test
# needed: dir1/file*txt dir2 # files needed
# excluded: dir1/file0.txt dir2/file1 # file to exclude
# checkfiles: dir2/file1 # files used to check validity
# checkscript: ./check.sh # script to check validity
# test2:
# ...
export NETLOC_TESTS_PATH="@HWLOC_top_srcdir@/tests/netloc"
export NETLOC_BUILD_PATH="@HWLOC_top_builddir@/tests/netloc"
export NETLOC_UTIL_PATH="@HWLOC_top_builddir@/utils/netloc"
origpwd="$(pwd)"
red="\e[31m"
green="\e[32m"
default="\e[0m"
function write_output
{
color=$1
shift
echo -e $color$@$default
}
function quit
{
write_output $red "Test failed"
rm -fr $TEMPDIR
}
function getvalues
{
for i in $@; do
echo "$params" | $SED -n "s/^[[:space:]]*$i:[[:space:]]*\(.*\)\$/\1/p"
done | tr '\n' ' '
}
function getCopies
{
local t=$1
local copies=$(getvalues copy copy_${t})
for f in $copies; do
local name=$(echo $f | $SED 's/\([^=]*\)\(=.*\)\{0,1\}/\1/')
local ext=$(echo $f | $SED 's/\([^=]*\)\(=.*\)\{0,1\}/\2/')
if [ -z "$ext" ]; then
cp -r "$NETLOC_TESTS_PATH/data/$name" "$REFDIR"
chmod -R u+w $REFDIR
cp -r "$NETLOC_BUILD_PATH/data/$name" "$REFDIR"
chmod -R u+w $REFDIR
elif [ "$ext" = "=txz" ]; then
# TODO prevent from extracting it again
$COMPRESS -d --stdout "$NETLOC_TESTS_PATH/data/$name.txz" > "$REFDIR/$name.tar"
tar -xf "$REFDIR/$name.tar" -C "$REFDIR"
rm "$REFDIR/$name.tar"
fi
done
}
trap 'quit' 0
set -e
compress=xz
hash $compress 2>/dev/null || \
{ echo >&2 "It requires $compress but it's not installed."; exit 1; }
COMPRESS=$(which $compress)
GREP=$(which grep)
SED=$(which sed)
AWK=$(which awk)
# Folder structure like that
# TEMPDIR
# ├── ref <- copy of the data directory
# │ ├── machine1
# │ │ └── file1
# │ └── machine2
# │ └── file1
# └── test
# └── file1
TEMPDIR=$(mktemp -d -t netloc_tests_XXXXX)
TESTDIR=$TEMPDIR/tests
REFDIR=$TEMPDIR/ref && mkdir $REFDIR
TESTFILE=$REFDIR/$(basename $1); cp $NETLOC_TESTS_PATH/data/$(basename $1) $REFDIR
# Remove comments from the test file
$SED 's/#.*$//g; /^[[:space:]]*$/d' $TESTFILE > $TESTFILE.new
mv -f $TESTFILE.new $TESTFILE
# Get tests
tests=$($SED -n 's/^\([^[:space:]]*\):[[:space:]]*$/\1/p' $TESTFILE)
S=0
F=0
for t in $tests; do
params_sv=$($AWK '/^'$t':\s*$/{flag=1;next}; /^\S*:\s*$/{flag=0}; {if (flag) print}' $TESTFILE)
params="$params_sv"
sets=$(getvalues testset)
# For each set to test
for s in $sets; do
NETLOC_TEST=$s
params="$(echo "$params_sv" | $SED 's/%/'$NETLOC_TEST'/g')"
mkdir $TESTDIR
cd $TESTDIR
# Copy or extract files if needed
getCopies $s
# Copy needed files
cd "$REFDIR"
needed=$(getvalues needed)
if [ -z "needed" ]; then
cp -r $s $TESTDIR
else
files=$(eval "echo \"$needed\"")
for f in $files; do
mkdir -p "$TESTDIR/$(dirname "$f")"
cp -r "$f" "$TESTDIR/$(dirname "$f")"
done
fi
# Remove excluded files
cd "$TESTDIR"
excluded=$(getvalues excluded)
if [ -n "$excluded" ]; then
files=$(eval "echo \"$excluded\"")
for f in $files; do
rm -f "$f"
done
fi
while true; do
# Remove output files
cd $TESTDIR
for cf in $checkfiles; do
files=$(eval "echo \"$cf\"")
for f in $files; do
rm -f "$f"
done
done
# Execute the command
cd $TESTDIR
cmd=$(getvalues command)
eval " $cmd" > /dev/null || \
{
eval "echo \"Command $cmd failed\""
write_output $red "Test $t on $NETLOC_TEST failed!"
failed=1
break
}
# Check files
cd "$REFDIR"
checkfiles=$(getvalues checkfiles)
for cf in $checkfiles; do
files=$(eval "echo \"$cf\"")
for f in $files; do
cmp "$f" "$TESTDIR/$f" || \
{
echo "$f: wrong file"
eval "echo \"Command was: $cmd\""
write_output $red "Test $t on $NETLOC_TEST failed!"
failed=1
break
}
done
done
if [ "$failed" = 1 ]; then break; fi
# Check program
cd $TESTDIR
checkcmd=$(getvalues checkcommand)
eval " $checkcmd" > /dev/null || \
{
echo "Check command failed: $checkcmd"
eval "echo \"Command was: $cmd\""
write_output $red "Test $t on $NETLOC_TEST failed!"
failed=1
break
}
break
done
cd "$origpwd"
rm -fr $TESTDIR
if [ -n "$failed" ]; then
((F+=1))
else
((S+=1))
fi
failed=
done
done
if [[ $F -ne O ]]; then
color=$red
returncode=1
else
color=$green
returncode=0
fi
echo "### Summary ###"
write_output $color "$F tests failed"
write_output $green "$S tests succeeded"
trap 0
rm -fr $TEMPDIR
exit $returncode