PageRenderTime 57ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantExceptionClassesTests.java

https://github.com/ftaiolivista/spring-batch
Java | 332 lines | 253 code | 40 blank | 39 comment | 0 complexity | 4f7f5324199772c61998c5d7274fa58b MD5 | raw file
  1. package org.springframework.batch.core.step.item;
  2. import static org.junit.Assert.assertEquals;
  3. import static org.junit.Assert.assertNotNull;
  4. import java.util.ArrayList;
  5. import java.util.Date;
  6. import java.util.List;
  7. import org.junit.Before;
  8. import org.junit.Test;
  9. import org.junit.runner.RunWith;
  10. import org.springframework.batch.core.BatchStatus;
  11. import org.springframework.batch.core.JobExecution;
  12. import org.springframework.batch.core.JobParametersBuilder;
  13. import org.springframework.batch.core.Step;
  14. import org.springframework.batch.core.StepExecution;
  15. import org.springframework.batch.core.job.SimpleJob;
  16. import org.springframework.batch.core.launch.JobLauncher;
  17. import org.springframework.batch.core.repository.JobRepository;
  18. import org.springframework.beans.BeansException;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.context.ApplicationContext;
  21. import org.springframework.context.ApplicationContextAware;
  22. import org.springframework.test.context.ContextConfiguration;
  23. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  24. import org.springframework.transaction.UnexpectedRollbackException;
  25. /**
  26. * @author Dan Garrette
  27. * @since 2.0.2
  28. */
  29. @ContextConfiguration
  30. @RunWith(SpringJUnit4ClassRunner.class)
  31. public class FaultTolerantExceptionClassesTests implements ApplicationContextAware {
  32. @Autowired
  33. private JobRepository jobRepository;
  34. @Autowired
  35. private JobLauncher jobLauncher;
  36. @Autowired
  37. private SkipReaderStub<String> reader;
  38. @Autowired
  39. private SkipWriterStub<String> writer;
  40. @Autowired
  41. private ExceptionThrowingTaskletStub tasklet;
  42. private ApplicationContext applicationContext;
  43. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
  44. this.applicationContext = applicationContext;
  45. }
  46. @Before
  47. public void setup() {
  48. reader.clear();
  49. writer.clear();
  50. }
  51. @Test
  52. public void testNonSkippable() throws Exception {
  53. writer.setExceptionType(RuntimeException.class);
  54. StepExecution stepExecution = launchStep("nonSkippableStep");
  55. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  56. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  57. assertEquals("[]", writer.getCommitted().toString());
  58. }
  59. @Test
  60. public void testNonSkippableChecked() throws Exception {
  61. writer.setExceptionType(Exception.class);
  62. StepExecution stepExecution = launchStep("nonSkippableStep");
  63. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  64. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  65. assertEquals("[]", writer.getCommitted().toString());
  66. }
  67. @Test
  68. public void testSkippable() throws Exception {
  69. writer.setExceptionType(SkippableRuntimeException.class);
  70. StepExecution stepExecution = launchStep("skippableStep");
  71. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  72. assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  73. assertEquals("[1, 2, 4]", writer.getCommitted().toString());
  74. }
  75. @Test
  76. public void testRegularRuntimeExceptionNotSkipped() throws Exception {
  77. writer.setExceptionType(RuntimeException.class);
  78. StepExecution stepExecution = launchStep("skippableStep");
  79. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  80. // BATCH-1327:
  81. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  82. // BATCH-1327:
  83. assertEquals("[]", writer.getCommitted().toString());
  84. }
  85. @Test
  86. public void testFatalOverridesSkippable() throws Exception {
  87. writer.setExceptionType(FatalRuntimeException.class);
  88. StepExecution stepExecution = launchStep("skippableFatalStep");
  89. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  90. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  91. assertEquals("[]", writer.getCommitted().toString());
  92. }
  93. @Test
  94. public void testDefaultFatalChecked() throws Exception {
  95. writer.setExceptionType(Exception.class);
  96. StepExecution stepExecution = launchStep("skippableFatalStep");
  97. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  98. // BATCH-1327:
  99. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  100. // BATCH-1327:
  101. assertEquals("[]", writer.getCommitted().toString());
  102. }
  103. @Test
  104. public void testSkippableChecked() throws Exception {
  105. writer.setExceptionType(SkippableException.class);
  106. StepExecution stepExecution = launchStep("skippableStep");
  107. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  108. assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  109. assertEquals("[1, 2, 4]", writer.getCommitted().toString());
  110. }
  111. @Test
  112. public void testNonSkippableUnchecked() throws Exception {
  113. writer.setExceptionType(UnexpectedRollbackException.class);
  114. StepExecution stepExecution = launchStep("skippableStep");
  115. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  116. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  117. assertEquals("[]", writer.getCommitted().toString());
  118. }
  119. @Test
  120. public void testFatalChecked() throws Exception {
  121. writer.setExceptionType(FatalSkippableException.class);
  122. StepExecution stepExecution = launchStep("skippableFatalStep");
  123. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  124. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  125. assertEquals("[]", writer.getCommitted().toString());
  126. }
  127. @Test
  128. public void testRetryableButNotSkippable() throws Exception {
  129. writer.setExceptionType(RuntimeException.class);
  130. StepExecution stepExecution = launchStep("retryable");
  131. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  132. assertEquals("[1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
  133. // BATCH-1327:
  134. assertEquals("[]", writer.getCommitted().toString());
  135. }
  136. @Test
  137. public void testRetryableSkippable() throws Exception {
  138. writer.setExceptionType(SkippableRuntimeException.class);
  139. StepExecution stepExecution = launchStep("retryable");
  140. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  141. assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  142. assertEquals("[1, 2, 4]", writer.getCommitted().toString());
  143. }
  144. @Test
  145. public void testRetryableFatal() throws Exception {
  146. // User wants all exceptions to be retried, but only some are skippable
  147. // FatalRuntimeException is not skippable because it is fatal, but is a
  148. // subclass of another skippable
  149. writer.setExceptionType(FatalRuntimeException.class);
  150. StepExecution stepExecution = launchStep("retryable");
  151. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  152. // BATCH-1333:
  153. assertEquals("[1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
  154. assertEquals("[]", writer.getCommitted().toString());
  155. }
  156. @Test
  157. public void testRetryableButNotSkippableChecked() throws Exception {
  158. writer.setExceptionType(Exception.class);
  159. StepExecution stepExecution = launchStep("retryable");
  160. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  161. assertEquals("[1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
  162. // BATCH-1327:
  163. assertEquals("[]", writer.getCommitted().toString());
  164. }
  165. @Test
  166. public void testRetryableSkippableChecked() throws Exception {
  167. writer.setExceptionType(SkippableException.class);
  168. StepExecution stepExecution = launchStep("retryable");
  169. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  170. assertEquals("[1, 2, 3, 1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  171. assertEquals("[1, 2, 4]", writer.getCommitted().toString());
  172. }
  173. @Test
  174. public void testRetryableFatalChecked() throws Exception {
  175. writer.setExceptionType(FatalSkippableException.class);
  176. StepExecution stepExecution = launchStep("retryable");
  177. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  178. // BATCH-1333:
  179. assertEquals("[1, 2, 3, 1, 2, 3]", writer.getWritten().toString());
  180. assertEquals("[]", writer.getCommitted().toString());
  181. assertEquals(0, stepExecution.getWriteSkipCount());
  182. }
  183. @Test
  184. public void testNoRollbackDefaultRollbackException() throws Exception {
  185. // Exception is neither no-rollback nor skippable
  186. writer.setExceptionType(Exception.class);
  187. StepExecution stepExecution = launchStep("noRollbackDefault");
  188. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  189. // BATCH-1318:
  190. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  191. // BATCH-1318:
  192. assertEquals("[]", writer.getCommitted().toString());
  193. assertEquals(0, stepExecution.getWriteSkipCount());
  194. }
  195. @Test
  196. public void testNoRollbackDefaultNoRollbackException() throws Exception {
  197. // Exception is no-rollback and not skippable
  198. writer.setExceptionType(IllegalStateException.class);
  199. StepExecution stepExecution = launchStep("noRollbackDefault");
  200. assertNotNull(stepExecution);
  201. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  202. // BATCH-1334:
  203. assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  204. // BATCH-1334:
  205. assertEquals("[1, 2, 3, 4]", writer.getCommitted().toString());
  206. // BATCH-1334:
  207. assertEquals(0, stepExecution.getWriteSkipCount());
  208. }
  209. @Test
  210. public void testNoRollbackPathology() throws Exception {
  211. // Exception is neither no-rollback nor skippable and no-rollback is
  212. // RuntimeException (potentially pathological because other obviously
  213. // rollback signalling Exceptions also extend RuntimeException)
  214. writer.setExceptionType(Exception.class);
  215. StepExecution stepExecution = launchStep("noRollbackPathology");
  216. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  217. // BATCH-1335:
  218. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  219. // BATCH-1335:
  220. assertEquals("[]", writer.getCommitted().toString());
  221. }
  222. @Test
  223. public void testNoRollbackSkippableRollbackException() throws Exception {
  224. writer.setExceptionType(SkippableRuntimeException.class);
  225. StepExecution stepExecution = launchStep("noRollbackSkippable");
  226. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  227. assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  228. assertEquals("[1, 2, 4]", writer.getCommitted().toString());
  229. }
  230. @Test
  231. public void testNoRollbackSkippableNoRollbackException() throws Exception {
  232. writer.setExceptionType(FatalRuntimeException.class);
  233. StepExecution stepExecution = launchStep("noRollbackSkippable");
  234. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  235. // BATCH-1332:
  236. assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  237. // BATCH-1334:
  238. // Skipped but also committed (because it was marked as no-rollback)
  239. assertEquals("[1, 2, 3, 4]", writer.getCommitted().toString());
  240. assertEquals(1, stepExecution.getWriteSkipCount());
  241. }
  242. @Test
  243. public void testNoRollbackFatalRollbackException() throws Exception {
  244. writer.setExceptionType(SkippableRuntimeException.class);
  245. StepExecution stepExecution = launchStep("noRollbackFatal");
  246. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  247. assertEquals("[1, 2, 3]", writer.getWritten().toString());
  248. assertEquals("[]", writer.getCommitted().toString());
  249. }
  250. @Test
  251. public void testNoRollbackFatalNoRollbackException() throws Exception {
  252. // User has asked for no rollback on a fatal exception. What should the
  253. // outcome be? As per BATCH-1333 it is interpreted as not skippable, but
  254. // retryable if requested. Here it was not requested to be retried, but
  255. // it was marked as no-rollback. As per BATCH-1334 this has to be ignored
  256. // so that the failed item can be isolated.
  257. writer.setExceptionType(FatalRuntimeException.class);
  258. StepExecution stepExecution = launchStep("noRollbackFatal");
  259. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  260. // BATCH-1331:
  261. assertEquals("[1, 2, 3, 1, 2, 3, 4]", writer.getWritten().toString());
  262. // BATCH-1331:
  263. assertEquals("[1, 2, 3, 4]", writer.getCommitted().toString());
  264. }
  265. @Test
  266. public void testNoRollbackTaskletRollbackException() throws Exception {
  267. tasklet.setExceptionType(RuntimeException.class);
  268. StepExecution stepExecution = launchStep("noRollbackTasklet");
  269. assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  270. assertEquals("[]", tasklet.getCommitted().toString());
  271. }
  272. @Test
  273. public void testNoRollbackTaskletNoRollbackException() throws Exception {
  274. tasklet.setExceptionType(SkippableRuntimeException.class);
  275. StepExecution stepExecution = launchStep("noRollbackTasklet");
  276. // assertEquals(BatchStatus.FAILED, stepExecution.getStatus());
  277. // BATCH-1298:
  278. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
  279. assertEquals("[1, 1, 1, 1]", tasklet.getCommitted().toString());
  280. }
  281. private StepExecution launchStep(String stepName) throws Exception {
  282. SimpleJob job = new SimpleJob();
  283. job.setName("job");
  284. job.setJobRepository(jobRepository);
  285. List<Step> stepsToExecute = new ArrayList<Step>();
  286. stepsToExecute.add((Step) applicationContext.getBean(stepName));
  287. job.setSteps(stepsToExecute);
  288. JobExecution jobExecution = jobLauncher.run(job, new JobParametersBuilder().addLong("timestamp",
  289. new Date().getTime()).toJobParameters());
  290. return jobExecution.getStepExecutions().iterator().next();
  291. }
  292. }