def test_run_loop__fail_with_node_reach_run_limit(self): with patch(PIPELINE_SETTING_RERUN_MAX_LIMIT, 10): current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(False, [])) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.subproc_sleep_check.assert_called() FunctionSwitch.objects.is_frozen.assert_called_once() process.freeze.assert_not_called() Status.objects.transit.assert_called_with( id=current_node.id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)) Status.objects.fail.assert_called_once_with( current_node, 'rerun times exceed max limit: 10') process.sleep.assert_called_once_with(adjust_status=True) process.refresh_current_node.assert_not_called()
def dispatch(child_id): process = PipelineProcess.objects.get(id=child_id) if not process.is_alive: logger.info('process(%s) is not alive, mission cancel.' % child_id) return runtime.run_loop(process)
def process_unfreeze(process_id): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.info('process(%s) is not alive, mission cancel.' % process_id) return runtime.run_loop(process)
def wake_from_schedule(process_id, service_act_id): process = PipelineProcess.objects.get(id=process_id) process.wake_up() service_act = process.top_pipeline.node(service_act_id) process.current_node_id = service_act.next().id runtime.run_loop(process)
def process_wake_up(process_id, current_node_id=None, call_from_child=False): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.warning('process(%s) is not alive, mission cancel.' % process_id) return pipeline_id = process.root_pipeline.id if not call_from_child: # success_when_unchanged to deal with parallel wake up action_result = Status.objects.transit(pipeline_id, to_state=states.RUNNING, is_pipeline=True, unchanged_pass=True) if not action_result.result: # BLOCKED is a tolerant running state if action_result.extra.state != states.BLOCKED: logger.warning('can not start pipeline(%s), message: %s' % (pipeline_id, action_result.message)) return process.wake_up() if current_node_id: process.current_node_id = current_node_id runtime.run_loop(process)
def wake_up(process_id): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.warning('process(%s) is not alive, mission cancel.' % process_id) return process.wake_up() runtime.run_loop(process)
def start(process_id): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.info('process(%s) is not alive, mission cancel.' % process_id) return pipeline_id = process.root_pipeline.id # try to run if not Status.objects.transit( pipeline_id, states.RUNNING, is_pipeline=True, start=True): logger.info( 'can not start pipeline(%s), perhaps state of the pipeline has been changed' % pipeline_id) return NodeRelationship.objects.build_relationship(pipeline_id, pipeline_id) runtime.run_loop(process)
def start(process_id): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.info('process(%s) is not alive, mission cancel.' % process_id) return pipeline_id = process.root_pipeline.id # try to run action_result = Status.objects.transit(pipeline_id, states.RUNNING, is_pipeline=True, start=True) if not action_result.result: logger.info('can not start pipeline(%s), message: %s' % (pipeline_id, action_result.message)) return NodeRelationship.objects.build_relationship(pipeline_id, pipeline_id) runtime.run_loop(process)
def process_wake_up(process_id, current_node_id=None, call_from_child=False): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.info('process(%s) is not alive, mission cancel.' % process_id) return pipeline_id = process.root_pipeline.id if not call_from_child: if not Status.objects.transit( pipeline_id, to_state=states.RUNNING, is_pipeline=True): logger.info( 'can not start pipeline(%s), perhaps state of the pipeline has been changed' % pipeline_id) return else: process.sync_with_children() process.wake_up() if current_node_id: process.current_node_id = current_node_id runtime.run_loop(process)
def process_wake_up(process_id, current_node_id=None, call_from_child=False): process = PipelineProcess.objects.get(id=process_id) if not process.is_alive: logger.info('process(%s) is not alive, mission cancel.' % process_id) return pipeline_id = process.root_pipeline.id if not call_from_child: action_result = Status.objects.transit(pipeline_id, to_state=states.RUNNING, is_pipeline=True, unchanged_pass=True) if not action_result.result: logger.info('can not start pipeline(%s), message: %s' % (pipeline_id, action_result.message)) return process.wake_up() if current_node_id: process.current_node_id = current_node_id runtime.run_loop(process)
def test_run_loop(self): # 1. test child meet destination destination_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=destination_node), destination_id=destination_node.id, current_node_id=destination_node.id) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_called_with( destination_node.id) process.root_sleep_check.assert_not_called() process.sleep.assert_not_called() process.subproc_sleep_check.assert_not_called() FunctionSwitch.objects.is_frozen.assert_not_called() process.freeze.assert_not_called() Status.objects.transit.assert_not_called() process.refresh_current_node.assert_not_called() NodeRelationship.objects.build_relationship.assert_not_called() self.assertEqual(process.current_node_id, destination_node.id) # 2. test root sleep check return true、 # 2.1. root pipeline is revoke current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(True, states.REVOKED)) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.sleep.assert_called_once() process.sleep.assert_called_with(do_not_save=True) process.subproc_sleep_check.assert_not_called() FunctionSwitch.objects.is_frozen.assert_not_called() process.freeze.assert_not_called() Status.objects.transit.assert_not_called() process.refresh_current_node.assert_not_called() NodeRelationship.objects.build_relationship.assert_not_called() self.assertEqual(process.current_node_id, current_node.id) # 2.2. root pipeline is not revoke for state in states.SLEEP_STATES.difference({states.REVOKED}): current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(True, state)) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.sleep.assert_called_once_with(do_not_save=False) process.subproc_sleep_check.assert_not_called() FunctionSwitch.objects.is_frozen.assert_not_called() process.freeze.assert_not_called() Status.objects.transit.assert_not_called() process.refresh_current_node.assert_not_called() NodeRelationship.objects.build_relationship.assert_not_called() self.assertEqual(process.current_node_id, current_node.id) # 3. test sub process sleep check return true current_node = IdentifyObject() subproc_above = uniqid() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(True, subproc_above)) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.subproc_sleep_check.assert_called() process.sleep.assert_called_once_with(adjust_status=True, adjust_scope=subproc_above) FunctionSwitch.objects.is_frozen.assert_not_called() process.freeze.assert_not_called() Status.objects.transit.assert_not_called() process.refresh_current_node.assert_not_called() NodeRelationship.objects.build_relationship.assert_not_called() self.assertEqual(process.current_node_id, current_node.id) # 4. test engine is frozen with patch(PIPELINE_ENGINE_IS_FROZEN, MagicMock(return_value=True)): current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(False, [])) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.subproc_sleep_check.assert_called() process.sleep.assert_not_called() FunctionSwitch.objects.is_frozen.assert_called_once() process.freeze.assert_called_once() Status.objects.transit.assert_not_called() process.refresh_current_node.assert_not_called() NodeRelationship.objects.build_relationship.assert_not_called() self.assertEqual(process.current_node_id, current_node.id) FunctionSwitch.objects.is_frozen.reset_mock() # 5. test transit fail with patch(PIPELINE_STATUS_TRANSIT, MagicMock(return_value=MockActionResult(result=False))): current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(False, [])) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.subproc_sleep_check.assert_called() FunctionSwitch.objects.is_frozen.assert_called_once() process.freeze.assert_not_called() Status.objects.transit.assert_called_with( id=current_node.id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)) process.sleep.assert_called_once_with(adjust_status=True) process.refresh_current_node.assert_not_called() NodeRelationship.objects.build_relationship.assert_not_called() self.assertEqual(process.current_node_id, current_node.id) FunctionSwitch.objects.is_frozen.reset_mock() Status.objects.transit.reset_mock() # 6. test normal hdl = MagicMock(return_value=MockHandlerResult(should_return=True, should_sleep=False)) mock_handlers = {IdentifyObject().__class__: hdl} with patch('pipeline.engine.core.runtime.FLOW_NODE_HANDLERS', mock_handlers): # 6.1. test should return current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(False, [])) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.subproc_sleep_check.assert_called() FunctionSwitch.objects.is_frozen.assert_called_once() process.freeze.assert_not_called() Status.objects.transit.assert_called_with( id=current_node.id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)) process.refresh_current_node.assert_called_once_with( current_node.id) NodeRelationship.objects.build_relationship.assert_called_once_with( process.top_pipeline.id, current_node.id) hdl.assert_called_once_with(process, current_node, None) process.sleep.assert_not_called() self.assertEqual(process.current_node_id, current_node.id) FunctionSwitch.objects.is_frozen.reset_mock() Status.objects.transit.reset_mock() NodeRelationship.objects.build_relationship.reset_mock() hdl.reset_mock() # 6.2. test should sleep for should_return in (False, True): hdl.return_value = MockHandlerResult( should_return=should_return, should_sleep=True) current_node = IdentifyObject() process = MockPipelineProcess( top_pipeline=PipelineObject(node=current_node), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock( return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(False, [])) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_called() process.subproc_sleep_check.assert_called() FunctionSwitch.objects.is_frozen.assert_called_once() process.freeze.assert_not_called() Status.objects.transit.assert_called_with( id=current_node.id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)) process.refresh_current_node.assert_called_once_with( current_node.id) NodeRelationship.objects.build_relationship.assert_called_once_with( process.top_pipeline.id, current_node.id) hdl.assert_called_once_with(process, current_node, None) process.sleep.assert_called_once_with(adjust_status=True) self.assertEqual(process.current_node_id, current_node.id) FunctionSwitch.objects.is_frozen.reset_mock() Status.objects.transit.reset_mock() NodeRelationship.objects.build_relationship.reset_mock() hdl.reset_mock() # 6.3. test execute 3 node and return nodes = [IdentifyObject(), IdentifyObject(), IdentifyObject()] hdl.return_value = None hdl.side_effect = [ MockHandlerResult(should_return=False, should_sleep=False, next_node=nodes[0]), MockHandlerResult(should_return=False, should_sleep=False, next_node=nodes[1]), MockHandlerResult(should_return=True, should_sleep=True, next_node=nodes[2]) ] current_node = IdentifyObject() process = MockPipelineProcess(top_pipeline=PipelineObject( nodes={ current_node.id: current_node, nodes[0].id: nodes[0], nodes[1].id: nodes[1], nodes[2].id: nodes[2] }), destination_id=uniqid(), current_node_id=current_node.id) process.root_sleep_check = MagicMock(return_value=(False, states.RUNNING)) process.subproc_sleep_check = MagicMock(return_value=(False, [])) runtime.run_loop(process) process.destroy_and_wake_up_parent.assert_not_called() process.root_sleep_check.assert_has_calls( [mock.call(), mock.call(), mock.call()]) process.subproc_sleep_check.assert_has_calls( [mock.call(), mock.call(), mock.call()]) FunctionSwitch.objects.is_frozen.assert_has_calls( [mock.call(), mock.call(), mock.call()]) process.freeze.assert_not_called() Status.objects.transit.assert_has_calls([ mock.call(id=current_node.id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)), mock.call(id=nodes[0].id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)), mock.call(id=nodes[1].id, to_state=states.RUNNING, start=True, name=str(current_node.__class__)) ]) process.refresh_current_node.assert_has_calls([ mock.call(current_node.id), mock.call(nodes[0].id), mock.call(nodes[1].id) ]) NodeRelationship.objects.build_relationship.assert_has_calls([ mock.call(process.top_pipeline.id, current_node.id), mock.call(process.top_pipeline.id, nodes[0].id), mock.call(process.top_pipeline.id, nodes[1].id) ]) hdl.assert_has_calls([ mock.call(process, current_node, None), mock.call(process, nodes[0], None), mock.call(process, nodes[1], None) ]) process.sleep.assert_called_once_with(adjust_status=True) self.assertEqual(process.current_node_id, nodes[1].id)