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 $*" |
099638eb | 35 | make "$@" 2>&1 | tee mgear.log |
21a50371 MM |
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 { | |
099638eb | 49 | if grep -q "$@" mgear.log; then |
21a50371 MM |
50 | echo "Good, saw '${@:$#}' in build log." |
51 | else | |
52 | echo "Expected '${@:$#}' in build log but didn't see it! Log:" | |
099638eb | 53 | cat mgear.log |
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 | |
61 | echo "Did not expect '${@:$#}' in build log but saw it! Log:" | |
099638eb | 62 | cat mgear.log |
21a50371 MM |
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 | ||
59ba5775 MM |
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 | ||
21a50371 MM |
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! | |
59ba5775 | 116 | |
21a50371 | 117 | cat >Makefile <<'EOF' |
099638eb | 118 | include mgear.mk |
21a50371 | 119 | .SECONDARY: |
59ba5775 | 120 | |
21a50371 MM |
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) | |
59ba5775 MM |
124 | |
125 | clean: | |
126 | $(call mg-clean-cmd,.) | |
127 | .PHONY: clean | |
21a50371 | 128 | EOF |
59ba5775 | 129 | |
21a50371 MM |
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" | |
099638eb | 155 | do_mgear foo bar index |
21a50371 MM |
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" | |
099638eb | 185 | do_mgear foo bar index |
21a50371 MM |
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 | |
099638eb | 198 | do_mgear bar |
21a50371 MM |
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 | |
099638eb | 208 | do_mgear index foo |
21a50371 MM |
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 | |
099638eb | 227 | do_mgear foo |
21a50371 MM |
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 | |
099638eb | 245 | do_mgear foo |
21a50371 MM |
246 | |
247 | assert_generated foo | |
248 | assert_touched foo.g | |
249 | assert_not_touched foo | |
250 | ||
59ba5775 MM |
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 | ||
21a50371 MM |
290 | cd .. |
291 | rm -rf test-zone | |
292 | echo | |
293 | echo "TEST SUITE SUCCEEDED" |