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 |
21a50371 MM |
59 | echo "Good, saw '${@:$#}' in build log." |
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 MM |
120 | include hc-rule.mk |
121 | $(call mg-define-rule,%,%.ssc,sleep 1 && grep 'warn' $$< && sed -e 's_//.*$$$$__' $$< >$$t) | |
122 | $(call mg-define-rule,index,index.in,sort $$< >$$t) | |
59ba5775 MM |
123 | |
124 | clean: | |
125 | $(call mg-clean-cmd,.) | |
126 | .PHONY: clean | |
21a50371 | 127 | EOF |
59ba5775 | 128 | |
21a50371 MM |
129 | cat >hc-rule.mk <<'EOF' |
130 | $(call mg-define-rule,%,%.hc,sed -e 's_#.*$$$$__' $$< >$$t) | |
131 | EOF | |
132 | ||
133 | # Input files. | |
134 | cat >foo.hc <<'EOF' | |
135 | This is the foo file. | |
136 | # You don't get to see this. | |
137 | But you do get to see this! | |
138 | // Needles: you can lean but you can't hide! | |
139 | EOF | |
140 | cat >bar.ssc <<'EOF' | |
141 | the bar file has a different personality | |
142 | // hey there | |
143 | # I slip through | |
144 | warn: tell me about it! | |
145 | EOF | |
146 | cat >index.in <<'EOF' | |
147 | foo | |
148 | bar | |
149 | EOF | |
150 | ||
151 | # Run and make sure the files were compiled correctly. | |
152 | ||
153 | start_section "Initial full build" | |
099638eb | 154 | do_mgear foo bar index |
21a50371 MM |
155 | |
156 | assert_contents foo <<'EOF' | |
157 | This is the foo file. | |
158 | ||
159 | But you do get to see this! | |
160 | // Needles: you can lean but you can't hide! | |
161 | EOF | |
162 | assert_contents bar <<'EOF' | |
163 | the bar file has a different personality | |
164 | ||
165 | # I slip through | |
166 | warn: tell me about it! | |
167 | EOF | |
168 | assert_contents index <<'EOF' | |
169 | bar | |
170 | foo | |
171 | EOF | |
172 | assert_generated foo | |
173 | assert_generated bar | |
174 | assert_generated index | |
175 | assert_saw "sed -e 's_#.*\$__' foo.hc >foo.tmp" | |
176 | assert_saw "sleep 1 && grep 'warn' bar.ssc && sed -e 's_//.*\$__' bar.ssc >bar.tmp" | |
177 | assert_saw 'warn: tell me about it!' | |
178 | assert_saw sort index.in >index.tmp | |
179 | ||
180 | # Run it again. Make sure the warning is replayed and bar isn't overridden due | |
181 | # to bar.g accidentally being too old. | |
182 | ||
183 | start_section "Replay bar warning" | |
099638eb | 184 | do_mgear foo bar index |
21a50371 MM |
185 | |
186 | assert_uptodate foo | |
187 | assert_uptodate bar | |
188 | assert_uptodate index | |
189 | assert_saw -i '#.*warning.*replay' # Indication of warning replay | |
190 | assert_saw 'warn: tell me about it!' # Actual warning | |
191 | assert_not_saw -i overrid | |
192 | ||
193 | # Now override bar and make sure it stays that way and the warning isn't replayed. | |
194 | start_section "Override bar" | |
195 | sleep 1 # No racy cleanliness | |
196 | echo NEWCONTENT >bar | |
099638eb | 197 | do_mgear bar |
21a50371 MM |
198 | |
199 | assert_saw -i overrid | |
200 | assert_contents bar <<<NEWCONTENT | |
201 | ||
202 | # Change foo.hc and make sure foo is updated properly. | |
203 | ||
204 | start_section "Change foo.hc" | |
205 | sleep 1 # No racy cleanliness | |
206 | echo 'look: # Last-minute addition.' >>foo.hc | |
099638eb | 207 | do_mgear index foo |
21a50371 MM |
208 | |
209 | assert_uptodate index | |
210 | assert_generated foo | |
211 | assert_contents foo <<'EOF' | |
212 | This is the foo file. | |
213 | ||
214 | But you do get to see this! | |
215 | // Needles: you can lean but you can't hide! | |
216 | look: | |
217 | EOF | |
218 | ||
219 | # Change the rule for # comments to strip spaces before a #. | |
220 | # Make sure foo is updated properly. | |
221 | ||
222 | start_section "Command change for % <- %.hc" | |
223 | cat >hc-rule.mk <<'EOF' | |
224 | $(call mg-define-rule,%,%.hc,sed -e 's_ *#.*$$$$__' $$< >$$t) | |
225 | EOF | |
099638eb | 226 | do_mgear foo |
21a50371 MM |
227 | |
228 | assert_generated foo | |
229 | assert_contents foo <<'EOF' | |
230 | This is the foo file. | |
231 | ||
232 | But you do get to see this! | |
233 | // Needles: you can lean but you can't hide! | |
234 | look: | |
235 | EOF | |
236 | ||
237 | # Remove a space before a # from foo.hc. This is an inconsequential change. | |
238 | # Make sure that foo.g is touched but foo is not. | |
239 | ||
240 | start_section "Inconsequential change to foo.hc" | |
241 | sleep 1 # No racy cleanliness | |
242 | remember_mtime foo foo.g | |
243 | sed -e '$s/look: /look:/' -i foo.hc | |
099638eb | 244 | do_mgear foo |
21a50371 MM |
245 | |
246 | assert_generated foo | |
247 | assert_touched foo.g | |
248 | assert_not_touched foo | |
249 | ||
59ba5775 MM |
250 | # Test cleaning. Remember, bar is still overridden. |
251 | ||
252 | start_section "Cleaning" | |
253 | do_mgear clean | |
254 | ||
255 | assert_saw 'rm.*foo' # Some sort of indication of foo's deletion | |
256 | assert ! [ -f foo ] # foo deleted | |
257 | assert ! [ -f foo.g ] # foo.g deleted | |
258 | assert [ -f bar ] # bar not actually deleted... | |
259 | assert_contents bar <<<NEWCONTENT # and contents still correct. | |
260 | ||
261 | # Test rebuild and clean after override removal. | |
262 | ||
263 | start_section "Rebuild after override removal" | |
264 | rm bar | |
265 | do_mgear bar | |
266 | assert_generated bar | |
267 | assert_contents bar <<'EOF' # contents of bar restored according to rule | |
268 | the bar file has a different personality | |
269 | ||
270 | # I slip through | |
271 | warn: tell me about it! | |
272 | EOF | |
273 | ||
274 | start_section "Clean after override removal" | |
275 | do_mgear clean | |
276 | assert_saw 'rm.*bar' | |
277 | assert ! [ -f bar ] # bar finally deleted | |
278 | ||
279 | # Override bar again. Make sure an override works if bar.g doesn't exist just | |
280 | # as well as if bar.g is older than bar. | |
281 | ||
282 | start_section "Override bar before it is ever built" | |
283 | echo NEWERCONTENT >bar | |
284 | do_mgear bar | |
285 | ||
286 | assert_saw -i overrid | |
287 | assert_contents bar <<<NEWERCONTENT | |
288 | ||
21a50371 MM |
289 | cd .. |
290 | rm -rf test-zone | |
291 | echo | |
292 | echo "TEST SUITE SUCCEEDED" |