提交 79ddba5d 编写于 作者: R Rossen Stoyanchev

Polish WebSocket integration tests

上级 fee3148b
/*
* Copyright 2002-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.messaging.simp;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.runners.Parameterized.Parameter;
import org.springframework.context.Lifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.server.DefaultHandshakeHandler;
import org.springframework.web.socket.server.HandshakeHandler;
import org.springframework.web.socket.server.RequestUpgradeStrategy;
import org.springframework.web.socket.server.support.JettyRequestUpgradeStrategy;
import org.springframework.web.socket.server.support.TomcatRequestUpgradeStrategy;
import reactor.util.Assert;
/**
* Base class for WebSocket integration tests.
*
* @author Rossen Stoyanchev
*/
public abstract class AbstractWebSocketIntegrationTests {
protected Log logger = LogFactory.getLog(getClass());
private static Map<Class<?>, Class<?>> upgradeStrategyConfigTypes = new HashMap<Class<?>, Class<?>>();
static {
upgradeStrategyConfigTypes.put(JettyTestServer.class, JettyUpgradeStrategyConfig.class);
upgradeStrategyConfigTypes.put(TomcatTestServer.class, TomcatUpgradeStrategyConfig.class);
}
@Parameter(0)
public TestServer server;
@Parameter(1)
public WebSocketClient webSocketClient;
protected AnnotationConfigWebApplicationContext wac;
@Before
public void setup() throws Exception {
Class<?> upgradeStrategyConfigClass = upgradeStrategyConfigTypes.get(this.server.getClass());
Assert.notNull(upgradeStrategyConfigClass, "No UpgradeStrategyConfig class");
this.wac = new AnnotationConfigWebApplicationContext();
this.wac.register(getAnnotatedConfigClasses());
this.wac.register(upgradeStrategyConfigClass);
this.wac.refresh();
if (this.webSocketClient instanceof Lifecycle) {
((Lifecycle) this.webSocketClient).start();
}
this.server.deployConfig(this.wac);
this.server.start();
}
protected abstract Class<?>[] getAnnotatedConfigClasses();
@After
public void teardown() throws Exception {
try {
if (this.webSocketClient instanceof Lifecycle) {
((Lifecycle) this.webSocketClient).stop();
}
}
catch (Throwable t) {
logger.error("Failed to stop WebSocket client", t);
}
try {
this.server.undeployConfig();
}
catch (Throwable t) {
logger.error("Failed to undeploy application config", t);
}
try {
this.server.stop();
}
catch (Throwable t) {
logger.error("Failed to stop server", t);
}
}
protected String getWsBaseUrl() {
return "ws://localhost:" + this.server.getPort();
}
static abstract class AbstractRequestUpgradeStrategyConfig {
@Bean
public HandshakeHandler handshakeHandler() {
return new DefaultHandshakeHandler(requestUpgradeStrategy());
}
public abstract RequestUpgradeStrategy requestUpgradeStrategy();
}
@Configuration
static class JettyUpgradeStrategyConfig extends AbstractRequestUpgradeStrategyConfig {
@Bean
public RequestUpgradeStrategy requestUpgradeStrategy() {
return new JettyRequestUpgradeStrategy();
}
}
@Configuration
static class TomcatUpgradeStrategyConfig extends AbstractRequestUpgradeStrategyConfig {
@Bean
public RequestUpgradeStrategy requestUpgradeStrategy() {
return new TomcatRequestUpgradeStrategy();
}
}
}
/*
* Copyright 2002-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.messaging.simp;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.util.SocketUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Jetty based {@link TestServer}.
*
* @author Rossen Stoyanchev
*/
public class JettyTestServer implements TestServer {
private final Server jettyServer;
private final int port;
public JettyTestServer() {
this.port = SocketUtils.findAvailableTcpPort();
this.jettyServer = new Server(this.port);
}
@Override
public int getPort() {
return this.port;
}
@Override
public void deployConfig(WebApplicationContext cxt) {
ServletContextHandler contextHandler = new ServletContextHandler();
ServletHolder servletHolder = new ServletHolder(new DispatcherServlet(cxt));
contextHandler.addServlet(servletHolder, "/");
this.jettyServer.setHandler(contextHandler);
}
@Override
public void undeployConfig() {
// Stopping jetty will undeploy the servlet
}
@Override
public void start() throws Exception {
this.jettyServer.start();
}
@Override
public void stop() throws Exception {
if (this.jettyServer.isRunning()) {
this.jettyServer.stop();
}
}
}
/*
* Copyright 2002-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.messaging.simp;
import org.springframework.web.context.WebApplicationContext;
/**
* Contract for a test server to use for integration tests.
*
* @author Rossen Stoyanchev
*/
public interface TestServer {
int getPort();
void deployConfig(WebApplicationContext cxt);
void undeployConfig();
void start() throws Exception;
void stop() throws Exception;
}
\ No newline at end of file
/*
* Copyright 2002-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.messaging.simp;
import java.io.File;
import java.io.IOException;
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.http11.Http11NioProtocol;
import org.apache.tomcat.util.descriptor.web.ApplicationListener;
import org.apache.tomcat.websocket.server.WsListener;
import org.springframework.core.NestedRuntimeException;
import org.springframework.util.SocketUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
/**
* Tomcat based {@link TestServer}.
*
* @author Rossen Stoyanchev
*/
public class TomcatTestServer implements TestServer {
private static final ApplicationListener WS_APPLICATION_LISTENER =
new ApplicationListener(WsListener.class.getName(), false);
private final Tomcat tomcatServer;
private final int port;
private Context context;
public TomcatTestServer() {
this.port = SocketUtils.findAvailableTcpPort();
Connector connector = new Connector(Http11NioProtocol.class.getName());
connector.setPort(this.port);
File baseDir = createTempDir("tomcat");
String baseDirPath = baseDir.getAbsolutePath();
this.tomcatServer = new Tomcat();
this.tomcatServer.setBaseDir(baseDirPath);
this.tomcatServer.setPort(this.port);
this.tomcatServer.getService().addConnector(connector);
this.tomcatServer.setConnector(connector);
}
private File createTempDir(String prefix) {
try {
File tempFolder = File.createTempFile(prefix + ".", "." + getPort());
tempFolder.delete();
tempFolder.mkdir();
tempFolder.deleteOnExit();
return tempFolder;
}
catch (IOException ex) {
throw new NestedRuntimeException("Unable to create temp directory", ex) {};
}
}
@Override
public int getPort() {
return this.port;
}
@Override
public void deployConfig(WebApplicationContext wac) {
this.context = this.tomcatServer.addContext("", System.getProperty("java.io.tmpdir"));
this.context.addApplicationListener(WS_APPLICATION_LISTENER);
Tomcat.addServlet(context, "dispatcherServlet", new DispatcherServlet(wac));
this.context.addServletMapping("/", "dispatcherServlet");
}
@Override
public void undeployConfig() {
if (this.context != null) {
this.context.removeServletMapping("/");
this.tomcatServer.getHost().removeChild(this.context);
}
}
@Override
public void start() throws Exception {
this.tomcatServer.start();
}
@Override
public void stop() throws Exception {
this.tomcatServer.stop();
}
}
......@@ -29,14 +29,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.SubscribableChannel;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.AbstractWebSocketIntegrationTests;
import org.springframework.messaging.simp.JettyTestServer;
import org.springframework.messaging.simp.TomcatTestServer;
import org.springframework.messaging.simp.stomp.StompCommand;
import org.springframework.messaging.simp.stomp.StompTextMessageBuilder;
import org.springframework.messaging.support.channel.ExecutorSubscribableChannel;
import org.springframework.stereotype.Controller;
import org.springframework.web.socket.AbstractWebSocketIntegrationTests;
import org.springframework.web.socket.JettyWebSocketTestServer;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.TomcatWebSocketTestServer;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.TextWebSocketHandlerAdapter;
......@@ -60,8 +60,8 @@ public class WebSocketMessageBrokerConfigurationTests extends AbstractWebSocketI
@Parameters
public static Iterable<Object[]> arguments() {
return Arrays.asList(new Object[][] {
{new JettyTestServer(), new JettyWebSocketClient()},
{new TomcatTestServer(), new StandardWebSocketClient()}
{new JettyWebSocketTestServer(), new JettyWebSocketClient()},
{new TomcatWebSocketTestServer(), new StandardWebSocketClient()}
});
};
......
......@@ -47,12 +47,12 @@ public abstract class AbstractWebSocketIntegrationTests {
private static Map<Class<?>, Class<?>> upgradeStrategyConfigTypes = new HashMap<Class<?>, Class<?>>();
static {
upgradeStrategyConfigTypes.put(JettyTestServer.class, JettyUpgradeStrategyConfig.class);
upgradeStrategyConfigTypes.put(TomcatTestServer.class, TomcatUpgradeStrategyConfig.class);
upgradeStrategyConfigTypes.put(JettyWebSocketTestServer.class, JettyUpgradeStrategyConfig.class);
upgradeStrategyConfigTypes.put(TomcatWebSocketTestServer.class, TomcatUpgradeStrategyConfig.class);
}
@Parameter(0)
public TestServer server;
public WebSocketTestServer server;
@Parameter(1)
public WebSocketClient webSocketClient;
......
......@@ -25,18 +25,18 @@ import org.springframework.web.servlet.DispatcherServlet;
/**
* Jetty based {@link TestServer}.
* Jetty based {@link WebSocketTestServer}.
*
* @author Rossen Stoyanchev
*/
public class JettyTestServer implements TestServer {
public class JettyWebSocketTestServer implements WebSocketTestServer {
private final Server jettyServer;
private final int port;
public JettyTestServer() {
public JettyWebSocketTestServer() {
this.port = SocketUtils.findAvailableTcpPort();
this.jettyServer = new Server(this.port);
}
......
......@@ -33,11 +33,11 @@ import org.springframework.web.servlet.DispatcherServlet;
/**
* Tomcat based {@link TestServer}.
* Tomcat based {@link WebSocketTestServer}.
*
* @author Rossen Stoyanchev
*/
public class TomcatTestServer implements TestServer {
public class TomcatWebSocketTestServer implements WebSocketTestServer {
private static final ApplicationListener WS_APPLICATION_LISTENER =
new ApplicationListener(WsListener.class.getName(), false);
......@@ -49,7 +49,7 @@ public class TomcatTestServer implements TestServer {
private Context context;
public TomcatTestServer() {
public TomcatWebSocketTestServer() {
this.port = SocketUtils.findAvailableTcpPort();
......
......@@ -19,11 +19,11 @@ package org.springframework.web.socket;
import org.springframework.web.context.WebApplicationContext;
/**
* Contract for a test server to use for integration tests.
* Contract for a test server to use for WebSocket integration tests.
*
* @author Rossen Stoyanchev
*/
public interface TestServer {
public interface WebSocketTestServer {
int getPort();
......
......@@ -28,8 +28,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.AbstractWebSocketIntegrationTests;
import org.springframework.web.socket.JettyTestServer;
import org.springframework.web.socket.TomcatTestServer;
import org.springframework.web.socket.JettyWebSocketTestServer;
import org.springframework.web.socket.TomcatWebSocketTestServer;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.adapter.WebSocketHandlerAdapter;
import org.springframework.web.socket.client.endpoint.StandardWebSocketClient;
......@@ -51,8 +51,8 @@ public class WebSocketConfigurationTests extends AbstractWebSocketIntegrationTes
@Parameters
public static Iterable<Object[]> arguments() {
return Arrays.asList(new Object[][] {
{new JettyTestServer(), new JettyWebSocketClient()},
{new TomcatTestServer(), new StandardWebSocketClient()}
{new JettyWebSocketTestServer(), new JettyWebSocketClient()},
{new TomcatWebSocketTestServer(), new StandardWebSocketClient()}
});
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册