def test_passes_exception(self): with patchForDelay(__name__ + '.fun_to_patch_exception') as delay: d = fun_to_patch_exception() self.assertEqual(len(delay), 1) delay.fire() f = self.failureResultOf(d) f.check(TestException)
def test_sever_connection_before_ping_then_timeout_get_requeued(self): """ If a latent worker connects, but its connection is severed without notification in the TCP layer, we successfully wait until TCP times out and requeue the build. """ controller, master, builder_id = \ yield self.create_single_worker_config( controller_kwargs=dict(build_wait_timeout=1)) bsid, brids = yield self.createBuildrequest(master, [builder_id]) # sever connection just before ping() with patchForDelay('buildbot.process.workerforbuilder.AbstractWorkerForBuilder.ping') as delay: yield controller.start_instance(True) controller.sever_connection() delay.fire() # lose connection after TCP times out self.reactor.advance(100) yield controller.disconnect_worker() yield self.assertBuildResults(1, RETRY) # the worker will be put into quarantine self.reactor.advance(controller.worker.quarantine_initial_timeout) yield controller.stop_instance(True) yield controller.start_instance(True) yield self.assertBuildResults(2, SUCCESS) self.reactor.advance(1) yield controller.stop_instance(True) self.flushLoggedErrors(pb.PBConnectionLost)
def test_passes_arguments(self): with patchForDelay(__name__ + '.fun_to_patch') as delay: d = fun_to_patch('arg', kw='kwarg') self.assertEqual(len(delay), 1) delay.fire() args = self.successResultOf(d) self.assertEqual(args, (('arg', ), {'kw': 'kwarg'}))
def test_passes_arguments(self): with patchForDelay(__name__ + '.fun_to_patch') as delay: d = fun_to_patch('arg', kw='kwarg') self.assertEqual(len(delay), 1) delay.fire() args = self.successResultOf(d) self.assertEqual(args, (('arg',), {'kw': 'kwarg'}))
def test_auto_fires_unfired_delay_exception(self): try: with patchForDelay(__name__ + '.fun_to_patch') as delay: d = fun_to_patch() self.assertEqual(len(delay), 1) self.assertFalse(d.called) raise TestException() except TestException: pass self.assertTrue(d.called)
def test_patches_within_context(self): d = fun_to_patch() self.assertTrue(d.called) with patchForDelay(__name__ + '.fun_to_patch') as delay: d = fun_to_patch() self.assertEqual(len(delay), 1) self.assertFalse(d.called) delay.fire() self.assertEqual(len(delay), 0) self.assertTrue(d.called) d = fun_to_patch() self.assertTrue(d.called)
def test_substantiation_during_stop_instance_canStartBuild_race(self): ''' If build attempts substantiation after the latent worker detaches, but stop_instance() is not completed yet, then we should successfully complete substantiation without causing an erroneous cancellation. The above sequence of events was possible even if canStartBuild checked for a in-progress insubstantiation, as if the build is scheduled before insubstantiation, its start could be delayed until when stop_instance() is in progress. ''' controller, master, builder_ids = \ yield self.create_single_worker_two_builder_config( controller_kwargs=dict(build_wait_timeout=1)) # Trigger a single buildrequest yield self.createBuildrequest(master, [builder_ids[0]]) self.assertEqual(True, controller.starting) # start instance controller.start_instance(True) yield self.assertBuildResults(1, SUCCESS) with patchForDelay( 'buildbot.process.builder.Builder.maybeStartBuild') as delay: # create a build request which will result in a build, but it won't # attempt to substantiate until after stop_instance() is in progress yield self.createBuildrequest(master, [builder_ids[1]]) self.assertEqual(len(delay), 1) self.reactor.advance(1) self.assertTrue(controller.stopping) delay.fire() yield controller.stop_instance(True) self.assertTrue(controller.starting) yield controller.start_instance(True) yield self.assertBuildResults(2, SUCCESS) self.reactor.advance(1) yield controller.stop_instance(True)
def test_substantiation_during_stop_instance_canStartBuild_race(self): ''' If build attempts substantiation after the latent worker detaches, but stop_instance() is not completed yet, then we should successfully complete substantiation without causing an erroneous cancellation. The above sequence of events was possible even if canStartBuild checked for a in-progress insubstantiation, as if the build is scheduled before insubstantiation, its start could be delayed until when stop_instance() is in progress. ''' controller, master, builder_ids = \ yield self.create_single_worker_two_builder_config( controller_kwargs=dict(build_wait_timeout=1)) # Trigger a single buildrequest yield self.createBuildrequest(master, [builder_ids[0]]) self.assertEqual(True, controller.starting) # start instance controller.start_instance(True) yield self.assertBuildResults(1, SUCCESS) with patchForDelay('buildbot.process.builder.Builder.maybeStartBuild') as delay: # create a build request which will result in a build, but it won't # attempt to substantiate until after stop_instance() is in progress yield self.createBuildrequest(master, [builder_ids[1]]) self.assertEqual(len(delay), 1) self.reactor.advance(1) self.assertTrue(controller.stopping) delay.fire() yield controller.stop_instance(True) self.assertTrue(controller.starting) yield controller.start_instance(True) yield self.assertBuildResults(2, SUCCESS) self.reactor.advance(1) yield controller.stop_instance(True)
def test_sever_connection_during_insubstantiation_and_buildrequest(self): """ If latent worker connection is severed without notification in the TCP layer, we successfully wait until TCP times out, insubstantiate and can substantiate after that. In this the subsequent build request is created during insubstantiation """ controller, master, builder_id = \ yield self.create_single_worker_config( controller_kwargs=dict(build_wait_timeout=1)) yield self.createBuildrequest(master, [builder_id]) controller.start_instance(True) yield self.assertBuildResults(1, SUCCESS) # sever connection just before insubstantiation and lose it after TCP # times out with patchForDelay( 'buildbot.worker.base.AbstractWorker.disconnect') as delay: self.reactor.advance(1) self.assertTrue(controller.stopping) yield self.createBuildrequest(master, [builder_id]) controller.sever_connection() delay.fire() yield controller.stop_instance(True) self.reactor.advance(100) yield controller.disconnect_worker() # verify the previously created build successfully completes yield controller.start_instance(True) yield self.assertBuildResults(1, SUCCESS) self.reactor.advance(1) yield controller.stop_instance(True) self.flushLoggedErrors(pb.PBConnectionLost)
def test_sever_connection_during_insubstantiation_and_buildrequest(self): """ If latent worker connection is severed without notification in the TCP layer, we successfully wait until TCP times out, insubstantiate and can substantiate after that. In this the subsequent build request is created during insubstantiation """ controller, master, builder_id = \ yield self.create_single_worker_config( controller_kwargs=dict(build_wait_timeout=1)) yield self.createBuildrequest(master, [builder_id]) controller.start_instance(True) yield self.assertBuildResults(1, SUCCESS) # sever connection just before insubstantiation and lose it after TCP # times out with patchForDelay('buildbot.worker.base.AbstractWorker.disconnect') as delay: self.reactor.advance(1) self.assertTrue(controller.stopping) yield self.createBuildrequest(master, [builder_id]) controller.sever_connection() delay.fire() yield controller.stop_instance(True) self.reactor.advance(100) yield controller.disconnect_worker() # verify the previously created build successfully completes yield controller.start_instance(True) yield self.assertBuildResults(1, SUCCESS) self.reactor.advance(1) yield controller.stop_instance(True) self.flushLoggedErrors(pb.PBConnectionLost)
def test_raises_not_callable(self): with self.assertRaises(Exception): with patchForDelay(__name__ + '.non_callable'): pass
def test_auto_fires_unfired_delay(self): with patchForDelay(__name__ + '.fun_to_patch') as delay: d = fun_to_patch() self.assertEqual(len(delay), 1) self.assertFalse(d.called) self.assertTrue(d.called)
def test_raises_not_found(self): with self.assertRaises(Exception): with patchForDelay(__name__ + '.notfound'): pass