def test_get_dirpath(self): tempdir = tempfile.mkdtemp() try: config = Configuration(properties={'somepkg.home': tempdir}) self.assertEqual(tempdir, config.get_dirpath('somepkg.home')) finally: os.rmdir(tempdir)
def test_interpolate_default(self): config = Configuration() self.assertEqual('python2.3', config.interpolate('${python.path:python2.3}')) self.assertEqual( 'foo python2.3 bar', config.interpolate('foo ${python.path:python2.3} bar'))
def test_interpolate(self): config = Configuration(properties={ 'python.version': '2.3.5', 'python.path': '/usr/local/bin/python2.3' }) self.assertEqual('/usr/local/bin/python2.3', config.interpolate('${python.path}')) self.assertEqual('foo /usr/local/bin/python2.3 bar', config.interpolate('foo ${python.path} bar'))
def test_package_configfile_non_existant(self): try: conf = Configuration(filename='doesnotexist.ini') self.fail('Expected ConfigFileNotFound') except ConfigFileNotFound, e: self.assertEquals( str(e), "Configuration file 'doesnotexist.ini' not found.")
def test_vars_basedir(self): config = Configuration(properties={'foo.bar': 'baz'}) ctxt = Context('%s/${path}/${foo.bar}' % os.path.realpath('/foo'), config, {'path': 'bar'}) self.assertEquals(os.path.realpath('/foo/bar/baz'), os.path.realpath(ctxt.vars['basedir'])) if os.name == 'nt': # Make sure paths are double-escaped self.failUnless('\\\\' in ctxt.vars['basedir'])
def test_sysinfo_defaults(self): config = Configuration() self.assertEqual(platform.machine(), config['machine']) self.assertEqual(platform.processor(), config['processor']) system, release, version = platform.system_alias( platform.system(), platform.release(), platform.version()) self.assertEqual(system, config['os']) self.assertEqual(os.name, config['family']) self.assertEqual(release, config['version'])
def test_attach_file_non_existing(self): # Verify that it raises error and that it gets logged ctxt = Context(self.basedir, Configuration()) ctxt.attach(file_='nonexisting.txt', description='build build') self.assertEquals(1, len(ctxt.output)) self.assertEquals(Recipe.ERROR, ctxt.output[0][0]) self.assertEquals('Failed to read file nonexisting.txt as attachment', ctxt.output[0][3])
def test_attach_file_build(self): # Verify output from attaching a file to a build ctxt = Context(self.basedir, Configuration()) ctxt.attach(file_='build.txt', description='build build') self.assertEquals(1, len(ctxt.output)) self.assertEquals(Recipe.ATTACH, ctxt.output[0][0]) attach_xml = ctxt.output[0][3] self.assertEquals('<file resource="build" ' 'description="build build" ' 'filename="build.txt"/>', str(attach_xml))
def test_package_properties(self): config = Configuration( properties={ 'python.version': '2.3.5', 'python.path': '/usr/local/bin/python2.3', 'python.name': 'invalid option' }) self.assertEqual(True, 'python' in config.packages) self.assertEqual('/usr/local/bin/python2.3', config['python.path']) self.assertEqual('2.3.5', config['python.version']) self.failIf('name' in config.packages['python'], "Invalid option 'name' should not be included...")
def test_sysinfo_properties_override(self): config = Configuration( properties={ 'machine': 'MACHINE', 'processor': 'PROCESSOR', 'os': 'OS', 'family': 'FAMILY', 'version': 'VERSION' }) self.assertEqual('MACHINE', config['machine']) self.assertEqual('PROCESSOR', config['processor']) self.assertEqual('OS', config['os']) self.assertEqual('FAMILY', config['family']) self.assertEqual('VERSION', config['version'])
def __init__(self, basedir, config=None, vars=None): """Initialize the context. :param basedir: a string containing the working directory for the build. (may be a pattern for replacement ex: 'build_${build}' :param config: the build slave configuration :type config: `Configuration` """ self.config = config or Configuration() self.vars = vars or {} self.output = [] self.basedir = os.path.realpath( self.config.interpolate(basedir, **self.vars)) self.vars['basedir'] = self.basedir.replace('\\', '\\\\')
def test_attach_file_build(self): # Verify output from attaching a file to a build ctxt = Context(self.basedir, Configuration()) test_file = open(os.path.join(self.basedir, 'build.txt'), 'w') test_file.write('hello build') test_file.close() ctxt.attach(file_='build.txt', description='build build') self.assertEquals(1, len(ctxt.output)) self.assertEquals(Recipe.ATTACH, ctxt.output[0][0]) attach_xml = ctxt.output[0][3] self.assertEquals('<file resource="build" ' 'description="build build" ' 'filename="build.txt">' 'aGVsbG8gYnVpbGQ=\n' '</file>', str(attach_xml))
def test_attach_file_config(self): # Verify output from attaching a file to a config ctxt = Context(self.basedir, Configuration()) test_file = open(os.path.join(self.basedir, 'config.txt'), 'w') test_file.write('hello config') test_file.close() ctxt.attach(file_='config.txt', description='config config', resource='config') self.assertEquals(1, len(ctxt.output)) self.assertEquals(Recipe.ATTACH, ctxt.output[0][0]) attach_xml = ctxt.output[0][3] self.assertEquals('<file resource="config" ' 'description="config config" ' 'filename="config.txt">' 'aGVsbG8gY29uZmln\n' '</file>', str(attach_xml))
def test_package_configfile(self): inifd, ininame = tempfile.mkstemp(prefix='bitten_test') try: os.write( inifd, """ [python] path = /usr/local/bin/python2.3 version = 2.3.5 name = invalid option """) os.close(inifd) config = Configuration(ininame) self.assertEqual(True, 'python' in config.packages) self.assertEqual('/usr/local/bin/python2.3', config['python.path']) self.assertEqual('2.3.5', config['python.version']) self.failIf('name' in config.packages['python'], "Invalid option 'name' should not be included...") finally: os.remove(ininame)
def test_interpolate_environment(self): config = Configuration() os.environ['BITTEN_TEST'] = 'foo' try: # regular substitutions self.assertEquals(os.environ['BITTEN_TEST'], config.interpolate('$BITTEN_TEST')) self.assertEquals(os.environ['BITTEN_TEST'], config.interpolate('${BITTEN_TEST}')) if os.name == 'posix': # case-sensitive self.assertEquals('${bitten_test}', config.interpolate('${bitten_test}')) self.assertEquals('$bitten_test', config.interpolate('$bitten_test')) elif os.name == 'nt': # case-insensitive self.assertEquals(os.environ['bitten_test'], config.interpolate('$bitten_test')) self.assertEquals(os.environ['bitten_test'], config.interpolate('${bitten_test}')) finally: del os.environ['BITTEN_TEST']
def test_sysinfo_configfile_partial_override(self): inifd, ininame = tempfile.mkstemp(prefix='bitten_test') try: os.write(inifd, """ [machine] name = MACHINE [os] name = OS """) os.close(inifd) config = Configuration(ininame) self.assertEqual('MACHINE', config['machine']) self.assertEqual('OS', config['os']) # Remaining options should be set to default value system, release, version = platform.system_alias( platform.system(), platform.release(), platform.version()) self.assertEqual(platform.processor(), config['processor']) self.assertEqual(os.name, config['family']) self.assertEqual(release, config['version']) finally: os.remove(ininame)
def test_sysinfo_configfile_override(self): inifd, ininame = tempfile.mkstemp(prefix='bitten_test') try: os.write( inifd, """ [machine] name = MACHINE processor = PROCESSOR [os] name = OS family = FAMILY version = VERSION """) os.close(inifd) config = Configuration(ininame) self.assertEqual('MACHINE', config['machine']) self.assertEqual('PROCESSOR', config['processor']) self.assertEqual('OS', config['os']) self.assertEqual('FAMILY', config['family']) self.assertEqual('VERSION', config['version']) finally: os.remove(ininame)
def test_get_filepath_non_existant(self): testfile, testname = tempfile.mkstemp(prefix='bitten_test') os.close(testfile) os.remove(testname) config = Configuration(properties={'somepkg.path': testname}) self.assertEqual(None, config.get_filepath('somepkg.path'))
def test_interpolate_missing(self): config = Configuration() self.assertEqual('${python.path}', config.interpolate('${python.path}')) self.assertEqual('foo ${python.path} bar', config.interpolate('foo ${python.path} bar'))
def __init__(self, urls, name=None, config=None, dry_run=False, work_dir=None, build_dir="build_${build}", keep_files=False, single_build=False, poll_interval=300, keepalive_interval=60, username=None, password=None, dump_reports=False, no_loop=False, form_auth=False): """Create the build slave instance. :param urls: a list of URLs of the build masters to connect to, or a single-element list containing the path to a build recipe file :param name: the name with which this slave should identify itself :param config: the path to the slave configuration file :param dry_run: wether the build outcome should not be reported back to the master :param work_dir: the working directory to use for build execution :param build_dir: the pattern to use for naming the build subdir :param keep_files: whether files and directories created for build execution should be kept when done :param single_build: whether this slave should exit after completing a single build, or continue processing builds forever :param poll_interval: the time in seconds to wait between requesting builds from the build master (default is five minutes) :param keepalive_interval: the time in seconds to wait between sending keepalive heartbeats (default is 30 seconds) :param username: the username to use when authentication against the build master is requested :param password: the password to use when authentication is needed :param dump_reports: whether report data should be written to the standard output, in addition to being transmitted to the build master :param no_loop: for this slave to just perform a single check, regardless of whether a build is done or not :param form_auth: login using AccountManager HTML form instead of HTTP authentication for all urls """ self.local = len(urls) == 1 and not urls[0].startswith('http://') \ and not urls[0].startswith('https://') if self.local: self.urls = urls else: self.urls = [ not url.endswith('/builds') and url.rstrip('/') + '/builds' or url for url in urls ] if name is None: name = platform.node().split('.', 1)[0].lower() self.name = name self.config = Configuration(config) self.dry_run = dry_run if not work_dir: work_dir = tempfile.mkdtemp(prefix='bitten') elif not os.path.exists(work_dir): os.makedirs(work_dir) self.work_dir = work_dir self.build_dir = build_dir self.keep_files = keep_files self.single_build = single_build self.no_loop = no_loop self.poll_interval = poll_interval self.keepalive_interval = keepalive_interval self.dump_reports = dump_reports self.cookiejar = cookielib.CookieJar() self.username = username \ or self.config['authentication.username'] or '' if not self.local: self.password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() if self.username: log.debug('Enabling authentication with username %r', self.username) self.form_auth = form_auth password = password \ or self.config['authentication.password'] or '' self.config.packages.pop('authentication', None) urls = [url[:-len('/builds')] for url in self.urls] self.password_mgr.add_password(None, urls, self.username, password) self.auth_map = dict(map(lambda x: (x, False), urls))
def test_get_dirpath_non_existant(self): tempdir = tempfile.mkdtemp() os.rmdir(tempdir) config = Configuration(properties={'somepkg.home': tempdir}) self.assertEqual(None, config.get_dirpath('somepkg.home'))
def test_interpolate_default(self): config = Configuration() self.assertEqual('python2.3', config.interpolate('${python.path:python2.3}')) self.assertEqual('foo python2.3 bar', config.interpolate('foo ${python.path:python2.3} bar'))
def test_get_filepath(self): testfile = tempfile.NamedTemporaryFile(prefix='bitten_test') config = Configuration(properties={'somepkg.path': testfile.name}) self.assertEqual(testfile.name, config.get_filepath('somepkg.path'))