|
@@ -0,0 +1,793 @@
|
|
|
+# Licensed to the Apache Software Foundation (ASF) under one
|
|
|
+# or more contributor license agreements. See the NOTICE file
|
|
|
+# distributed with this work for additional information
|
|
|
+# regarding copyright ownership. The ASF licenses this file
|
|
|
+# to you under the Apache License, Version 2.0 (the
|
|
|
+# "License"); you may not use this file except in compliance
|
|
|
+# with the License. You may obtain a copy of the License at
|
|
|
+#
|
|
|
+# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
+#
|
|
|
+# Unless required by applicable law or agreed to in writing,
|
|
|
+# software distributed under the License is distributed on an
|
|
|
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
|
+# KIND, either express or implied. See the License for the
|
|
|
+# specific language governing permissions and limitations
|
|
|
+# under the License.
|
|
|
+
|
|
|
+"""Test Task dependent."""
|
|
|
+import itertools
|
|
|
+from typing import Dict, List, Optional, Tuple, Union
|
|
|
+from unittest.mock import patch
|
|
|
+
|
|
|
+import pytest
|
|
|
+
|
|
|
+from pydolphinscheduler.exceptions import PyDSParamException
|
|
|
+from pydolphinscheduler.tasks.dependent import (
|
|
|
+ And,
|
|
|
+ Dependent,
|
|
|
+ DependentDate,
|
|
|
+ DependentItem,
|
|
|
+ DependentOperator,
|
|
|
+ Or,
|
|
|
+)
|
|
|
+
|
|
|
+TEST_PROJECT = "test-project"
|
|
|
+TEST_PROCESS_DEFINITION = "test-process-definition"
|
|
|
+TEST_TASK = "test-task"
|
|
|
+TEST_PROJECT_CODE, TEST_DEFINITION_CODE, TEST_TASK_CODE = 12345, 123456, 1234567
|
|
|
+
|
|
|
+TEST_OPERATOR_LIST = ("AND", "OR")
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.parametrize(
|
|
|
+ "dep_date, dep_cycle",
|
|
|
+ [
|
|
|
+ # hour
|
|
|
+ (DependentDate.CURRENT_HOUR, "hour"),
|
|
|
+ (DependentDate.LAST_ONE_HOUR, "hour"),
|
|
|
+ (DependentDate.LAST_TWO_HOURS, "hour"),
|
|
|
+ (DependentDate.LAST_THREE_HOURS, "hour"),
|
|
|
+ (DependentDate.LAST_TWENTY_FOUR_HOURS, "hour"),
|
|
|
+ # day
|
|
|
+ (DependentDate.TODAY, "day"),
|
|
|
+ (DependentDate.LAST_ONE_DAYS, "day"),
|
|
|
+ (DependentDate.LAST_TWO_DAYS, "day"),
|
|
|
+ (DependentDate.LAST_THREE_DAYS, "day"),
|
|
|
+ (DependentDate.LAST_SEVEN_DAYS, "day"),
|
|
|
+ # week
|
|
|
+ (DependentDate.THIS_WEEK, "week"),
|
|
|
+ (DependentDate.LAST_WEEK, "week"),
|
|
|
+ (DependentDate.LAST_MONDAY, "week"),
|
|
|
+ (DependentDate.LAST_TUESDAY, "week"),
|
|
|
+ (DependentDate.LAST_WEDNESDAY, "week"),
|
|
|
+ (DependentDate.LAST_THURSDAY, "week"),
|
|
|
+ (DependentDate.LAST_FRIDAY, "week"),
|
|
|
+ (DependentDate.LAST_SATURDAY, "week"),
|
|
|
+ (DependentDate.LAST_SUNDAY, "week"),
|
|
|
+ # month
|
|
|
+ (DependentDate.THIS_MONTH, "month"),
|
|
|
+ (DependentDate.LAST_MONTH, "month"),
|
|
|
+ (DependentDate.LAST_MONTH_BEGIN, "month"),
|
|
|
+ (DependentDate.LAST_MONTH_END, "month"),
|
|
|
+ ],
|
|
|
+)
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.tasks.dependent.DependentItem.get_code_from_gateway",
|
|
|
+ return_value={
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "processDefinitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "taskDefinitionCode": TEST_TASK_CODE,
|
|
|
+ },
|
|
|
+)
|
|
|
+def test_dependent_item_get_define(mock_task_info, dep_date, dep_cycle):
|
|
|
+ """Test dependent.DependentItem get define.
|
|
|
+
|
|
|
+ Here we have test some cases as below.
|
|
|
+ ```py
|
|
|
+ {
|
|
|
+ "projectCode": "project code",
|
|
|
+ "definitionCode": "definition code",
|
|
|
+ "depTaskCode": "dep task code",
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": "today"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+ """
|
|
|
+ attr = {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": dep_date,
|
|
|
+ }
|
|
|
+ expect = {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": dep_cycle,
|
|
|
+ "dateValue": dep_date,
|
|
|
+ }
|
|
|
+ task = DependentItem(**attr)
|
|
|
+ assert expect == task.get_define()
|
|
|
+
|
|
|
+
|
|
|
+def test_dependent_item_date_error():
|
|
|
+ """Test error when pass None to dependent_date."""
|
|
|
+ with pytest.raises(
|
|
|
+ PyDSParamException, match="Parameter dependent_date must provider.*?"
|
|
|
+ ):
|
|
|
+ DependentItem(
|
|
|
+ project_name=TEST_PROJECT,
|
|
|
+ process_definition_name=TEST_PROCESS_DEFINITION,
|
|
|
+ dependent_date=None,
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.parametrize(
|
|
|
+ "task_name, result",
|
|
|
+ [
|
|
|
+ ({"dependent_task_name": TEST_TASK}, TEST_TASK),
|
|
|
+ ({}, None),
|
|
|
+ ],
|
|
|
+)
|
|
|
+def test_dependent_item_code_parameter(task_name: dict, result: Optional[str]):
|
|
|
+ """Test dependent item property code_parameter."""
|
|
|
+ dependent_item = DependentItem(
|
|
|
+ project_name=TEST_PROJECT,
|
|
|
+ process_definition_name=TEST_PROCESS_DEFINITION,
|
|
|
+ **task_name,
|
|
|
+ )
|
|
|
+ expect = (TEST_PROJECT, TEST_PROCESS_DEFINITION, result)
|
|
|
+ assert dependent_item.code_parameter == expect
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.parametrize(
|
|
|
+ "arg_list",
|
|
|
+ [
|
|
|
+ [1, 2],
|
|
|
+ [
|
|
|
+ DependentItem(
|
|
|
+ project_name=TEST_PROJECT,
|
|
|
+ process_definition_name=TEST_PROCESS_DEFINITION,
|
|
|
+ ),
|
|
|
+ 1,
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ And(
|
|
|
+ DependentItem(
|
|
|
+ project_name=TEST_PROJECT,
|
|
|
+ process_definition_name=TEST_PROCESS_DEFINITION,
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ 1,
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ DependentItem(
|
|
|
+ project_name=TEST_PROJECT,
|
|
|
+ process_definition_name=TEST_PROCESS_DEFINITION,
|
|
|
+ ),
|
|
|
+ And(
|
|
|
+ DependentItem(
|
|
|
+ project_name=TEST_PROJECT,
|
|
|
+ process_definition_name=TEST_PROCESS_DEFINITION,
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ],
|
|
|
+)
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.tasks.dependent.DependentItem.get_code_from_gateway",
|
|
|
+ return_value={
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "processDefinitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "taskDefinitionCode": TEST_TASK_CODE,
|
|
|
+ },
|
|
|
+)
|
|
|
+def test_dependent_operator_set_define_error(mock_code, arg_list):
|
|
|
+ """Test dependent operator function :func:`set_define` with not support type."""
|
|
|
+ dep_op = DependentOperator(*arg_list)
|
|
|
+ with pytest.raises(PyDSParamException, match="Dependent .*? operator.*?"):
|
|
|
+ dep_op.set_define_attr()
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.parametrize(
|
|
|
+ # Test dependent operator, Test dependent item parameters, expect operator define
|
|
|
+ "operators, kwargs, expect",
|
|
|
+ [
|
|
|
+ # Test dependent operator (And | Or) with single dependent item
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": op,
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ for op in TEST_OPERATOR_LIST
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ # Test dependent operator (And | Or) with two dependent item
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": op,
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "week",
|
|
|
+ "dateValue": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ for op in TEST_OPERATOR_LIST
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ # Test dependent operator (And | Or) with multiply dependent item
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_ONE_DAYS,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": op,
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "week",
|
|
|
+ "dateValue": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": DependentDate.LAST_ONE_DAYS,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ for op in TEST_OPERATOR_LIST
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+)
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.tasks.dependent.DependentItem.get_code_from_gateway",
|
|
|
+ return_value={
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "processDefinitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "taskDefinitionCode": TEST_TASK_CODE,
|
|
|
+ },
|
|
|
+)
|
|
|
+def test_operator_dependent_item(
|
|
|
+ mock_code_info,
|
|
|
+ operators: Tuple[DependentOperator],
|
|
|
+ kwargs: Tuple[dict],
|
|
|
+ expect: List[Dict],
|
|
|
+):
|
|
|
+ """Test DependentOperator(DependentItem) function get_define.
|
|
|
+
|
|
|
+ Here we have test some cases as below, including single dependentItem and multiply dependentItem.
|
|
|
+ ```py
|
|
|
+ {
|
|
|
+ "relation": "AND",
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": "project code",
|
|
|
+ "definitionCode": "definition code",
|
|
|
+ "depTaskCode": "dep task code",
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": "today"
|
|
|
+ },
|
|
|
+ ...
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ```
|
|
|
+ """
|
|
|
+ for idx, operator in enumerate(operators):
|
|
|
+ # Use variable to keep one or more dependent item to test dependent operator behavior
|
|
|
+ dependent_item_list = []
|
|
|
+ for kwarg in kwargs:
|
|
|
+ dependent_item = DependentItem(**kwarg)
|
|
|
+ dependent_item_list.append(dependent_item)
|
|
|
+ op = operator(*dependent_item_list)
|
|
|
+ assert expect[idx] == op.get_define()
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.parametrize(
|
|
|
+ # Test dependent operator, Test dependent item parameters, expect operator define
|
|
|
+ "operators, args, expect",
|
|
|
+ [
|
|
|
+ # Test dependent operator (And | Or) with single dependent task list
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": par_op,
|
|
|
+ "dependTaskList": [
|
|
|
+ {
|
|
|
+ "relation": chr_op,
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ for (par_op, chr_op) in itertools.product(
|
|
|
+ TEST_OPERATOR_LIST, TEST_OPERATOR_LIST
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ # Test dependent operator (And | Or) with two dependent task list
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": par_op,
|
|
|
+ "dependTaskList": [
|
|
|
+ {
|
|
|
+ "relation": chr_op,
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "week",
|
|
|
+ "dateValue": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ for (par_op, chr_op) in itertools.product(
|
|
|
+ TEST_OPERATOR_LIST, TEST_OPERATOR_LIST
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ # Test dependent operator (And | Or) with multiply dependent task list
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_ONE_DAYS,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": par_op,
|
|
|
+ "dependTaskList": [
|
|
|
+ {
|
|
|
+ "relation": chr_op,
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "week",
|
|
|
+ "dateValue": DependentDate.LAST_WEEK,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": DependentDate.LAST_ONE_DAYS,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ for (par_op, chr_op) in itertools.product(
|
|
|
+ TEST_OPERATOR_LIST, TEST_OPERATOR_LIST
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+)
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.tasks.dependent.DependentItem.get_code_from_gateway",
|
|
|
+ return_value={
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "processDefinitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "taskDefinitionCode": TEST_TASK_CODE,
|
|
|
+ },
|
|
|
+)
|
|
|
+def test_operator_dependent_task_list_multi_dependent_item(
|
|
|
+ mock_code_info,
|
|
|
+ operators: Tuple[DependentOperator],
|
|
|
+ args: Tuple[Union[Tuple, dict]],
|
|
|
+ expect: List[Dict],
|
|
|
+):
|
|
|
+ """Test DependentOperator(DependentOperator(DependentItem)) single operator function get_define.
|
|
|
+
|
|
|
+ Here we have test some cases as below. This test case only test single DependTaskList with one or
|
|
|
+ multiply dependItemList.
|
|
|
+ ```py
|
|
|
+ {
|
|
|
+ "relation": "OR",
|
|
|
+ "dependTaskList": [
|
|
|
+ {
|
|
|
+ "relation": "AND",
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": "project code",
|
|
|
+ "definitionCode": "definition code",
|
|
|
+ "depTaskCode": "dep task code",
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": "today"
|
|
|
+ },
|
|
|
+ ...
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ```
|
|
|
+ """
|
|
|
+ # variable expect_idx record idx should be use to get specific expect
|
|
|
+ expect_idx = 0
|
|
|
+
|
|
|
+ for op_idx, operator in enumerate(operators):
|
|
|
+ dependent_operator = args[0]
|
|
|
+ dependent_item_kwargs = args[1]
|
|
|
+
|
|
|
+ for dop_idx, dpt_op in enumerate(dependent_operator):
|
|
|
+ dependent_item_list = []
|
|
|
+ for dpt_kwargs in dependent_item_kwargs:
|
|
|
+ dpti = DependentItem(**dpt_kwargs)
|
|
|
+ dependent_item_list.append(dpti)
|
|
|
+ child_dep_op = dpt_op(*dependent_item_list)
|
|
|
+ op = operator(child_dep_op)
|
|
|
+ assert expect[expect_idx] == op.get_define()
|
|
|
+ expect_idx += 1
|
|
|
+
|
|
|
+
|
|
|
+def get_dep_task_list(*operator):
|
|
|
+ """Return dependent task list from given operators list."""
|
|
|
+ result = []
|
|
|
+ for op in operator:
|
|
|
+ result.append(
|
|
|
+ {
|
|
|
+ "relation": op.operator_name(),
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "month",
|
|
|
+ "dateValue": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ )
|
|
|
+ return result
|
|
|
+
|
|
|
+
|
|
|
+@pytest.mark.parametrize(
|
|
|
+ # Test dependent operator, Test dependent item parameters, expect operator define
|
|
|
+ "operators, args, expect",
|
|
|
+ [
|
|
|
+ # Test dependent operator (And | Or) with two dependent task list
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ ((And, And), (And, Or), (Or, And), (Or, Or)),
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": parent_op.operator_name(),
|
|
|
+ "dependTaskList": get_dep_task_list(*child_ops),
|
|
|
+ }
|
|
|
+ for parent_op in (And, Or)
|
|
|
+ for child_ops in ((And, And), (And, Or), (Or, And), (Or, Or))
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ # Test dependent operator (And | Or) with multiple dependent task list
|
|
|
+ (
|
|
|
+ (And, Or),
|
|
|
+ (
|
|
|
+ ((And, And, And), (And, And, And, And), (And, And, And, And, And)),
|
|
|
+ {
|
|
|
+ "project_name": TEST_PROJECT,
|
|
|
+ "process_definition_name": TEST_PROCESS_DEFINITION,
|
|
|
+ "dependent_task_name": TEST_TASK,
|
|
|
+ "dependent_date": DependentDate.LAST_MONTH_END,
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "relation": parent_op.operator_name(),
|
|
|
+ "dependTaskList": get_dep_task_list(*child_ops),
|
|
|
+ }
|
|
|
+ for parent_op in (And, Or)
|
|
|
+ for child_ops in (
|
|
|
+ (And, And, And),
|
|
|
+ (And, And, And, And),
|
|
|
+ (And, And, And, And, And),
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+)
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.tasks.dependent.DependentItem.get_code_from_gateway",
|
|
|
+ return_value={
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "processDefinitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "taskDefinitionCode": TEST_TASK_CODE,
|
|
|
+ },
|
|
|
+)
|
|
|
+def test_operator_dependent_task_list_multi_dependent_list(
|
|
|
+ mock_code_info,
|
|
|
+ operators: Tuple[DependentOperator],
|
|
|
+ args: Tuple[Union[Tuple, dict]],
|
|
|
+ expect: List[Dict],
|
|
|
+):
|
|
|
+ """Test DependentOperator(DependentOperator(DependentItem)) multiply operator function get_define.
|
|
|
+
|
|
|
+ Here we have test some cases as below. This test case only test single DependTaskList with one or
|
|
|
+ multiply dependTaskList.
|
|
|
+ ```py
|
|
|
+ {
|
|
|
+ "relation": "OR",
|
|
|
+ "dependTaskList": [
|
|
|
+ {
|
|
|
+ "relation": "AND",
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": "project code",
|
|
|
+ "definitionCode": "definition code",
|
|
|
+ "depTaskCode": "dep task code",
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": "today"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ ...
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ```
|
|
|
+ """
|
|
|
+ # variable expect_idx record idx should be use to get specific expect
|
|
|
+ expect_idx = 0
|
|
|
+ for op_idx, operator in enumerate(operators):
|
|
|
+ dependent_operator = args[0]
|
|
|
+ dependent_item_kwargs = args[1]
|
|
|
+
|
|
|
+ for dop_idx, dpt_ops in enumerate(dependent_operator):
|
|
|
+ dependent_task_list = [
|
|
|
+ dpt_op(DependentItem(**dependent_item_kwargs)) for dpt_op in dpt_ops
|
|
|
+ ]
|
|
|
+ op = operator(*dependent_task_list)
|
|
|
+ assert (
|
|
|
+ expect[expect_idx] == op.get_define()
|
|
|
+ ), f"Failed with operator syntax {operator}.{dpt_ops}"
|
|
|
+ expect_idx += 1
|
|
|
+
|
|
|
+
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.tasks.dependent.DependentItem.get_code_from_gateway",
|
|
|
+ return_value={
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "processDefinitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "taskDefinitionCode": TEST_TASK_CODE,
|
|
|
+ },
|
|
|
+)
|
|
|
+@patch(
|
|
|
+ "pydolphinscheduler.core.task.Task.gen_code_and_version",
|
|
|
+ return_value=(123, 1),
|
|
|
+)
|
|
|
+def test_dependent_get_define(mock_code_version, mock_dep_code):
|
|
|
+ """Test task dependent function get_define."""
|
|
|
+ project_name = "test-dep-project"
|
|
|
+ process_definition_name = "test-dep-definition"
|
|
|
+ dependent_task_name = "test-dep-task"
|
|
|
+ dep_operator = And(
|
|
|
+ Or(
|
|
|
+ # test dependence with add tasks
|
|
|
+ DependentItem(
|
|
|
+ project_name=project_name,
|
|
|
+ process_definition_name=process_definition_name,
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ And(
|
|
|
+ # test dependence with specific task
|
|
|
+ DependentItem(
|
|
|
+ project_name=project_name,
|
|
|
+ process_definition_name=process_definition_name,
|
|
|
+ dependent_task_name=dependent_task_name,
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ )
|
|
|
+
|
|
|
+ name = "test_dependent_get_define"
|
|
|
+ expect = {
|
|
|
+ "code": 123,
|
|
|
+ "name": name,
|
|
|
+ "version": 1,
|
|
|
+ "description": None,
|
|
|
+ "delayTime": 0,
|
|
|
+ "taskType": "DEPENDENT",
|
|
|
+ "taskParams": {
|
|
|
+ "resourceList": [],
|
|
|
+ "localParams": [],
|
|
|
+ "dependence": {
|
|
|
+ "relation": "AND",
|
|
|
+ "dependTaskList": [
|
|
|
+ {
|
|
|
+ "relation": "OR",
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": "0",
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": "today",
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "relation": "AND",
|
|
|
+ "dependItemList": [
|
|
|
+ {
|
|
|
+ "projectCode": TEST_PROJECT_CODE,
|
|
|
+ "definitionCode": TEST_DEFINITION_CODE,
|
|
|
+ "depTaskCode": TEST_TASK_CODE,
|
|
|
+ "cycle": "day",
|
|
|
+ "dateValue": "today",
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ "conditionResult": {"successNode": [""], "failedNode": [""]},
|
|
|
+ "waitStartTimeout": {},
|
|
|
+ },
|
|
|
+ "flag": "YES",
|
|
|
+ "taskPriority": "MEDIUM",
|
|
|
+ "workerGroup": "default",
|
|
|
+ "failRetryTimes": 0,
|
|
|
+ "failRetryInterval": 1,
|
|
|
+ "timeoutFlag": "CLOSE",
|
|
|
+ "timeoutNotifyStrategy": None,
|
|
|
+ "timeout": 0,
|
|
|
+ }
|
|
|
+
|
|
|
+ task = Dependent(name, dependence=dep_operator)
|
|
|
+ assert task.get_define() == expect
|