diff options
Diffstat (limited to 'src/engine/SCons/ExecutorTests.py')
-rw-r--r-- | src/engine/SCons/ExecutorTests.py | 466 |
1 files changed, 466 insertions, 0 deletions
diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py new file mode 100644 index 0000000..a0194e9 --- /dev/null +++ b/src/engine/SCons/ExecutorTests.py @@ -0,0 +1,466 @@ +# +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "src/engine/SCons/ExecutorTests.py 4577 2009/12/27 19:44:43 scons" + +import string +import sys +import unittest + +import SCons.Executor + + +class MyEnvironment: + def __init__(self, **kw): + self._dict = {} + self._dict.update(kw) + def __getitem__(self, key): + return self._dict[key] + def Override(self, overrides): + d = self._dict.copy() + d.update(overrides) + return apply(MyEnvironment, (), d) + def _update(self, dict): + self._dict.update(dict) + +class MyAction: + def __init__(self, actions=['action1', 'action2']): + self.actions = actions + def __call__(self, target, source, env, **kw): + for action in self.actions: + apply(action, (target, source, env), kw) + def genstring(self, target, source, env): + return string.join(['GENSTRING'] + map(str, self.actions) + target + source) + def get_contents(self, target, source, env): + return string.join(self.actions + target + source) + def get_implicit_deps(self, target, source, env): + return [] + +class MyBuilder: + def __init__(self, env, overrides): + self.env = env + self.overrides = overrides + self.action = MyAction() + +class MyNode: + def __init__(self, name=None, pre=[], post=[]): + self.name = name + self.implicit = [] + self.pre_actions = pre + self.post_actions = post + self.missing_val = None + def __str__(self): + return self.name + def build(self): + executor = SCons.Executor.Executor(MyAction(self.pre_actions + + [self.builder.action] + + self.post_actions), + self.builder.env, + [], + [self], + ['s1', 's2']) + apply(executor, (self), {}) + def get_env_scanner(self, env, kw): + return MyScanner('dep-') + def get_implicit_deps(self, env, scanner, path): + return [scanner.prefix + str(self)] + def add_to_implicit(self, deps): + self.implicit.extend(deps) + def missing(self): + return self.missing_val + def calc_signature(self, calc): + return 'cs-'+calc+'-'+self.name + def disambiguate(self): + return self + +class MyScanner: + def __init__(self, prefix): + self.prefix = prefix + def path(self, env, cwd, target, source): + return () + def select(self, node): + return self + +class ExecutorTestCase(unittest.TestCase): + + def test__init__(self): + """Test creating an Executor""" + source_list = ['s1', 's2'] + x = SCons.Executor.Executor('a', 'e', ['o'], 't', source_list) + assert x.action_list == ['a'], x.action_list + assert x.env == 'e', x.env + assert x.overridelist == ['o'], x.overridelist + targets = x.get_all_targets() + assert targets == ['t'], targets + source_list.append('s3') + sources = x.get_all_sources() + assert sources == ['s1', 's2'], sources + try: + x = SCons.Executor.Executor(None, 'e', ['o'], 't', source_list) + except SCons.Errors.UserError: + pass + else: + raise "Did not catch expected UserError" + + def test__action_list(self): + """Test the {get,set}_action_list() methods""" + x = SCons.Executor.Executor('a', 'e', 'o', 't', ['s1', 's2']) + + l = x.get_action_list() + assert l == ['a'], l + + x.add_pre_action('pre') + x.add_post_action('post') + l = x.get_action_list() + assert l == ['pre', 'a', 'post'], l + + x.set_action_list('b') + l = x.get_action_list() + assert l == ['pre', 'b', 'post'], l + + x.set_action_list(['c']) + l = x.get_action_list() + assert l == ['pre', 'c', 'post'], l + + def test_get_build_env(self): + """Test fetching and generating a build environment""" + x = SCons.Executor.Executor(MyAction(), MyEnvironment(e=1), [], + 't', ['s1', 's2']) + x.env = MyEnvironment(eee=1) + be = x.get_build_env() + assert be['eee'] == 1, be + + env = MyEnvironment(X='xxx') + x = SCons.Executor.Executor(MyAction(), + env, + [{'O':'o2'}], + 't', + ['s1', 's2']) + be = x.get_build_env() + assert be['O'] == 'o2', be['O'] + assert be['X'] == 'xxx', be['X'] + + env = MyEnvironment(Y='yyy') + overrides = [{'O':'ob3'}, {'O':'oo3'}] + x = SCons.Executor.Executor(MyAction(), env, overrides, ['t'], ['s']) + be = x.get_build_env() + assert be['O'] == 'oo3', be['O'] + assert be['Y'] == 'yyy', be['Y'] + overrides = [{'O':'ob3'}] + x = SCons.Executor.Executor(MyAction(), env, overrides, ['t'], ['s']) + be = x.get_build_env() + assert be['O'] == 'ob3', be['O'] + assert be['Y'] == 'yyy', be['Y'] + + def test_get_build_scanner_path(self): + """Test fetching the path for the specified scanner.""" + t = MyNode('t') + t.cwd = 'here' + x = SCons.Executor.Executor(MyAction(), + MyEnvironment(SCANNERVAL='sss'), + [], + [t], + ['s1', 's2']) + + class LocalScanner: + def path(self, env, dir, target, source): + target = map(str, target) + source = map(str, source) + return "scanner: %s, %s, %s, %s" % (env['SCANNERVAL'], dir, target, source) + s = LocalScanner() + + p = x.get_build_scanner_path(s) + assert p == "scanner: sss, here, ['t'], ['s1', 's2']", p + + def test_get_kw(self): + """Test the get_kw() method""" + t = MyNode('t') + x = SCons.Executor.Executor(MyAction(), + MyEnvironment(), + [], + [t], + ['s1', 's2'], + builder_kw={'X':1, 'Y':2}) + kw = x.get_kw() + assert kw == {'X':1, 'Y':2, 'executor':x}, kw + kw = x.get_kw({'Z':3}) + assert kw == {'X':1, 'Y':2, 'Z':3, 'executor':x}, kw + kw = x.get_kw({'X':4}) + assert kw == {'X':4, 'Y':2, 'executor':x}, kw + + def test__call__(self): + """Test calling an Executor""" + result = [] + def pre(target, source, env, result=result, **kw): + result.append('pre') + def action1(target, source, env, result=result, **kw): + result.append('action1') + def action2(target, source, env, result=result, **kw): + result.append('action2') + def post(target, source, env, result=result, **kw): + result.append('post') + + env = MyEnvironment() + a = MyAction([action1, action2]) + t = MyNode('t') + + x = SCons.Executor.Executor(a, env, [], [t], ['s1', 's2']) + x.add_pre_action(pre) + x.add_post_action(post) + x(t) + assert result == ['pre', 'action1', 'action2', 'post'], result + del result[:] + + def pre_err(target, source, env, result=result, **kw): + result.append('pre_err') + return 1 + + x = SCons.Executor.Executor(a, env, [], [t], ['s1', 's2']) + x.add_pre_action(pre_err) + x.add_post_action(post) + try: + x(t) + except SCons.Errors.BuildError: + pass + else: + raise Exception, "Did not catch expected BuildError" + assert result == ['pre_err'], result + del result[:] + + def test_cleanup(self): + """Test cleaning up an Executor""" + orig_env = MyEnvironment(e=1) + x = SCons.Executor.Executor('b', orig_env, [{'o':1}], + 't', ['s1', 's2']) + + be = x.get_build_env() + assert be['e'] == 1, be['e'] + + x.cleanup() + + x.env = MyEnvironment(eee=1) + be = x.get_build_env() + assert be['eee'] == 1, be['eee'] + + x.cleanup() + + be = x.get_build_env() + assert be['eee'] == 1, be['eee'] + + def test_add_sources(self): + """Test adding sources to an Executor""" + x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) + sources = x.get_all_sources() + assert sources == ['s1', 's2'], sources + + x.add_sources(['s1', 's2']) + sources = x.get_all_sources() + assert sources == ['s1', 's2'], sources + + x.add_sources(['s3', 's1', 's4']) + sources = x.get_all_sources() + assert sources == ['s1', 's2', 's3', 's4'], sources + + def test_get_sources(self): + """Test getting sources from an Executor""" + x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) + sources = x.get_sources() + assert sources == ['s1', 's2'], sources + + x.add_sources(['s1', 's2']) + sources = x.get_sources() + assert sources == ['s1', 's2'], sources + + x.add_sources(['s3', 's1', 's4']) + sources = x.get_sources() + assert sources == ['s1', 's2', 's3', 's4'], sources + + def test_prepare(self): + """Test the Executor's prepare() method""" + env = MyEnvironment() + t1 = MyNode('t1') + s1 = MyNode('s1') + s2 = MyNode('s2') + s3 = MyNode('s3') + x = SCons.Executor.Executor('b', env, [{}], [t1], [s1, s2, s3]) + + s2.missing_val = True + + try: + r = x.prepare() + except SCons.Errors.StopError, e: + assert str(e) == "Source `s2' not found, needed by target `t1'.", e + else: + raise AssertionError, "did not catch expected StopError: %s" % r + + def test_add_pre_action(self): + """Test adding pre-actions to an Executor""" + x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) + x.add_pre_action('a1') + assert x.pre_actions == ['a1'] + x.add_pre_action('a2') + assert x.pre_actions == ['a1', 'a2'] + + def test_add_post_action(self): + """Test adding post-actions to an Executor""" + x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) + x.add_post_action('a1') + assert x.post_actions == ['a1'] + x.add_post_action('a2') + assert x.post_actions == ['a1', 'a2'] + + def test___str__(self): + """Test the __str__() method""" + env = MyEnvironment(S='string') + + x = SCons.Executor.Executor(MyAction(), env, [], ['t'], ['s']) + c = str(x) + assert c == 'GENSTRING action1 action2 t s', c + + x = SCons.Executor.Executor(MyAction(), env, [], ['t'], ['s']) + x.add_pre_action(MyAction(['pre'])) + x.add_post_action(MyAction(['post'])) + c = str(x) + expect = 'GENSTRING pre t s\n' + \ + 'GENSTRING action1 action2 t s\n' + \ + 'GENSTRING post t s' + assert c == expect, c + + def test_nullify(self): + """Test the nullify() method""" + env = MyEnvironment(S='string') + + result = [] + def action1(target, source, env, result=result, **kw): + result.append('action1') + + env = MyEnvironment() + a = MyAction([action1]) + x = SCons.Executor.Executor(a, env, [], ['t1', 't2'], ['s1', 's2']) + + x(MyNode('', [], [])) + assert result == ['action1'], result + s = str(x) + assert s[:10] == 'GENSTRING ', s + + del result[:] + x.nullify() + + assert result == [], result + x(MyNode('', [], [])) + assert result == [], result + s = str(x) + assert s == '', s + + def test_get_contents(self): + """Test fetching the signatures contents""" + env = MyEnvironment(C='contents') + + x = SCons.Executor.Executor(MyAction(), env, [], ['t'], ['s']) + c = x.get_contents() + assert c == 'action1 action2 t s', c + + x = SCons.Executor.Executor(MyAction(actions=['grow']), env, [], + ['t'], ['s']) + x.add_pre_action(MyAction(['pre'])) + x.add_post_action(MyAction(['post'])) + c = x.get_contents() + assert c == 'pre t sgrow t spost t s', c + + def test_get_timestamp(self): + """Test fetching the "timestamp" """ + x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) + ts = x.get_timestamp() + assert ts == 0, ts + + def test_scan_targets(self): + """Test scanning the targets for implicit dependencies""" + env = MyEnvironment(S='string') + t1 = MyNode('t1') + t2 = MyNode('t2') + sources = [MyNode('s1'), MyNode('s2')] + x = SCons.Executor.Executor(MyAction(), env, [{}], [t1, t2], sources) + + deps = x.scan_targets(None) + assert t1.implicit == ['dep-t1', 'dep-t2'], t1.implicit + assert t2.implicit == ['dep-t1', 'dep-t2'], t2.implicit + + t1.implicit = [] + t2.implicit = [] + + deps = x.scan_targets(MyScanner('scanner-')) + assert t1.implicit == ['scanner-t1', 'scanner-t2'], t1.implicit + assert t2.implicit == ['scanner-t1', 'scanner-t2'], t2.implicit + + def test_scan_sources(self): + """Test scanning the sources for implicit dependencies""" + env = MyEnvironment(S='string') + t1 = MyNode('t1') + t2 = MyNode('t2') + sources = [MyNode('s1'), MyNode('s2')] + x = SCons.Executor.Executor(MyAction(), env, [{}], [t1, t2], sources) + + deps = x.scan_sources(None) + assert t1.implicit == ['dep-s1', 'dep-s2'], t1.implicit + assert t2.implicit == ['dep-s1', 'dep-s2'], t2.implicit + + t1.implicit = [] + t2.implicit = [] + + deps = x.scan_sources(MyScanner('scanner-')) + assert t1.implicit == ['scanner-s1', 'scanner-s2'], t1.implicit + assert t2.implicit == ['scanner-s1', 'scanner-s2'], t2.implicit + + def test_get_unignored_sources(self): + """Test fetching the unignored source list""" + env = MyEnvironment() + s1 = MyNode('s1') + s2 = MyNode('s2') + s3 = MyNode('s3') + x = SCons.Executor.Executor('b', env, [{}], [], [s1, s2, s3]) + + r = x.get_unignored_sources(None, []) + assert r == [s1, s2, s3], map(str, r) + + r = x.get_unignored_sources(None, [s2]) + assert r == [s1, s3], map(str, r) + + r = x.get_unignored_sources(None, [s1, s3]) + assert r == [s2], map(str, r) + + + +if __name__ == "__main__": + suite = unittest.TestSuite() + tclasses = [ ExecutorTestCase ] + for tclass in tclasses: + names = unittest.getTestCaseNames(tclass, 'test_') + suite.addTests(map(tclass, names)) + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |