def test_triggerProperties(self): sched = self.makeScheduler(name='test', builderNames=['test'], minute=[5], codebases={'cb':{'repository':'annoying'}}) self.db.insertTestData([ fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'), ]) sched.startService() sched.trigger({'cb': dict(revision='myrev', branch='br', project='p', repository='r'), }, properties.Properties(testprop='test')) self.db.state.assertState(self.SCHEDULERID, lastTrigger=[{'cb': dict(revision='myrev', branch='br', project='p', repository='r'), }, {'testprop': ['test', 'TEST']}]) self.clock.advance(60*60) # Run for 1h self.db.buildsets.assertBuildset('?', dict(external_idstring=None, properties=[ ('scheduler', ('test', 'Scheduler')), ('testprop', ('test', 'TEST')), ], reason="The NightlyTriggerable scheduler named 'test' triggered this build", sourcestampsetid=100), {'cb': dict(branch='br', project='p', repository='r', codebase='cb', revision='myrev', sourcestampsetid=100) })
def test_triggerProperties(self): sched = self.makeScheduler(name='test', builderNames=['test'], minute=[5], codebases={'cb': {'repository': 'annoying'}}) self.db.insertTestData([ fakedb.Object( id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'), ]) sched.activate() sched.trigger(False, [ dict(codebase='cb', revision='myrev', branch='br', project='p', repository='r'), ], properties.Properties(testprop='test')) self.db.state.assertState(self.SCHEDULERID, lastTrigger=[[ dict(codebase='cb', revision='myrev', branch='br', project='p', repository='r'), ], {'testprop': ['test', 'TEST']}, None, None]) self.clock.advance(60 * 60) # Run for 1h self.assertBuildsetAdded( properties=dict(testprop=('test', 'TEST')), sourcestamps=[ dict(codebase='cb', branch='br', project='p', repository='r', revision='myrev'), ])
def __init__(self, props=None, buildrequests=[]): self.build_status = FakeBuildStatus() self.builder = mock.Mock(name='build.builder') self.slavebuilder = mock.Mock(name='build.slavebuilder') self.path_module = posixpath pr = self.build_status.properties = properties.Properties() pr.build = self self.requests = buildrequests self.steps = [] self.slavename = None self.sources = {} if props is None: props = properties.Properties() props.build = self self.build_status.properties = props
def startBuild(self): if not self.enabled: log.msg(format='ignoring build from %(name)s because scheduler ' 'has been disabled by the user', name=self.name) return if self._lastTrigger is None: return (sourcestamps, set_props, parent_buildid, parent_relationship) = self._lastTrigger self._lastTrigger = None yield self.setState('lastTrigger', None) # properties for this buildset are composed of our own properties, # potentially overridden by anything from the triggering build props = properties.Properties() props.updateFromProperties(self.properties) if set_props: props.updateFromProperties(set_props) yield self.addBuildsetForSourceStampsWithDefaults( reason=self.reason, sourcestamps=sourcestamps, properties=props, parent_buildid=parent_buildid, parent_relationship=parent_relationship)
def test_trigger(self): sched = self.makeScheduler() self.db.insertTestData([ fakedb.SourceStamp(id=91, revision='myrev', branch='br', project='p', repository='r'), ]) # no subscription should be in place yet callbacks = self.master.getSubscriptionCallbacks() self.assertEqual(callbacks['buildset_completion'], None) # trigger the scheduler, exercising properties while we're at it set_props = properties.Properties() set_props.setProperty('pr', 'op', 'test') d = sched.trigger(91, set_props=set_props) # set up a boolean so that we can know when the deferred fires self.fired = False def fired(result): self.assertEqual(result, 13) # 13 comes from the result below self.fired = True d.addCallback(fired) bsid = self.db.buildsets.assertBuildset( '?', dict(builderNames=['b'], external_idstring=None, properties=[ ('pr', ('op', 'test')), ('scheduler', ('n', 'Scheduler')), ], reason='Triggerable(n)'), dict(branch='br', project='p', repository='r', revision='myrev')) # check that the scheduler has subscribed to buildset changes, but # not fired yet callbacks = self.master.getSubscriptionCallbacks() self.assertNotEqual(callbacks['buildset_completion'], None) self.assertFalse(self.fired) # pretend a non-matching buildset is complete callbacks['buildset_completion'](bsid + 27, 3) # scheduler should not have reacted callbacks = self.master.getSubscriptionCallbacks() self.assertNotEqual(callbacks['buildset_completion'], None) self.assertFalse(self.fired) # pretend the matching buildset is complete callbacks['buildset_completion'](bsid, 13) # scheduler should have reacted callbacks = self.master.getSubscriptionCallbacks() self.assertEqual(callbacks['buildset_completion'], None) self.assertTrue(self.fired)
def test_addBuildsetForLatest_properties(self): props = properties.Properties(xxx="yyy") sched = self.makeScheduler(name='xyz', builderNames=['y', 'z']) d = sched.addBuildsetForLatest(reason='cuz', branch='default', project='myp', repository='hgmo', external_idstring='try_1234', properties=props) def check((bsid, brids)): self.db.buildsets.assertBuildset( bsid, dict(reason='cuz', brids=brids, external_idstring='try_1234', properties=[ ('scheduler', ('xyz', 'Scheduler')), ('xxx', ('yyy', 'TEST')), ], sourcestampsetid=100), { '': dict(branch='default', revision=None, repository='hgmo', codebase='', project='myp', sourcestampsetid=100) }) d.addCallback(check) return d
def __init__(self): # local import to avoid circular imports from buildbot.process import properties # default values for all attributes # global self.title = 'Buildbot' self.titleURL = 'http://buildbot.net' self.buildbotURL = 'http://localhost:8080/' self.changeHorizon = None self.eventHorizon = 50 self.logHorizon = None self.buildHorizon = None self.logCompressionLimit = 4 * 1024 self.logCompressionMethod = 'gz' self.logEncoding = 'utf-8' self.logMaxSize = None self.logMaxTailSize = None self.properties = properties.Properties() self.collapseRequests = None self.codebaseGenerator = None self.prioritizeBuilders = None self.multiMaster = False self.manhole = None self.protocols = {} self.validation = dict( branch=re.compile(r'^[\w.+/~-]*$'), revision=re.compile(r'^[ \w\.\-/]*$'), property_name=re.compile(r'^[\w\.\-/~:]*$'), property_value=re.compile(r'^[\w\.\-/~:]*$'), ) self.db = dict( db_url=DEFAULT_DB_URL, ) self.mq = dict( type='simple', ) self.metrics = None self.caches = dict( Builds=15, Changes=10, ) self.schedulers = {} self.builders = [] self.workers = [] self._registerOldWorkerAttr("workers") self.change_sources = [] self.status = [] self.user_managers = [] self.revlink = default_revlink_matcher self.www = dict( port=None, plugins=dict(), auth=auth.NoAuth(), authz=authz.Authz(), avatar_methods=avatar.AvatarGravatar(), logfileName='http.log', ) self.services = {}
def test_addBuildsetForChanges_properties(self): props = properties.Properties(xxx="yyy") sched = self.makeScheduler(name='n', builderNames=['c']) self.db.insertTestData([ fakedb.Change(changeid=14, branch='default', revision='123:abc', repository='', project=''), ]) d = sched.addBuildsetForChanges(reason='downstream', changeids=[14], properties=props) def check((bsid, brids)): self.db.buildsets.assertBuildset( bsid, dict(reason='downstream', brids=brids, external_idstring=None, properties=[ ('scheduler', ('n', 'Scheduler')), ('xxx', ('yyy', 'TEST')), ]), dict(branch='default', revision='123:abc', repository='', project='', changeids=set([14]))) d.addCallback(check) return d
def test_addBuildsetForSourceStamp_properties(self): props = properties.Properties(xxx="yyy") sched = self.makeScheduler(name='n', builderNames=['b']) d = self.db.insertTestData([ fakedb.SourceStamp(id=91, branch='fixins', revision='abc', patchid=None, repository='r', project='p'), ]) d.addCallback(lambda _: sched.addBuildsetForSourceStamp( reason='whynot', ssid=91, properties=props)) def check((bsid, brids)): self.db.buildsets.assertBuildset( bsid, dict(reason='whynot', brids=brids, external_idstring=None, properties=[ ('scheduler', ('n', 'Scheduler')), ('xxx', ('yyy', 'TEST')), ]), dict(branch='fixins', revision='abc', repository='r', project='p')) d.addCallback(check) return d
def __init__(self, requests): self.requests = requests self.locks = [] # build a source stamp self.sources = requests[0].mergeSourceStampsWith(requests[1:]) self.reason = requests[0].mergeReasons(requests[1:]) self.currentStep = None self.workerEnvironment = {} self.buildid = None self.number = None self.executedSteps = [] self.stepnames = {} self.terminate = False self._acquiringLock = None self._builderid = None # overall results, may downgrade after each step self.results = SUCCESS self.properties = properties.Properties() # tracks execution during the build finish phase self._locks_released = False self._build_finished = False # tracks the config version for locks self.config_version = None
def __init__(self, d): for k, v in iteritems(d): setattr(self, k, v) self.properties = properties.Properties() for k, v in iteritems(d['properties']): self.properties.setProperty(k, v[0], v[1]) self.who = d['author']
def __init__(self, build_status_oracle, is_try_slave=False, gclient_solution_name=WEBRTC_SOLUTION_NAME, svn_url=WEBRTC_SVN_LOCATION, custom_deps_list=None, safesync_url=None): """Creates the abstract factory. Args: build_status_oracle: An instance of BuildStatusOracle which is used to keep track of our build state. is_try_slave: If this bot is a try slave. Needed since we're handling some things differently between normal slaves and try slaves. gclient_solution_name: The name of the solution used for gclient. svn_url: The Subversion URL for gclient to sync agains. custom_deps_list: Content to be put in the custom_deps entry of the .gclient file. The parameter must be a list of tuples with two strings in each: path and remote URL. safesync_url: If a LKGR URL shall be used for the gclient sync command. """ factory.BuildFactory.__init__(self) self.build_status_oracle = build_status_oracle self.is_try_slave = is_try_slave self.properties = properties.Properties() self.gyp_params = ['-Dfastbuild=1'] # No debug symbols = build speedup self.release = False self.path_joiner = PosixPathJoin # For GClient solution definition: self.gclient_solution_name = gclient_solution_name self.svn_url = svn_url self.custom_deps_list = custom_deps_list self.safesync_url = safesync_url
def startService(self): BaseUpstreamScheduler.startService(self) log.msg("starting l10n scheduler") if self.inipath is None: # testing, don't trigger tree builds return # trigger tree builds for our trees, clear() first cp = ConfigParser() cp.read(self.inipath) self.trees.clear() _ds = [] for tree in cp.sections(): # create a BuildSet, submit it to the BuildMaster props = properties.Properties() props.update({ 'tree': tree, 'l10nbuilds': self.inipath, }, "Scheduler") bs = buildset.BuildSet([self.treebuilder], SourceStamp(), properties=props) self.submitBuildSet(bs) _ds.append(bs.waitUntilFinished()) d = defer.DeferredList(_ds) d.addCallback(self.onTreesBuilt) self.waitOnTree = d
def _cbLoadedLocales(self, t, locales, reason, set_props): """ This is the callback function that gets called once the list of locales are ready to be processed Let's fill the queues per builder and submit the BuildSets per each locale """ log.msg("L10nMixin:: loaded locales' list") db = self.parent.db for locale in locales: # Ignore en-US. It appears in locales files but we do not repack it. if locale == "en-US": continue # Some locales should only be built on certain platforms, make sure to # obey those rules. if len(locales[locale]) > 0: if self.platform not in locales[locale]: continue props = properties.Properties() props.updateFromProperties(self.properties) if set_props: props.updateFromProperties(set_props) #I do not know exactly what to pass as the source parameter props.update(dict(locale=locale), "Scheduler") props.setProperty("en_revision", self.baseTag, "L10nMixin") props.setProperty("l10n_revision", self.baseTag, "L10nMixin") log.msg('Submitted ' + locale + ' locale') # let's submit the BuildSet for this locale # Create a sourcestamp ss = SourceStamp(branch=self.branch) ssid = db.get_sourcestampid(ss, t) self.create_buildset(ssid, reason, t, props=props)
def insertTestData(self, rows): for row in rows: if isinstance(row, Change): ch = self.ChangeInstance() ch.__dict__.update(dict( # TODO: this renaming sucks. number=row.changeid, who=row.author, files=[], comments=row.comments, isdir=row.is_dir, links=[], revision=row.revision, when=row.when_timestamp, branch=row.branch, category=row.category, revlink=row.revlink, properties=properties.Properties(), repository=row.repository, project=row.project)) self.changes[row.changeid] = ch elif isinstance(row, ChangeFile): ch = self.changes[row.changeid] ch.files.append(row.filename) elif isinstance(row, ChangeLink): ch = self.changes[row.changeid] ch.links.append(row.link) elif isinstance(row, ChangeProperty): ch = self.changes[row.changeid] n, vs = row.property_name, row.property_value v, s = json.loads(vs) ch.properties.setProperty(n, v, s)
def _make_br(cls, brid, brdict, master): buildrequest = cls() buildrequest.id = brid buildrequest.bsid = brdict['buildsetid'] buildrequest.buildername = brdict['buildername'] buildrequest.priority = brdict['priority'] dt = brdict['submitted_at'] buildrequest.submittedAt = dt and calendar.timegm(dt.utctimetuple()) buildrequest.master = master # fetch the buildset to get the reason wfd = defer.waitForDeferred( master.db.buildsets.getBuildset(brdict['buildsetid'])) yield wfd buildset = wfd.getResult() assert buildset # schema should guarantee this buildrequest.reason = buildset['reason'] # fetch the buildset properties, and convert to Properties wfd = defer.waitForDeferred( master.db.buildsets.getBuildsetProperties(brdict['buildsetid'])) yield wfd buildset_properties = wfd.getResult() pr = properties.Properties() for name, (value, source) in buildset_properties.iteritems(): pr.setProperty(name, value, source) buildrequest.properties = pr # fetch the sourcestamp dictionary wfd = defer.waitForDeferred( master.db.sourcestamps.getSourceStamps( buildset['sourcestampsetid'])) yield wfd sslist = wfd.getResult() assert len( sslist ) > 0, "Empty sourcestampset: db schema enforces set to exist but cannot enforce a non empty set" # and turn it into a SourceStamps buildrequest.sources = {} def store_source(source): buildrequest.sources[source.codebase] = source dlist = [] for ssdict in sslist: d = sourcestamp.SourceStamp.fromSsdict(master, ssdict) d.addCallback(store_source) dlist.append(d) dl = defer.gatherResults(dlist) wfd = defer.waitForDeferred(dl) yield wfd wfd.getResult() if buildrequest.sources: buildrequest.source = buildrequest.sources.values()[0] yield buildrequest # return value
def oldConstructor(cls, reason, source, builderName, props): buildrequest = cls() buildrequest.reason = reason buildrequest.source = source buildrequest.buildername = builderName buildrequest.properties = properties.Properties() if props: buildrequest.properties.updateFromProperties(props) return buildrequest
def test_trigger(self): sched = self.makeScheduler(codebases = {'cb':{'repository':'r'}}) # no subscription should be in place yet callbacks = self.master.getSubscriptionCallbacks() self.assertEqual(callbacks['buildset_completion'], None) # trigger the scheduler, exercising properties while we're at it set_props = properties.Properties() set_props.setProperty('pr', 'op', 'test') ss = {'revision':'myrev', 'branch':'br', 'project':'p', 'repository':'r', 'codebase':'cb' } d = sched.trigger({'cb': ss}, set_props=set_props) bsid = self.db.buildsets.assertBuildset('?', dict(external_idstring=None, properties=[ ('pr', ('op', 'test')), ('scheduler', ('n', 'Scheduler')), ], reason='Triggerable(n)', sourcestampsetid=100), {'cb': dict(branch='br', project='p', repository='r', codebase='cb', revision='myrev', sourcestampsetid=100) }) # set up a boolean so that we can know when the deferred fires self.fired = False def fired((result, brids)): self.assertEqual(result, 13) # 13 comes from the result below self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid)) self.fired = True d.addCallback(fired) # check that the scheduler has subscribed to buildset changes, but # not fired yet callbacks = self.master.getSubscriptionCallbacks() self.assertNotEqual(callbacks['buildset_completion'], None) self.assertFalse(self.fired) # pretend a non-matching buildset is complete callbacks['buildset_completion'](bsid+27, 3) # scheduler should not have reacted callbacks = self.master.getSubscriptionCallbacks() self.assertNotEqual(callbacks['buildset_completion'], None) self.assertFalse(self.fired) # pretend the matching buildset is complete callbacks['buildset_completion'](bsid, 13) # scheduler should have reacted callbacks = self.master.getSubscriptionCallbacks() self.assertEqual(callbacks['buildset_completion'], None) self.assertTrue(self.fired)
def __init__(self, build_factory_properties=None, steps=None, build_inherit_factory_properties=True): factory.BuildFactory.__init__(self, steps) self.properties = properties.Properties() if build_factory_properties: self.properties.update(build_factory_properties, 'BuildFactory') self._build_inherit_factory_properties = build_inherit_factory_properties
class FakeBuildStatus(properties.PropertiesMixin, mock.Mock): properties = properties.Properties() # work around http://code.google.com/p/mock/issues/detail?id=105 def _get_child_mock(self, **kw): return mock.Mock(**kw) def getInterestedUsers(self): return []
def __init__(self, props=None): self.build_status = FakeBuildStatus() self.builder = mock.Mock(name='build.builder') self.path_module = posixpath self.sources = {} if props is None: props = properties.Properties() props.build = self self.build_status.properties = props
def test_createEmail_extraHeaders_one_build(self): builds = [ FakeBuildStatus(name="build") ] builds[0].properties = properties.Properties() builds[0].setProperty('hhh','vvv') msgdict = create_msgdict() mn = MailNotifier('*****@*****.**', extraHeaders=dict(hhh='vvv')) # add some Unicode to detect encoding problems m = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me', SUCCESS, builds) txt = m.as_string() self.assertIn('hhh: vvv', txt)
def __init__(self, props=None, master=None): self.builder = fakemaster.FakeBuilder(master) self.workerforbuilder = mock.Mock( spec=workerforbuilder.WorkerForBuilder) self.workerforbuilder.worker = mock.Mock(spec=base.Worker) self.workerforbuilder.worker.info = properties.Properties() self.builder.config = config.BuilderConfig( name='bldr', workernames=['a'], factory=factory.BuildFactory()) self.path_module = posixpath self.buildid = 92 self.number = 13 self.workdir = 'build' self.locks = [] self.sources = {} if props is None: props = properties.Properties() props.build = self self.properties = props self.master = None self.config_version = 0
def _make_br(cls, brid, brdict, master): buildrequest = cls() buildrequest.id = brid buildrequest.bsid = brdict['buildsetid'] buildrequest.buildername = brdict['buildername'] buildrequest.priority = brdict['priority'] dt = brdict['submitted_at'] buildrequest.submittedAt = dt and calendar.timegm(dt.utctimetuple()) buildrequest.master = master # fetch the buildset to get the reason wfd = defer.waitForDeferred( master.db.buildsets.getBuildset(brdict['buildsetid'])) yield wfd buildset = wfd.getResult() assert buildset # schema should guarantee this buildrequest.reason = buildset['reason'] # fetch the buildset properties, and convert to Properties wfd = defer.waitForDeferred( master.db.buildsets.getBuildsetProperties(brdict['buildsetid'])) yield wfd buildset_properties = wfd.getResult() pr = properties.Properties() for name, (value, source) in buildset_properties.iteritems(): pr.setProperty(name, value, source) buildrequest.properties = pr # fetch the sourcestamp dictionary wfd = defer.waitForDeferred( master.db.sourcestamps.getSourceStamps( buildset['sourcestampsetid'])) yield wfd sslist = wfd.getResult() assert len( sslist ) > 0, "Empty sourcestampset: db schema enforces set to exist but cannot enforce a non empty set" # and turn it into a SourceStamp buildrequest.sources = [] for ssdict in sslist: wfd = defer.waitForDeferred( sourcestamp.SourceStamp.fromSsdict(master, ssdict)) yield wfd buildrequest.sources.append(wfd.getResult()) # support old interface where only one source could exist # TODO: remove and change all client objects that use this property if len(buildrequest.sources) > 0: buildrequest.source = buildrequest.sources[0] yield buildrequest # return value
def fromBrdict(cls, master, brdict): """ Construct a new L{BuildRequest} from a dictionary as returned by L{BuildRequestsConnectorComponent.getBuildRequest}. @param master: current build master @param brdict: build request dictionary @returns: L{BuildRequest}, via Deferred """ buildrequest = cls() buildrequest.id = brdict['brid'] buildrequest.bsid = brdict['buildsetid'] buildrequest.buildername = brdict['buildername'] buildrequest.priority = brdict['priority'] dt = brdict['submitted_at'] buildrequest.submittedAt = dt and calendar.timegm(dt.utctimetuple()) buildrequest.master = master # fetch the buildset to get the reason wfd = defer.waitForDeferred( master.db.buildsets.getBuildset(brdict['buildsetid'])) yield wfd buildset = wfd.getResult() assert buildset # schema should guarantee this buildrequest.reason = buildset['reason'] # fetch the buildset properties, and convert to Properties wfd = defer.waitForDeferred( master.db.buildsets.getBuildsetProperties(brdict['buildsetid'])) yield wfd buildset_properties = wfd.getResult() pr = properties.Properties() for name, (value, source) in buildset_properties.iteritems(): pr.setProperty(name, value, source) buildrequest.properties = pr # fetch the sourcestamp dictionary wfd = defer.waitForDeferred( master.db.sourcestamps.getSourceStamp(buildset['sourcestampid'])) yield wfd ssdict = wfd.getResult() assert ssdict # db schema should enforce this anyway # and turn it into a SourceStamp wfd = defer.waitForDeferred( sourcestamp.SourceStamp.fromSsdict(master, ssdict)) yield wfd buildrequest.source = wfd.getResult() yield buildrequest # return value
def __init__(self, props=None): self.build_status = FakeBuildStatus() self.builder = mock.Mock(name='build.builder') self.builder.config = config.BuilderConfig( name='bldr', slavenames=['a'], factory=factory.BuildFactory()) self.path_module = posixpath self.workdir = 'build' self.sources = {} if props is None: props = properties.Properties() props.build = self self.build_status.properties = props
def __init__(self, parent, number): """ @type parent: L{BuilderStatus} @type number: int """ assert interfaces.IBuilderStatus(parent) self.builder = parent self.number = number self.watchers = [] self.updates = {} self.finishedWatchers = [] self.steps = [] self.testResults = {} self.properties = properties.Properties()
def test_setupProperties(self): props = properties.Properties() props.setProperty('foo', 1, 'Scheduler') props.setProperty('bar', 'bleh', 'Change') props.setProperty('omg', 'wtf', 'Builder') wrkr = yield self.createWorker( 'bot', 'passwd', defaultProperties={'bar': 'onoes', 'cuckoo': 42}) wrkr.setupProperties(props) self.assertEquals(props.getProperty('bar'), 'bleh') self.assertEquals(props.getProperty('cuckoo'), 42)
def __init__(self): # local import to avoid circular imports from buildbot.process import properties # default values for all attributes # global self.title = 'Buildbot' self.titleURL = 'http://buildbot.net' self.buildbotURL = 'http://localhost:8080/' self.changeHorizon = None self.eventHorizon = 50 self.logHorizon = None self.buildHorizon = None self.logCompressionLimit = 4 * 1024 self.logCompressionMethod = 'bz2' self.logMaxTailSize = None self.logMaxSize = None self.properties = properties.Properties() self.mergeRequests = None self.codebaseGenerator = None self.prioritizeBuilders = None self.slavePortnum = None self.multiMaster = False self.debugPassword = None self.manhole = None self.protocols = {} self.validation = dict( branch=re.compile(r'^[\w.+/~-]*$'), revision=re.compile(r'^[ \w\.\-\/]*$'), property_name=re.compile(r'^[\w\.\-\/\~:]*$'), property_value=re.compile(r'^[\w\.\-\/\~:]*$'), ) self.db = dict( db_url='sqlite:///state.sqlite', db_poll_interval=None, ) self.metrics = None self.caches = dict( Builds=15, Changes=10, ) self.schedulers = {} self.builders = [] self.slaves = [] self.change_sources = [] self.status = [] self.user_managers = [] self.revlink = default_revlink_matcher
def __init__(self, props=None, master=None): self.build_status = FakeBuildStatus() self.builder = fakemaster.FakeBuilderStatus(master) self.builder.config = config.BuilderConfig( name='bldr', slavenames=['a'], factory=factory.BuildFactory()) self.path_module = posixpath self.buildid = 92 self.number = 13 self.workdir = 'build' self.sources = {} if props is None: props = properties.Properties() props.build = self self.build_status.properties = props