BATCH-1318: Added tests for various situations to test the exception classes

This commit is contained in:
dhgarrette
2009-07-04 10:37:00 +00:00
parent 746f455ba9
commit a6075e3bd1
10 changed files with 358 additions and 48 deletions

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.batch.core.step.item;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -26,34 +28,33 @@ import org.apache.commons.logging.LogFactory;
* @author Dan Garrette
* @since 2.0.1
*/
public abstract class ExceptionThrowingItemHandlerStub<T> {
public abstract class AbstractExceptionThrowingItemHandlerStub<T> {
protected Log logger = LogFactory.getLog(getClass());
private Collection<T> failures = Collections.emptyList();
private boolean runtimeException = false;
private Constructor<? extends Exception> exception;
public AbstractExceptionThrowingItemHandlerStub() throws Exception {
exception = SkippableRuntimeException.class.getConstructor(String.class);
}
public void setFailures(T... failures) {
this.failures = Arrays.asList(failures);
this.failures = new ArrayList<T>(Arrays.asList(failures));
}
public void setRuntimeException(boolean runtimeException) {
this.runtimeException = runtimeException;
public void setExceptionType(Class<? extends Exception> exceptionType) throws Exception {
exception = exceptionType.getConstructor(String.class);
}
public void clear() {
public void clearFailures() {
failures.clear();
}
protected void checkFailure(T item) throws Exception {
if (isFailure(item)) {
if (runtimeException) {
throw new SkippableRuntimeException("Intended Failure: "+item);
}
else {
throw new SkippableException("Intended Failure: "+item);
}
throw exception.newInstance("Intended Failure: " + item);
}
}

View File

@@ -0,0 +1,11 @@
package org.springframework.batch.core.step.item;
/**
* @author Dan Garrette
* @since 2.0.2
*/
public class FatalException extends SkippableException {
public FatalException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,11 @@
package org.springframework.batch.core.step.item;
/**
* @author Dan Garrette
* @since 2.0.2
*/
public class FatalRuntimeException extends SkippableRuntimeException {
public FatalRuntimeException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,204 @@
package org.springframework.batch.core.step.item;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.SimpleJob;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.JobRestartException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author Dan Garrette
* @since 2.0.2
*/
public class FaultTolerantExceptionClassesTests {
//
// TODO BATCH-1318: Commented out tests are related to this issue
//
private static ApplicationContext ctx;
private static JobRepository jobRepository;
private static JobLauncher jobLauncher;
private static SkipReaderStub<String> reader;
private static SkipWriterStub<String> writer;
@SuppressWarnings("unchecked")
@BeforeClass
public static void setCtx() {
ctx = new ClassPathXmlApplicationContext(
"/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests-context.xml");
jobRepository = (JobRepository) ctx.getBean("jobRepository");
jobLauncher = (JobLauncher) ctx.getBean("jobLauncher");
reader = (SkipReaderStub<String>) ctx.getBean("reader");
writer = (SkipWriterStub<String>) ctx.getBean("writer");
}
@Before
public void setup() {
reader.clear();
writer.clear();
}
@Test
public void testNonSkippable() throws Exception {
writer.setExceptionType(RuntimeException.class);
StepExecution stepExecution = launchStep("nonSkippableStep");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals("[1, 2, 3]", writer.getWritten().toString());
assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testNonSkippableChecked() throws Exception {
writer.setExceptionType(Exception.class);
StepExecution stepExecution = launchStep("nonSkippableStep");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals("[1, 2, 3]", writer.getWritten().toString());
assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testDefaultFatal() throws Exception {
writer.setExceptionType(RuntimeException.class);
StepExecution stepExecution = launchStep("skippableStep");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
// TODO BATCH-1318: assertEquals("[1, 2, 3]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testSkippable() throws Exception {
writer.setExceptionType(SkippableRuntimeException.class);
StepExecution stepExecution = launchStep("skippableStep");
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
assertEquals("[1, 2, 4]", writer.getCommitted().toString());
}
@Test
public void testFatal() throws Exception {
writer.setExceptionType(FatalRuntimeException.class);
StepExecution stepExecution = launchStep("skippableStep");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals("[1, 2, 3]", writer.getWritten().toString());
assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testDefaultFatalChecked() throws Exception {
writer.setExceptionType(Exception.class);
StepExecution stepExecution = launchStep("skippableStep");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
// TODO BATCH-1318: assertEquals("[1, 2, 3]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testSkippableChecked() throws Exception {
writer.setExceptionType(SkippableException.class);
StepExecution stepExecution = launchStep("skippableStep");
// TODO BATCH-1318: assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
// TODO BATCH-1318: assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[1, 2, 4]", writer.getCommitted().toString());
}
@Test
public void testFatalChecked() throws Exception {
writer.setExceptionType(FatalException.class);
StepExecution stepExecution = launchStep("skippableStep");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
// TODO BATCH-1318: assertEquals("[1, 2, 3]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testRetryableDefaultFatal() throws Exception {
writer.setExceptionType(RuntimeException.class);
StepExecution stepExecution = launchStep("retryable");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testRetryableSkippable() throws Exception {
writer.setExceptionType(SkippableRuntimeException.class);
StepExecution stepExecution = launchStep("retryable");
assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
assertEquals("[1, 2, 4]", writer.getCommitted().toString());
}
@Test
public void testRetryableFatal() throws Exception {
writer.setExceptionType(FatalRuntimeException.class);
StepExecution stepExecution = launchStep("retryable");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
// TODO BATCH-1318: assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testRetryableDefaultFatalChecked() throws Exception {
writer.setExceptionType(Exception.class);
StepExecution stepExecution = launchStep("retryable");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[]", writer.getCommitted().toString());
}
@Test
public void testRetryableSkippableChecked() throws Exception {
writer.setExceptionType(SkippableException.class);
StepExecution stepExecution = launchStep("retryable");
// TODO BATCH-1318: assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
// TODO BATCH-1318: assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[1, 2, 4]", writer.getCommitted().toString());
}
@Test
public void testRetryableFatalChecked() throws Exception {
writer.setExceptionType(FatalException.class);
StepExecution stepExecution = launchStep("retryable");
assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
// TODO BATCH-1318: assertEquals("[]", writer.getCommitted().toString());
}
private StepExecution launchStep(String stepName) throws JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException {
SimpleJob job = new SimpleJob();
job.setName("job");
job.setJobRepository(jobRepository);
List<Step> stepsToExecute = new ArrayList<Step>();
stepsToExecute.add((Step) ctx.getBean(stepName));
job.setSteps(stepsToExecute);
JobExecution jobExecution = jobLauncher.run(job, new JobParametersBuilder().addLong("timestamp",
new Date().getTime()).toJobParameters());
return jobExecution.getStepExecutions().iterator().next();
}
}

View File

@@ -37,11 +37,11 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
private FaultTolerantStepFactoryBean<String, String> factory;
private SkipReaderStub<String> reader = new SkipReaderStub<String>();
private SkipReaderStub<String> reader;
private SkipProcessorStub<String> processor = new SkipProcessorStub<String>();
private SkipProcessorStub<String> processor;
private SkipWriterStub<String> writer = new SkipWriterStub<String>();
private SkipWriterStub<String> writer;
private JobExecution jobExecution;
@@ -49,6 +49,12 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
private JobRepository repository;
public FaultTolerantStepFactoryBeanRollbackTests() throws Exception {
reader = new SkipReaderStub<String>();
processor = new SkipProcessorStub<String>();
writer = new SkipWriterStub<String>();
}
@Before
public void setUp() throws Exception {
factory = new FaultTolerantStepFactoryBean<String, String>();
@@ -118,7 +124,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
public void testReaderDefaultNoRollbackOnCheckedException() throws Exception {
reader.setItems("1", "2", "3", "4");
reader.setFailures("2", "3");
reader.setRuntimeException(false);
reader.setExceptionType(SkippableException.class);
Step step = (Step) factory.getObject();
@@ -135,7 +141,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
public void testReaderAttributesOverrideSkippableNoRollback() throws Exception {
reader.setFailures("2", "3");
reader.setItems("1", "2", "3", "4");
reader.setRuntimeException(false);
reader.setExceptionType(SkippableException.class);
// No skips by default
factory.setSkippableExceptionClasses(new HashSet<Class<? extends Throwable>>());
@@ -159,7 +165,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
reader.setItems("1", "2", "3", "4");
processor.setFailures("1", "3");
processor.setRuntimeException(false);
processor.setExceptionType(SkippableException.class);
Step step = (Step) factory.getObject();
@@ -177,7 +183,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
reader.setItems("1", "2", "3", "4");
processor.setFailures("1", "3");
processor.setRuntimeException(true);
processor.setExceptionType(SkippableRuntimeException.class);
Step step = (Step) factory.getObject();
@@ -190,7 +196,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
@Test
public void testProcessSkipWithNoRollbackForCheckedException() throws Exception {
processor.setFailures("4");
processor.setRuntimeException(false);
processor.setExceptionType(SkippableException.class);
factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class));
@@ -220,7 +226,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
@Test
public void testWriterDefaultRollbackOnCheckedException() throws Exception {
writer.setFailures("2", "3");
writer.setRuntimeException(false);
writer.setExceptionType(SkippableException.class);
Step step = (Step) factory.getObject();
@@ -236,7 +242,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
@Test
public void testWriterDefaultRollbackOnRuntimeException() throws Exception {
writer.setFailures("2", "3");
writer.setRuntimeException(true);
writer.setExceptionType(SkippableRuntimeException.class);
Step step = (Step) factory.getObject();
@@ -253,7 +259,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
@Test
public void testWriterNoRollbackOnRuntimeException() throws Exception {
writer.setFailures("2", "3");
writer.setRuntimeException(true);
writer.setExceptionType(SkippableRuntimeException.class);
factory.setNoRollbackExceptionClasses(getExceptionList(SkippableRuntimeException.class));
@@ -274,7 +280,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
@Test
public void testWriterNoRollbackOnCheckedException() throws Exception {
writer.setFailures("2", "3");
writer.setRuntimeException(false);
writer.setExceptionType(SkippableException.class);
factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class));
@@ -352,8 +358,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
assertEquals("[1, 2, 3, 5]", writer.getCommitted().toString());
assertEquals("[1, 2, 3, 4, 1, 2, 3, 4, 5]", writer.getWritten().toString());
// TODO: Fix this with BATCH-1259?
assertEquals("[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]", processor.getProcessed()
.toString());
assertEquals("[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]", processor.getProcessed().toString());
}
@Test
@@ -387,8 +392,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
assertEquals("[1, 2, 1, 2, 3, 4, 5]", writer.getWritten().toString());
assertEquals("[1, 3, 5]", processor.getCommitted().toString());
// TODO: Fix this with BATCH-1259?
assertEquals("[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]", processor.getProcessed()
.toString());
assertEquals("[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]", processor.getProcessed().toString());
}
@SuppressWarnings("unchecked")

View File

@@ -59,11 +59,11 @@ public class FaultTolerantStepFactoryBeanTests {
private FaultTolerantStepFactoryBean<String, String> factory;
private SkipReaderStub<String> reader = new SkipReaderStub<String>();
private SkipReaderStub<String> reader;
private SkipProcessorStub<String> processor = new SkipProcessorStub<String>();;
private SkipProcessorStub<String> processor;
private SkipWriterStub<String> writer = new SkipWriterStub<String>();
private SkipWriterStub<String> writer;
private JobExecution jobExecution;
@@ -75,6 +75,12 @@ public class FaultTolerantStepFactoryBeanTests {
private boolean closed = false;
public FaultTolerantStepFactoryBeanTests() throws Exception {
reader = new SkipReaderStub<String>();
processor = new SkipProcessorStub<String>();
writer = new SkipWriterStub<String>();
}
@Before
public void setUp() throws Exception {
factory = new FaultTolerantStepFactoryBean<String, String>();
@@ -786,12 +792,6 @@ public class FaultTolerantStepFactoryBeanTests {
}
}
private static class FatalRuntimeException extends SkippableRuntimeException {
public FatalRuntimeException(String message) {
super(message);
}
}
private void assertStepExecutionsAreEqual(StepExecution expected, StepExecution actual) {
assertEquals(expected.getId(), actual.getId());
assertEquals(expected.getStartTime(), actual.getStartTime());

View File

@@ -25,7 +25,7 @@ import org.springframework.batch.support.transaction.TransactionAwareProxyFactor
* @author Dan Garrette
* @since 2.0.1
*/
public class SkipProcessorStub<T> extends ExceptionThrowingItemHandlerStub<T> implements ItemProcessor<T, T> {
public class SkipProcessorStub<T> extends AbstractExceptionThrowingItemHandlerStub<T> implements ItemProcessor<T, T> {
private List<T> processed = new ArrayList<T>();
@@ -33,6 +33,10 @@ public class SkipProcessorStub<T> extends ExceptionThrowingItemHandlerStub<T> im
private boolean filter = false;
public SkipProcessorStub() throws Exception {
super();
}
public List<T> getProcessed() {
return processed;
}
@@ -46,7 +50,6 @@ public class SkipProcessorStub<T> extends ExceptionThrowingItemHandlerStub<T> im
}
public void clear() {
super.clear();
processed.clear();
committed.clear();
filter = false;

View File

@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
* @author Dan Garrette
* @since 2.0.1
*/
public class SkipReaderStub<T> extends ExceptionThrowingItemHandlerStub<T> implements ItemReader<T> {
public class SkipReaderStub<T> extends AbstractExceptionThrowingItemHandlerStub<T> implements ItemReader<T> {
private T[] items;
@@ -35,10 +35,12 @@ public class SkipReaderStub<T> extends ExceptionThrowingItemHandlerStub<T> imple
private int counter = -1;
public SkipReaderStub() {
public SkipReaderStub() throws Exception {
super();
}
public SkipReaderStub(T... items) {
public SkipReaderStub(T... items) throws Exception {
super();
this.items = items;
}
@@ -52,7 +54,6 @@ public class SkipReaderStub<T> extends ExceptionThrowingItemHandlerStub<T> imple
}
public void clear() {
super.clear();
counter = -1;
read.clear();
}

View File

@@ -25,12 +25,16 @@ import org.springframework.batch.support.transaction.TransactionAwareProxyFactor
* @author Dan Garrette
* @since 2.0.1
*/
public class SkipWriterStub<T> extends ExceptionThrowingItemHandlerStub<T> implements ItemWriter<T> {
public class SkipWriterStub<T> extends AbstractExceptionThrowingItemHandlerStub<T> implements ItemWriter<T> {
private List<T> written = new ArrayList<T>();
private List<T> committed = TransactionAwareProxyFactory.createTransactionalList();
public SkipWriterStub() throws Exception {
super();
}
public List<T> getWritten() {
return written;
}
@@ -40,13 +44,12 @@ public class SkipWriterStub<T> extends ExceptionThrowingItemHandlerStub<T> imple
}
public void clear() {
super.clear();
written.clear();
committed.clear();
}
public void write(List<? extends T> items) throws Exception {
logger.debug("Writing: "+items);
logger.debug("Writing: " + items);
for (T item : items) {
written.add(item);
checkFailure(item);