a0dc8aa79e031baba948823f4c868dcccacb0aad
[mgear/mgear.git] / testsuite
1 #!/bin/bash
2 # Test suite for mgear.
3
4 echo "Test suite for mgear"
5
6 cd "$(dirname "$0")"
7 Z=test-zone
8 rm -rf $Z
9 mkdir $Z
10 cd $Z
11
12 #exec 3>&2
13 #exec 1>test.log 2>&1
14 exec </dev/null
15 set -e
16 set -o errtrace
17 section=Initialization
18 trap 'echo; echo "TEST SUITE FAILED in section $section!" >&2' ERR
19 #set -x
20
21 ln -s ../mgear.mk .
22
23 function fail {
24         false
25 }
26
27 function start_section {
28         section="$1"
29         echo
30         echo "SECTION: $1"
31 }
32
33 function do_mgear {
34         echo "Running: make $*"
35         make "$@" 2>&1 | tee mgear.log
36 }
37
38 function assert_contents {
39         if diff -u - "$1"; then
40                 echo "File '$1' looks good."
41         else
42                 echo "File '$1' has the wrong contents!"
43                 fail
44         fi
45 }
46
47 # Options can be passed to grep: assert_saw -i override
48 function assert_saw {
49         if grep -q "$@" mgear.log; then
50                 echo "Good, saw '${@:$#}' in build log."
51         else
52                 echo "Expected '${@:$#}' in build log but didn't see it!  Log:"
53                 cat mgear.log
54                 fail
55         fi
56 }
57 function assert_not_saw {
58         if ! grep -q "$@" mgear.log; then
59                 echo "Good, saw '${@:$#}' in build log."
60         else
61                 echo "Did not expect '${@:$#}' in build log but saw it!  Log:"
62                 cat mgear.log
63                 fail
64         fi
65 }
66 function assert_uptodate {
67         assert_saw "make: \`$1' is up to date."
68 }
69 function assert_generated {
70         assert_saw "$1.tmp"
71 }
72
73 function assert {
74         if eval $*; then
75                 echo "Good, $* returned true."
76         else
77                 echo "Expected $* to return true but it returned false!"
78                 fail
79         fi
80 }
81
82 function remember_mtime {
83         while [ $# != 0 ]; do
84                 eval "orig_mtime_${1//[^A-Za-z]/}=$(stat --format=%Y $1)"
85                 shift
86         done
87 }
88 function assert_touched {
89         mtvar=orig_mtime_${1//[^A-Za-z]/}
90         t1="${!mtvar}"
91         t2="$(stat --format=%Y $1)"
92         echo "Times for '$1': $t1, $t2"
93         if [ "$t1" != "$t2" ]; then
94                 echo "Good, '$1' was touched."
95         else
96                 echo "Expected '$1' to be touched but it wasn't!"
97                 fail
98         fi
99 }
100 function assert_not_touched {
101         mtvar=orig_mtime_${1//[^A-Za-z]/}
102         t1="${!mtvar}"
103         t2="$(stat --format=%Y $1)"
104         echo "Times for '$1': $t1, $t2"
105         if [ "$t1" == "$t2" ]; then
106                 echo "Good, '$1' was not touched."
107         else
108                 echo "Expected '$1' to be not touched but it was!"
109                 fail
110         fi
111 }
112
113 # Simple makefile for stripping two kinds of comments.
114 # Tests an implicit rule and two competing explicit rules.
115 # Watch those dollar signs!
116
117 cat >Makefile <<'EOF'
118 include mgear.mk
119 .SECONDARY:
120
121 include hc-rule.mk
122 $(call mg-define-rule,%,%.ssc,sleep 1 && grep 'warn' $$< && sed -e 's_//.*$$$$__' $$< >$$t)
123 $(call mg-define-rule,index,index.in,sort $$< >$$t)
124
125 clean:
126         $(call mg-clean-cmd,.)
127 .PHONY: clean
128 EOF
129
130 cat >hc-rule.mk <<'EOF'
131 $(call mg-define-rule,%,%.hc,sed -e 's_#.*$$$$__' $$< >$$t)
132 EOF
133
134 # Input files.
135 cat >foo.hc <<'EOF'
136 This is the foo file.
137 # You don't get to see this.
138 But you do get to see this!
139 // Needles: you can lean but you can't hide!
140 EOF
141 cat >bar.ssc <<'EOF'
142 the bar file has a different personality
143 // hey there
144 # I slip through
145 warn: tell me about it!
146 EOF
147 cat >index.in <<'EOF'
148 foo
149 bar
150 EOF
151
152 # Run and make sure the files were compiled correctly.
153
154 start_section "Initial full build"
155 do_mgear foo bar index
156
157 assert_contents foo <<'EOF'
158 This is the foo file.
159
160 But you do get to see this!
161 // Needles: you can lean but you can't hide!
162 EOF
163 assert_contents bar <<'EOF'
164 the bar file has a different personality
165
166 # I slip through
167 warn: tell me about it!
168 EOF
169 assert_contents index <<'EOF'
170 bar
171 foo
172 EOF
173 assert_generated foo
174 assert_generated bar
175 assert_generated index
176 assert_saw "sed -e 's_#.*\$__' foo.hc >foo.tmp"
177 assert_saw "sleep 1 && grep 'warn' bar.ssc && sed -e 's_//.*\$__' bar.ssc >bar.tmp"
178 assert_saw 'warn: tell me about it!'
179 assert_saw sort index.in >index.tmp
180
181 # Run it again.  Make sure the warning is replayed and bar isn't overridden due
182 # to bar.g accidentally being too old.
183
184 start_section "Replay bar warning"
185 do_mgear foo bar index
186
187 assert_uptodate foo
188 assert_uptodate bar
189 assert_uptodate index
190 assert_saw -i '#.*warning.*replay' # Indication of warning replay
191 assert_saw 'warn: tell me about it!' # Actual warning
192 assert_not_saw -i overrid
193
194 # Now override bar and make sure it stays that way and the warning isn't replayed.
195 start_section "Override bar"
196 sleep 1 # No racy cleanliness
197 echo NEWCONTENT >bar
198 do_mgear bar
199
200 assert_saw -i overrid
201 assert_contents bar <<<NEWCONTENT
202
203 # Change foo.hc and make sure foo is updated properly.
204
205 start_section "Change foo.hc"
206 sleep 1 # No racy cleanliness
207 echo 'look: # Last-minute addition.' >>foo.hc
208 do_mgear index foo
209
210 assert_uptodate index
211 assert_generated foo
212 assert_contents foo <<'EOF'
213 This is the foo file.
214
215 But you do get to see this!
216 // Needles: you can lean but you can't hide!
217 look: 
218 EOF
219
220 # Change the rule for # comments to strip spaces before a #.
221 # Make sure foo is updated properly.
222
223 start_section "Command change for % <- %.hc"
224 cat >hc-rule.mk <<'EOF'
225 $(call mg-define-rule,%,%.hc,sed -e 's_ *#.*$$$$__' $$< >$$t)
226 EOF
227 do_mgear foo
228
229 assert_generated foo
230 assert_contents foo <<'EOF'
231 This is the foo file.
232
233 But you do get to see this!
234 // Needles: you can lean but you can't hide!
235 look:
236 EOF
237
238 # Remove a space before a # from foo.hc.  This is an inconsequential change.
239 # Make sure that foo.g is touched but foo is not.
240
241 start_section "Inconsequential change to foo.hc"
242 sleep 1 # No racy cleanliness
243 remember_mtime foo foo.g
244 sed -e '$s/look: /look:/' -i foo.hc
245 do_mgear foo
246
247 assert_generated foo
248 assert_touched foo.g
249 assert_not_touched foo
250
251 # Test cleaning.  Remember, bar is still overridden.
252
253 start_section "Cleaning"
254 do_mgear clean
255
256 assert_saw 'rm.*foo' # Some sort of indication of foo's deletion
257 assert ! [ -f foo ] # foo deleted
258 assert ! [ -f foo.g ] # foo.g deleted
259 assert [ -f bar ] # bar not actually deleted...
260 assert_contents bar <<<NEWCONTENT # and contents still correct.
261
262 # Test rebuild and clean after override removal.
263
264 start_section "Rebuild after override removal"
265 rm bar
266 do_mgear bar
267 assert_generated bar
268 assert_contents bar <<'EOF' # contents of bar restored according to rule
269 the bar file has a different personality
270
271 # I slip through
272 warn: tell me about it!
273 EOF
274
275 start_section "Clean after override removal"
276 do_mgear clean
277 assert_saw 'rm.*bar'
278 assert ! [ -f bar ] # bar finally deleted
279
280 # Override bar again.  Make sure an override works if bar.g doesn't exist just
281 # as well as if bar.g is older than bar.
282
283 start_section "Override bar before it is ever built"
284 echo NEWERCONTENT >bar
285 do_mgear bar
286
287 assert_saw -i overrid
288 assert_contents bar <<<NEWERCONTENT
289
290 cd ..
291 rm -rf test-zone
292 echo
293 echo "TEST SUITE SUCCEEDED"