예제 #1
0
    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()
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
파일: tasks.py 프로젝트: zyh1234/bk-sops
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)
예제 #6
0
파일: tasks.py 프로젝트: zyh1234/bk-sops
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)
예제 #7
0
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)
예제 #8
0
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)
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
    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)