Exemple #1
0
    def _test_single_node(self):

        yawf.clear_polices()

        class FooPolicy(yawf.Policy):
            pass

        yawf.register_policy(FooPolicy)

        _NodeModel = yawf.WorkFlowEngine.instance.node_model

        with patch.object(FooPolicy, "__call__") as mock_method1:
            with patch.object(FooPolicy, "on_approved") as mock_method2:
                with patch.object(FooPolicy, "after_executed") as mock_method3:
                    work_flow = yawf.new_work_flow(
                        'foo work flow',
                        lambda work_flow: _NodeModel(work_flow=work_flow,
                                                     name='foo task',
                                                     policy_name='FooPolicy'))
                    work_flow.start()
                    mock_method1.assert_called_once_with()
                    mock_method2.assert_called_once_with()
                    mock_method3.assert_called_once_with()
                    assert work_flow.status == yawf.constants.WORK_FLOW_EXECUTED

        with patch.object(FooPolicy, "__call__") as mock_method1:
            with patch.object(FooPolicy, "on_approved") as mock_method2:
                with patch.object(FooPolicy, "after_executed") as mock_method3:
                    with patch.object(FooPolicy, "on_refused") as mock_method4:
                        work_flow = yawf.new_work_flow(
                            'foo work flow', lambda work_flow: _NodeModel(
                                work_flow=work_flow,
                                name='foo task',
                                policy_name='FooPolicy'))
                        work_flow.root_node.refuse()
                        assert mock_method1.call_count == 0
                        assert mock_method2.call_count == 0
                        assert mock_method3.call_count == 0
                        mock_method4.assert_called_once_with(True)
                        assert work_flow.status == yawf.constants.WORK_FLOW_REFUSED

        work_flow = yawf.new_work_flow(
            'foo work flow',
            lambda work_flow: yawf.WorkFlowEngine.instance.node_model(
                work_flow=work_flow, name='foo task', policy_name='FooPolicy'))
        work_flow.start()
        raises(yawf.exceptions.NodeAlreadyApproved,
               work_flow.root_node.approve)
Exemple #2
0
def node_view():
    class _Form(Form):
        destination = TextField('destination', validators=[DataRequired()])
        contact = TextField('contact', validators=[DataRequired()])

    form = _Form()

    if form.validate_on_submit():
        work_flow = yawf.new_work_flow(
            'travel application', lambda work_flow: models.Node(
                name='Submit Travel Application',
                policy_name="Travel",
                work_flow=work_flow,
                handler_group=models.Group.query.filter(models.Group.name ==
                                                        'Customers').one()),
            lambda work_flow: do_commit(
                models.Application(username=current_user.username,
                                   destination=form.destination.data,
                                   contact=form.contact.data,
                                   work_flow=work_flow)).id)
        try:
            work_flow.start()
        except yawf.exceptions.WorkFlowDelayed:
            flash('You have just submitted an travel application')
            return redirect(url_for('node_list_view'))
    return render_template('/request.html', form=form)
Exemple #3
0
    def _test_execution(self):

        yawf.clear_polices()

        class E(yawf.Policy):
            def __call__(self):
                raise RuntimeError()

            @property
            def dependencies(self):
                return [('F', {
                    'name': 'F',
                })]

        class F(yawf.Policy):
            pass

        yawf.register_policy(E)
        yawf.register_policy(F)

        work_flow = yawf.new_work_flow(
            'foo work flow', lambda work_flow: yawf.WorkFlowEngine.instance.
            node_model(work_flow=work_flow, name='E', policy_name='E'))
        try:
            work_flow.start()
        except yawf.exceptions.WorkFlowDelayed, e:
            delayed_node = e.node
Exemple #4
0
    def _test_binding(self):

        yawf.clear_polices()

        class G(yawf.Policy):
            pass

        yawf.register_policy(G)

        work_flow = yawf.new_work_flow(
            'foo work flow',
            lambda work_flow: yawf.WorkFlowEngine.instance.node_model(
                work_flow=work_flow, name='G', policy_name='G'),
            token='foo')

        assert yawf.token_bound('foo work flow', 'foo')

        work_flow.start()
        assert not yawf.token_bound('foo work flow', 'foo')
Exemple #5
0
def delivery_task():
    is_finished = request.args.get("is_finished", type=int)
    remain = request.args.get("remain", type=int)

    json_sb_list = json.loads(request.data)
    if len(json_sb_list) == 0:
        return _(u"至少需要一个仓单"), 403
    finished_store_bill_id_list = []
    unfinished_store_bill_id_list = []
    for json_sb in json_sb_list:
        if json_sb["is_finished"]:
            try:
                finished_store_bill_id_list.append(
                    int(json_sb["store_bill_id"]))
            except ValueError:
                return _(u"仓单id只能为非整数"), 403
        else:
            try:
                unfinished_store_bill_id_list.append(
                    int(json_sb["store_bill_id"]))
            except ValueError:
                return _(u"仓单id只能为非整数"), 403
    if len(unfinished_store_bill_id_list) > 1:
        return _(u"最多只有一个仓单可以部分完成"), 403
    if unfinished_store_bill_id_list:
        if not remain:
            return _(u"需要remain字段"), 403

    delivery_session_id = request.args.get("sid", type=int)

    if yawf.token_bound(constants.work_flow.DELIVERY_TASK_WITH_ABNORMAL_WEIGHT,
                        str(delivery_session_id)):
        return u'本卸货会话有待处理的工作流,请先敦促工作人员处理该工作流', 403

    ds = apis.delivery.get_delivery_session(delivery_session_id)
    if not ds:
        return _(u"需要发货会话字段"), 403
    id_list = [store_bill.id for store_bill in ds.store_bill_list]
    for id_ in finished_store_bill_id_list + unfinished_store_bill_id_list:
        if id_ not in id_list:
            return _(u"仓单%s未关联到发货会话%s" % (id_, delivery_session_id)), 403

    unfinished_store_bill = get_or_404(
        models.StoreBill, unfinished_store_bill_id_list[0]
    ) if unfinished_store_bill_id_list else None
    if unfinished_store_bill and apis.delivery.store_bill_remain_unacceptable(
            unfinished_store_bill, remain):
        try:
            doc = database.codernity_db.insert(
                dict(delivery_session_id=delivery_session_id,
                     remain=remain,
                     finished_store_bill_id_list=finished_store_bill_id_list,
                     unfinished_store_bill_id=unfinished_store_bill.id,
                     loader_id=current_user.id,
                     is_last_task=is_finished))
            # 保存token,以避免重复提交工作流, 显然,对于一个卸货会话而言,只能同时存在一个正在处理的工作流
            work_flow = yawf.new_work_flow(
                constants.work_flow.DELIVERY_TASK_WITH_ABNORMAL_WEIGHT,
                lambda work_flow: models.Node(
                    work_flow=work_flow,
                    name=u"生成异常剩余重量的发货任务",
                    policy_name='CreateDeliveryTaskWithAbnormalWeight'),
                tag_creator=lambda work_flow: doc['_id'],
                token=str(delivery_session_id))
            work_flow.start()
        except yawf.exceptions.WorkFlowDelayed, e:
            return "", 201
Exemple #6
0
class Test(BaseTest):
    def test(self):
        self._test_single_node()
        self._test_multiple_node()
        self._test_execution()
        self._test_binding()
        self._test_web_services()

    def _test_single_node(self):

        yawf.clear_polices()

        class FooPolicy(yawf.Policy):
            pass

        yawf.register_policy(FooPolicy)

        _NodeModel = yawf.WorkFlowEngine.instance.node_model

        with patch.object(FooPolicy, "__call__") as mock_method1:
            with patch.object(FooPolicy, "on_approved") as mock_method2:
                with patch.object(FooPolicy, "after_executed") as mock_method3:
                    work_flow = yawf.new_work_flow(
                        'foo work flow',
                        lambda work_flow: _NodeModel(work_flow=work_flow,
                                                     name='foo task',
                                                     policy_name='FooPolicy'))
                    work_flow.start()
                    mock_method1.assert_called_once_with()
                    mock_method2.assert_called_once_with()
                    mock_method3.assert_called_once_with()
                    assert work_flow.status == yawf.constants.WORK_FLOW_EXECUTED

        with patch.object(FooPolicy, "__call__") as mock_method1:
            with patch.object(FooPolicy, "on_approved") as mock_method2:
                with patch.object(FooPolicy, "after_executed") as mock_method3:
                    with patch.object(FooPolicy, "on_refused") as mock_method4:
                        work_flow = yawf.new_work_flow(
                            'foo work flow', lambda work_flow: _NodeModel(
                                work_flow=work_flow,
                                name='foo task',
                                policy_name='FooPolicy'))
                        work_flow.root_node.refuse()
                        assert mock_method1.call_count == 0
                        assert mock_method2.call_count == 0
                        assert mock_method3.call_count == 0
                        mock_method4.assert_called_once_with(True)
                        assert work_flow.status == yawf.constants.WORK_FLOW_REFUSED

        work_flow = yawf.new_work_flow(
            'foo work flow',
            lambda work_flow: yawf.WorkFlowEngine.instance.node_model(
                work_flow=work_flow, name='foo task', policy_name='FooPolicy'))
        work_flow.start()
        raises(yawf.exceptions.NodeAlreadyApproved,
               work_flow.root_node.approve)

    def _test_multiple_node(self):

        yawf.clear_polices()

        class A(yawf.Policy):
            @property
            def dependencies(self):
                return [('B', {'name': 'B'}), ('C', {'name': 'C'})]

        class B(yawf.Policy):
            pass

        class C(yawf.Policy):
            @property
            def dependencies(self):
                return [('D', {'name': 'D'})]

        class D(yawf.Policy):
            pass

        yawf.register_policy(A)
        yawf.register_policy(B)
        yawf.register_policy(C)
        yawf.register_policy(D)

        with patch.object(A, "__call__") as call_a:
            with patch.object(B, "__call__") as call_b:
                with patch.object(C, "__call__") as call_c:
                    with patch.object(D, "__call__") as call_d:
                        work_flow = yawf.new_work_flow(
                            'foo work flow',
                            lambda work_flow: yawf.WorkFlowEngine.instance.
                            node_model(work_flow=work_flow,
                                       name='A',
                                       policy_name='A'))
                        e_info = raises(yawf.exceptions.WorkFlowDelayed,
                                        work_flow.start)
                        assert work_flow.root_node.approved
                        delayed_node = e_info.value.node
                        assert not delayed_node.approved

                        e_info = raises(yawf.exceptions.WorkFlowDelayed,
                                        delayed_node.approve)
                        assert delayed_node.approved
                        delayed_node = e_info.value.node
                        assert not delayed_node.approved
                        assert delayed_node.id == work_flow.current_node_id

                        e_info = raises(yawf.exceptions.WorkFlowDelayed,
                                        delayed_node.approve)
                        assert delayed_node.approved
                        delayed_node = e_info.value.node
                        assert not delayed_node.approved

                        delayed_node.approve()
                        call_a.assert_called_once_with()
                        call_b.assert_called_once_with()
                        call_c.assert_called_once_with()
                        call_d.assert_called_once_with()

                        assert not delayed_node.failed
                        assert not work_flow.failed

        ## test refused
        with patch.object(B, "on_refused") as mock_method:
            work_flow = yawf.new_work_flow(
                'foo work flow', lambda work_flow: yawf.WorkFlowEngine.instance
                .node_model(work_flow=work_flow, name='A', policy_name='A'))
            try:
                work_flow.start()
            except yawf.exceptions.WorkFlowDelayed, e:
                delayed_node = e.node
            delayed_node.refuse()
            assert work_flow.status == yawf.constants.WORK_FLOW_REFUSED
            mock_method.assert_called_once_with(True)
            raises(yawf.exceptions.WorkFlowRefused, delayed_node.approve)

        # test approve twice
        work_flow = yawf.new_work_flow(
            'foo work flow', lambda work_flow: yawf.WorkFlowEngine.instance.
            node_model(work_flow=work_flow, name='A', policy_name='A'))
        try:
            work_flow.start()
        except yawf.exceptions.WorkFlowDelayed:
            pass
        raises(yawf.exceptions.NodeAlreadyApproved,
               work_flow.root_node.approve)
Exemple #7
0
    def _test_multiple_node(self):

        yawf.clear_polices()

        class A(yawf.Policy):
            @property
            def dependencies(self):
                return [('B', {'name': 'B'}), ('C', {'name': 'C'})]

        class B(yawf.Policy):
            pass

        class C(yawf.Policy):
            @property
            def dependencies(self):
                return [('D', {'name': 'D'})]

        class D(yawf.Policy):
            pass

        yawf.register_policy(A)
        yawf.register_policy(B)
        yawf.register_policy(C)
        yawf.register_policy(D)

        with patch.object(A, "__call__") as call_a:
            with patch.object(B, "__call__") as call_b:
                with patch.object(C, "__call__") as call_c:
                    with patch.object(D, "__call__") as call_d:
                        work_flow = yawf.new_work_flow(
                            'foo work flow',
                            lambda work_flow: yawf.WorkFlowEngine.instance.
                            node_model(work_flow=work_flow,
                                       name='A',
                                       policy_name='A'))
                        e_info = raises(yawf.exceptions.WorkFlowDelayed,
                                        work_flow.start)
                        assert work_flow.root_node.approved
                        delayed_node = e_info.value.node
                        assert not delayed_node.approved

                        e_info = raises(yawf.exceptions.WorkFlowDelayed,
                                        delayed_node.approve)
                        assert delayed_node.approved
                        delayed_node = e_info.value.node
                        assert not delayed_node.approved
                        assert delayed_node.id == work_flow.current_node_id

                        e_info = raises(yawf.exceptions.WorkFlowDelayed,
                                        delayed_node.approve)
                        assert delayed_node.approved
                        delayed_node = e_info.value.node
                        assert not delayed_node.approved

                        delayed_node.approve()
                        call_a.assert_called_once_with()
                        call_b.assert_called_once_with()
                        call_c.assert_called_once_with()
                        call_d.assert_called_once_with()

                        assert not delayed_node.failed
                        assert not work_flow.failed

        ## test refused
        with patch.object(B, "on_refused") as mock_method:
            work_flow = yawf.new_work_flow(
                'foo work flow', lambda work_flow: yawf.WorkFlowEngine.instance
                .node_model(work_flow=work_flow, name='A', policy_name='A'))
            try:
                work_flow.start()
            except yawf.exceptions.WorkFlowDelayed, e:
                delayed_node = e.node
            delayed_node.refuse()
            assert work_flow.status == yawf.constants.WORK_FLOW_REFUSED
            mock_method.assert_called_once_with(True)
            raises(yawf.exceptions.WorkFlowRefused, delayed_node.approve)
Exemple #8
0
    def _test_web_services(self):

        yawf.clear_polices()

        class FooPolicy(yawf.Policy):
            pass

        yawf.register_policy(FooPolicy)
        work_flow = yawf.new_work_flow(
            'foo work flow', lambda work_flow: self.node_model(
                work_flow=work_flow, name='foo task', policy_name='FooPolicy'))
        work_flow.start()

        with self.app.test_client() as c:
            rv = c.get('/__flask_yawf__/node/' + str(work_flow.root_node.id))
            assert rv.status_code == 200
            d = json.loads(rv.data)
            assert d['id'] == work_flow.root_node.id
            assert d['work_flow_id'] == work_flow.id
            assert d['name'] == work_flow.root_node.name
            assert not d['failed']
            assert d['policy_name'] == 'FooPolicy'

        class A(yawf.Policy):
            @property
            def dependencies(self):
                return [('B', {'name': 'B'})]

        class B(yawf.Policy):

            pass

        yawf.register_policies(A, B)
        work_flow = yawf.new_work_flow(
            'foo work flow', lambda work_flow: self.node_model(
                work_flow=work_flow, name='foo task', policy_name='FooPolicy'))
        work_flow.start()
        with patch.object(B, '__call__') as mock_method1:
            with self.app.test_client() as c:
                rv = c.put('/__flask_yawf__/node/%d?action=approve' %
                           work_flow.root_node.id)
                assert rv.status_code == 200

                node = self.node_model.query.get(work_flow.root_node.id)
                assert node.approved
                assert mock_method1.call_count == 0

        work_flow = yawf.new_work_flow(
            'foo work flow', lambda work_flow: self.node_model(
                work_flow=work_flow, name='foo task', policy_name='FooPolicy'))
        work_flow.start()
        with patch.object(B, '__call__') as mock_method1:
            with patch.object(B, 'on_refused') as mock_method2:
                with patch.object(B, 'on_refused') as mock_method2:
                    rv = c.put('/__flask_yawf__/node/%d?action=refuse' %
                               work_flow.root_node.id)
                assert rv.status_code == 200

                root_node = self.node_model.query.get(work_flow.root_node.id)
                assert root_node.approved
                for node in root_node.dependencies:
                    assert not node.approved
                assert mock_method1.call_count == 0
                assert mock_method2.called_once_with(True)
                assert mock_method1.called_once_with(False)
Exemple #9
0
        assert work_flow.failed
        assert not delayed_node.failed
        assert work_flow.root_node.failed
        assert work_flow.status == yawf.constants.WORK_FLOW_APPROVED

        class E_(yawf.Policy):
            @property
            def dependencies(self):
                return [('F', {
                    'name': 'F',
                })]

        yawf.register_policy(E_)
        work_flow = yawf.new_work_flow(
            'foo work flow', lambda work_flow: yawf.WorkFlowEngine.instance.
            node_model(work_flow=work_flow, name='E_', policy_name='E_'))
        try:
            work_flow.start()
        except yawf.exceptions.WorkFlowDelayed, e:
            delayed_node = e.node

        delayed_node.approve()
        assert work_flow.status == yawf.constants.WORK_FLOW_EXECUTED

    def _test_binding(self):

        yawf.clear_polices()

        class G(yawf.Policy):
            pass