4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
16 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
17 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
33 def __init__(self, **kw):
36 def __getitem__(self, key):
37 return self._dict[key]
38 def Override(self, overrides):
41 return MyEnvironment(**d)
42 def _update(self, dict):
43 self._dict.update(dict)
46 def __init__(self, actions=['action1', 'action2']):
47 self.actions = actions
48 def __call__(self, target, source, env, **kw):
49 for action in self.actions:
50 action(target, source, env, **kw)
51 def genstring(self, target, source, env):
52 return ' '.join(['GENSTRING'] + list(map(str, self.actions)) + target + source)
53 def get_contents(self, target, source, env):
54 return ' '.join(self.actions + target + source)
55 def get_implicit_deps(self, target, source, env):
59 def __init__(self, env, overrides):
61 self.overrides = overrides
62 self.action = MyAction()
65 def __init__(self, name=None, pre=[], post=[]):
68 self.pre_actions = pre
69 self.post_actions = post
70 self.missing_val = None
74 executor = SCons.Executor.Executor(MyAction(self.pre_actions +
75 [self.builder.action] +
82 def get_env_scanner(self, env, kw):
83 return MyScanner('dep-')
84 def get_implicit_deps(self, env, scanner, path):
85 return [scanner.prefix + str(self)]
86 def add_to_implicit(self, deps):
87 self.implicit.extend(deps)
89 return self.missing_val
90 def calc_signature(self, calc):
91 return 'cs-'+calc+'-'+self.name
92 def disambiguate(self):
96 def __init__(self, prefix):
98 def path(self, env, cwd, target, source):
100 def select(self, node):
103 class ExecutorTestCase(unittest.TestCase):
105 def test__init__(self):
106 """Test creating an Executor"""
107 source_list = ['s1', 's2']
108 x = SCons.Executor.Executor('a', 'e', ['o'], 't', source_list)
109 assert x.action_list == ['a'], x.action_list
110 assert x.env == 'e', x.env
111 assert x.overridelist == ['o'], x.overridelist
112 targets = x.get_all_targets()
113 assert targets == ['t'], targets
114 source_list.append('s3')
115 sources = x.get_all_sources()
116 assert sources == ['s1', 's2'], sources
118 x = SCons.Executor.Executor(None, 'e', ['o'], 't', source_list)
119 except SCons.Errors.UserError:
122 raise "Did not catch expected UserError"
124 def test__action_list(self):
125 """Test the {get,set}_action_list() methods"""
126 x = SCons.Executor.Executor('a', 'e', 'o', 't', ['s1', 's2'])
128 l = x.get_action_list()
131 x.add_pre_action('pre')
132 x.add_post_action('post')
133 l = x.get_action_list()
134 assert l == ['pre', 'a', 'post'], l
136 x.set_action_list('b')
137 l = x.get_action_list()
138 assert l == ['pre', 'b', 'post'], l
140 x.set_action_list(['c'])
141 l = x.get_action_list()
142 assert l == ['pre', 'c', 'post'], l
144 def test_get_build_env(self):
145 """Test fetching and generating a build environment"""
146 x = SCons.Executor.Executor(MyAction(), MyEnvironment(e=1), [],
148 x.env = MyEnvironment(eee=1)
149 be = x.get_build_env()
150 assert be['eee'] == 1, be
152 env = MyEnvironment(X='xxx')
153 x = SCons.Executor.Executor(MyAction(),
158 be = x.get_build_env()
159 assert be['O'] == 'o2', be['O']
160 assert be['X'] == 'xxx', be['X']
162 env = MyEnvironment(Y='yyy')
163 overrides = [{'O':'ob3'}, {'O':'oo3'}]
164 x = SCons.Executor.Executor(MyAction(), env, overrides, ['t'], ['s'])
165 be = x.get_build_env()
166 assert be['O'] == 'oo3', be['O']
167 assert be['Y'] == 'yyy', be['Y']
168 overrides = [{'O':'ob3'}]
169 x = SCons.Executor.Executor(MyAction(), env, overrides, ['t'], ['s'])
170 be = x.get_build_env()
171 assert be['O'] == 'ob3', be['O']
172 assert be['Y'] == 'yyy', be['Y']
174 def test_get_build_scanner_path(self):
175 """Test fetching the path for the specified scanner."""
178 x = SCons.Executor.Executor(MyAction(),
179 MyEnvironment(SCANNERVAL='sss'),
185 def path(self, env, dir, target, source):
186 target = list(map(str, target))
187 source = list(map(str, source))
188 return "scanner: %s, %s, %s, %s" % (env['SCANNERVAL'], dir, target, source)
191 p = x.get_build_scanner_path(s)
192 assert p == "scanner: sss, here, ['t'], ['s1', 's2']", p
194 def test_get_kw(self):
195 """Test the get_kw() method"""
197 x = SCons.Executor.Executor(MyAction(),
202 builder_kw={'X':1, 'Y':2})
204 assert kw == {'X':1, 'Y':2, 'executor':x}, kw
205 kw = x.get_kw({'Z':3})
206 assert kw == {'X':1, 'Y':2, 'Z':3, 'executor':x}, kw
207 kw = x.get_kw({'X':4})
208 assert kw == {'X':4, 'Y':2, 'executor':x}, kw
210 def test__call__(self):
211 """Test calling an Executor"""
213 def pre(target, source, env, result=result, **kw):
215 def action1(target, source, env, result=result, **kw):
216 result.append('action1')
217 def action2(target, source, env, result=result, **kw):
218 result.append('action2')
219 def post(target, source, env, result=result, **kw):
220 result.append('post')
222 env = MyEnvironment()
223 a = MyAction([action1, action2])
226 x = SCons.Executor.Executor(a, env, [], [t], ['s1', 's2'])
227 x.add_pre_action(pre)
228 x.add_post_action(post)
230 assert result == ['pre', 'action1', 'action2', 'post'], result
233 def pre_err(target, source, env, result=result, **kw):
234 result.append('pre_err')
237 x = SCons.Executor.Executor(a, env, [], [t], ['s1', 's2'])
238 x.add_pre_action(pre_err)
239 x.add_post_action(post)
242 except SCons.Errors.BuildError:
245 raise Exception, "Did not catch expected BuildError"
246 assert result == ['pre_err'], result
249 def test_cleanup(self):
250 """Test cleaning up an Executor"""
251 orig_env = MyEnvironment(e=1)
252 x = SCons.Executor.Executor('b', orig_env, [{'o':1}],
255 be = x.get_build_env()
256 assert be['e'] == 1, be['e']
260 x.env = MyEnvironment(eee=1)
261 be = x.get_build_env()
262 assert be['eee'] == 1, be['eee']
266 be = x.get_build_env()
267 assert be['eee'] == 1, be['eee']
269 def test_add_sources(self):
270 """Test adding sources to an Executor"""
271 x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2'])
272 sources = x.get_all_sources()
273 assert sources == ['s1', 's2'], sources
275 x.add_sources(['s1', 's2'])
276 sources = x.get_all_sources()
277 assert sources == ['s1', 's2'], sources
279 x.add_sources(['s3', 's1', 's4'])
280 sources = x.get_all_sources()
281 assert sources == ['s1', 's2', 's3', 's4'], sources
283 def test_get_sources(self):
284 """Test getting sources from an Executor"""
285 x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2'])
286 sources = x.get_sources()
287 assert sources == ['s1', 's2'], sources
289 x.add_sources(['s1', 's2'])
290 sources = x.get_sources()
291 assert sources == ['s1', 's2'], sources
293 x.add_sources(['s3', 's1', 's4'])
294 sources = x.get_sources()
295 assert sources == ['s1', 's2', 's3', 's4'], sources
297 def test_prepare(self):
298 """Test the Executor's prepare() method"""
299 env = MyEnvironment()
304 x = SCons.Executor.Executor('b', env, [{}], [t1], [s1, s2, s3])
306 s2.missing_val = True
310 except SCons.Errors.StopError, e:
311 assert str(e) == "Source `s2' not found, needed by target `t1'.", e
313 raise AssertionError, "did not catch expected StopError: %s" % r
315 def test_add_pre_action(self):
316 """Test adding pre-actions to an Executor"""
317 x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2'])
318 x.add_pre_action('a1')
319 assert x.pre_actions == ['a1']
320 x.add_pre_action('a2')
321 assert x.pre_actions == ['a1', 'a2']
323 def test_add_post_action(self):
324 """Test adding post-actions to an Executor"""
325 x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2'])
326 x.add_post_action('a1')
327 assert x.post_actions == ['a1']
328 x.add_post_action('a2')
329 assert x.post_actions == ['a1', 'a2']
331 def test___str__(self):
332 """Test the __str__() method"""
333 env = MyEnvironment(S='string')
335 x = SCons.Executor.Executor(MyAction(), env, [], ['t'], ['s'])
337 assert c == 'GENSTRING action1 action2 t s', c
339 x = SCons.Executor.Executor(MyAction(), env, [], ['t'], ['s'])
340 x.add_pre_action(MyAction(['pre']))
341 x.add_post_action(MyAction(['post']))
343 expect = 'GENSTRING pre t s\n' + \
344 'GENSTRING action1 action2 t s\n' + \
346 assert c == expect, c
348 def test_nullify(self):
349 """Test the nullify() method"""
350 env = MyEnvironment(S='string')
353 def action1(target, source, env, result=result, **kw):
354 result.append('action1')
356 env = MyEnvironment()
357 a = MyAction([action1])
358 x = SCons.Executor.Executor(a, env, [], ['t1', 't2'], ['s1', 's2'])
360 x(MyNode('', [], []))
361 assert result == ['action1'], result
363 assert s[:10] == 'GENSTRING ', s
368 assert result == [], result
369 x(MyNode('', [], []))
370 assert result == [], result
374 def test_get_contents(self):
375 """Test fetching the signatures contents"""
376 env = MyEnvironment(C='contents')
378 x = SCons.Executor.Executor(MyAction(), env, [], ['t'], ['s'])
380 assert c == 'action1 action2 t s', c
382 x = SCons.Executor.Executor(MyAction(actions=['grow']), env, [],
384 x.add_pre_action(MyAction(['pre']))
385 x.add_post_action(MyAction(['post']))
387 assert c == 'pre t sgrow t spost t s', c
389 def test_get_timestamp(self):
390 """Test fetching the "timestamp" """
391 x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2'])
392 ts = x.get_timestamp()
395 def test_scan_targets(self):
396 """Test scanning the targets for implicit dependencies"""
397 env = MyEnvironment(S='string')
400 sources = [MyNode('s1'), MyNode('s2')]
401 x = SCons.Executor.Executor(MyAction(), env, [{}], [t1, t2], sources)
403 deps = x.scan_targets(None)
404 assert t1.implicit == ['dep-t1', 'dep-t2'], t1.implicit
405 assert t2.implicit == ['dep-t1', 'dep-t2'], t2.implicit
410 deps = x.scan_targets(MyScanner('scanner-'))
411 assert t1.implicit == ['scanner-t1', 'scanner-t2'], t1.implicit
412 assert t2.implicit == ['scanner-t1', 'scanner-t2'], t2.implicit
414 def test_scan_sources(self):
415 """Test scanning the sources for implicit dependencies"""
416 env = MyEnvironment(S='string')
419 sources = [MyNode('s1'), MyNode('s2')]
420 x = SCons.Executor.Executor(MyAction(), env, [{}], [t1, t2], sources)
422 deps = x.scan_sources(None)
423 assert t1.implicit == ['dep-s1', 'dep-s2'], t1.implicit
424 assert t2.implicit == ['dep-s1', 'dep-s2'], t2.implicit
429 deps = x.scan_sources(MyScanner('scanner-'))
430 assert t1.implicit == ['scanner-s1', 'scanner-s2'], t1.implicit
431 assert t2.implicit == ['scanner-s1', 'scanner-s2'], t2.implicit
433 def test_get_unignored_sources(self):
434 """Test fetching the unignored source list"""
435 env = MyEnvironment()
439 x = SCons.Executor.Executor('b', env, [{}], [], [s1, s2, s3])
441 r = x.get_unignored_sources(None, [])
442 assert r == [s1, s2, s3], list(map(str, r))
444 r = x.get_unignored_sources(None, [s2])
445 assert r == [s1, s3], list(map(str, r))
447 r = x.get_unignored_sources(None, [s1, s3])
448 assert r == [s2], list(map(str, r))
452 if __name__ == "__main__":
453 suite = unittest.TestSuite()
454 tclasses = [ ExecutorTestCase ]
455 for tclass in tclasses:
456 names = unittest.getTestCaseNames(tclass, 'test_')
457 suite.addTests(list(map(tclass, names)))
458 if not unittest.TextTestRunner().run(suite).wasSuccessful():
463 # indent-tabs-mode:nil
465 # vim: set expandtab tabstop=4 shiftwidth=4: