RESOLVED - issue BATCH-454: broken step's isAllowedStartIfComplete property

http://jira.springframework.org/browse/BATCH-454

job does not pass the restored context to step if the exit status of last execution is FINISHED
This commit is contained in:
robokaso
2008-03-14 10:18:23 +00:00
parent 8c281d1021
commit fe79a4dbe0
2 changed files with 104 additions and 54 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.batch.core.job;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import junit.framework.TestCase;
@@ -51,8 +52,8 @@ import org.springframework.batch.retry.RetryPolicy;
import org.springframework.transaction.PlatformTransactionManager;
/**
* Tests for DefaultJobLifecycle. MapJobDao and MapStepExecutionDao are used instead of a mock repository to test that
* status is being stored correctly.
* Tests for DefaultJobLifecycle. MapJobDao and MapStepExecutionDao are used
* instead of a mock repository to test that status is being stored correctly.
*
* @author Lucas Ward
*/
@@ -76,18 +77,14 @@ public class SimpleJobTests extends TestCase {
private StepExecution stepExecution2;
private StubStep stepConfiguration1;
private StubStep step1;
private StubStep stepConfiguration2;
private StubStep step2;
private JobParameters jobParameters = new JobParameters();
private SimpleJob job;
private Step step1;
private Step step2;
protected void setUp() throws Exception {
super.setUp();
@@ -101,33 +98,30 @@ public class SimpleJobTests extends TestCase {
job = new SimpleJob();
job.setJobRepository(jobRepository);
stepConfiguration1 = new StubStep("TestStep1");
stepConfiguration1.setCallback(new Runnable() {
step1 = new StubStep("TestStep1");
step1.setCallback(new Runnable() {
public void run() {
list.add("default");
}
});
stepConfiguration2 = new StubStep("TestStep2");
stepConfiguration2.setCallback(new Runnable() {
step2 = new StubStep("TestStep2");
step2.setCallback(new Runnable() {
public void run() {
list.add("default");
}
});
stepConfiguration1.setJobRepository(jobRepository);
stepConfiguration2.setJobRepository(jobRepository);
step1.setJobRepository(jobRepository);
step2.setJobRepository(jobRepository);
List stepConfigurations = new ArrayList();
stepConfigurations.add(stepConfiguration1);
stepConfigurations.add(stepConfiguration2);
List steps = new ArrayList();
steps.add(step1);
steps.add(step2);
job.setName("testJob");
job.setSteps(stepConfigurations);
job.setSteps(steps);
jobExecution = jobRepository.createJobExecution(job, jobParameters);
jobInstance = jobExecution.getJobInstance();
List steps = jobInstance.getJob().getSteps();
step1 = (Step) steps.get(0);
step2 = (Step) steps.get(1);
stepExecution1 = new StepExecution(step1, jobExecution, null);
stepExecution2 = new StepExecution(step2, jobExecution, null);
@@ -168,8 +162,8 @@ public class SimpleJobTests extends TestCase {
}
public void testRunNormally() throws Exception {
stepConfiguration1.setStartLimit(5);
stepConfiguration2.setStartLimit(5);
step1.setStartLimit(5);
step2.setStartLimit(5);
job.execute(jobExecution);
assertEquals(2, list.size());
checkRepository(BatchStatus.COMPLETED);
@@ -195,15 +189,15 @@ public class SimpleJobTests extends TestCase {
job.setJobRepository(jobRepository);
// do not set StepExecutorFactory...
stepConfiguration1.setStartLimit(5);
stepConfiguration1.setItemReader(new AbstractItemReader() {
step1.setStartLimit(5);
step1.setItemReader(new AbstractItemReader() {
public Object read() throws Exception {
list.add("1");
return null;
}
});
stepConfiguration2.setStartLimit(5);
stepConfiguration2.setItemReader(new AbstractItemReader() {
step2.setStartLimit(5);
step2.setItemReader(new AbstractItemReader() {
public Object read() throws Exception {
list.add("2");
return null;
@@ -224,13 +218,15 @@ public class SimpleJobTests extends TestCase {
}
public void testInterrupted() throws Exception {
stepConfiguration1.setStartLimit(5);
stepConfiguration2.setStartLimit(5);
step1.setStartLimit(5);
step2.setStartLimit(5);
final JobInterruptedException exception = new JobInterruptedException("Interrupt!");
stepConfiguration1.setProcessException(exception);
step1.setProcessException(exception);
try {
job.execute(jobExecution);
} catch (UnexpectedJobExecutionException e) {
fail();
}
catch (UnexpectedJobExecutionException e) {
assertEquals(exception, e.getCause());
}
assertEquals(0, list.size());
@@ -238,19 +234,21 @@ public class SimpleJobTests extends TestCase {
}
public void testFailed() throws Exception {
stepConfiguration1.setStartLimit(5);
stepConfiguration2.setStartLimit(5);
step1.setStartLimit(5);
step2.setStartLimit(5);
final RuntimeException exception = new RuntimeException("Foo!");
stepConfiguration1.setProcessException(exception);
step1.setProcessException(exception);
try {
job.execute(jobExecution);
} catch (RuntimeException e) {
fail();
}
catch (RuntimeException e) {
assertEquals(exception, e);
}
assertEquals(0, list.size());
checkRepository(BatchStatus.FAILED, ExitStatus.FAILED);
}
public void testFailedWithListener() throws Exception {
job.setJobListeners(new JobListenerSupport[] { new JobListenerSupport() {
public void onError(JobExecution jobExecution, Throwable t) {
@@ -258,11 +256,13 @@ public class SimpleJobTests extends TestCase {
}
} });
final RuntimeException exception = new RuntimeException("Foo!");
stepConfiguration1.setProcessException(exception);
step1.setProcessException(exception);
try {
job.execute(jobExecution);
} catch (RuntimeException e) {
fail();
}
catch (RuntimeException e) {
assertEquals(exception, e);
}
assertEquals(1, list.size());
@@ -271,13 +271,15 @@ public class SimpleJobTests extends TestCase {
}
public void testFailedWithError() throws Exception {
stepConfiguration1.setStartLimit(5);
stepConfiguration2.setStartLimit(5);
step1.setStartLimit(5);
step2.setStartLimit(5);
final Error exception = new Error("Foo!");
stepConfiguration1.setProcessException(exception);
step1.setProcessException(exception);
try {
job.execute(jobExecution);
} catch (Error e) {
fail();
}
catch (Error e) {
assertEquals(exception, e);
}
System.err.println(list);
@@ -287,15 +289,16 @@ public class SimpleJobTests extends TestCase {
public void testStepShouldNotStart() throws Exception {
// Start policy will return false, keeping the step from being started.
stepConfiguration1.setStartLimit(0);
step1.setStartLimit(0);
try {
job.execute(jobExecution);
fail("Expected BatchCriticalException");
} catch (UnexpectedJobExecutionException ex) {
}
catch (UnexpectedJobExecutionException ex) {
// expected
assertTrue("Wrong message in exception: " + ex.getMessage(), ex.getMessage()
.indexOf("start limit exceeded") >= 0);
.indexOf("start limit exceeded") >= 0);
}
}
@@ -305,17 +308,19 @@ public class SimpleJobTests extends TestCase {
job.execute(jobExecution);
ExitStatus exitStatus = jobExecution.getExitStatus();
assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().indexOf(
"No steps configured") >= 0);
"No steps configured") >= 0);
}
// public void testNoStepsExecuted() throws Exception {
// StepExecution completedExecution = new StepExecution("completedExecution", jobExecution);
// StepExecution completedExecution = new
// StepExecution("completedExecution", jobExecution);
// completedExecution.setStatus(BatchStatus.COMPLETED);
//
// job.execute(jobExecution);
// ExitStatus exitStatus = jobExecution.getExitStatus();
// assertEquals(ExitStatus.NOOP.getExitCode(), exitStatus.getExitCode());
// assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().contains(
// assertTrue("Wrong message in execution: " + exitStatus,
// exitStatus.getExitDescription().contains(
// "steps already completed"));
// }
@@ -323,7 +328,9 @@ public class SimpleJobTests extends TestCase {
jobExecution.stop();
try {
job.execute(jobExecution);
} catch (UnexpectedJobExecutionException e) {
fail();
}
catch (UnexpectedJobExecutionException e) {
assertTrue(e.getCause() instanceof JobInterruptedException);
}
assertEquals(0, list.size());
@@ -332,6 +339,31 @@ public class SimpleJobTests extends TestCase {
assertEquals(ExitStatus.NOOP.getExitCode(), exitStatus.getExitCode());
}
public void testRestart() throws Exception {
step1.setAllowStartIfComplete(true);
final RuntimeException exception = new RuntimeException("Foo!");
step2.setProcessException(exception);
try {
job.execute(jobExecution);
fail();
}
catch (RuntimeException e) {
assertSame(exception, e);
}
try {
job.execute(jobExecution);
fail();
}
catch (RuntimeException e) {
assertSame(exception, e);
}
assertTrue(step1.passedInContext.isEmpty());
assertFalse(step2.passedInContext.isEmpty());
}
/*
* Check JobRepository to ensure status is being saved.
*/
@@ -350,18 +382,28 @@ public class SimpleJobTests extends TestCase {
checkRepository(status, null);
}
private class StubStep extends AbstractStep {
private static class StubStep extends AbstractStep {
private Runnable runnable;
private Throwable exception;
protected ExceptionHandler exceptionHandler;
protected RetryPolicy retryPolicy;
protected JobRepository jobRepository;
protected PlatformTransactionManager transactionManager;
protected ItemReader itemReader;
protected ItemWriter itemWriter;
protected ItemSkipPolicy itemSkipPolicy = new NeverSkipItemSkipPolicy();
Properties passedInContext;
/**
* @param string
*/
@@ -383,7 +425,13 @@ public class SimpleJobTests extends TestCase {
this.runnable = runnable;
}
public void execute(StepExecution stepExecution) throws JobInterruptedException, UnexpectedJobExecutionException {
public void execute(StepExecution stepExecution) throws JobInterruptedException,
UnexpectedJobExecutionException {
passedInContext = stepExecution.getExecutionContext().getProperties();
stepExecution.getExecutionContext().putString("key", "value");
jobRepository.saveOrUpdateExecutionContext(stepExecution);
if (exception instanceof RuntimeException) {
stepExecution.setExitStatus(ExitStatus.FAILED);
throw (RuntimeException) exception;
@@ -403,7 +451,8 @@ public class SimpleJobTests extends TestCase {
}
/**
* Set the name property. Always overrides the default value if this object is a Spring bean.
* Set the name property. Always overrides the default value if this
* object is a Spring bean.
*
* @see #setBeanName(java.lang.String)
*/