Skip to content

Commit

Permalink
Polish "Add async task execution cleanup" (fixing test)
Browse files Browse the repository at this point in the history
  • Loading branch information
onobc committed Nov 1, 2023
1 parent 6c63af8 commit eb30fb8
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -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<String> 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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 {

Expand Down Expand Up @@ -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"));
}

}
}

0 comments on commit eb30fb8

Please sign in to comment.