/** * Check items causing errors are skipped as expected. */ @Test public void testSkipOnWriteNotDoubleCounted() throws Exception { reader.setItems(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6,7")); reader.setFailures(StringUtils.commaDelimitedListToStringArray("2,3")); writer.setFailures("4", "5"); factory.setSkipLimit(4); factory.setCommitInterval(3); // includes all expected skips Step step = factory.getObject(); step.execute(stepExecution); assertEquals(4, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getReadSkipCount()); assertEquals(2, stepExecution.getWriteSkipCount()); // skipped 2,3,4,5 List<String> expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,6,7")); assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Check items causing errors are skipped as expected. */ @Test public void testSkipOnReadNotDoubleCounted() throws Exception { reader.setItems(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6")); reader.setFailures(StringUtils.commaDelimitedListToStringArray("2,3,5")); writer.setFailures("4"); factory.setSkipLimit(4); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(4, stepExecution.getSkipCount()); assertEquals(3, stepExecution.getReadSkipCount()); assertEquals(1, stepExecution.getWriteSkipCount()); // skipped 2,3,4,5 List<String> expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,6")); assertEquals(expectedOutput, writer.getCommitted()); // reader exceptions should not cause rollback, 1 writer exception // causes 2 rollbacks assertEquals(2, stepExecution.getRollbackCount()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Check items causing errors are skipped as expected. */ @SuppressWarnings("unchecked") @Test public void testSkipListenerFailsOnRead() throws Exception { reader.setItems(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6")); reader.setFailures(StringUtils.commaDelimitedListToStringArray("2,3,5")); writer.setFailures("4"); factory.setSkipLimit(3); factory.setListeners(new StepListener[] { new SkipListenerSupport<String, String>() { @Override public void onSkipInRead(Throwable t) { throw new RuntimeException("oops"); } } }); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("oops", stepExecution.getFailureExceptions().get(0).getCause().getMessage()); // listeners are called only once chunk is about to commit, so // listener failure does not affect other statistics assertEquals(2, stepExecution.getReadSkipCount()); // but we didn't get as far as the write skip in the scan: assertEquals(0, stepExecution.getWriteSkipCount()); assertEquals(2, stepExecution.getSkipCount()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Check items causing errors are skipped as expected. */ @SuppressWarnings("unchecked") @Test public void testSkipOverLimitOnReadWithAllSkipsAtEnd() throws Exception { reader.setItems(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6,7,8,9,10,11,12,13,14,15")); reader.setFailures(StringUtils.commaDelimitedListToStringArray("6,12,13,14,15")); writer.setFailures("4"); factory.setCommitInterval(5); factory.setSkipLimit(3); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("bad skip count", 3, stepExecution.getSkipCount()); assertEquals("bad read skip count", 2, stepExecution.getReadSkipCount()); assertEquals("bad write skip count", 1, stepExecution.getWriteSkipCount()); // writer did not skip "6" as it never made it to writer, only "4" did assertFalse(reader.getRead().contains("6")); assertTrue(reader.getRead().contains("4")); // only "1" was ever committed List<String> expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1,2,3,5,7,8,9,10,11")); assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
@Test public void testReprocessingAfterWriterRollback() throws Exception { reader.setItems("1", "2", "3", "4"); writer.setFailures("4"); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(1, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getRollbackCount()); // 1,2,3,4,3,4 - one scan until the item is // identified and finally skipped on the second attempt assertEquals("[1, 2, 3, 4, 3, 4]", processor.getProcessed().toString()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Check items causing errors are skipped as expected. */ @SuppressWarnings("unchecked") @Test public void testSkipOverLimitOnRead() throws Exception { reader.setItems(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6")); reader.setFailures(StringUtils.commaDelimitedListToStringArray("2,3,5")); writer.setFailures("4"); factory.setSkipLimit(3); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(3, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getReadSkipCount()); assertEquals(1, stepExecution.getWriteSkipCount()); assertEquals(2, stepExecution.getReadCount()); // writer did not skip "2" as it never made it to writer, only "4" did assertFalse(reader.getRead().contains("2")); assertTrue(reader.getRead().contains("4")); // only "1" was ever committed List<String> expectedOutput = Arrays.asList(StringUtils.commaDelimitedListToStringArray("1")); assertEquals(expectedOutput, writer.getCommitted()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
@SuppressWarnings("unchecked") @Test public void testDefaultSkipPolicy() throws Exception { reader.setItems("a", "b", "c"); reader.setFailures("b"); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); factory.setSkipLimit(1); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(1, stepExecution.getSkipCount()); assertEquals("[a, c]", reader.getRead().toString()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Check items causing errors are skipped as expected. */ @SuppressWarnings("unchecked") @Test public void testSkipListenerFailsOnWrite() throws Exception { reader.setItems(StringUtils.commaDelimitedListToStringArray("1,2,3,4,5,6")); writer.setFailures("4"); factory.setSkipLimit(3); factory.setListeners(new StepListener[] { new SkipListenerSupport<String, String>() { @Override public void onSkipInWrite(String item, Throwable t) { throw new RuntimeException("oops"); } } }); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("oops", stepExecution.getFailureExceptions().get(0).getCause().getMessage()); assertEquals(1, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getReadSkipCount()); assertEquals(1, stepExecution.getWriteSkipCount()); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Scenario: Exception in processor that should cause rollback */ @Test public void testProcessorDefaultRollbackOnRuntimeException() throws Exception { reader.setItems("1", "2", "3", "4"); processor.setFailures("1", "3"); processor.setExceptionType(SkippableRuntimeException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getRollbackCount()); }
reader.setItems("1", "2", "3", "4", "5"); factory.setItemReader(reader); writer.clear();
/** * Scenario: Exception in processor that should cause rollback because of * checked exception */ @Test public void testProcessorDefaultRollbackOnCheckedException() throws Exception { reader.setItems("1", "2", "3", "4"); processor.setFailures("1", "3"); processor.setExceptionType(SkippableException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(2, stepExecution.getRollbackCount()); }
/** * Scenario: Exception in reader that should not cause rollback */ @Test public void testReaderDefaultNoRollbackOnCheckedException() throws Exception { reader.setItems("1", "2", "3", "4"); reader.setFailures("2", "3"); reader.setExceptionType(SkippableException.class); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(2, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getRollbackCount()); }
@SuppressWarnings("unchecked") @Test public void testNonSkippableException() throws Exception { // nothing is skippable factory.setSkippableExceptionClasses(getExceptionMap(NonExistentException.class)); factory.setCommitInterval(1); // no failures on read reader.setItems("1", "2", "3", "4", "5"); writer.setFailures("1"); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(1, reader.getRead().size()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); assertTrue(stepExecution.getExitStatus().getExitDescription().contains("Intended Failure")); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }
/** * Scenario: Exception in reader that should not cause rollback */ @SuppressWarnings("unchecked") @Test public void testReaderAttributesOverrideSkippableNoRollback() throws Exception { reader.setFailures("2", "3"); reader.setItems("1", "2", "3", "4"); reader.setExceptionType(SkippableException.class); // No skips by default factory.setSkippableExceptionClasses(getExceptionMap(RuntimeException.class)); // But this one is explicit in the tx-attrs so it should be skipped factory.setNoRollbackExceptionClasses(getExceptionList(SkippableException.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); assertEquals(0, stepExecution.getSkipCount()); assertEquals(0, stepExecution.getRollbackCount()); }
@SuppressWarnings("unchecked") @Before public void setUp() throws Exception { factory = new FaultTolerantStepFactoryBean<>(); factory.setBeanName("stepName"); factory.setTransactionManager(new ResourcelessTransactionManager()); factory.setCommitInterval(2); reader.clear(); reader.setItems("1", "2", "3", "4", "5"); factory.setItemReader(reader); processor.clear(); factory.setItemProcessor(processor); writer.clear(); factory.setItemWriter(writer); factory.setSkipLimit(2); factory .setSkippableExceptionClasses(getExceptionMap(SkippableException.class, SkippableRuntimeException.class)); MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean(); repositoryFactory.afterPropertiesSet(); repository = repositoryFactory.getObject(); factory.setJobRepository(repository); jobExecution = repository.createJobExecution("skipJob", new JobParameters()); stepExecution = jobExecution.createStepExecution(factory.getName()); repository.add(stepExecution); }
@SuppressWarnings("unchecked") @Before public void setUp() throws Exception { reader = new SkipReaderStub<>(); processor = new SkipProcessorStub<>(); writer = new SkipWriterStub<>(); factory = new FaultTolerantStepFactoryBean<>(); factory.setBeanName("stepName"); ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager(); factory.setTransactionManager(transactionManager); factory.setCommitInterval(2); reader.clear(); reader.setItems("1", "2", "3", "4", "5"); factory.setItemReader(reader); processor.clear(); factory.setItemProcessor(processor); writer.clear(); factory.setItemWriter(writer); factory.setSkipLimit(2); factory.setSkippableExceptionClasses(getExceptionMap(Exception.class)); MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean(); repositoryFactory.setTransactionManager(transactionManager); repositoryFactory.afterPropertiesSet(); repository = repositoryFactory.getObject(); factory.setJobRepository(repository); jobExecution = repository.createJobExecution("skipJob", new JobParameters()); stepExecution = jobExecution.createStepExecution(factory.getName()); repository.add(stepExecution); }