INT-3188 Make Direct Handler Call Tests Robust

Previously, these tests examined specific stack frames to
verify the handler was directly invoked by the Dispatcher.

JIRA: https://jira.springsource.org/browse/INT-3188

Add a utility method to scan the stack trace instead to
verify that the Dispatcher frame exists before any
MessagingMethodInvokerHelper frame.
This commit is contained in:
Gary Russell
2013-10-31 11:10:18 -04:00
parent 435064453f
commit 945eea7a36
3 changed files with 71 additions and 8 deletions

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.util;
/**
* Utility methods for analyzing stack traces.
*
* @author Gary Russell
* @since 3.0
*
*/
public class StackTraceUtils {
private StackTraceUtils() {}
/**
* Traverses the stack trace element array looking for instances that contain the first or second
* Strings in the className property.
* @param firstClass The first class to look for.
* @param secondClass The second class to look for.
* @param stackTrace The stack trace.
* @return true if the first class appears first, false if the second appears first
* @throws IllegalArgumentException if neither class is found.
*/
public static boolean isFrameContainingXBeforeFrameContainingY(String firstClass, String secondClass, StackTraceElement[] stackTrace) {
for (StackTraceElement element : stackTrace) {
if (element.getClassName().contains(firstClass)) {
return true;
}
else if (element.getClassName().contains(secondClass)) {
return false;
}
}
throw new IllegalArgumentException("Neither " + firstClass + " nor " + secondClass + " class found");
}
}

View File

@@ -17,8 +17,10 @@
package org.springframework.integration.handler;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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 org.hamcrest.Matchers;
@@ -35,6 +37,7 @@ import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.StackTraceUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -95,7 +98,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
assertEquals("TEST", reply.getPayload());
assertEquals("replyingHandlerTestInputChannel,replyingHandlerTestService", reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertEquals("doDispatch", st[3].getMethodName()); // close to the metal
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st)); // close to the metal
}
@Test
@@ -108,7 +111,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
assertEquals("optimizedRefReplyingHandlerTestInputChannel,optimizedRefReplyingHandlerTestService",
reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertEquals("doDispatch", st[3].getMethodName());
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st)); // close to the metal
}
@Test
@@ -120,7 +123,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
assertEquals("TEST", reply.getPayload());
assertEquals("replyingHandlerWithStandardMethodTestInputChannel,replyingHandlerWithStandardMethodTestService", reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertEquals("doDispatch", st[3].getMethodName()); // close to the metal
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st)); // close to the metal
}
@Test
@@ -183,6 +186,10 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
}
public String foo(String in) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
// use this to test that StackTraceUtils works as expected and returns false
assertFalse(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st));
return "bar";
}
@@ -195,7 +202,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
public void handleMessage(Message<?> requestMessage) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
assertEquals("doDispatch", st[4].getMethodName());
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st)); // close to the metal
}
}

View File

@@ -17,8 +17,10 @@
package org.springframework.integration.jmx;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
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 org.hamcrest.Matchers;
@@ -37,6 +39,7 @@ import org.springframework.integration.handler.AbstractReplyProducingMessageHand
import org.springframework.integration.handler.MessageProcessor;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.StackTraceUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -97,7 +100,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
assertEquals("TEST", reply.getPayload());
assertEquals("replyingHandlerTestInputChannel,replyingHandlerTestService", reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertEquals("doDispatch", st[15].getMethodName()); // close to the metal
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st));
}
@Test
@@ -110,7 +113,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
assertEquals("optimizedRefReplyingHandlerTestInputChannel,optimizedRefReplyingHandlerTestService",
reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertEquals("doDispatch", st[15].getMethodName());
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st));
}
@Test
@@ -122,7 +125,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
assertEquals("TEST", reply.getPayload());
assertEquals("replyingHandlerWithStandardMethodTestInputChannel,replyingHandlerWithStandardMethodTestService", reply.getHeaders().get("history").toString());
StackTraceElement[] st = (StackTraceElement[]) reply.getHeaders().get("callStack");
assertEquals("doDispatch", st[15].getMethodName()); // close to the metal
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st));
}
@Test
@@ -191,6 +194,10 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
}
public String foo(String in) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
// use this to test that StackTraceUtils works as expected and returns false
assertFalse(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st));
return "bar";
}
@@ -203,7 +210,7 @@ public class ServiceActivatorDefaultFrameworkMethodTests {
public void handleMessage(Message<?> requestMessage) {
Exception e = new RuntimeException();
StackTraceElement[] st = e.getStackTrace();
assertEquals("doDispatch", st[16].getMethodName());
assertTrue(StackTraceUtils.isFrameContainingXBeforeFrameContainingY("Dispatcher", "MethodInvokerHelper", st));
}
}