From eb30fb8bdf6d2dcacc2b239c83b2bb3c6f512e1c Mon Sep 17 00:00:00 2001 From: Chris Bono Date: Wed, 1 Nov 2023 15:23:35 -0500 Subject: [PATCH] Polish "Add async task execution cleanup" (fixing test) --- ...kExecutionControllerCleanupAsyncTests.java | 155 ++++++++++++++++++ .../TaskExecutionControllerTests.java | 23 +-- 2 files changed, 156 insertions(+), 22 deletions(-) create mode 100644 spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerCleanupAsyncTests.java diff --git a/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerCleanupAsyncTests.java b/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerCleanupAsyncTests.java new file mode 100644 index 0000000000..c43547d766 --- /dev/null +++ b/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerCleanupAsyncTests.java @@ -0,0 +1,155 @@ +/* + * Copyright 2016-2020 the original author or authors. + * + * Licensed 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 + * + * https://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.springframework.cloud.dataflow.server.controller; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.awaitility.Awaitility; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.batch.BatchProperties; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.dataflow.aggregate.task.AggregateExecutionSupport; +import org.springframework.cloud.dataflow.aggregate.task.TaskDefinitionReader; +import org.springframework.cloud.dataflow.core.Launcher; +import org.springframework.cloud.dataflow.core.TaskDefinition; +import org.springframework.cloud.dataflow.core.TaskDeployment; +import org.springframework.cloud.dataflow.core.TaskPlatform; +import org.springframework.cloud.dataflow.schema.SchemaVersionTarget; +import org.springframework.cloud.dataflow.server.EnableDataFlowServer; +import org.springframework.cloud.dataflow.server.config.DataflowAsyncAutoConfiguration; +import org.springframework.cloud.dataflow.server.config.apps.CommonApplicationProperties; +import org.springframework.cloud.dataflow.server.configuration.JobDependencies; +import org.springframework.cloud.dataflow.server.job.LauncherRepository; +import org.springframework.cloud.dataflow.server.repository.TaskDefinitionRepository; +import org.springframework.cloud.dataflow.server.repository.TaskDeploymentRepository; +import org.springframework.cloud.dataflow.server.repository.TaskExecutionDaoContainer; +import org.springframework.cloud.deployer.spi.task.TaskLauncher; +import org.springframework.cloud.task.repository.TaskExecution; +import org.springframework.cloud.task.repository.dao.TaskExecutionDao; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.internal.verification.VerificationModeFactory.times; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Unit tests for the {@link TaskExecutionController#cleanupAll async cleanup} API. + * + * @author Chris Bono + */ +@SpringBootTest( + properties = "spring.cloud.dataflow.async.enabled=true", + classes = { JobDependencies.class, TaskExecutionAutoConfiguration.class, DataflowAsyncAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, BatchProperties.class}) +@EnableConfigurationProperties({CommonApplicationProperties.class}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) +@AutoConfigureTestDatabase(replace = Replace.ANY) +@EnableDataFlowServer +public class TaskExecutionControllerCleanupAsyncTests { + + @Autowired + private TaskExecutionDaoContainer daoContainer; + + @Autowired + private TaskDefinitionRepository taskDefinitionRepository; + + private MockMvc mockMvc; + + @Autowired + private WebApplicationContext wac; + + @Autowired + private AggregateExecutionSupport aggregateExecutionSupport; + + @Autowired + private TaskLauncher taskLauncher; + + @Autowired + private LauncherRepository launcherRepository; + + @Autowired + private TaskPlatform taskPlatform; + + @Autowired + private TaskDeploymentRepository taskDeploymentRepository; + + @Autowired + TaskDefinitionReader taskDefinitionReader; + + @BeforeEach + public void setupMockMVC() { + assertThat(this.launcherRepository.findByName("default")).isNull(); + Launcher launcher = new Launcher("default", "local", taskLauncher); + launcherRepository.save(launcher); + taskPlatform.setLaunchers(Collections.singletonList(launcher)); + this.mockMvc = MockMvcBuilders.webAppContextSetup(wac) + .defaultRequest(get("/").accept(MediaType.APPLICATION_JSON)).build(); + } + + @Test + void cleanupAll() throws Exception { + String taskExecutionId = "asyncCleanupAllTaskExecId"; + setupTaskExecutions("asyncCleanupAllTaskName", taskExecutionId); + mockMvc.perform(delete("/tasks/executions")) + .andDo(print()) + .andExpect(status().is(200)); + verify(taskLauncher, times(0)).cleanup(taskExecutionId); + Awaitility.await() + .atMost(Duration.ofSeconds(3)) + .untilAsserted(() -> verify(taskLauncher, times(2)).cleanup(taskExecutionId)); + } + + private void setupTaskExecutions(String taskName, String taskExecutionId) { + taskDefinitionRepository.save(new TaskDefinition(taskName, "taskDslGoesHere")); + SchemaVersionTarget schemaVersionTarget = aggregateExecutionSupport.findSchemaVersionTarget(taskName, taskDefinitionReader); + TaskExecutionDao taskExecutionDao = daoContainer.get(schemaVersionTarget.getName()); + + List taskArgs = new ArrayList<>(); + taskArgs.add("foo=bar"); + TaskExecution taskExecution1 = taskExecutionDao.createTaskExecution(taskName, new Date(), taskArgs, taskExecutionId); + taskExecutionDao.createTaskExecution(taskName, new Date(), taskArgs, taskExecutionId, taskExecution1.getExecutionId()); + + TaskDeployment taskDeployment = new TaskDeployment(); + taskDeployment.setTaskDefinitionName(taskName); + taskDeployment.setTaskDeploymentId(taskExecutionId); + taskDeployment.setPlatformName("default"); + taskDeployment.setCreatedOn(Instant.now()); + taskDeploymentRepository.save(taskDeployment); + } + +} diff --git a/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerTests.java b/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerTests.java index ef22def39a..20f6896ef9 100644 --- a/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerTests.java +++ b/spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/controller/TaskExecutionControllerTests.java @@ -17,7 +17,6 @@ package org.springframework.cloud.dataflow.server.controller; import java.net.URI; -import java.time.Duration; import java.time.Instant; import java.util.Collections; import java.util.Date; @@ -29,9 +28,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.batch.core.JobExecution; @@ -80,8 +77,6 @@ import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; import org.springframework.http.MediaType; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.NestedTestConfiguration; -import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -117,7 +112,7 @@ classes = { JobDependencies.class, TaskExecutionAutoConfiguration.class, DataflowAsyncAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, BatchProperties.class}) @EnableConfigurationProperties({CommonApplicationProperties.class}) -@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @AutoConfigureTestDatabase(replace = Replace.ANY) public class TaskExecutionControllerTests { @@ -652,20 +647,4 @@ void sorting() throws Exception { .andExpect(content().string(containsString("Sorting column wrong_field not allowed"))); } - @Nested - @NestedTestConfiguration(value = NestedTestConfiguration.EnclosingConfiguration.INHERIT) - @TestPropertySource(properties = "spring.cloud.dataflow.async.enabled=true") - class CleanupAsyncTests { - - @Test - void cleanupAll() throws Exception { - mockMvc.perform(delete("/tasks/executions")) - .andDo(print()) - .andExpect(status().is(200)); - Awaitility.await() - .atMost(Duration.ofSeconds(3)) - .untilAsserted(() -> verify(taskLauncher, times(2)).cleanup("foobar")); - } - - } }