/ db / test /
/db/test/run_sql.sh
1 # Copyright (C) 2012 The Meme Factory, Inc. http://www.meme.com/
2 #
3 # This file is part of Gombe-MI.
4 #
5 # Gombe-MI is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Gombe-MI. If not, see <http://www.gnu.org/licenses/>.
17 #
18 # Load data, possibly testing.
19 #
20 # Syntax:
21 # run_sql [ prereq | test | testcommit | save | show ] psql_args file
22 #
23 # Env vars: THIS_TEST Name of test.
24 # RUN_TEST_SOCK Socket to pipe test sql into.
25 #
26 # Karl O. Pinc <kop@meme.com>
27 #
28 # Actions:
29 # prereq: Loads the data into the db and compares with results/$file
30 # to see if it succeeds.
31 # test: Load data into db, compare with results/$file and report result.
32 # testcommit: Run a commit for the test and report (final) result.
33 # save: Save the result as a successful run in results/$file.
34 # show: Print output of load on screen.
35 #
36 # Side Effects:
37 # Loads data into the db.
38 # Touches loaded/$file to let make know the load prerequsites are
39 # satisfied.
40 # Actions prereq and test print to the screen. "test" leaves status on the
41 # screen when done.
42 #
43 # Bugs:
44 # Has a race condition. The initial inotifywait might, possibly,
45 # not establish it's wait until after the psql process has
46 # finished and closed the file. This is unlikely since we establish
47 # the wait before sending any sql, but possible. It all depends
48 # on the OS scheduler.
49 #
50
51 export action="$1"
52 export PSQL_ARGS="$2"
53 export path="$3"
54 export file=$(basename $path)
55
56 export tfile=/tmp/$0_$$
57 export sigfile=/tmp/$0_sig_$$
58
59 exec_sql () {
60 socat -u STDIN UNIX-SENDTO:$RUN_TEST_SOCK
61 }
62
63 reset_line () {
64 tput hpa 0
65 tput dl1
66 }
67
68 #filter_sql () {
69 # if [ -e filters/$file ] ; then
70 # if [ ! -x filters/$file ] ; then
71
72 cleanup () {
73 rm -rf $tfile $sigfile ;# also ends inotifywait process, if any
74 }
75 trap cleanup 0 1 2
76
77 # Make the file which notes sql completion exist so we can wait on it.
78 touch $sigfile
79 inotifywait -qq -e close $sigfile &
80 ## Get out of the run queue to avoid the race condition.
81 # (Be sure to note in the README that this requires GNU sleep.)
82 #env sleep 0.001
83 inotifypid=$!
84
85 if [ "$action" = "prereq" ] \
86 || [ "$action" = "test" ] \
87 || [ "$action" = "testcommit" ] ; then
88 printf '%-25s ........... ' "$THIS_TEST"
89 fi
90
91 case $action in
92 test)
93 if [ ! -e results/$file ] ; then
94 printf 'fail (no saved results)\n'
95 exit 1
96 fi
97 ;;
98 prereq|testcommit)
99 if [ ! -e results/$file ] ; then
100 printf 'fail (prereq %s, no saved results)\n' $file
101 exit 1
102 fi
103 ;;
104 esac
105
106 # Run the commands and capture the result.
107 printf '\\o %s\n' $tfile | exec_sql
108 # show what's executing
109 #printf '\n%s\n' $path
110 cat $path | exec_sql
111
112 if [ -n "$INCLUDE_COMMIT" ] \
113 && [ "$file" = "$THIS_TEST" ] \
114 && [ "$THIS_TEST" != 'commit' ] ; then
115 # The test is finished, but requires the transaction be commited.
116 # (Capture the output of the transaction commit in the test output.)
117 cat sql/commit | exec_sql
118 touch loaded/commit
119 fi
120
121 printf '\\o\n' | exec_sql
122
123 # Write a file with content when we're done.
124 # With this we can be sure that we're really finished.
125 # (We can't just wait on closure of our data file because it
126 # might be somebody else that closed it.)
127 printf '\\o %s\n' "$sigfile" | exec_sql
128 printf "select 'done' as data;\n" | exec_sql
129 printf '\\o\n' | exec_sql
130 # Wait on the inotifywait for sql completion.
131 wait $inotifypid
132 # Loop, in case it was somebody else that closed the file.
133 # (It would be nice to look for specific content, but
134 # if there's an aborted transaction then we'll get
135 # an error instead of our content.)
136 while [ -e $sigfile ] && [ ! -s $sigfile ] ; do
137 # Wait some more for file to close, but poll
138 # to break out of race condition. The
139 # file might have closed while we tested for done-ness.
140 inotifywait -t 1 -qq -e close $sigfile
141 done
142
143 cmp -s results/$file $tfile
144 result=$?
145 if [ $result -ne 0 ] ; then
146 case $action in
147 test)
148 printf 'fail\n'
149 ;;
150 prereq|testcommit)
151 # This with -v for debugging when things go wonky and prerequsites
152 # don't load as prerequsites but load file when tested independenly.
153 # (Having to do this is a sign that you're running in a transaction
154 # and need to commit and start a new one.)
155 #cat $tfile
156 printf 'fail (prereq %s)\n' $file
157 ;;
158 esac
159 else
160 case $action in
161 test|testcommit)
162 touch loaded/$file
163 printf 'pass'
164 if [ -e loaded/commit ] || [ ! -e loaded/begin ] ; then
165 # All done with transaction related stuff, test is done.
166 printf '\n'
167 else
168 reset_line
169 fi
170 ;;
171 prereq)
172 touch loaded/$file
173 printf 'pass (%s)' $file
174 reset_line
175 esac
176 fi
177
178 if [ "$action" = 'show' ] ; then
179 cat $tfile
180 exit 0
181 fi
182
183 if [ "$action" = 'save' -a "$file" = "$THIS_TEST" ] ; then
184 mv $tfile results/$file
185 exit $?
186 fi
187
188 exit $result