def test_worker_multiple_substantiations_succeed(self): """ If multiple builders trigger try to substantiate a worker at the same time, if the substantiation succeeds then all of the builds proceeed. """ controller = LatentController('local') config_dict = { 'builders': [ BuilderConfig(name="testy-1", workernames=["local"], factory=BuildFactory(), ), BuilderConfig(name="testy-2", workernames=["local"], factory=BuildFactory(), ), ], 'workers': [controller.worker], 'protocols': {'null': {}}, 'multiMaster': True, } master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_ids = [ self.successResultOf(master.data.updates.findBuilderId('testy-1')), self.successResultOf(master.data.updates.findBuilderId('testy-2')), ] finished_builds = [] self.successResultOf(master.mq.startConsuming( lambda key, build: finished_builds.append(build), ('builds', None, 'finished'))) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=builder_ids, sourcestamps=[ {'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': ''}, ], ) ) # The worker fails to substantiate. controller.start_instance(True) local_workdir = FilePath(self.mktemp()) local_workdir.createDirectory() controller.connect_worker(local_workdir) # We check that there were two builds that finished, and # that they both finished with success self.assertEqual([build['results'] for build in finished_builds], [SUCCESS] * 2)
def test_latent_max_builds(self): """ If max_builds is set, only one build is started on a latent worker at a time. """ controller = LatentController( 'local', max_builds=1, ) step_controller = StepController() config_dict = { 'builders': [ BuilderConfig(name="testy-1", workernames=["local"], factory=BuildFactory([step_controller]), ), BuilderConfig(name="testy-2", workernames=["local"], factory=BuildFactory([step_controller]), ), ], 'workers': [controller.worker], 'protocols': {'null': {}}, 'multiMaster': True, } self.master = master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_ids = [ self.successResultOf(master.data.updates.findBuilderId('testy-1')), self.successResultOf(master.data.updates.findBuilderId('testy-2')), ] started_builds = [] self.successResultOf(master.mq.startConsuming( lambda key, build: started_builds.append(build), ('builds', None, 'new'))) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=builder_ids, sourcestamps=[ {'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': ''}, ], ) ) # The worker fails to substantiate. controller.start_instance(True) controller.connect_worker(self) self.assertEqual(len(started_builds), 1) controller.auto_stop(True)
def test_refused_substantiations_get_requeued(self): """ If a latent worker refuses to substantiate, the build request becomes unclaimed. """ controller = LatentController('local') config_dict = { 'builders': [ BuilderConfig( name="testy", workernames=["local"], factory=BuildFactory(), ), ], 'workers': [controller.worker], 'protocols': { 'null': {} }, # Disable checks about missing scheduler. 'multiMaster': True, } master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_id = self.successResultOf( master.data.updates.findBuilderId('testy')) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=[builder_id], sourcestamps=[ { 'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': '' }, ], )) unclaimed_build_requests = [] self.successResultOf( master.mq.startConsuming( lambda key, request: unclaimed_build_requests.append(request), ('buildrequests', None, 'unclaimed'))) # Indicate that the worker can't start an instance. controller.start_instance(False) # When the substantiation fails, the buildrequest becomes unclaimed. self.assertEqual( set(brids), set([req['buildrequestid'] for req in unclaimed_build_requests]), )
def test_latent_max_builds(self): """ If max_builds is set, only one build is started on a latent worker at a time. """ controller = LatentController(self, 'local', max_builds=1) step_controller = StepController() config_dict = { 'builders': [ BuilderConfig(name="testy-1", workernames=["local"], factory=BuildFactory([step_controller]), ), BuilderConfig(name="testy-2", workernames=["local"], factory=BuildFactory([step_controller]), ), ], 'workers': [controller.worker], 'protocols': {'null': {}}, 'multiMaster': True, } self.master = master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_ids = [ self.successResultOf(master.data.updates.findBuilderId('testy-1')), self.successResultOf(master.data.updates.findBuilderId('testy-2')), ] started_builds = [] self.successResultOf(master.mq.startConsuming( lambda key, build: started_builds.append(build), ('builds', None, 'new'))) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=builder_ids, sourcestamps=[ {'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': ''}, ], ) ) # The worker fails to substantiate. controller.start_instance(True) controller.connect_worker() self.assertEqual(len(started_builds), 1) controller.auto_stop(True)
def test_worker_accepts_builds_after_failure(self): """ If a latent worker fails to substantiate, the worker is still able to accept jobs. """ controller = LatentController('local') config_dict = { 'builders': [ BuilderConfig(name="testy", workernames=["local"], factory=BuildFactory(), ), ], 'workers': [controller.worker], 'protocols': {'null': {}}, # Disable checks about missing scheduler. 'multiMaster': True, } master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_id = self.successResultOf( master.data.updates.findBuilderId('testy')) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=[builder_id], sourcestamps=[ {'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': ''}, ], ) ) unclaimed_build_requests = [] self.successResultOf(master.mq.startConsuming( lambda key, request: unclaimed_build_requests.append(request), ('buildrequests', None, 'unclaimed'))) # The worker fails to substantiate. controller.start_instance( Failure(TestException("substantiation failed"))) # Flush the errors logged by the failure. self.flushLoggedErrors(TestException) # If the worker started again after the failure, then the retry logic will have # already kicked in to start a new build on this (the only) worker. We check that # a new instance was requested, which indicates that the worker # accepted the build. self.assertEqual(controller.started, True)
def test_failed_substantiations_get_requeued(self): """ If a latent worker fails to substantiate, the build request becomes unclaimed. """ controller = LatentController('local') config_dict = { 'builders': [ BuilderConfig(name="testy", workernames=["local"], factory=BuildFactory(), ), ], 'workers': [controller.worker], 'protocols': {'null': {}}, # Disable checks about missing scheduler. 'multiMaster': True, } master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_id = self.successResultOf( master.data.updates.findBuilderId('testy')) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=[builder_id], sourcestamps=[ {'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': ''}, ], ) ) unclaimed_build_requests = [] self.successResultOf(master.mq.startConsuming( lambda key, request: unclaimed_build_requests.append(request), ('buildrequests', None, 'unclaimed'))) # The worker fails to substantiate. controller.start_instance( Failure(TestException("substantiation failed"))) # Flush the errors logged by the failure. self.flushLoggedErrors(TestException) # When the substantiation fails, the buildrequest becomes unclaimed. self.assertEqual( set(brids), set([req['buildrequestid'] for req in unclaimed_build_requests]), )
def test_local_worker_max_builds(self): """ If max_builds is set, only one build is started on a worker at a time. """ step_controller = StepController() config_dict = { 'builders': [ BuilderConfig( name="testy-1", workernames=["local"], factory=BuildFactory([step_controller]), ), BuilderConfig( name="testy-2", workernames=["local"], factory=BuildFactory([step_controller]), ), ], 'workers': [LocalWorker('local', max_builds=1)], 'protocols': { 'null': {} }, 'multiMaster': True, } self.master = master = yield getMaster(self, self.reactor, config_dict) builder_ids = [ (yield master.data.updates.findBuilderId('testy-1')), (yield master.data.updates.findBuilderId('testy-2')), ] started_builds = [] yield master.mq.startConsuming( lambda key, build: started_builds.append(build), ('builds', None, 'new')) # Trigger a buildrequest bsid, brids = yield master.data.updates.addBuildset( waited_for=False, builderids=builder_ids, sourcestamps=[ { 'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': '' }, ], ) self.assertEqual(len(started_builds), 1)
def test_latent_workers_start_in_parallel(self): """ If there are two latent workers configured, and two build requests for them, both workers will start substantiating conccurently. """ controllers = [ LatentController('local1'), LatentController('local2'), ] config_dict = { 'builders': [ BuilderConfig(name="testy", workernames=["local1", "local2"], factory=BuildFactory()), ], 'workers': [controller.worker for controller in controllers], 'protocols': { 'null': {} }, 'multiMaster': True, } master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_id = self.successResultOf( master.data.updates.findBuilderId('testy')) # Request two builds. for i in range(2): bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=[builder_id], sourcestamps=[ { 'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': '' }, ], )) # Check that both workers were requested to start. self.assertEqual(controllers[0].started, True) self.assertEqual(controllers[1].started, True)
def test_latent_workers_start_in_parallel(self): """ If there are two latent workers configured, and two build requests for them, both workers will start substantiating conccurently. """ controllers = [ LatentController('local1'), LatentController('local2'), ] config_dict = { 'builders': [ BuilderConfig(name="testy", workernames=["local1", "local2"], factory=BuildFactory()), ], 'workers': [controller.worker for controller in controllers], 'protocols': {'null': {}}, 'multiMaster': True, } master = self.successResultOf(getMaster(self, self.reactor, config_dict)) builder_id = self.successResultOf(master.data.updates.findBuilderId('testy')) # Request two builds. for i in range(2): bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=[builder_id], sourcestamps=[ {'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': ''}, ], ) ) # Check that both workers were requested to start. self.assertEqual(controllers[0].started, True) self.assertEqual(controllers[1].started, True)
def getMaster(self, config_dict): self.master = master = self.successResultOf( getMaster(self, self.reactor, config_dict)) return master
def getMaster(self, config_dict): self.master = master = yield getMaster(self, self.reactor, config_dict) defer.returnValue(master)
def getMaster(self, config_dict): master = self.successResultOf(getMaster(self, self.reactor, config_dict)) return master
def getMaster(self, config_dict): self.master = master = yield getMaster(self, self.reactor, config_dict) return master
def test_worker_multiple_substantiations_succeed(self): """ If multiple builders trigger try to substantiate a worker at the same time, if the substantiation succeeds then all of the builds proceeed. """ controller = LatentController('local') config_dict = { 'builders': [ BuilderConfig( name="testy-1", workernames=["local"], factory=BuildFactory(), ), BuilderConfig( name="testy-2", workernames=["local"], factory=BuildFactory(), ), ], 'workers': [controller.worker], 'protocols': { 'null': {} }, 'multiMaster': True, } master = self.successResultOf( getMaster(self, self.reactor, config_dict)) builder_ids = [ self.successResultOf(master.data.updates.findBuilderId('testy-1')), self.successResultOf(master.data.updates.findBuilderId('testy-2')), ] finished_builds = [] self.successResultOf( master.mq.startConsuming( lambda key, build: finished_builds.append(build), ('builds', None, 'finished'))) # Trigger a buildrequest bsid, brids = self.successResultOf( master.data.updates.addBuildset( waited_for=False, builderids=builder_ids, sourcestamps=[ { 'codebase': '', 'repository': '', 'branch': None, 'revision': None, 'project': '' }, ], )) # The worker fails to substantiate. controller.start_instance(True) local_workdir = FilePath(self.mktemp()) local_workdir.createDirectory() controller.connect_worker(local_workdir) # We check that there were two builds that finished, and # that they both finished with success self.assertEqual([build['results'] for build in finished_builds], [SUCCESS] * 2)