You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by zi...@apache.org on 2026/03/30 04:34:08 UTC
(dolphinscheduler) branch dev updated: [Improvement-18095][API-Test] Add dependent task api test case (#18096)
This is an automated email from the ASF dual-hosted git repository.
zihaoxiang pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 46f0f3c47a [Improvement-18095][API-Test] Add dependent task api test case (#18096)
46f0f3c47a is described below
commit 46f0f3c47aeef938efaee07f5c69a6e4bc2a614d
Author: xiangzihao <46...@qq.com>
AuthorDate: Mon Mar 30 12:34:02 2026 +0800
[Improvement-18095][API-Test] Add dependent task api test case (#18096)
---
.github/workflows/api-test.yml | 2 +
.../api/test/cases/tasks/DependentTaskAPITest.java | 353 +++++++++++++++++++++
.../pages/workflow/WorkflowDefinitionPage.java | 11 +-
.../task-dependent/dependentFailedWorkflow.json | 64 ++++
.../task-dependent/dependentSuccessWorkflow.json | 64 ++++
5 files changed, 492 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/api-test.yml b/.github/workflows/api-test.yml
index b8ea36110e..f39ffa5dea 100644
--- a/.github/workflows/api-test.yml
+++ b/.github/workflows/api-test.yml
@@ -119,6 +119,8 @@ jobs:
class: org.apache.dolphinscheduler.api.test.cases.GrpcTaskAPITest
- name: OidcLoginAPITest
class: org.apache.dolphinscheduler.api.test.cases.OidcLoginAPITest
+ - name: DependentTaskAPITest
+ class: org.apache.dolphinscheduler.api.test.cases.tasks.DependentTaskAPITest
env:
RECORDING_PATH: /tmp/recording-${{ matrix.case.name }}
steps:
diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/tasks/DependentTaskAPITest.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/tasks/DependentTaskAPITest.java
new file mode 100644
index 0000000000..9d15e4c92b
--- /dev/null
+++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/cases/tasks/DependentTaskAPITest.java
@@ -0,0 +1,353 @@
+/*
+ * 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.
+ */
+
+package org.apache.dolphinscheduler.api.test.cases.tasks;
+
+import org.apache.dolphinscheduler.api.test.core.DolphinScheduler;
+import org.apache.dolphinscheduler.api.test.entity.HttpResponse;
+import org.apache.dolphinscheduler.api.test.entity.LoginResponseData;
+import org.apache.dolphinscheduler.api.test.pages.LoginPage;
+import org.apache.dolphinscheduler.api.test.pages.project.ProjectPage;
+import org.apache.dolphinscheduler.api.test.pages.workflow.ExecutorPage;
+import org.apache.dolphinscheduler.api.test.pages.workflow.WorkflowDefinitionPage;
+import org.apache.dolphinscheduler.api.test.pages.workflow.WorkflowInstancePage;
+import org.apache.dolphinscheduler.api.test.utils.JSONUtils;
+import org.apache.dolphinscheduler.common.enums.FailureStrategy;
+import org.apache.dolphinscheduler.common.enums.ReleaseState;
+import org.apache.dolphinscheduler.common.enums.UserType;
+import org.apache.dolphinscheduler.common.enums.WarningType;
+import org.apache.dolphinscheduler.dao.entity.User;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junitpioneer.jupiter.DisableIfTestFails;
+
+@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
+@Slf4j
+@DisableIfTestFails
+public class DependentTaskAPITest {
+
+ private static final String username = "admin";
+
+ private static final String password = "dolphinscheduler123";
+
+ private static final String projectName = "dependent-test-project-" + System.currentTimeMillis();
+
+ private static String sessionId;
+
+ private static User loginUser;
+
+ private static ExecutorPage executorPage;
+
+ private static WorkflowDefinitionPage workflowDefinitionPage;
+
+ private static WorkflowInstancePage workflowInstancePage;
+
+ private static ProjectPage projectPage;
+
+ private static long projectCode;
+
+ private static long upstreamWorkflowDefinitionCode;
+
+ private static long dependentWorkflowDefinitionCode;
+
+ private static long failedDependentWorkflowDefinitionCode;
+
+ @BeforeAll
+ public static void setup() {
+ LoginPage loginPage = new LoginPage();
+ HttpResponse loginHttpResponse = loginPage.login(username, password);
+ sessionId =
+ JSONUtils.convertValue(loginHttpResponse.getBody().getData(), LoginResponseData.class).getSessionId();
+ executorPage = new ExecutorPage(sessionId);
+ workflowDefinitionPage = new WorkflowDefinitionPage(sessionId);
+ workflowInstancePage = new WorkflowInstancePage(sessionId);
+ projectPage = new ProjectPage(sessionId);
+ loginUser = new User();
+ loginUser.setUserName("admin");
+ loginUser.setId(1);
+ loginUser.setUserType(UserType.ADMIN_USER);
+ }
+
+ @AfterAll
+ public static void cleanup() {
+ log.info("success cleanup");
+ }
+
+ @Test
+ @Order(1)
+ public void testCreateUpstreamWorkflow() throws Exception {
+ // create test project
+ HttpResponse createProjectResponse = projectPage.createProject(loginUser, projectName);
+ Assertions.assertTrue(createProjectResponse.getBody().getSuccess());
+
+ HttpResponse queryAllProjectListResponse = projectPage.queryAllProjectList(loginUser);
+ Assertions.assertTrue(queryAllProjectListResponse.getBody().getSuccess());
+
+ // find the project by name
+ List<LinkedHashMap> projectList = (List<LinkedHashMap>) queryAllProjectListResponse.getBody().getData();
+ for (LinkedHashMap<String, Object> project : projectList) {
+ if (projectName.equals(project.get("name"))) {
+ projectCode = ((Number) project.get("code")).longValue();
+ break;
+ }
+ }
+ Assertions.assertNotEquals(0, projectCode, "project should be found by name");
+ log.info("project code: {}", projectCode);
+
+ // create upstream workflow definition (shell task: echo hello)
+ ClassLoader classLoader = getClass().getClassLoader();
+ File file = new File(classLoader.getResource("workflow-json/test.json").getFile());
+ String upstreamWorkflowName = "upstream_shell_workflow_" + System.currentTimeMillis();
+ HttpResponse createWorkflowResponse = workflowDefinitionPage
+ .createWorkflowDefinition(loginUser, projectCode, file, upstreamWorkflowName);
+ Assertions.assertTrue(createWorkflowResponse.getBody().getSuccess());
+
+ // get upstream workflow definition code
+ HttpResponse queryAllWorkflowResponse =
+ workflowDefinitionPage.queryAllWorkflowDefinitionByProjectCode(loginUser, projectCode);
+ Assertions.assertTrue(queryAllWorkflowResponse.getBody().getSuccess());
+ upstreamWorkflowDefinitionCode =
+ (long) ((LinkedHashMap<String, Object>) ((LinkedHashMap<String, Object>) ((List<LinkedHashMap>) queryAllWorkflowResponse
+ .getBody().getData()).get(0)).get("workflowDefinition")).get("code");
+ log.info("upstream workflow definition code: {}", upstreamWorkflowDefinitionCode);
+
+ // release upstream workflow
+ HttpResponse releaseResponse = workflowDefinitionPage.releaseWorkflowDefinition(loginUser,
+ projectCode, upstreamWorkflowDefinitionCode, ReleaseState.ONLINE);
+ Assertions.assertTrue(releaseResponse.getBody().getSuccess());
+
+ // trigger upstream workflow instance
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date date = new Date();
+ String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
+ log.info("use current time {} as scheduleTime", scheduleTime);
+ HttpResponse startWorkflowResponse = executorPage.startWorkflowInstance(loginUser, projectCode,
+ upstreamWorkflowDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE);
+ Assertions.assertTrue(startWorkflowResponse.getBody().getSuccess());
+
+ List<Integer> workflowInstanceIds = (List<Integer>) startWorkflowResponse.getBody().getData();
+ Assertions.assertFalse(workflowInstanceIds.isEmpty());
+ log.info("upstream workflow instance ids: {}", workflowInstanceIds);
+
+ // wait for upstream workflow to complete
+ int workflowInstanceId = workflowInstanceIds.get(0);
+ boolean completed = false;
+ for (int i = 0; i < 60; i++) {
+ Thread.sleep(2000);
+ HttpResponse queryResponse = workflowInstancePage.queryWorkflowInstanceById(loginUser,
+ projectCode, workflowInstanceId);
+ if (queryResponse.getBody().getSuccess() && queryResponse.getBody().getData() != null) {
+ LinkedHashMap<String, Object> instanceData =
+ (LinkedHashMap<String, Object>) queryResponse.getBody().getData();
+ String state = (String) instanceData.get("state");
+ log.info("upstream workflow instance state: {}", state);
+ if ("SUCCESS".equals(state)) {
+ completed = true;
+ break;
+ } else if ("FAILURE".equals(state) || "STOP".equals(state)) {
+ Assertions.fail("upstream workflow instance failed with state: " + state);
+ }
+ }
+ }
+ Assertions.assertTrue(completed, "upstream workflow instance should complete within 120 seconds");
+ }
+
+ @Test
+ @Order(10)
+ public void testDependentSuccessWorkflowInstance() throws Exception {
+ // read dependent success workflow json template and replace placeholders
+ ClassLoader classLoader = getClass().getClassLoader();
+ File file = new File(
+ classLoader.getResource("workflow-json/task-dependent/dependentSuccessWorkflow.json").getFile());
+ String jsonContent = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
+ jsonContent = jsonContent
+ .replace("${projectCode}", String.valueOf(projectCode))
+ .replace("${definitionCode}", String.valueOf(upstreamWorkflowDefinitionCode));
+
+ String dependentWorkflowName = "dependent_success_" + System.currentTimeMillis();
+ HttpResponse createResponse = workflowDefinitionPage
+ .createWorkflowDefinition(loginUser, projectCode, jsonContent, dependentWorkflowName);
+ Assertions.assertTrue(createResponse.getBody().getSuccess());
+
+ // get dependent workflow definition code from create response
+ LinkedHashMap<String, Object> createData =
+ (LinkedHashMap<String, Object>) createResponse.getBody().getData();
+ dependentWorkflowDefinitionCode = ((Number) createData.get("code")).longValue();
+ log.info("dependent workflow definition code: {}", dependentWorkflowDefinitionCode);
+
+ // release dependent workflow
+ HttpResponse releaseResponse = workflowDefinitionPage.releaseWorkflowDefinition(loginUser,
+ projectCode, dependentWorkflowDefinitionCode, ReleaseState.ONLINE);
+ Assertions.assertTrue(releaseResponse.getBody().getSuccess());
+
+ // trigger dependent workflow instance
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date date = new Date();
+ String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
+ log.info("use current time {} as scheduleTime", scheduleTime);
+ HttpResponse startWorkflowResponse = executorPage.startWorkflowInstance(loginUser, projectCode,
+ dependentWorkflowDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE);
+ Assertions.assertTrue(startWorkflowResponse.getBody().getSuccess());
+
+ List<Integer> workflowInstanceIds = (List<Integer>) startWorkflowResponse.getBody().getData();
+ Assertions.assertFalse(workflowInstanceIds.isEmpty());
+ log.info("dependent workflow instance ids: {}", workflowInstanceIds);
+
+ // wait for dependent workflow to complete
+ int workflowInstanceId = workflowInstanceIds.get(0);
+ boolean completed = false;
+ for (int i = 0; i < 60; i++) {
+ Thread.sleep(2000);
+ HttpResponse queryResponse = workflowInstancePage.queryWorkflowInstanceById(loginUser,
+ projectCode, workflowInstanceId);
+ if (queryResponse.getBody().getSuccess() && queryResponse.getBody().getData() != null) {
+ LinkedHashMap<String, Object> instanceData =
+ (LinkedHashMap<String, Object>) queryResponse.getBody().getData();
+ String state = (String) instanceData.get("state");
+ log.info("dependent success workflow instance state: {}", state);
+ if ("SUCCESS".equals(state)) {
+ completed = true;
+ break;
+ } else if ("FAILURE".equals(state) || "STOP".equals(state)) {
+ Assertions.fail("dependent workflow instance failed with state: " + state);
+ }
+ }
+ }
+ Assertions.assertTrue(completed, "dependent workflow instance should complete within 120 seconds");
+
+ // query task instances and verify DEPENDENT task type
+ HttpResponse queryTaskListResponse = workflowInstancePage.queryTaskListByWorkflowInstanceId(loginUser,
+ projectCode, workflowInstanceId);
+ Assertions.assertTrue(queryTaskListResponse.getBody().getSuccess());
+
+ List<LinkedHashMap<String, Object>> taskList;
+ Object taskData = queryTaskListResponse.getBody().getData();
+ if (taskData instanceof List) {
+ taskList = (List<LinkedHashMap<String, Object>>) taskData;
+ } else {
+ LinkedHashMap<String, Object> pageData = (LinkedHashMap<String, Object>) taskData;
+ taskList = (List<LinkedHashMap<String, Object>>) pageData.get("taskList");
+ }
+ Assertions.assertNotNull(taskList);
+ Assertions.assertFalse(taskList.isEmpty());
+
+ LinkedHashMap<String, Object> dependentTask = taskList.get(0);
+ Assertions.assertEquals("DEPENDENT", dependentTask.get("taskType"));
+ Assertions.assertEquals("SUCCESS", dependentTask.get("state"));
+ log.info("dependent task instance verified: taskType={}, state={}",
+ dependentTask.get("taskType"), dependentTask.get("state"));
+ }
+
+ @Test
+ @Order(20)
+ public void testDependentFailedWorkflowInstance() throws Exception {
+ // read dependent failed workflow json template and replace placeholders
+ // this workflow depends on a non-existent definition code, so the dependent task should fail
+ ClassLoader classLoader = getClass().getClassLoader();
+ File file = new File(
+ classLoader.getResource("workflow-json/task-dependent/dependentFailedWorkflow.json").getFile());
+ String jsonContent = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
+ jsonContent = jsonContent.replace("${projectCode}", String.valueOf(projectCode));
+
+ String dependentWorkflowName = "dependent_failed_" + System.currentTimeMillis();
+ HttpResponse createResponse = workflowDefinitionPage
+ .createWorkflowDefinition(loginUser, projectCode, jsonContent, dependentWorkflowName);
+ Assertions.assertTrue(createResponse.getBody().getSuccess());
+
+ // get failed dependent workflow definition code from create response
+ LinkedHashMap<String, Object> createData =
+ (LinkedHashMap<String, Object>) createResponse.getBody().getData();
+ failedDependentWorkflowDefinitionCode = ((Number) createData.get("code")).longValue();
+ log.info("failed dependent workflow definition code: {}", failedDependentWorkflowDefinitionCode);
+
+ // release failed dependent workflow
+ HttpResponse releaseResponse = workflowDefinitionPage.releaseWorkflowDefinition(loginUser,
+ projectCode, failedDependentWorkflowDefinitionCode, ReleaseState.ONLINE);
+ Assertions.assertTrue(releaseResponse.getBody().getSuccess());
+
+ // trigger failed dependent workflow instance
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date date = new Date();
+ String scheduleTime = String.format("%s,%s", formatter.format(date), formatter.format(date));
+ log.info("use current time {} as scheduleTime", scheduleTime);
+ HttpResponse startWorkflowResponse = executorPage.startWorkflowInstance(loginUser, projectCode,
+ failedDependentWorkflowDefinitionCode, scheduleTime, FailureStrategy.END, WarningType.NONE);
+ Assertions.assertTrue(startWorkflowResponse.getBody().getSuccess());
+
+ List<Integer> workflowInstanceIds = (List<Integer>) startWorkflowResponse.getBody().getData();
+ Assertions.assertFalse(workflowInstanceIds.isEmpty());
+ log.info("failed dependent workflow instance ids: {}", workflowInstanceIds);
+
+ // wait for dependent workflow to fail
+ int workflowInstanceId = workflowInstanceIds.get(0);
+ boolean failed = false;
+ for (int i = 0; i < 60; i++) {
+ Thread.sleep(2000);
+ HttpResponse queryResponse = workflowInstancePage.queryWorkflowInstanceById(loginUser,
+ projectCode, workflowInstanceId);
+ if (queryResponse.getBody().getSuccess() && queryResponse.getBody().getData() != null) {
+ LinkedHashMap<String, Object> instanceData =
+ (LinkedHashMap<String, Object>) queryResponse.getBody().getData();
+ String state = (String) instanceData.get("state");
+ log.info("failed dependent workflow instance state: {}", state);
+ if ("FAILURE".equals(state)) {
+ failed = true;
+ break;
+ } else if ("SUCCESS".equals(state)) {
+ Assertions.fail("dependent workflow instance should not succeed");
+ }
+ }
+ }
+ Assertions.assertTrue(failed, "dependent workflow referencing non-existent definition should fail");
+
+ // query task instances and verify DEPENDENT task type with FAILURE state
+ HttpResponse queryTaskListResponse = workflowInstancePage.queryTaskListByWorkflowInstanceId(loginUser,
+ projectCode, workflowInstanceId);
+ Assertions.assertTrue(queryTaskListResponse.getBody().getSuccess());
+
+ List<LinkedHashMap<String, Object>> failedTaskList;
+ Object failedTaskData = queryTaskListResponse.getBody().getData();
+ if (failedTaskData instanceof List) {
+ failedTaskList = (List<LinkedHashMap<String, Object>>) failedTaskData;
+ } else {
+ LinkedHashMap<String, Object> pageData = (LinkedHashMap<String, Object>) failedTaskData;
+ failedTaskList = (List<LinkedHashMap<String, Object>>) pageData.get("taskList");
+ }
+ Assertions.assertNotNull(failedTaskList);
+ Assertions.assertFalse(failedTaskList.isEmpty());
+
+ LinkedHashMap<String, Object> dependentTask = failedTaskList.get(0);
+ Assertions.assertEquals("DEPENDENT", dependentTask.get("taskType"));
+ Assertions.assertEquals("FAILURE", dependentTask.get("state"));
+ log.info("failed dependent task instance verified: taskType={}, state={}",
+ dependentTask.get("taskType"), dependentTask.get("state"));
+ }
+}
diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/WorkflowDefinitionPage.java b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/WorkflowDefinitionPage.java
index e64c898933..2d82bd2b69 100644
--- a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/WorkflowDefinitionPage.java
+++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/java/org/apache/dolphinscheduler/api/test/pages/workflow/WorkflowDefinitionPage.java
@@ -48,11 +48,18 @@ public class WorkflowDefinitionPage {
long projectCode,
File file,
String workflowDefinitionName) {
+ String fileContent = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
+ return createWorkflowDefinition(loginUser, projectCode, fileContent, workflowDefinitionName);
+ }
+
+ public HttpResponse createWorkflowDefinition(User loginUser,
+ long projectCode,
+ String jsonContent,
+ String workflowDefinitionName) {
Map<String, Object> params = new HashMap<>();
params.put("loginUser", loginUser);
- String fileContent = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
- Map<String, Object> fileContentMap = JSONUtils.parseObject(fileContent, new TypeReference<>() {
+ Map<String, Object> fileContentMap = JSONUtils.parseObject(jsonContent, new TypeReference<>() {
});
if (fileContentMap == null) {
throw new RuntimeException("file content parse error");
diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/workflow-json/task-dependent/dependentFailedWorkflow.json b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/workflow-json/task-dependent/dependentFailedWorkflow.json
new file mode 100644
index 0000000000..54c01bdc2e
--- /dev/null
+++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/workflow-json/task-dependent/dependentFailedWorkflow.json
@@ -0,0 +1,64 @@
+{
+ "taskDefinitionJson": [
+ {
+ "code": 264597693773601,
+ "delayTime": "0",
+ "description": "",
+ "environmentCode": -1,
+ "failRetryInterval": "1",
+ "failRetryTimes": "0",
+ "flag": "YES",
+ "name": "dependent_failed_test",
+ "taskParams": {
+ "localParams": [],
+ "resourceList": [],
+ "dependence": {
+ "relation": "AND",
+ "dependTaskList": [
+ {
+ "relation": "AND",
+ "dependItemList": [
+ {
+ "projectCode": ${projectCode},
+ "definitionCode": 999999999999,
+ "depTaskCode": 0,
+ "cycle": "day",
+ "dateValue": "today",
+ "dependentType": "DEPENDENT_ON_WORKFLOW"
+ }
+ ]
+ }
+ ],
+ "checkInterval": 10,
+ "failurePolicy": "DEPENDENT_FAILURE_FAILURE",
+ "failureWaitingTime": 1
+ }
+ },
+ "taskPriority": "MEDIUM",
+ "taskType": "DEPENDENT",
+ "timeout": 0,
+ "timeoutFlag": "CLOSE",
+ "timeoutNotifyStrategy": "",
+ "workerGroup": "default",
+ "cpuQuota": -1,
+ "memoryMax": -1,
+ "taskExecuteType": "BATCH"
+ }
+ ],
+ "taskRelationJson": [
+ {
+ "name": "",
+ "preTaskCode": 0,
+ "preTaskVersion": 0,
+ "postTaskCode": 264597693773601,
+ "postTaskVersion": 0,
+ "conditionType": "NONE",
+ "conditionParams": {}
+ }
+ ],
+ "name": "dependentFailedWorkflow",
+ "executionType": "PARALLEL",
+ "description": "",
+ "globalParams": [],
+ "timeout": 0
+}
diff --git a/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/workflow-json/task-dependent/dependentSuccessWorkflow.json b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/workflow-json/task-dependent/dependentSuccessWorkflow.json
new file mode 100644
index 0000000000..8d2f53e018
--- /dev/null
+++ b/dolphinscheduler-api-test/dolphinscheduler-api-test-case/src/test/resources/workflow-json/task-dependent/dependentSuccessWorkflow.json
@@ -0,0 +1,64 @@
+{
+ "taskDefinitionJson": [
+ {
+ "code": 264597693773600,
+ "delayTime": "0",
+ "description": "",
+ "environmentCode": -1,
+ "failRetryInterval": "1",
+ "failRetryTimes": "0",
+ "flag": "YES",
+ "name": "dependent_success_test",
+ "taskParams": {
+ "localParams": [],
+ "resourceList": [],
+ "dependence": {
+ "relation": "AND",
+ "dependTaskList": [
+ {
+ "relation": "AND",
+ "dependItemList": [
+ {
+ "projectCode": ${projectCode},
+ "definitionCode": ${definitionCode},
+ "depTaskCode": 0,
+ "cycle": "day",
+ "dateValue": "today",
+ "dependentType": "DEPENDENT_ON_WORKFLOW"
+ }
+ ]
+ }
+ ],
+ "checkInterval": 10,
+ "failurePolicy": "DEPENDENT_FAILURE_FAILURE",
+ "failureWaitingTime": 1
+ }
+ },
+ "taskPriority": "MEDIUM",
+ "taskType": "DEPENDENT",
+ "timeout": 0,
+ "timeoutFlag": "CLOSE",
+ "timeoutNotifyStrategy": "",
+ "workerGroup": "default",
+ "cpuQuota": -1,
+ "memoryMax": -1,
+ "taskExecuteType": "BATCH"
+ }
+ ],
+ "taskRelationJson": [
+ {
+ "name": "",
+ "preTaskCode": 0,
+ "preTaskVersion": 0,
+ "postTaskCode": 264597693773600,
+ "postTaskVersion": 0,
+ "conditionType": "NONE",
+ "conditionParams": {}
+ }
+ ],
+ "name": "dependentSuccessWorkflow",
+ "executionType": "PARALLEL",
+ "description": "",
+ "globalParams": [],
+ "timeout": 0
+}