A test case for my last commit.
[scons.git] / test / Copy-Action.py
1 #!/usr/bin/env python
2 #
3 # __COPYRIGHT__
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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
26
27 """
28 Verify that the Copy() Action works, and preserves file modification
29 times and modes.
30 """
31
32 import os
33 import os.path
34 import sys
35 import stat
36
37 import TestSCons
38
39 test = TestSCons.TestSCons()
40
41 test.write('SConstruct', """
42 Execute(Copy('f1.out', 'f1.in'))
43 Execute(Copy(File('d2.out'), 'd2.in'))
44 Execute(Copy('d3.out', File('f3.in')))
45 def cat(env, source, target):
46     target = str(target[0])
47     source = map(str, source)
48     f = open(target, "wb")
49     for src in source:
50         f.write(open(src, "rb").read())
51     f.close()
52 Cat = Action(cat)
53 env = Environment()
54 env.Command('bar.out', 'bar.in', [Cat,
55                                   Copy("f4.out", "f4.in"),
56                                   Copy("d5.out", "d5.in"),
57                                   Copy("d6.out", "f6.in")])
58 env = Environment(OUTPUT = 'f7.out', INPUT = 'f7.in')
59 env.Command('f8.out', 'f8.in', [Copy('$OUTPUT', '$INPUT'), Cat])
60 env.Command('f9.out', 'f9.in', [Cat, Copy('${TARGET}-Copy', '$SOURCE')])
61
62 env.CopyTo( 'd4', 'f10.in' )
63 env.CopyAs( 'd4/f11.out', 'f11.in')
64 env.CopyAs( 'd4/f12.out', 'd5/f12.in')
65
66 env.Command('f   13.out', 'f   13.in', Copy('$TARGET', '$SOURCE'))
67 """)
68
69 test.write('f1.in', "f1.in\n")
70 test.subdir('d2.in')
71 test.write(['d2.in', 'file'], "d2.in/file\n")
72 test.write('f3.in', "f3.in\n")
73 test.subdir('d3.out')
74 test.write('bar.in', "bar.in\n")
75 test.write('f4.in', "f4.in\n")
76 test.subdir('d5.in')
77 test.write(['d5.in', 'file'], "d5.in/file\n")
78 test.write('f6.in', "f6.in\n")
79 test.subdir('d6.out')
80 test.write('f7.in', "f7.in\n")
81 test.write('f8.in', "f8.in\n")
82 test.write('f9.in', "f9.in\n")
83 test.write('f10.in', "f10.in\n")
84 test.write('f11.in', "f11.in\n")
85 test.subdir('d5')
86 test.write(['d5', 'f12.in'], "f12.in\n")
87 test.write('f   13.in', "f   13.in\n")
88
89 os.chmod('f1.in', 0646)
90 os.chmod('f4.in', 0644)
91
92 test.sleep()
93
94 d4_f10_in   = os.path.join('d4', 'f10.in')
95 d4_f11_out  = os.path.join('d4', 'f11.out')
96 d4_f12_out  = os.path.join('d4', 'f12.out')
97 d5_f12_in   = os.path.join('d5', 'f12.in')
98
99 expect = test.wrap_stdout(read_str = """\
100 Copy("f1.out", "f1.in")
101 Copy("d2.out", "d2.in")
102 Copy("d3.out", "f3.in")
103 """,
104                           build_str = """\
105 cat(["bar.out"], ["bar.in"])
106 Copy("f4.out", "f4.in")
107 Copy("d5.out", "d5.in")
108 Copy("d6.out", "f6.in")
109 Copy file(s): "f10.in" to "%(d4_f10_in)s"
110 Copy file(s): "f11.in" to "%(d4_f11_out)s"
111 Copy file(s): "%(d5_f12_in)s" to "%(d4_f12_out)s"
112 Copy("f   13.out", "f   13.in")
113 Copy("f7.out", "f7.in")
114 cat(["f8.out"], ["f8.in"])
115 cat(["f9.out"], ["f9.in"])
116 Copy("f9.out-Copy", "f9.in")
117 """ % locals())
118
119 test.run(options = '-n', arguments = '.', stdout = expect)
120
121 test.must_not_exist('f1.out')
122 test.must_not_exist('d2.out')
123 test.must_not_exist(os.path.join('d3.out', 'f3.in'))
124 test.must_not_exist('f4.out')
125 test.must_not_exist('d5.out')
126 test.must_not_exist(os.path.join('d6.out', 'f6.in'))
127 test.must_not_exist('f7.out')
128 test.must_not_exist('f8.out')
129 test.must_not_exist('f9.out')
130 test.must_not_exist('f9.out-Copy')
131 test.must_not_exist('d4/f10.in')
132 test.must_not_exist('d4/f11.out')
133 test.must_not_exist('d4/f12.out')
134 test.must_not_exist('f 13.out')
135 test.must_not_exist('f    13.out')
136
137 test.run()
138
139 test.must_match('f1.out', "f1.in\n")
140 test.must_match(['d2.out', 'file'], "d2.in/file\n")
141 test.must_match(['d3.out', 'f3.in'], "f3.in\n")
142 test.must_match('f4.out', "f4.in\n")
143 test.must_match(['d5.out', 'file'], "d5.in/file\n")
144 test.must_match(['d6.out', 'f6.in'], "f6.in\n")
145 test.must_match('f7.out', "f7.in\n")
146 test.must_match('f8.out', "f8.in\n")
147 test.must_match('f9.out', "f9.in\n")
148 test.must_match('f9.out-Copy', "f9.in\n")
149 test.must_match('d4/f10.in', 'f10.in\n')
150 test.must_match('d4/f11.out', 'f11.in\n')
151 test.must_match('d4/f12.out', 'f12.in\n')
152 test.must_match('f   13.out', 'f   13.in\n')
153
154 errors = 0
155
156 def must_be_same(f1, f2):
157     global errors
158     if type(f1) is type([]):
159         f1 = apply(os.path.join, f1)
160     if type(f2) is type([]):
161         f2 = apply(os.path.join, f2)
162     s1 = os.stat(f1)
163     s2 = os.stat(f2)
164     for value in ['ST_MODE', 'ST_MTIME']:
165         v = getattr(stat, value)
166         if s1[v] != s2[v]:
167             msg = '%s[%s] %s != %s[%s] %s\n' % \
168                   (repr(f1), value, s1[v],
169                    repr(f2), value, s2[v],)
170             sys.stderr.write(msg)
171             errors = errors + 1
172
173 must_be_same('f1.out',                  'f1.in')
174 must_be_same(['d2.out', 'file'],        ['d2.in', 'file'])
175 must_be_same(['d3.out', 'f3.in'],       'f3.in')
176 must_be_same('f4.out',                  'f4.in')
177 must_be_same(['d5.out', 'file'],        ['d5.in', 'file'])
178 must_be_same(['d6.out', 'f6.in'],       'f6.in')
179 must_be_same('f7.out',                  'f7.in')
180 must_be_same(['d4', 'f10.in'],          'f10.in')
181 must_be_same(['d4', 'f11.out'],         'f11.in')
182 must_be_same(['d4', 'f12.out'],         ['d5', 'f12.in'])
183 must_be_same('f   13.out',              'f   13.in')
184
185 if errors:
186     test.fail_test()
187
188 test.pass_test()