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