Support using a single .sconsign file. (Stephen Kennedy)
[scons.git] / test / sconsign-script.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2001, 2002, 2003 Steven Knight
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #
24
25 __revision__ = "/home/scons/scons/branch.0/baseline/test/sconsign.py 0.90.D001 2003/06/25 15:32:24 knight"
26
27 import os.path
28 import string
29 import time
30
31 import TestCmd
32 import TestSCons
33
34 # Check for the sconsign script before we instantiate TestSCons(),
35 # because that will change directory on us.
36 if os.path.exists('sconsign.py'):
37     sconsign = 'sconsign.py'
38 elif os.path.exists('sconsign'):
39     sconsign = 'sconsign'
40 else:
41     print "Can find neither 'sconsign.py' nor 'sconsign' scripts."
42     test.no_result(1)
43
44 def sort_match(test, lines, expect):
45     lines = string.split(lines, '\n')
46     lines.sort()
47     expect = string.split(expect, '\n')
48     expect.sort()
49     return test.match_re(lines, expect)
50
51 test = TestSCons.TestSCons(match = TestCmd.match_re)
52
53
54
55
56 test.subdir('work1', ['work1', 'sub1'], ['work1', 'sub2'],
57             'work2', ['work2', 'sub1'], ['work2', 'sub2'])
58
59 test.write(['work1', 'SConstruct'], """
60 env1 = Environment(PROGSUFFIX = '.exe', OBJSUFFIX = '.obj')
61 env1.Program('sub1/hello.c')
62 env2 = env1.Copy(CPPPATH = ['sub2'])
63 env2.Program('sub2/hello.c')
64 """)
65
66 test.write(['work1', 'sub1', 'hello.c'], r"""\
67 int
68 main(int argc, char *argv[])
69 {
70         argv[argc++] = "--";
71         printf("sub1/hello.c\n");
72         exit (0);
73 }
74 """)
75
76 test.write(['work1', 'sub2', 'hello.c'], r"""\
77 #include <inc1.h>
78 #include <inc2.h>
79 int
80 main(int argc, char *argv[])
81 {
82         argv[argc++] = "--";
83         printf("sub2/goodbye.c\n");
84         exit (0);
85 }
86 """)
87
88 test.write(['work1', 'sub2', 'inc1.h'], r"""\
89 #define STRING1 "inc1.h"
90 """)
91
92 test.write(['work1', 'sub2', 'inc2.h'], r"""\
93 #define STRING2 "inc2.h"
94 """)
95
96 test.run(chdir = 'work1', arguments = '--implicit-cache .')
97
98 test.run(interpreter = TestSCons.python,
99          program = sconsign,
100          arguments = "work1/sub1/.sconsign",
101          stdout = """\
102 hello.exe: None \S+ None
103 hello.obj: None \S+ None
104 """)
105
106 test.run(interpreter = TestSCons.python,
107          program = sconsign,
108          arguments = "-v work1/sub1/.sconsign",
109          stdout = """\
110 hello.exe:
111     timestamp: None
112     bsig: \S+
113     csig: None
114 hello.obj:
115     timestamp: None
116     bsig: \S+
117     csig: None
118 """)
119
120 test.run(interpreter = TestSCons.python,
121          program = sconsign,
122          arguments = "-b -v work1/sub1/.sconsign",
123          stdout = """\
124 hello.exe:
125     bsig: \S+
126 hello.obj:
127     bsig: \S+
128 """)
129
130 test.run(interpreter = TestSCons.python,
131          program = sconsign,
132          arguments = "-c -v work1/sub1/.sconsign",
133          stdout = """\
134 hello.exe:
135     csig: None
136 hello.obj:
137     csig: None
138 """)
139
140 test.run(interpreter = TestSCons.python,
141          program = sconsign,
142          arguments = "-e hello.obj work1/sub1/.sconsign",
143          stdout = """\
144 hello.obj: None \S+ None
145 """)
146
147 test.run(interpreter = TestSCons.python,
148          program = sconsign,
149          arguments = "-e hello.obj -e hello.exe -e hello.obj work1/sub1/.sconsign",
150          stdout = """\
151 hello.obj: None \S+ None
152 hello.exe: None \S+ None
153 hello.obj: None \S+ None
154 """)
155
156 test.run(interpreter = TestSCons.python,
157          program = sconsign,
158          arguments = "work1/sub2/.sconsign",
159          stdout = """\
160 hello.exe: None \S+ None
161 hello.obj: None \S+ None
162         %s
163         %s
164 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
165        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
166
167 test.run(interpreter = TestSCons.python,
168          program = sconsign,
169          arguments = "-i -v work1/sub2/.sconsign",
170          stdout = """\
171 hello.exe:
172 hello.obj:
173     implicit:
174         %s
175         %s
176 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
177        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
178
179 test.run(interpreter = TestSCons.python,
180          program = sconsign,
181          arguments = "-e hello.obj work1/sub2/.sconsign work1/sub1/.sconsign",
182          stdout = """\
183 hello.obj: None \S+ None
184         %s
185         %s
186 hello.obj: None \S+ None
187 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
188        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
189
190 test.run(chdir = 'work1', arguments = '--clean .')
191
192 test.write(['work1', 'SConstruct'], """
193 SourceSignatures('timestamp')
194 TargetSignatures('content')
195 env1 = Environment(PROGSUFFIX = '.exe', OBJSUFFIX = '.obj')
196 env1.Program('sub1/hello.c')
197 env2 = env1.Copy(CPPPATH = ['sub2'])
198 env2.Program('sub2/hello.c')
199 """)
200
201 time.sleep(1)
202
203 test.run(chdir = 'work1', arguments = '. --max-drift=1')
204
205 test.run(interpreter = TestSCons.python,
206          program = sconsign,
207          arguments = "work1/sub1/.sconsign")
208
209 test.fail_test(not sort_match(test, test.stdout(), """\
210 hello.exe: None \S+ None
211 hello.c: \d+ None \d+
212 hello.obj: None \S+ None
213 """))
214
215 test.run(interpreter = TestSCons.python,
216          program = sconsign,
217          arguments = "-r work1/sub1/.sconsign")
218
219 test.fail_test(not sort_match(test, test.stdout(), """\
220 hello.exe: None \S+ None
221 hello.c: '\S+ \S+ [ \d]\d \d\d:\d\d:\d\d \d\d\d\d' None \d+
222 hello.obj: None \S+ None
223 """))
224
225
226 ##############################################################################
227
228 test.write(['work2', 'SConstruct'], """
229 SConsignFile()
230 env1 = Environment(PROGSUFFIX = '.exe', OBJSUFFIX = '.obj')
231 env1.Program('sub1/hello.c')
232 env2 = env1.Copy(CPPPATH = ['sub2'])
233 env2.Program('sub2/hello.c')
234 """)
235
236 test.write(['work2', 'sub1', 'hello.c'], r"""\
237 int
238 main(int argc, char *argv[])
239 {
240         argv[argc++] = "--";
241         printf("sub1/hello.c\n");
242         exit (0);
243 }
244 """)
245
246 test.write(['work2', 'sub2', 'hello.c'], r"""\
247 #include <inc1.h>
248 #include <inc2.h>
249 int
250 main(int argc, char *argv[])
251 {
252         argv[argc++] = "--";
253         printf("sub2/goodbye.c\n");
254         exit (0);
255 }
256 """)
257
258 test.write(['work2', 'sub2', 'inc1.h'], r"""\
259 #define STRING1 "inc1.h"
260 """)
261
262 test.write(['work2', 'sub2', 'inc2.h'], r"""\
263 #define STRING2 "inc2.h"
264 """)
265
266 test.run(chdir = 'work2', arguments = '--implicit-cache .')
267
268 test.run(interpreter = TestSCons.python,
269          program = sconsign,
270          arguments = "work2/.sconsign.dbm",
271          stdout = """\
272 === sub1:
273 hello.exe: None \S+ None
274 hello.obj: None \S+ None
275 === sub2:
276 hello.exe: None \S+ None
277 hello.obj: None \S+ None
278         %s
279         %s
280 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
281        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
282
283 test.run(interpreter = TestSCons.python,
284          program = sconsign,
285          arguments = "-v work2/.sconsign.dbm",
286          stdout = """\
287 === sub1:
288 hello.exe:
289     timestamp: None
290     bsig: \S+
291     csig: None
292 hello.obj:
293     timestamp: None
294     bsig: \S+
295     csig: None
296 === sub2:
297 hello.exe:
298     timestamp: None
299     bsig: \S+
300     csig: None
301 hello.obj:
302     timestamp: None
303     bsig: \S+
304     csig: None
305     implicit:
306         %s
307         %s
308 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
309        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
310
311 test.run(interpreter = TestSCons.python,
312          program = sconsign,
313          arguments = "-b -v work2/.sconsign.dbm",
314          stdout = """\
315 === sub1:
316 hello.exe:
317     bsig: \S+
318 hello.obj:
319     bsig: \S+
320 === sub2:
321 hello.exe:
322     bsig: \S+
323 hello.obj:
324     bsig: \S+
325 """)
326
327 test.run(interpreter = TestSCons.python,
328          program = sconsign,
329          arguments = "-c -v work2/.sconsign.dbm",
330          stdout = """\
331 === sub1:
332 hello.exe:
333     csig: None
334 hello.obj:
335     csig: None
336 === sub2:
337 hello.exe:
338     csig: None
339 hello.obj:
340     csig: None
341 """)
342
343 test.run(interpreter = TestSCons.python,
344          program = sconsign,
345          arguments = "-e hello.obj work2/.sconsign.dbm",
346          stdout = """\
347 === sub1:
348 hello.obj: None \S+ None
349 === sub2:
350 hello.obj: None \S+ None
351         %s
352         %s
353 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
354        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
355
356 test.run(interpreter = TestSCons.python,
357          program = sconsign,
358          arguments = "-e hello.obj -e hello.exe -e hello.obj work2/.sconsign.dbm",
359          stdout = """\
360 === sub1:
361 hello.obj: None \S+ None
362 hello.exe: None \S+ None
363 hello.obj: None \S+ None
364 === sub2:
365 hello.obj: None \S+ None
366         %s
367         %s
368 hello.exe: None \S+ None
369 hello.obj: None \S+ None
370         %s
371         %s
372 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
373        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\'),
374        string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
375        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
376
377 test.run(interpreter = TestSCons.python,
378          program = sconsign,
379          arguments = "-i -v work2/.sconsign.dbm",
380          stdout = """\
381 === sub1:
382 hello.exe:
383 hello.obj:
384 === sub2:
385 hello.exe:
386 hello.obj:
387     implicit:
388         %s
389         %s
390 """ % (string.replace(os.path.join('sub2', 'inc1.h'), '\\', '\\\\'),
391        string.replace(os.path.join('sub2', 'inc2.h'), '\\', '\\\\')))
392
393 test.run(chdir = 'work2', arguments = '--clean .')
394
395 test.write(['work2','SConstruct'], """
396 SConsignFile('my_sconsign')
397 SourceSignatures('timestamp')
398 TargetSignatures('content')
399 env1 = Environment(PROGSUFFIX = '.exe', OBJSUFFIX = '.obj')
400 env1.Program('sub1/hello.c')
401 env2 = env1.Copy(CPPPATH = ['sub2'])
402 env2.Program('sub2/hello.c')
403 """)
404
405 time.sleep(1)
406
407 test.run(chdir = 'work2', arguments = '. --max-drift=1')
408
409 test.run(interpreter = TestSCons.python,
410          program = sconsign,
411          arguments = "-d sub1 -f dbm work2/my_sconsign")
412
413 test.fail_test(not sort_match(test, test.stdout(), """\
414 === sub1:
415 hello.exe: None \S+ None
416 hello.obj: None \S+ None
417 hello.c: \d+ None \d+
418 """))
419
420 test.run(interpreter = TestSCons.python,
421          program = sconsign,
422          arguments = "-r -d sub1 -f dbm work2/my_sconsign")
423
424 test.fail_test(not sort_match(test, test.stdout(), """\
425 === sub1:
426 hello.exe: None \S+ None
427 hello.obj: None \S+ None
428 hello.c: '\S+ \S+ [ \d]\d \d\d:\d\d:\d\d \d\d\d\d' None \d+
429 """))
430
431 ##############################################################################
432
433 test.write('bad_sconsign', "bad_sconsign\n")
434
435 test.run(interpreter = TestSCons.python,
436          program = sconsign,
437          arguments = "-f dbm no_sconsign",
438          stderr = "sconsign: \[Errno 2\] No such file or directory: 'no_sconsign'\n")
439
440 test.run(interpreter = TestSCons.python,
441          program = sconsign,
442          arguments = "-f dbm bad_sconsign",
443          stderr = "sconsign: ignoring invalid .sconsign.dbm file `bad_sconsign': db type could not be determined\n")
444
445 test.run(interpreter = TestSCons.python,
446          program = sconsign,
447          arguments = "-f sconsign no_sconsign",
448          stderr = "sconsign: \[Errno 2\] No such file or directory: 'no_sconsign'\n")
449
450 test.run(interpreter = TestSCons.python,
451          program = sconsign,
452          arguments = "-f sconsign bad_sconsign",
453          stderr = "sconsign: ignoring invalid .sconsign file `bad_sconsign'\n")
454
455
456 test.pass_test()