@Override public String toString() { return String.format(getSummary() + ", exitDescription=%s", exitStatus.getExitDescription()); }
@Test public void testAddExitDescriptionWIthStacktrace() throws Exception { ExitStatus status = ExitStatus.EXECUTING.addExitDescription(new RuntimeException("Foo")); assertTrue(ExitStatus.EXECUTING != status); String description = status.getExitDescription(); assertTrue("Wrong description: "+description, description.contains("Foo")); assertTrue("Wrong description: "+description, description.contains("RuntimeException")); }
@Test public void testExitStatusNullDescription() { ExitStatus status = new ExitStatus("10", null); assertEquals("", status.getExitDescription()); }
@Test public void testNoSteps() throws Exception { job.setSteps(new ArrayList<>()); job.execute(jobExecution); ExitStatus exitStatus = jobExecution.getExitStatus(); assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().indexOf( "no steps configured") >= 0); }
/** * Long exit descriptions are truncated on both save and update. */ @Transactional @Test public void testTruncateExitDescription() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) { sb.append("too long exit description"); } String longDescription = sb.toString(); ExitStatus exitStatus = ExitStatus.FAILED.addExitDescription(longDescription); stepExecution.setExitStatus(exitStatus); ((JdbcStepExecutionDao) dao).setExitMessageLength(250); dao.saveStepExecution(stepExecution); StepExecution retrievedAfterSave = dao.getStepExecution(jobExecution, stepExecution.getId()); assertTrue("Exit description should be truncated", retrievedAfterSave.getExitStatus().getExitDescription() .length() < stepExecution.getExitStatus().getExitDescription().length()); dao.updateStepExecution(stepExecution); StepExecution retrievedAfterUpdate = dao.getStepExecution(jobExecution, stepExecution.getId()); assertTrue("Exit description should be truncated", retrievedAfterUpdate.getExitStatus().getExitDescription() .length() < stepExecution.getExitStatus().getExitDescription().length()); }
@Test public void testAddExitDescription() throws Exception { ExitStatus status = ExitStatus.EXECUTING.addExitDescription("Foo"); assertTrue(ExitStatus.EXECUTING != status); assertEquals("Foo", status.getExitDescription()); }
@Test public void testAddEmptyExitDescription() throws Exception { ExitStatus status = ExitStatus.EXECUTING.addExitDescription("Foo").addExitDescription((String)null); assertEquals("Foo", status.getExitDescription()); }
@Test public void testAddExitDescriptionToSameStatus() throws Exception { ExitStatus status = ExitStatus.EXECUTING.addExitDescription("Foo").addExitDescription("Foo"); assertTrue(ExitStatus.EXECUTING != status); assertEquals("Foo", status.getExitDescription()); }
@Test public void testSetValidator() throws Exception { job.setJobParametersValidator(new DefaultJobParametersValidator() { @Override public void validate(JobParameters parameters) throws JobParametersInvalidException { throw new JobParametersInvalidException("FOO"); } }); JobExecution execution = jobRepository.createJobExecution("job", new JobParameters()); job.execute(execution); assertEquals(BatchStatus.FAILED, execution.getStatus()); assertEquals("FOO", execution.getFailureExceptions().get(0).getMessage()); String description = execution.getExitStatus().getExitDescription(); assertTrue("Wrong description: "+description, description.contains("FOO")); }
@Test public void testAddExitCodeWithDescription() throws Exception { ExitStatus status = new ExitStatus("BAR", "Bar").replaceExitCode("FOO"); assertEquals("FOO", status.getExitCode()); assertEquals("Bar", status.getExitDescription()); }
@Test public void testLaunchJob() throws Exception { int before = jobExplorer.getJobInstances(job.getName(), 0, 100).size(); assertNotNull(jobLauncher.run(job, new JobParameters())); List<JobInstance> jobInstances = jobExplorer.getJobInstances(job.getName(), 0, 100); int after = jobInstances.size(); assertEquals(1, after - before); JobExecution jobExecution = jobExplorer.getJobExecutions(jobInstances.get(jobInstances.size() - 1)).get(0); assertEquals(jobExecution.getExitStatus().getExitDescription(), BatchStatus.COMPLETED, jobExecution.getStatus()); assertEquals(3, jobExecution.getStepExecutions().size()); for (StepExecution stepExecution : jobExecution.getStepExecutions()) { // BATCH-1703: we are using a map dao so the step executions in the job execution are old and we need to // pull them back out of the repository... stepExecution = jobExplorer.getStepExecution(jobExecution.getId(), stepExecution.getId()); logger.debug("" + stepExecution); assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); } } }
/** * This one is flakey - we try to force it to wait until after the step to * finish processing just by waiting for long enough. */ @Test public void testFailureInStepListener() throws Exception { factory.setItemReader(new ListItemReader<>(Arrays.asList(StringUtils .commaDelimitedListToStringArray("wait,fail,3,4,5,6")))); Step step = factory.getObject(); StepExecution stepExecution = getStepExecution(step); step.execute(stepExecution); waitForResults(2, 10); // The number of items processed is actually between 1 and 6, because // the one that failed might have been processed out of order. assertTrue(1 <= TestItemWriter.count); assertTrue(6 >= TestItemWriter.count); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); String exitDescription = stepExecution.getExitStatus().getExitDescription(); assertTrue("Exit description does not contain exception type name: " + exitDescription, exitDescription .contains(AsynchronousFailureException.class.getName())); }
@Test public void testRemoteChunkingJob() throws Exception { // when JobExecution jobExecution = this.jobLauncherTestUtils.launchJob(); // then Assert.assertEquals(ExitStatus.COMPLETED.getExitCode(), jobExecution.getExitStatus().getExitCode()); Assert.assertEquals( "Waited for 2 results.", // the master sent 2 chunks ({1, 2, 3} and {4, 5, 6}) to workers jobExecution.getExitStatus().getExitDescription()); }
@Test public void testAfterStep() throws Exception { final ExitStatus customStatus = new ExitStatus("COMPLETED_CUSTOM"); step.setStepExecutionListeners(new StepExecutionListener[] { new StepExecutionListenerSupport() { @Override public ExitStatus afterStep(StepExecution stepExecution) { list.add("afterStepCalled"); return customStatus; } } }); RepeatTemplate stepTemplate = new RepeatTemplate(); stepTemplate.setCompletionPolicy(new SimpleCompletionPolicy(5)); step.setStepOperations(stepTemplate); JobExecution jobExecution = new JobExecution(jobInstance, jobParameters); StepExecution stepExecution = new StepExecution(step.getName(), jobExecution); step.execute(stepExecution); assertEquals(1, list.size()); ExitStatus returnedStatus = stepExecution.getExitStatus(); assertEquals(customStatus.getExitCode(), returnedStatus.getExitCode()); assertEquals(customStatus.getExitDescription(), returnedStatus.getExitDescription()); }
@Test public void testStatusForFinalUpdateFailedException() throws Exception { step.setJobRepository(new JobRepositorySupport()); step.setStreams(new ItemStream[] { new ItemStreamSupport() { @Override public void close() throws ItemStreamException { super.close(); throw new RuntimeException("Bar"); } } }); JobExecution jobExecutionContext = new JobExecution(jobInstance, jobParameters); StepExecution stepExecution = new StepExecution(step.getName(), jobExecutionContext); step.execute(stepExecution); // The job actually completed, but the streams couldn't be closed. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); String msg = stepExecution.getExitStatus().getExitDescription(); assertEquals("", msg); Throwable ex = stepExecution.getFailureExceptions().get(0); // The original rollback was caused by this one: assertEquals("Bar", ex.getMessage()); }
@Test public void testSimulatedRestartWithNoBacklog() throws Exception { factory.setItemReader(new ListItemReader<>(Arrays.asList(StringUtils .commaDelimitedListToStringArray("1,2,3,4,5,6")))); Step step = factory.getObject(); StepExecution stepExecution = getStepExecution(step); // Set up expectation of three messages (chunks) in the backlog stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.EXPECTED, 6); stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.ACTUAL, 3); writer.setMaxWaitTimeouts(2); /* * With no backlog we process all the items, but the listener can't * reconcile the expected number of items with the actual. An infinite * loop would be bad, so the best we can do is fail as fast as possible. */ step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); String message = stepExecution.getExitStatus().getExitDescription(); assertTrue("Message did not contain 'timed out': " + message, message.toLowerCase().contains("timed out")); assertEquals(0, TestItemWriter.count); assertEquals(0, stepExecution.getReadCount()); }
@Test public void testEarlyCompletionSignalledInHandler() throws Exception { factory.setItemReader(new ListItemReader<>(Arrays.asList(StringUtils .commaDelimitedListToStringArray("1,fail,3,4,5,6")))); factory.setCommitInterval(2); Step step = factory.getObject(); StepExecution stepExecution = getStepExecution(step); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); String message = stepExecution.getExitStatus().getExitDescription(); assertTrue("Message does not contain 'fail': " + message, message.contains("fail")); waitForResults(2, 10); // The number of items processed is actually between 1 and 6, because // the one that failed might have been processed out of order. assertTrue(1 <= TestItemWriter.count); assertTrue(6 >= TestItemWriter.count); // But it should fail the step in any case assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); }
@Test public void testSimulatedRestartWithBadMessagesFromAnotherJob() throws Exception { factory.setItemReader(new ListItemReader<>(Arrays.asList(StringUtils .commaDelimitedListToStringArray("1,2,3,4,5,6")))); Step step = factory.getObject(); StepExecution stepExecution = getStepExecution(step); // Set up context with two messages (chunks) in the backlog stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.EXPECTED, 3); stepExecution.getExecutionContext().putInt(ChunkMessageChannelItemWriter.ACTUAL, 2); // Speed up the eventual failure writer.setMaxWaitTimeouts(2); // And make the back log real requests.send(getSimpleMessage("foo", 4321L)); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); String message = stepExecution.getExitStatus().getExitDescription(); assertTrue("Message does not contain 'wrong job': " + message, message.contains("wrong job")); waitForResults(1, 10); assertEquals(1, TestItemWriter.count); assertEquals(0, stepExecution.getReadCount()); }
@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())); }
/** * Non-skippable (and non-fatal) exception causes failure immediately. * * @throws Exception */ @SuppressWarnings("unchecked") @Test public void testNonSkippableExceptionOnRead() throws Exception { reader.setFailures("2"); // nothing is skippable factory.setSkippableExceptionClasses(getExceptionMap(NonExistentException.class)); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals(ExitStatus.FAILED.getExitCode(), stepExecution.getExitStatus().getExitCode()); assertTrue(stepExecution.getExitStatus().getExitDescription().contains("Non-skippable exception during read")); assertStepExecutionsAreEqual(stepExecution, repository.getLastStepExecution(jobExecution.getJobInstance(), step .getName())); }