BATCH-1132: Unit tests for "parent" and "abstract" attributes on <step/>

This commit is contained in:
dhgarrette
2009-03-12 05:15:34 +00:00
parent 1d3a2f0c6f
commit 5441a642d1
4 changed files with 165 additions and 16 deletions

View File

@@ -0,0 +1,18 @@
package org.springframework.batch.core.configuration.xml;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
/**
* @author Dan Garrette
* @since 2.0
*/
public class DummyTasklet implements Tasklet {
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
return null;
}
}

View File

@@ -20,10 +20,16 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.springframework.aop.framework.Advised;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.listener.CompositeStepExecutionListener;
import org.springframework.batch.core.listener.StepExecutionListenerSupport;
import org.springframework.batch.core.step.AbstractStep;
import org.springframework.batch.core.step.item.ChunkOrientedTasklet;
import org.springframework.batch.core.step.item.ChunkProvider;
import org.springframework.batch.core.step.item.FaultTolerantStepFactoryBean;
@@ -97,10 +103,25 @@ public class StepParserTests {
assertTrue("'s1' bean not found", beans.containsKey("s1"));
Step s1 = (Step) ctx.getBean("s1");
CompletionPolicy completionPolicy = getCompletionPolicy(s1);
System.err.println(completionPolicy);
assertTrue(completionPolicy instanceof DummyCompletionPolicy);
}
@SuppressWarnings("unchecked")
private CompletionPolicy getCompletionPolicy(Step s1) throws NoSuchFieldException, IllegalAccessException {
Field taskletField = TaskletStep.class.getDeclaredField("tasklet");
taskletField.setAccessible(true);
Tasklet tasklet = (Tasklet) taskletField.get(s1);
Field chunkProviderField = ChunkOrientedTasklet.class.getDeclaredField("chunkProvider");
chunkProviderField.setAccessible(true);
ChunkProvider chunkProvider = (ChunkProvider) chunkProviderField.get(tasklet);
Field repeatOperationsField = SimpleChunkProvider.class.getDeclaredField("repeatOperations");
repeatOperationsField.setAccessible(true);
RepeatOperations repeatOperations = (RepeatOperations) repeatOperationsField.get(chunkProvider);
Field completionPolicyField = RepeatTemplate.class.getDeclaredField("completionPolicy");
completionPolicyField.setAccessible(true);
return (CompletionPolicy) completionPolicyField.get(repeatOperations);
}
@Test(expected = BeanDefinitionParsingException.class)
public void testStepParserNoCommitIntervalOrCompletionPolicy() throws Exception {
new ClassPathXmlApplicationContext(
@@ -121,25 +142,75 @@ public class StepParserTests {
try {
new ClassPathXmlApplicationContext(contextLocation);
fail("Context should not load!");
} catch (BeanDefinitionParsingException e) {
}
catch (BeanDefinitionParsingException e) {
assertTrue(e.getMessage().contains("'ref' and 'class'"));
}
}
@SuppressWarnings("unchecked")
private CompletionPolicy getCompletionPolicy(Step s1) throws NoSuchFieldException, IllegalAccessException {
Field taskletField = TaskletStep.class.getDeclaredField("tasklet");
taskletField.setAccessible(true);
Tasklet tasklet = (Tasklet) taskletField.get(s1);
Field chunkProviderField = ChunkOrientedTasklet.class.getDeclaredField("chunkProvider");
chunkProviderField.setAccessible(true);
ChunkProvider chunkProvider = (ChunkProvider) chunkProviderField.get(tasklet);
Field repeatOperationsField = SimpleChunkProvider.class.getDeclaredField("repeatOperations");
repeatOperationsField.setAccessible(true);
RepeatOperations repeatOperations = (RepeatOperations) repeatOperationsField.get(chunkProvider);
Field completionPolicyField = RepeatTemplate.class.getDeclaredField("completionPolicy");
completionPolicyField.setAccessible(true);
return (CompletionPolicy) completionPolicyField.get(repeatOperations);
@Test(expected = BeanDefinitionParsingException.class)
public void testStepParserParentAndRef() throws Exception {
new ClassPathXmlApplicationContext(
"org/springframework/batch/core/configuration/xml/StepParserParentAndRefTests-context.xml");
}
@SuppressWarnings("unchecked")
@Test
public void testStepParserParentAttribute() throws Exception {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
"org/springframework/batch/core/configuration/xml/StepParserParentAttributeTests-context.xml");
Map<String, Object> beans = ctx.getBeansOfType(Step.class);
assertTrue(beans.containsKey("s1"));
Step s1 = (Step) ctx.getBean("s1");
assertTrue(beans.containsKey("s2"));
Step s2 = (Step) ctx.getBean("s2");
assertTrue(beans.containsKey("s3"));
Step s3 = (Step) ctx.getBean("s3");
assertTrue(beans.containsKey("s4"));
Step s4 = (Step) ctx.getBean("s4");
assertTrue(s1 instanceof TaskletStep);
assertTrue(getListener((TaskletStep) s1) instanceof StepExecutionListenerSupport);
assertTrue(s2 instanceof DelegatingStep);
assertTrue(getListener((DelegatingStep) s2) instanceof StepExecutionListenerSupport);
assertTrue(s3 instanceof TaskletStep);
assertTrue(getListener((TaskletStep) s3) instanceof StepExecutionListenerSupport);
assertTrue(s4 instanceof DelegatingStep);
assertTrue(getListener((DelegatingStep) s4) instanceof StepExecutionListenerSupport);
}
private StepExecutionListener getListener(DelegatingStep step) throws Exception {
assertTrue(step instanceof DelegatingStep);
Field delegateField = DelegatingStep.class.getDeclaredField("delegate");
delegateField.setAccessible(true);
Object delegate = delegateField.get(step);
assertTrue(delegate instanceof TaskletStep);
return getListener((TaskletStep) delegate);
}
@SuppressWarnings("unchecked")
private StepExecutionListener getListener(TaskletStep step) throws Exception {
Field listenerField = AbstractStep.class.getDeclaredField("stepExecutionListener");
listenerField.setAccessible(true);
Object compositeListener = listenerField.get(step);
Field compositeField = CompositeStepExecutionListener.class.getDeclaredField("list");
compositeField.setAccessible(true);
Object composite = compositeField.get(compositeListener);
Class cls = Class.forName("org.springframework.batch.core.listener.OrderedComposite");
Field listField = cls.getDeclaredField("list");
listField.setAccessible(true);
List<StepExecutionListener> list = (List<StepExecutionListener>) listField.get(composite);
assertEquals(1, list.size());
StepExecutionListener listener = list.get(0);
if (listener instanceof Advised) {
listener = (StepExecutionListener) ((Advised) listener).getTargetSource().getTarget();
}
return listener;
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<beans:import resource="common-context.xml" />
<job id="job">
<step id="s1" parent="baseStep" ref="step1"/>
</job>
<step id="baseStep" abstract="false">
<listeners>
<listener class="org.springframework.batch.core.listener.StepExecutionListenerSupport"/>
</listeners>
</step>
</beans:beans>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<beans:import resource="common-context.xml" />
<job id="job">
<step id="s1" parent="baseStep" next="s2">
<tasklet reader="reader" writer="writer" commit-interval="5"/>
</step>
<step id="s2" ref="standalone2" next="s3"/>
<step id="s3" parent="baseTaskletStep" tasklet="dummyTasklet" next="s4"/>
<step id="s4" ref="standalone4"/>
</job>
<step id="standalone2" parent="baseStep">
<tasklet reader="reader" writer="writer" commit-interval="5"/>
</step>
<step id="standalone4" tasklet="dummyTasklet" parent="baseTaskletStep">
<tasklet reader="reader" writer="writer" commit-interval="5"/>
</step>
<step id="baseStep" abstract="true">
<listeners>
<listener class="org.springframework.batch.core.listener.StepExecutionListenerSupport"/>
</listeners>
</step>
<!-- TODO: Use baseStep instead once BATCH-1136 is implemented -->
<beans:bean id="baseTaskletStep" abstract="true">
<beans:property name="stepExecutionListeners">
<beans:bean class="org.springframework.batch.core.listener.StepExecutionListenerSupport"/>
</beans:property>
</beans:bean>
<beans:bean id="dummyTasklet" class="org.springframework.batch.core.configuration.xml.DummyTasklet"/>
</beans:beans>