Checks for invalid ExecutionId in the TaskLifeCycleListener

resolves #115
* Fixes bug where if the user set the environment variable and commandline args a unique constraint would fire.
* Updated docs
* Removed deprecation
* Fixed version number for integration test.

Added integration tests for externally generated task executions
This commit is contained in:
Michael Minella
2016-08-22 12:55:31 -05:00
parent bf0c27dd1a
commit 441bbfe492
21 changed files with 619 additions and 36 deletions

View File

@@ -7,8 +7,9 @@ import org.junit.Test;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.OutputCapture;
import org.springframework.boot.test.rule.OutputCapture;
import org.springframework.cloud.task.configuration.EnableTask;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -28,6 +29,8 @@ public class TaskCoreTests {
private static final String UPDATE_TASK_MESSAGE = "Updating: TaskExecution with executionId=";
private static final String SUCCESS_EXIT_CODE_MESSAGE = "with the following {exitCode=0";
private static final String EXCEPTION_EXIT_CODE_MESSAGE = "with the following {exitCode=1";
private static final String EXCEPTION_INVALID_TASK_EXECUTION_ID =
"java.lang.IllegalArgumentException: Invalid TaskExecution, ID 55 not found";
private static final String ERROR_MESSAGE =
"errorMessage='java.lang.IllegalStateException: Failed to execute CommandLineRunner";
@@ -88,6 +91,27 @@ public class TaskCoreTests {
output.contains(EXCEPTION_MESSAGE));
}
@Test
public void invalidExecutionId() {
boolean exceptionFired = false;
try {
applicationContext = new SpringApplicationBuilder().sources(new Object[]{TaskExceptionConfiguration.class,
PropertyPlaceholderAutoConfiguration.class}).build().run(new String[]{
"--spring.cloud.task.closecontext.enable=false",
"--spring.cloud.task.name=" + TASK_NAME,
"--spring.main.web-environment=false",
"--spring.cloud.task.executionid=55"});
}
catch (ApplicationContextException exception) {
exceptionFired = true;
}
assertTrue("An ApplicationContextException should have been thrown", exceptionFired);
String output = this.outputCapture.toString();
assertTrue("Test results do not show the correct exception message: " + output,
output.contains(EXCEPTION_INVALID_TASK_EXECUTION_ID));
}
@Configuration
@EnableTask
public static class TaskConfiguration {

View File

@@ -35,10 +35,15 @@ import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.repository.TaskExplorer;
import org.springframework.cloud.task.util.TestDefaultConfiguration;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
@@ -139,6 +144,17 @@ public class TaskLifecycleListenerTests {
}
}
@Test(expected = ApplicationContextException.class)
public void testInvalidTaskExecutionId() {
ConfigurableEnvironment environment = new StandardEnvironment();
MutablePropertySources propertySources = environment.getPropertySources();
Map myMap = new HashMap();
myMap.put("spring.cloud.task.executionid", "55");
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
context.setEnvironment(environment);
context.refresh();
}
private void verifyTaskExecution(int numberOfParams, boolean update, Integer exitCode, Throwable exception) {
Sort sort = new Sort("id");

View File

@@ -16,11 +16,16 @@
package org.springframework.cloud.task.repository.dao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.UUID;
import javax.sql.DataSource;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
@@ -56,7 +61,24 @@ public class JdbcTaskExecutionDaoTests {
@Test
@DirtiesContext
public void saveTaskExecution() {
public void testStartTaskExecution() {
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
new ArrayList<String>(0));
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void createTaskExecution() {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments());
@@ -65,6 +87,16 @@ public class JdbcTaskExecutionDaoTests {
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void createEmptyTaskExecution() {
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
new ArrayList<String>(0));
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void completeTaskExecution() {

View File

@@ -16,28 +16,72 @@
package org.springframework.cloud.task.repository.dao;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.util.TestVerifierUtils;
import static org.junit.Assert.assertNotNull;
/**
* Executes unit tests on MapTaskExecutionDaoTests.
* @author Glenn Renfro
*/
public class MapTaskExecutionDaoTests {
private MapTaskExecutionDao dao;
@Before
public void setUp() {
this.dao = new MapTaskExecutionDao();
}
@Test
public void testStartTaskExecution() {
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, null, new ArrayList<String>(0));
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments());
Map<Long, TaskExecution> taskExecutionMap = this.dao.getTaskExecutions();
assertNotNull("taskExecutionMap must not be null", taskExecutionMap);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test
public void createEmptyTaskExecution() {
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
new ArrayList<String>(0));
Map<Long, TaskExecution> taskExecutionMap = this.dao.getTaskExecutions();
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test(expected = IllegalStateException.class)
public void completeTaskExecutionWithNoCreate() {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
}
@Test
public void saveTaskExecution(){
MapTaskExecutionDao dao = new MapTaskExecutionDao();
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution = this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments());
Map<Long, TaskExecution> taskExecutionMap = dao.getTaskExecutions();
Map<Long, TaskExecution> taskExecutionMap = this.dao.getTaskExecutions();
assertNotNull("taskExecutionMap must not be null", taskExecutionMap);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
@@ -45,14 +89,13 @@ public class MapTaskExecutionDaoTests {
@Test
public void completeTaskExecution(){
MapTaskExecutionDao dao = new MapTaskExecutionDao();
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution = this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments());
dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
Map<Long, TaskExecution> taskExecutionMap = dao.getTaskExecutions();
Map<Long, TaskExecution> taskExecutionMap = this.dao.getTaskExecutions();
assertNotNull("taskExecutionMap must not be null", taskExecutionMap);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.task.repository.support;
import java.util.Collections;
import java.util.Date;
import java.util.UUID;
@@ -61,6 +62,17 @@ public class SimpleTaskRepositoryJdbcTests {
@Autowired
private TaskExplorer taskExplorer;
@Test
@DirtiesContext
public void testCreateEmptyExecution() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution actualTaskExecution = TestDBUtils.getTaskExecutionFromDB(dataSource,
expectedTaskExecution.getExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
actualTaskExecution);
}
@Test
@DirtiesContext
public void testCreateTaskExecutionNoParam() {
@@ -81,6 +93,39 @@ public class SimpleTaskRepositoryJdbcTests {
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void startTaskExecutionWithParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void startTaskExecutionWithNoParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void testCompleteTaskExecution() {
@@ -200,7 +245,6 @@ public class SimpleTaskRepositoryJdbcTests {
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test(expected=IllegalArgumentException.class)
@DirtiesContext
public void testCreateTaskExecutionNullEndTime(){

View File

@@ -16,8 +16,10 @@
package org.springframework.cloud.task.repository.support;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
@@ -43,6 +45,14 @@ public class SimpleTaskRepositoryMapTests {
this.taskRepository = new SimpleTaskRepository(new TaskExecutionDaoFactoryBean());
}
@Test
public void testCreateEmptyExecution() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
}
@Test
public void testCreateTaskExecutionNoParam() {
TaskExecution expectedTaskExecution =
@@ -59,6 +69,37 @@ public class SimpleTaskRepositoryMapTests {
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
}
@Test
public void startTaskExecutionWithParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
public void startTaskExecutionWithNoParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
public void testCompleteTaskExecution() {
TaskExecution expectedTaskExecution =

View File

@@ -30,6 +30,16 @@ import org.springframework.cloud.task.repository.TaskRepository;
*/
public class TaskExecutionCreator {
/**
* Creates a sample TaskExecution and stores it in the taskRepository.
*
* @param taskRepository the taskRepository where the taskExecution should be stored.
* @return the taskExecution created.
*/
public static TaskExecution createAndStoreEmptyTaskExecution(TaskRepository taskRepository) {
return taskRepository.createTaskExecution();
}
/**
* Creates a sample TaskExecution and stores it in the taskRepository.
*

View File

@@ -69,8 +69,8 @@ public class TestDefaultConfiguration implements InitializingBean {
}
@Bean
public TaskLifecycleListener taskHandler(){
return new TaskLifecycleListener(taskRepository(), taskNameResolver(), applicationArguments);
public TaskLifecycleListener taskHandler(TaskExplorer taskExplorer){
return new TaskLifecycleListener(taskRepository(), taskNameResolver(), applicationArguments, taskExplorer);
}
@Override