Skip to content

Commit 965bece

Browse files
committed
Fix flaky tests
JsrSplitParsingTests#test and DecisionStepTests#testDecisionAfterSplit were failing intermittently with: ``` org.springframework.batch.core.JobExecutionException: Flow execution ended unexpectedly at org.springframework.batch.core.jsr.job.flow.JsrFlowJob.doExecute(JsrFlowJob.java:88) ~[main/:?] at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:320) [main/:?] at org.springframework.batch.core.jsr.launch.JsrJobOperator$2.run(JsrJobOperator.java:674) [main/:?] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232] Caused by: org.springframework.batch.core.job.flow.FlowExecutionException: Ended flow=flow1.step1 at state=flow1.step1.flow1.step1 with exception at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:178) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:94) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:91) ~[main/:?] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_232] ... 1 more Caused by: org.springframework.dao.ConcurrencyFailureException: PreparedStatementCallback; SQL [INSERT INTO BATCH_STEP_EXECUTION_CONTEXT (SHORT_CONTEXT, SERIALIZED_CONTEXT, STEP_EXECUTION_ID) VALUES(?, ?, ?)]; transaction rollback: serialization failure; nested exception is java.sql.SQLTransactionRollbackException: transaction rollback: serialization failure at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:73) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:79) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1541) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:667) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:960) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1015) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:236) ~[main/:?] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.saveExecutionContext(JdbcExecutionContextDao.java:189) ~[main/:?] at org.springframework.batch.core.repository.support.SimpleJobRepository.add(SimpleJobRepository.java:177) ~[main/:?] at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source) ~[?:?] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_232] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_232] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:371) ~[spring-tx-5.3.0.jar:5.3.0] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:134) ~[spring-tx-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.0.jar:5.3.0] at com.sun.proxy.$Proxy41.add(Unknown Source) ~[?:?] at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68) ~[main/:?] at org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState.handle(JsrStepState.java:53) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:94) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:91) ~[main/:?] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_232] ... 1 more Caused by: java.sql.SQLTransactionRollbackException: transaction rollback: serialization failure at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136) ~[commons-dbcp2-2.8.0.jar:2.8.0] at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136) ~[commons-dbcp2-2.8.0.jar:2.8.0] at org.springframework.jdbc.core.JdbcTemplate.lambda$update$2(JdbcTemplate.java:965) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:960) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1015) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:236) ~[main/:?] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.saveExecutionContext(JdbcExecutionContextDao.java:189) ~[main/:?] at org.springframework.batch.core.repository.support.SimpleJobRepository.add(SimpleJobRepository.java:177) ~[main/:?] at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source) ~[?:?] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_232] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_232] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:371) ~[spring-tx-5.3.0.jar:5.3.0] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:134) ~[spring-tx-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.0.jar:5.3.0] at com.sun.proxy.$Proxy41.add(Unknown Source) ~[?:?] at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68) ~[main/:?] at org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState.handle(JsrStepState.java:53) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:94) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:91) ~[main/:?] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_232] ... 1 more Caused by: org.hsqldb.HsqlException: transaction rollback: serialization failure at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.error.Error.error(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.Session.handleAbortTransaction(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.Session.executeCompiledStatement(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.Session.execute(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown Source) ~[hsqldb-2.5.1.jar:2.5.1] at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136) ~[commons-dbcp2-2.8.0.jar:2.8.0] at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:136) ~[commons-dbcp2-2.8.0.jar:2.8.0] at org.springframework.jdbc.core.JdbcTemplate.lambda$update$2(JdbcTemplate.java:965) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:651) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:960) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:1015) ~[spring-jdbc-5.3.0.jar:5.3.0] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:236) ~[main/:?] at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.saveExecutionContext(JdbcExecutionContextDao.java:189) ~[main/:?] at org.springframework.batch.core.repository.support.SimpleJobRepository.add(SimpleJobRepository.java:177) ~[main/:?] at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source) ~[?:?] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_232] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_232] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:371) ~[spring-tx-5.3.0.jar:5.3.0] at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:134) ~[spring-tx-5.3.0.jar:5.3.0] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.0.jar:5.3.0] at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.0.jar:5.3.0] at com.sun.proxy.$Proxy41.add(Unknown Source) ~[?:?] at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68) ~[main/:?] at org.springframework.batch.core.jsr.job.flow.support.state.JsrStepState.handle(JsrStepState.java:53) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) ~[main/:?] at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:94) ~[main/:?] at org.springframework.batch.core.job.flow.support.state.SplitState$1.call(SplitState.java:91) ~[main/:?] at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_232] ... 1 more ``` This failure is due to a concurrency issue when executing the split flow with the default SimpleAsyncTaskExecutor. Several attempts have been made to fix this issue with no success: * use `@DirtiesContext` annotation * use a separate db for each test * use `READ_COMMITTED` isolation level in the job repository * downgrade hsqldb from v2.5.1 to v2.4.1 (since v2.5.1 has introduced several changes in the MVCC mode) The issue seems to be related to how the in-memory database is shared between tests *and* how the test context is cached (ie the combination of both). This commit moves these tests to a separate test class which seem to fix the issue. (cherry picked from commit 1090731)
1 parent 938e0d7 commit 965bece

File tree

5 files changed

+122
-56
lines changed

5 files changed

+122
-56
lines changed

spring-batch-core/src/test/java/org/springframework/batch/core/jsr/configuration/xml/JsrSplitParsingTests.java

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013 the original author or authors.
2+
* Copyright 2013-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,14 +27,6 @@
2727
import org.springframework.context.support.ClassPathXmlApplicationContext;
2828
import org.springframework.core.task.SimpleAsyncTaskExecutor;
2929

30-
import javax.batch.api.AbstractBatchlet;
31-
import javax.batch.runtime.BatchRuntime;
32-
import javax.batch.runtime.StepExecution;
33-
import javax.batch.runtime.context.JobContext;
34-
import javax.inject.Inject;
35-
import java.util.List;
36-
37-
import static org.junit.Assert.assertEquals;
3830
import static org.junit.Assert.assertTrue;
3931
import static org.junit.Assert.fail;
4032

@@ -43,16 +35,6 @@ public class JsrSplitParsingTests extends AbstractJsrTestCase {
4335
@Rule
4436
public ExpectedException expectedException = ExpectedException.none();
4537

46-
@Test
47-
public void test() throws Exception {
48-
javax.batch.runtime.JobExecution execution = runJob("JsrSplitParsingTests-context", null, 10000L);
49-
assertEquals(javax.batch.runtime.BatchStatus.COMPLETED, execution.getBatchStatus());
50-
assertEquals("COMPLETED", execution.getExitStatus());
51-
52-
List<StepExecution> stepExecutions = BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId());
53-
assertEquals(5, stepExecutions.size());
54-
}
55-
5638
@Test
5739
public void testOneFlowInSplit() {
5840
try {
@@ -86,15 +68,4 @@ public void testDefaultTaskExecutor() {
8668
context.close();
8769
}
8870

89-
public static class ExitStatusSettingBatchlet extends AbstractBatchlet {
90-
91-
@Inject
92-
JobContext jobContext;
93-
94-
@Override
95-
public String process() throws Exception {
96-
jobContext.setExitStatus("Should be ignored");
97-
return null;
98-
}
99-
}
10071
}

spring-batch-core/src/test/java/org/springframework/batch/core/jsr/step/DecisionStepTests.java

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2017 the original author or authors.
2+
* Copyright 2013-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,7 +27,6 @@
2727
import org.junit.Test;
2828

2929
import org.springframework.batch.core.jsr.AbstractJsrTestCase;
30-
import org.springframework.test.util.ReflectionTestUtils;
3130
import org.springframework.util.Assert;
3231

3332
import static org.junit.Assert.assertEquals;
@@ -82,15 +81,6 @@ public void testDecisionAfterFlow() throws Exception {
8281
assertEquals(3, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size());
8382
}
8483

85-
@Test
86-
public void testDecisionAfterSplit() throws Exception {
87-
JobExecution execution = runJob("DecisionStepTests-decisionAfterSplit-context", new Properties(), 10000L);
88-
org.springframework.batch.core.JobExecution jobExecution = (org.springframework.batch.core.JobExecution) ReflectionTestUtils.getField(execution, "execution");
89-
assertEquals(String.format("Received a %s because of %s", execution.getBatchStatus(), jobExecution.getExitStatus().getExitDescription()), BatchStatus.COMPLETED, execution.getBatchStatus());
90-
assertEquals(4, BatchRuntime.getJobOperator().getStepExecutions(execution.getExecutionId()).size());
91-
assertEquals(2, StepExecutionCountingDecider.previousStepCount);
92-
}
93-
9484
@Test
9585
public void testDecisionRestart() throws Exception {
9686
JobExecution execution = runJob("DecisionStepTests-restart-context", new Properties(), 10000L);
@@ -130,17 +120,6 @@ public String decide(StepExecution[] executions) throws Exception {
130120
}
131121
}
132122

133-
public static class StepExecutionCountingDecider implements Decider {
134-
135-
static int previousStepCount = 0;
136-
137-
@Override
138-
public String decide(StepExecution[] executions) throws Exception {
139-
previousStepCount = executions.length;
140-
return "next";
141-
}
142-
}
143-
144123
public static class NextDecider implements Decider {
145124

146125
@Override
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.batch.core.jsr.step;
17+
18+
import java.time.Duration;
19+
import java.time.Instant;
20+
import java.util.EnumSet;
21+
import java.util.List;
22+
import java.util.Properties;
23+
import java.util.Set;
24+
25+
import javax.batch.api.AbstractBatchlet;
26+
import javax.batch.api.Decider;
27+
import javax.batch.operations.JobOperator;
28+
import javax.batch.runtime.BatchRuntime;
29+
import javax.batch.runtime.BatchStatus;
30+
import javax.batch.runtime.JobExecution;
31+
import javax.batch.runtime.StepExecution;
32+
import javax.batch.runtime.context.JobContext;
33+
import javax.inject.Inject;
34+
35+
import org.junit.Test;
36+
37+
import static org.junit.Assert.assertEquals;
38+
import static org.junit.Assert.fail;
39+
40+
/**
41+
* @author Mahmoud Ben Hassine
42+
*/
43+
public class SplitTests {
44+
45+
private static final Set<BatchStatus> END_STATUSES =
46+
EnumSet.of(BatchStatus.COMPLETED, BatchStatus.FAILED, BatchStatus.STOPPED);
47+
private final JobOperator jobOperator = BatchRuntime.getJobOperator();
48+
49+
@Test
50+
public void testSplit() {
51+
// given
52+
String jobXMLName = "SplitTests-testSplit-context";
53+
Properties jobParameters = new Properties();
54+
55+
// when
56+
long executionId = jobOperator.start(jobXMLName, jobParameters);
57+
waitFor(executionId, 10);
58+
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
59+
List<StepExecution> stepExecutions = jobOperator.getStepExecutions(executionId);
60+
61+
// then
62+
assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
63+
assertEquals("COMPLETED", jobExecution.getExitStatus());
64+
assertEquals(5, stepExecutions.size());
65+
}
66+
67+
@Test
68+
public void testDecisionAfterSplit() {
69+
// given
70+
String jobXMLName = "SplitTests-testDecisionAfterSplit-context";
71+
Properties jobParameters = new Properties();
72+
73+
// when
74+
long executionId = jobOperator.start(jobXMLName, jobParameters);
75+
waitFor(executionId, 10);
76+
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
77+
78+
// then
79+
assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
80+
assertEquals(4, jobOperator.getStepExecutions(executionId).size());
81+
assertEquals(2, StepExecutionCountingDecider.previousStepCount);
82+
}
83+
84+
private void waitFor(long executionId, int timeoutInSeconds) {
85+
Instant startTime = Instant.now();
86+
while (!END_STATUSES.contains(jobOperator.getJobExecution(executionId).getBatchStatus())) {
87+
if ((Duration.between(Instant.now(), startTime).getSeconds() > timeoutInSeconds)) {
88+
fail("Job processing did not complete in time");
89+
}
90+
}
91+
}
92+
93+
public static class StepExecutionCountingDecider implements Decider {
94+
95+
static int previousStepCount = 0;
96+
97+
@Override
98+
public String decide(StepExecution[] executions) {
99+
previousStepCount = executions.length;
100+
return "next";
101+
}
102+
}
103+
104+
public static class ExitStatusSettingBatchlet extends AbstractBatchlet {
105+
106+
@Inject
107+
JobContext jobContext;
108+
109+
@Override
110+
public String process() throws Exception {
111+
jobContext.setExitStatus("Should be ignored");
112+
return null;
113+
}
114+
}
115+
116+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</step>
2626
</job>
2727

28-
<bean id="nextDecider" class="org.springframework.batch.core.jsr.step.DecisionStepTests$StepExecutionCountingDecider"/>
28+
<bean id="nextDecider" class="org.springframework.batch.core.jsr.step.SplitTests$StepExecutionCountingDecider"/>
2929

3030
<bean id="doSomethingBatchlet" class="org.springframework.batch.core.jsr.step.batchlet.BatchletSupport"/>
3131

spring-batch-core/src/test/resources/META-INF/batch-jobs/JsrSplitParsingTests-context.xml renamed to spring-batch-core/src/test/resources/META-INF/batch-jobs/SplitTests-testSplit-context.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@
99

1010
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
1111
<step id="step1" next="step2">
12-
<batchlet ref="org.springframework.batch.core.jsr.configuration.xml.JsrSplitParsingTests$ExitStatusSettingBatchlet"/>
12+
<batchlet ref="org.springframework.batch.core.jsr.step.SplitTests$ExitStatusSettingBatchlet"/>
1313
</step>
1414
<split id="step2" next="step3">
1515
<flow id="step2a">
1616
<step id="step2aStep1">
17-
<batchlet ref="org.springframework.batch.core.jsr.configuration.xml.JsrSplitParsingTests$ExitStatusSettingBatchlet"/>
17+
<batchlet ref="org.springframework.batch.core.jsr.step.SplitTests$ExitStatusSettingBatchlet"/>
1818
</step>
1919
</flow>
2020
<flow id="step2b">
2121
<step id="step2bStep1" next="step2bStep2">
22-
<batchlet ref="org.springframework.batch.core.jsr.configuration.xml.JsrSplitParsingTests$ExitStatusSettingBatchlet"/>
22+
<batchlet ref="org.springframework.batch.core.jsr.step.SplitTests$ExitStatusSettingBatchlet"/>
2323
</step>
2424
<step id="step2bStep2">
2525
<chunk checkpoint-policy="item" item-count="3">

0 commit comments

Comments
 (0)