INT-3823: Fix EnableIntTests Race Condition
JIRA: https://jira.spring.io/browse/INT-3823 The test stops the endpoint. The previous poller thread can 'steal' the `input` message, but since it is interrupted, it can't send the message to the `publishedChannel`. Add logic to wait until the previous poller has been interrupted in `receive()`. Increase the endpoint `receiveTimeout` to ensure the thread will be interrupted. Bump SF Version to 4.2.3 Remove `TRACE` logging from the `EnableIntegrationTests` since we have the fix already Make some optimization around `@DirtiesContext`
This commit is contained in:
committed by
Artem Bilan
parent
0327666ca7
commit
9500d308a0
@@ -139,7 +139,7 @@ subprojects { subproject ->
|
||||
springSecurityVersion = project.hasProperty('springSecurityVersion') ? project.springSecurityVersion : '4.0.2.RELEASE'
|
||||
springSocialTwitterVersion = '1.1.1.RELEASE'
|
||||
springRetryVersion = '1.1.2.RELEASE'
|
||||
springVersion = project.hasProperty('springVersion') ? project.springVersion : '4.2.2.RELEASE'
|
||||
springVersion = project.hasProperty('springVersion') ? project.springVersion : '4.2.3.RELEASE'
|
||||
springWsVersion = '2.2.2.RELEASE'
|
||||
xmlUnitVersion = '1.5'
|
||||
xstreamVersion = '1.4.7'
|
||||
|
||||
@@ -26,7 +26,10 @@ import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -46,7 +49,10 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
@@ -129,13 +135,14 @@ import reactor.spring.context.config.EnableReactor;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
* @since 4.0
|
||||
*/
|
||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class,
|
||||
classes = {EnableIntegrationTests.ContextConfiguration.class, EnableIntegrationTests.ContextConfiguration2.class})
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
@DirtiesContext
|
||||
public class EnableIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
@@ -262,12 +269,15 @@ public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
@Qualifier("enableIntegrationTests.ContextConfiguration2.sendAsyncHandler.serviceActivator")
|
||||
private AbstractEndpoint sendAsyncHandler;
|
||||
|
||||
public EnableIntegrationTests() {
|
||||
super("org.springframework.integration", "org.springframework");
|
||||
}
|
||||
@Autowired
|
||||
private CountDownLatch inputReceiveLatch;
|
||||
|
||||
@Test
|
||||
public void testAnnotatedServiceActivator() {
|
||||
public void testAnnotatedServiceActivator() throws Exception {
|
||||
this.serviceActivatorEndpoint.setReceiveTimeout(10000);
|
||||
this.serviceActivatorEndpoint.start();
|
||||
assertTrue(this.inputReceiveLatch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
assertEquals(10L, TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "maxMessagesPerPoll"));
|
||||
|
||||
Trigger trigger = TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "trigger", Trigger.class);
|
||||
@@ -276,8 +286,25 @@ public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
assertFalse(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class));
|
||||
|
||||
assertTrue(this.annotationTestService.isRunning());
|
||||
Log logger = spy(TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "logger", Log.class));
|
||||
when(logger.isDebugEnabled()).thenReturn(true);
|
||||
final CountDownLatch pollerInterruptedLatch = new CountDownLatch(1);
|
||||
doAnswer(new Answer<Void>() {
|
||||
|
||||
@Override
|
||||
public Void answer(InvocationOnMock invocation) throws Throwable {
|
||||
pollerInterruptedLatch.countDown();
|
||||
invocation.callRealMethod();
|
||||
return null;
|
||||
}
|
||||
}).when(logger).debug("Received no Message during the poll, returning 'false'");
|
||||
new DirectFieldAccessor(this.serviceActivatorEndpoint).setPropertyValue("logger", logger);
|
||||
|
||||
this.serviceActivatorEndpoint.stop();
|
||||
assertFalse(this.annotationTestService.isRunning());
|
||||
|
||||
// wait until the service activator's poller is interrupted.
|
||||
assertTrue(pollerInterruptedLatch.await(10, TimeUnit.SECONDS));
|
||||
this.serviceActivatorEndpoint.start();
|
||||
assertTrue(this.annotationTestService.isRunning());
|
||||
|
||||
@@ -381,6 +408,7 @@ public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testChangePatterns() {
|
||||
try {
|
||||
this.configurer.setComponentNamePatterns(new String[] {"*"});
|
||||
@@ -603,6 +631,7 @@ public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
}
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testRoles() {
|
||||
this.roleController.stopLifecyclesInRole("foo");
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -625,9 +654,21 @@ public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
@EnableMessageHistory({"input", "publishedChannel", "annotationTestService*"})
|
||||
public static class ContextConfiguration {
|
||||
|
||||
@Bean
|
||||
public CountDownLatch inputReceiveLatch() {
|
||||
return new CountDownLatch(1);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public QueueChannel input() {
|
||||
return new QueueChannel();
|
||||
return new QueueChannel() {
|
||||
|
||||
@Override
|
||||
protected Message<?> doReceive(long timeout) {
|
||||
inputReceiveLatch().countDown();
|
||||
return super.doReceive(timeout);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -1060,7 +1101,7 @@ public class EnableIntegrationTests extends LogAdjustingTestSupport {
|
||||
private boolean running;
|
||||
|
||||
@Override
|
||||
@ServiceActivator(inputChannel = "input", outputChannel = "output",
|
||||
@ServiceActivator(inputChannel = "input", outputChannel = "output", autoStartup = "false",
|
||||
poller = @Poller(maxMessagesPerPoll = "${poller.maxMessagesPerPoll}", fixedDelay = "${poller.interval}"))
|
||||
@Publisher
|
||||
@Payload("#args[0].toLowerCase()")
|
||||
|
||||
Reference in New Issue
Block a user