| #!/usr/bin/python |
| |
| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import logging |
| import os |
| import cPickle |
| import sys |
| |
| sys.path.insert(0, os.path.abspath('%s/../..' % os.path.dirname(__file__))) |
| from chromite.buildbot import cbuildbot_run |
| from chromite.lib import cros_test_lib |
| |
| import mock |
| |
| DEFAULT_BUILDROOT = '/tmp/foo/bar/buildroot' |
| DEFAULT_BUILDNUMBER = 12345 |
| DEFAULT_BRANCH = 'TheBranch' |
| DEFAULT_CHROME_BRANCH = 'TheChromeBranch' |
| DEFAULT_VERSION_STRING = 'TheVersionString' |
| DEFAULT_BOARD = 'TheBoard' |
| |
| DEFAULT_OPTIONS = cros_test_lib.EasyAttr(buildroot=DEFAULT_BUILDROOT, |
| buildnumber=DEFAULT_BUILDNUMBER, |
| branch=DEFAULT_BRANCH, |
| ) |
| DEFAULT_CONFIG = cros_test_lib.EasyAttr( |
| master=True, |
| boards=[DEFAULT_BOARD], |
| child_configs=[cros_test_lib.EasyAttr(name='foo'), |
| cros_test_lib.EasyAttr(name='bar'), |
| ]) |
| |
| |
| def _NewBuilderRun(options=None, config=None): |
| """Create a BuilderRun objection from options and config values. |
| |
| Args: |
| options: Specify options or default to DEFAULT_OPTIONS. |
| config: Specify build config or default to DEFAULT_CONFIG. |
| Returns: |
| BuilderRun object. |
| """ |
| options = options or DEFAULT_OPTIONS |
| config = config or DEFAULT_CONFIG |
| return cbuildbot_run.BuilderRun(options, config) |
| |
| |
| def _NewChildBuilderRun(child_index, options=None, config=None): |
| """Create a ChildBuilderRun objection from options and config values. |
| |
| Args: |
| options: Specify options or default to DEFAULT_OPTIONS. |
| config: Specify build config or default to DEFAULT_CONFIG. |
| Returns: |
| ChildBuilderRun object. |
| """ |
| run = _NewBuilderRun(options, config) |
| return cbuildbot_run.ChildBuilderRun(run, child_index) |
| |
| |
| def _ExtendDefaultOptions(**kwargs): |
| """Extend DEFAULT_OPTIONS with keys/values in kwargs.""" |
| options_kwargs = DEFAULT_OPTIONS.copy() |
| options_kwargs.update(kwargs) |
| return cros_test_lib.EasyAttr(**options_kwargs) |
| |
| |
| def _ExtendDefaultConfig(**kwargs): |
| """Extend DEFAULT_CONFIG with keys/values in kwargs.""" |
| config_kwargs = DEFAULT_CONFIG.copy() |
| config_kwargs.update(kwargs) |
| return cros_test_lib.EasyAttr(**config_kwargs) |
| |
| |
| class BuilderRunPickleTest(cros_test_lib.TestCase): |
| """Make sure BuilderRun objects can be pickled.""" |
| |
| def testPickleBuilderRun(self): |
| run1 = _NewBuilderRun() |
| run1.attrs.release_tag = 'TheReleaseTag' |
| run2 = cPickle.loads(cPickle.dumps(run1, cPickle.HIGHEST_PROTOCOL)) |
| |
| self.assertEquals(run1.buildnumber, run2.buildnumber) |
| self.assertEquals(run1.config.boards, run2.config.boards) |
| self.assertEquals(run1.options.branch, run2.options.branch) |
| self.assertEquals(run1.attrs.release_tag, run2.attrs.release_tag) |
| self.assertRaises(AttributeError, getattr, run1.attrs, 'manifest_manager') |
| self.assertRaises(AttributeError, getattr, run2.attrs, 'manifest_manager') |
| |
| def testPickleChildBuilderRun(self): |
| run1 = _NewChildBuilderRun(0) |
| run1.attrs.release_tag = 'TheReleaseTag' |
| run2 = cPickle.loads(cPickle.dumps(run1, cPickle.HIGHEST_PROTOCOL)) |
| |
| self.assertEquals(run1.child_index, run2.child_index) |
| self.assertEquals(run1.buildnumber, run2.buildnumber) |
| self.assertEquals(run1.config.name, run2.config.name) |
| self.assertEquals(run1.options.branch, run2.options.branch) |
| self.assertEquals(run1.attrs.release_tag, run2.attrs.release_tag) |
| self.assertRaises(AttributeError, getattr, run1.attrs, 'manifest_manager') |
| self.assertRaises(AttributeError, getattr, run2.attrs, 'manifest_manager') |
| |
| |
| class BuilderRunTest(cros_test_lib.TestCase): |
| """Test the BuilderRun class.""" |
| |
| def testInit(self): |
| run = _NewBuilderRun() |
| self.assertEquals(DEFAULT_BUILDROOT, run.buildroot) |
| self.assertEquals(DEFAULT_BUILDNUMBER, run.buildnumber) |
| self.assertEquals(DEFAULT_BRANCH, run.manifest_branch) |
| self.assertEquals(DEFAULT_OPTIONS, run.options) |
| self.assertEquals(DEFAULT_CONFIG, run.config) |
| self.assertTrue(isinstance(run.attrs, cbuildbot_run.RunAttributes)) |
| |
| def testOptions(self): |
| options = _ExtendDefaultOptions(foo=True, bar=10) |
| run = _NewBuilderRun(options=options) |
| |
| self.assertEquals(True, run.options.foo) |
| self.assertEquals(10, run.options.__getattr__('bar')) |
| self.assertRaises(AttributeError, run.options.__getattr__, 'baz') |
| |
| def testConfig(self): |
| config = _ExtendDefaultOptions(foo=True, bar=10) |
| run = _NewBuilderRun(config=config) |
| |
| self.assertEquals(True, run.config.foo) |
| self.assertEquals(10, run.config.__getattr__('bar')) |
| self.assertRaises(AttributeError, run.config.__getattr__, 'baz') |
| |
| def testAttrs(self): |
| run = _NewBuilderRun() |
| |
| # manifest_manager is a valid run attribute. It gives Attribute error |
| # if accessed before being set, but thereafter works fine. |
| self.assertRaises(AttributeError, run.attrs.__getattribute__, |
| 'manifest_manager') |
| run.attrs.manifest_manager = 'foo' |
| self.assertEquals('foo', run.attrs.manifest_manager) |
| self.assertEquals('foo', run.attrs.__getattribute__('manifest_manager')) |
| |
| # foobar is not a valid run attribute. It gives AttributeError when |
| # accessed or changed. |
| self.assertRaises(AttributeError, run.attrs.__getattribute__, 'foobar') |
| self.assertRaises(AttributeError, run.attrs.__setattr__, 'foobar', 'foo') |
| |
| def _RunAccessor(self, method, options_dict, config_dict): |
| """Run the given accessor method of the BuilderRun class. |
| |
| Create a BuilderRun object with the options and config provided and |
| then return the result of calling the given method on it. |
| |
| Args: |
| method: A BuilderRun method to call. |
| options_dict: Extend default options with this. |
| config_dict: Extend default config with this. |
| Returns: |
| Result of calling the given method. |
| """ |
| options = _ExtendDefaultOptions(**options_dict) |
| config = _ExtendDefaultConfig(**config_dict) |
| run = _NewBuilderRun(options=options, config=config) |
| return method(run) |
| |
| def testDualEnableSetting(self): |
| settings = { |
| 'prebuilts': cbuildbot_run.BuilderRun.ShouldUploadPrebuilts, |
| 'postsync_patch': cbuildbot_run.BuilderRun.ShouldPatchAfterSync, |
| } |
| |
| # Both option and config enabled should result in True. |
| # Create truth table with three variables in this order: |
| # <key> option value, <key> config value (e.g. <key> == 'prebuilts'). |
| truth_table = cros_test_lib.TruthTable(inputs=[(True, True)]) |
| |
| for inputs in truth_table: |
| option_val, config_val = inputs |
| for key, accessor in settings.iteritems(): |
| self.assertEquals( |
| self._RunAccessor(accessor, {key: option_val}, {key: config_val}), |
| truth_table.GetOutput(inputs)) |
| |
| def testShouldReexecAfterSync(self): |
| # If option and config have postsync_reexec enabled, and this file is not |
| # in the build root, then we expect ShouldReexecAfterSync to return True. |
| |
| # Construct a truth table across three variables in this order: |
| # postsync_reexec option value, postsync_reexec config value, same_root. |
| truth_table = cros_test_lib.TruthTable(inputs=[(True, True, False)]) |
| |
| for inputs in truth_table: |
| option_val, config_val, same_root = inputs |
| |
| if same_root: |
| build_root = os.path.dirname(os.path.dirname(__file__)) |
| else: |
| build_root = DEFAULT_BUILDROOT |
| |
| result = self._RunAccessor( |
| cbuildbot_run.BuilderRun.ShouldReexecAfterSync, |
| {'postsync_reexec': option_val, 'buildroot': build_root}, |
| {'postsync_reexec': config_val}) |
| |
| self.assertEquals(result, truth_table.GetOutput(inputs)) |
| |
| |
| class GetVersionTest(cros_test_lib.MockTestCase): |
| """Test the GetVersion and GetVersionInfo methods of BuilderRun class.""" |
| |
| def testGetVersionInfo(self): |
| verinfo = object() |
| |
| with mock.patch('cbuildbot_run.manifest_version.VersionInfo.from_repo', |
| return_value=verinfo) as m: |
| result = cbuildbot_run.BuilderRun.GetVersionInfo(DEFAULT_BUILDROOT) |
| self.assertEquals(result, verinfo) |
| |
| m.assert_called_once_with(DEFAULT_BUILDROOT) |
| |
| def _TestGetVersionReleaseTag(self, release_tag): |
| with mock.patch.object(cbuildbot_run.BuilderRun, 'GetVersionInfo') as m: |
| verinfo_mock = mock.Mock() |
| verinfo_mock.chrome_branch = DEFAULT_CHROME_BRANCH |
| verinfo_mock.VersionString = mock.Mock(return_value='VS') |
| m.return_value = verinfo_mock |
| |
| # Prepare a real BuilderRun object with a release tag. |
| run = _NewBuilderRun() |
| if release_tag is not None: |
| run.attrs.release_tag = 'RT' |
| |
| # Run the test return the result. |
| result = run.GetVersion() |
| m.assert_called_once_with(DEFAULT_BUILDROOT) |
| if release_tag is None: |
| verinfo_mock.VersionString.assert_called_once() |
| |
| return result |
| |
| def testGetVersionReleaseTag(self): |
| result = self._TestGetVersionReleaseTag('RT') |
| self.assertEquals('R%s-%s' % (DEFAULT_CHROME_BRANCH, 'RT'), result) |
| |
| def testGetVersionNoReleaseTag(self): |
| result = self._TestGetVersionReleaseTag(None) |
| expected_result = ('R%s-%s-b%s' % |
| (DEFAULT_CHROME_BRANCH, 'VS', DEFAULT_BUILDNUMBER)) |
| self.assertEquals(result, expected_result) |
| |
| |
| class ChildBuilderRunTest(cros_test_lib.TestCase): |
| """Test the ChildBuilderRun class""" |
| |
| def testInit(self): |
| crun = _NewChildBuilderRun(0) |
| self.assertEquals(DEFAULT_BUILDROOT, crun.buildroot) |
| self.assertEquals(DEFAULT_BUILDNUMBER, crun.buildnumber) |
| self.assertEquals(DEFAULT_BRANCH, crun.manifest_branch) |
| self.assertEquals(DEFAULT_OPTIONS, crun.options) |
| self.assertEquals(DEFAULT_CONFIG.child_configs[0], crun.config) |
| self.assertEquals('foo', crun.config.name) |
| self.assertEquals(0, crun.child_index) |
| self.assertTrue(isinstance(crun.attrs, cbuildbot_run.RunAttributes)) |
| |
| |
| if __name__ == '__main__': |
| cros_test_lib.main(level=logging.DEBUG) |