blob: 7615f57e466607147c55933da45c9dbc9f2522eb [file] [log] [blame]
#!/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.
"""Test the cbuildbot_run module."""
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:
child_index: Index of child config to use within config.
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()
run.attrs.release_tag = release_tag
# 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)