# Copyright (C) 2012 The Meme Factory, Inc. http://www.meme.com/
#
# This file is part of Gombe-MI.
#
# Gombe-MI is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gombe-MI. If not, see .
#
# Load data, possibly testing.
#
# Syntax:
# run_sql [ prereq | test | testcommit | save | show ] psql_args file
#
# Env vars: THIS_TEST Name of test.
# RUN_TEST_SOCK Socket to pipe test sql into.
#
# Karl O. Pinc
#
# Actions:
# prereq: Loads the data into the db and compares with results/$file
# to see if it succeeds.
# test: Load data into db, compare with results/$file and report result.
# testcommit: Run a commit for the test and report (final) result.
# save: Save the result as a successful run in results/$file.
# show: Print output of load on screen.
#
# Side Effects:
# Loads data into the db.
# Touches loaded/$file to let make know the load prerequsites are
# satisfied.
# Actions prereq and test print to the screen. "test" leaves status on the
# screen when done.
#
# Bugs:
# Has a race condition. The initial inotifywait might, possibly,
# not establish it's wait until after the psql process has
# finished and closed the file. This is unlikely since we establish
# the wait before sending any sql, but possible. It all depends
# on the OS scheduler.
#
export action="$1"
export PSQL_ARGS="$2"
export path="$3"
export file=$(basename $path)
export tfile=/tmp/$0_$$
export sigfile=/tmp/$0_sig_$$
exec_sql () {
socat -u STDIN UNIX-SENDTO:$RUN_TEST_SOCK
}
reset_line () {
tput hpa 0
tput dl1
}
#filter_sql () {
# if [ -e filters/$file ] ; then
# if [ ! -x filters/$file ] ; then
cleanup () {
rm -rf $tfile $sigfile ;# also ends inotifywait process, if any
}
trap cleanup 0 1 2
# Make the file which notes sql completion exist so we can wait on it.
touch $sigfile
inotifywait -qq -e close $sigfile &
## Get out of the run queue to avoid the race condition.
# (Be sure to note in the README that this requires GNU sleep.)
#env sleep 0.001
inotifypid=$!
if [ "$action" = "prereq" ] \
|| [ "$action" = "test" ] \
|| [ "$action" = "testcommit" ] ; then
printf '%-25s ........... ' "$THIS_TEST"
fi
case $action in
test)
if [ ! -e results/$file ] ; then
printf 'fail (no saved results)\n'
exit 1
fi
;;
prereq|testcommit)
if [ ! -e results/$file ] ; then
printf 'fail (prereq %s, no saved results)\n' $file
exit 1
fi
;;
esac
# Run the commands and capture the result.
printf '\\o %s\n' $tfile | exec_sql
# show what's executing
#printf '\n%s\n' $path
cat $path | exec_sql
if [ -n "$INCLUDE_COMMIT" ] \
&& [ "$file" = "$THIS_TEST" ] \
&& [ "$THIS_TEST" != 'commit' ] ; then
# The test is finished, but requires the transaction be commited.
# (Capture the output of the transaction commit in the test output.)
cat sql/commit | exec_sql
touch loaded/commit
fi
printf '\\o\n' | exec_sql
# Write a file with content when we're done.
# With this we can be sure that we're really finished.
# (We can't just wait on closure of our data file because it
# might be somebody else that closed it.)
printf '\\o %s\n' "$sigfile" | exec_sql
printf "select 'done' as data;\n" | exec_sql
printf '\\o\n' | exec_sql
# Wait on the inotifywait for sql completion.
wait $inotifypid
# Loop, in case it was somebody else that closed the file.
# (It would be nice to look for specific content, but
# if there's an aborted transaction then we'll get
# an error instead of our content.)
while [ -e $sigfile ] && [ ! -s $sigfile ] ; do
# Wait some more for file to close, but poll
# to break out of race condition. The
# file might have closed while we tested for done-ness.
inotifywait -t 1 -qq -e close $sigfile
done
cmp -s results/$file $tfile
result=$?
if [ $result -ne 0 ] ; then
case $action in
test)
printf 'fail\n'
;;
prereq|testcommit)
# This with -v for debugging when things go wonky and prerequsites
# don't load as prerequsites but load file when tested independenly.
# (Having to do this is a sign that you're running in a transaction
# and need to commit and start a new one.)
#cat $tfile
printf 'fail (prereq %s)\n' $file
;;
esac
else
case $action in
test|testcommit)
touch loaded/$file
printf 'pass'
if [ -e loaded/commit ] || [ ! -e loaded/begin ] ; then
# All done with transaction related stuff, test is done.
printf '\n'
else
reset_line
fi
;;
prereq)
touch loaded/$file
printf 'pass (%s)' $file
reset_line
esac
fi
if [ "$action" = 'show' ] ; then
cat $tfile
exit 0
fi
if [ "$action" = 'save' -a "$file" = "$THIS_TEST" ] ; then
mv $tfile results/$file
exit $?
fi
exit $result