AMQP-728: Make BrokerRunning More Configurable
JIRA: https://jira.spring.io/browse/AMQP-728 Resolves: #592 Add more options to configure the `BrokerRunning` JUnit `@Rule`. Fix missing exclude from build.gradle for the junit subproject. Polishing - PR Comments More Polishing **Cherry-pick to 1.7.x**
This commit is contained in:
committed by
Artem Bilan
parent
0f2c23d0bb
commit
38f38c4d35
@@ -244,7 +244,10 @@ project('spring-rabbit-junit') {
|
||||
compile "org.springframework:spring-core:$springVersion"
|
||||
compile "junit:junit:$junitVersion"
|
||||
compile "com.rabbitmq:amqp-client:$rabbitmqVersion"
|
||||
compile "com.rabbitmq:http-client:$rabbitmqHttpClientVersion"
|
||||
compile ("com.rabbitmq:http-client:$rabbitmqHttpClientVersion") {
|
||||
exclude group: 'org.springframework', module: 'spring-web'
|
||||
}
|
||||
compile "org.springframework:spring-web:$springVersion"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -79,17 +79,33 @@ import com.rabbitmq.http.client.Client;
|
||||
*/
|
||||
public final class BrokerRunning extends TestWatcher {
|
||||
|
||||
public static final String BROKER_ADMIN_URI = "RABBITMQ_TEST_ADMIN_URI";
|
||||
|
||||
public static final String BROKER_HOSTNAME = "RABBITMQ_TEST_HOSTNAME";
|
||||
|
||||
public static final String BROKER_PORT = "RABBITMQ_TEST_PORT";
|
||||
|
||||
public static final String BROKER_USER = "RABBITMQ_TEST_USER";
|
||||
|
||||
public static final String BROKER_PW = "RABBITMQ_TEST_PASSWORD";
|
||||
|
||||
public static final String BROKER_ADMIN_USER = "RABBITMQ_TEST_ADMIN_USER";
|
||||
|
||||
public static final String BROKER_ADMIN_PW = "RABBITMQ_TEST_ADMIN_PASSWORD";
|
||||
|
||||
public static final String BROKER_REQUIRED = "RABBITMQ_SERVER_REQUIRED";
|
||||
|
||||
private static final String DEFAULT_QUEUE_NAME = BrokerRunning.class.getName();
|
||||
|
||||
private static Log logger = LogFactory.getLog(BrokerRunning.class);
|
||||
private static final Log logger = LogFactory.getLog(BrokerRunning.class);
|
||||
|
||||
// Static so that we only test once on failure: speeds up test suite
|
||||
private static Map<Integer, Boolean> brokerOnline = new HashMap<Integer, Boolean>();
|
||||
private static final Map<Integer, Boolean> brokerOnline = new HashMap<Integer, Boolean>();
|
||||
|
||||
// Static so that we only test once on failure
|
||||
private static Map<Integer, Boolean> brokerOffline = new HashMap<Integer, Boolean>();
|
||||
private static final Map<Integer, Boolean> brokerOffline = new HashMap<Integer, Boolean>();
|
||||
|
||||
private static final Map<String, String> environmentOverrides = new HashMap<>();
|
||||
|
||||
private final boolean assumeOnline;
|
||||
|
||||
@@ -99,14 +115,57 @@ public final class BrokerRunning extends TestWatcher {
|
||||
|
||||
private final String[] queues;
|
||||
|
||||
private final int defaultPort = BrokerTestUtils.getPort();
|
||||
private final int defaultPort = fromEnvironment(BROKER_PORT, null) == null ? BrokerTestUtils.getPort()
|
||||
: Integer.valueOf(fromEnvironment(BROKER_PORT, null));
|
||||
|
||||
private int port;
|
||||
|
||||
private String hostName = null;
|
||||
private String hostName = fromEnvironment(BROKER_HOSTNAME, "localhost");
|
||||
|
||||
private String adminUri = fromEnvironment(BROKER_ADMIN_URI, null);
|
||||
|
||||
private ConnectionFactory connectionFactory;
|
||||
|
||||
private String user = fromEnvironment(BROKER_USER, "guest");
|
||||
|
||||
private String password = fromEnvironment(BROKER_PW, "guest");
|
||||
|
||||
private String adminUser = fromEnvironment(BROKER_ADMIN_USER, "guest");
|
||||
|
||||
private String adminPassword = fromEnvironment(BROKER_ADMIN_PW, "guest");
|
||||
|
||||
private String fromEnvironment(String key, String defaultValue) {
|
||||
String environmentValue = environmentOverrides.get(key);
|
||||
if (!StringUtils.hasText(environmentValue)) {
|
||||
environmentValue = System.getenv(key);
|
||||
}
|
||||
if (StringUtils.hasText(environmentValue)) {
|
||||
return environmentValue;
|
||||
}
|
||||
else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set environment variable overrides for host, port etc. Will override any real
|
||||
* environment variables, if present.
|
||||
* <p><b>The variables will only apply to rule instances that are created after this
|
||||
* method is called.</b>
|
||||
* The overrides will remain until
|
||||
* @param environmentVariables the variables.
|
||||
*/
|
||||
public static void setEnvironmentVariableOverrides(Map<String, String> environmentVariables) {
|
||||
environmentOverrides.putAll(environmentVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any environment variable overrides set in {@link #setEnvironmentVariableOverrides(Map)}.
|
||||
*/
|
||||
public static void clearEnvironmentVariableOverrides() {
|
||||
environmentOverrides.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the broker is running and has a empty queue(s) with the specified name(s) in the
|
||||
* default exchange.
|
||||
@@ -192,6 +251,105 @@ public final class BrokerRunning extends TestWatcher {
|
||||
this.hostName = hostName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for the amqp connection default "guest".
|
||||
* @param user the user.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password for the amqp connection default "guest".
|
||||
* @param password the password.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the uri for the REST API.
|
||||
* @param adminUri the uri.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public void setAdminUri(String adminUri) {
|
||||
this.adminUri = adminUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the user for the management REST API connection default "guest".
|
||||
* @param user the user.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public void setAdminUser(String user) {
|
||||
this.adminUser = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password for the management REST API connection default "guest".
|
||||
* @param password the password.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public void setAdminPassword(String password) {
|
||||
this.adminPassword = password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the port.
|
||||
* @return the port.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public int getPort() {
|
||||
return this.port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the port.
|
||||
* @return the port.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public String getHostName() {
|
||||
return this.hostName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user.
|
||||
* @return the user.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public String getUser() {
|
||||
return this.user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the password.
|
||||
* @return the password.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public String getPassword() {
|
||||
return this.password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the admin user.
|
||||
* @return the user.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public String getAdminUser() {
|
||||
return this.adminUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the admin password.
|
||||
* @return the password.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public String getAdminPassword() {
|
||||
return this.adminPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
|
||||
@@ -235,7 +393,7 @@ public final class BrokerRunning extends TestWatcher {
|
||||
}
|
||||
|
||||
if (this.management) {
|
||||
Client client = new Client("http://localhost:15672/api/", "guest", "guest");
|
||||
Client client = new Client(getAdminUri(), this.adminUser, this.adminPassword);
|
||||
if (!client.alivenessTest("/")) {
|
||||
throw new RuntimeException("Aliveness test failed for localhost:15672 guest/quest; "
|
||||
+ "management not available");
|
||||
@@ -389,10 +547,29 @@ public final class BrokerRunning extends TestWatcher {
|
||||
this.connectionFactory.setHost("localhost");
|
||||
}
|
||||
this.connectionFactory.setPort(this.port);
|
||||
this.connectionFactory.setUsername(this.user);
|
||||
this.connectionFactory.setPassword(this.password);
|
||||
}
|
||||
return this.connectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the admin uri.
|
||||
* @return the uri.
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public String getAdminUri() {
|
||||
if (!StringUtils.hasText(this.adminUri)) {
|
||||
if (!StringUtils.hasText(this.hostName)) {
|
||||
this.adminUri = "http://localhost:15672/api/";
|
||||
}
|
||||
else {
|
||||
this.adminUri = "http://" + this.hostName + ":15672/api/";
|
||||
}
|
||||
}
|
||||
return this.adminUri;
|
||||
}
|
||||
|
||||
private void closeResources(Connection connection, Channel channel) {
|
||||
if (channel != null) {
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2017 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.amqp.rabbit.junit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
|
||||
import com.rabbitmq.client.ConnectionFactory;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 1.7.2
|
||||
*
|
||||
*/
|
||||
public class BrokerRunningTests {
|
||||
|
||||
@Test
|
||||
public void testVars() {
|
||||
BrokerRunning brokerRunning = BrokerRunning.isBrokerAndManagementRunning();
|
||||
brokerRunning.setAdminPassword("foo");
|
||||
brokerRunning.setAdminUser("bar");
|
||||
brokerRunning.setHostName("baz");
|
||||
brokerRunning.setPassword("qux");
|
||||
brokerRunning.setPort(1234);
|
||||
brokerRunning.setUser("fiz");
|
||||
|
||||
assertEquals("http://baz:15672/api/", brokerRunning.getAdminUri());
|
||||
ConnectionFactory connectionFactory = brokerRunning.getConnectionFactory();
|
||||
assertEquals("baz", connectionFactory.getHost());
|
||||
assertEquals(1234, connectionFactory.getPort());
|
||||
assertEquals("fiz", connectionFactory.getUsername());
|
||||
assertEquals("qux", connectionFactory.getPassword());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnvironmentVars() {
|
||||
Map<String, String> vars = new HashMap<>();
|
||||
vars.put("RABBITMQ_TEST_ADMIN_PASSWORD", "FOO");
|
||||
vars.put("RABBITMQ_TEST_ADMIN_URI", "http://foo/bar");
|
||||
vars.put("RABBITMQ_TEST_ADMIN_USER", "BAR");
|
||||
vars.put("RABBITMQ_TEST_HOSTNAME", "BAZ");
|
||||
vars.put("RABBITMQ_TEST_PASSWORD", "QUX");
|
||||
vars.put("RABBITMQ_TEST_PORT", "2345");
|
||||
vars.put("RABBITMQ_TEST_USER", "FIZ");
|
||||
BrokerRunning.setEnvironmentVariableOverrides(vars);
|
||||
BrokerRunning brokerRunning = BrokerRunning.isBrokerAndManagementRunning();
|
||||
|
||||
assertEquals("http://foo/bar", brokerRunning.getAdminUri());
|
||||
ConnectionFactory connectionFactory = brokerRunning.getConnectionFactory();
|
||||
assertEquals("BAZ", connectionFactory.getHost());
|
||||
assertEquals(2345, connectionFactory.getPort());
|
||||
assertEquals("FIZ", connectionFactory.getUsername());
|
||||
assertEquals("QUX", connectionFactory.getPassword());
|
||||
DirectFieldAccessor dfa = new DirectFieldAccessor(brokerRunning);
|
||||
assertEquals("BAR", dfa.getPropertyValue("adminUser"));
|
||||
assertEquals("FOO", dfa.getPropertyValue("adminPassword"));
|
||||
|
||||
BrokerRunning.clearEnvironmentVariableOverrides();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1165,7 +1165,10 @@ public class EnableRabbitIntegrationTests {
|
||||
@Bean
|
||||
public ConnectionFactory rabbitConnectionFactory() {
|
||||
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||
connectionFactory.setHost("localhost");
|
||||
connectionFactory.setHost(brokerRunning.getHostName());
|
||||
connectionFactory.setPort(brokerRunning.getPort());
|
||||
connectionFactory.setUsername(brokerRunning.getUser());
|
||||
connectionFactory.setPassword(brokerRunning.getPassword());
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setThreadNamePrefix("rabbitClientThread-");
|
||||
executor.afterPropertiesSet();
|
||||
@@ -1386,7 +1389,10 @@ public class EnableRabbitIntegrationTests {
|
||||
@Bean
|
||||
public ConnectionFactory rabbitConnectionFactory() {
|
||||
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||
connectionFactory.setHost("localhost");
|
||||
connectionFactory.setHost(brokerRunning.getHostName());
|
||||
connectionFactory.setPort(brokerRunning.getPort());
|
||||
connectionFactory.setUsername(brokerRunning.getUser());
|
||||
connectionFactory.setPassword(brokerRunning.getPassword());
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2016 the original author or authors.
|
||||
* Copyright 2014-2017 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.
|
||||
@@ -35,7 +35,6 @@ import org.apache.commons.logging.Log;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.amqp.utils.test.TestUtils;
|
||||
|
||||
@@ -266,9 +266,11 @@ to suspend the test thread.
|
||||
|
||||
Spring AMQP _version 1.7_ provides an additional jar `spring-rabbit-junit`; this jar contains a couple of utility `@Rule` s for use when running JUnit tests.
|
||||
|
||||
`BrokerRunning` provides a mechanism to allow tests to succeed when a broker is not running on `localhost`.
|
||||
===== BrokerRunning
|
||||
|
||||
It also has utility methods to delete queues and exchanges.
|
||||
`BrokerRunning` provides a mechanism to allow tests to succeed when a broker is not running (on `localhost`, by default).
|
||||
|
||||
It also has utility methods to initialize/empty queues, and delete queues and exchanges.
|
||||
|
||||
Usage:
|
||||
|
||||
@@ -284,10 +286,74 @@ public static void tearDown() {
|
||||
}
|
||||
----
|
||||
|
||||
Of course, there are times when you want tests to fail if there is no broker, such as a nightly CI build.
|
||||
There are several `isRunning...` static methods such as `isBrokerAndManagementRunning()` which verifies the broker has the management plugin enabled.
|
||||
|
||||
====== Configuring the Rule
|
||||
|
||||
There are times when you want tests to fail if there is no broker, such as a nightly CI build.
|
||||
To disable the rule at runtime, set an environment variable `RABBITMQ_SERVER_REQUIRED` to `true`.
|
||||
|
||||
There are several `isRunning...` static methods such as `isBrokerAndManagementRunning()` which verifies the broker has the management plugin enabled.
|
||||
You can override the broker properties, such as hostname in several ways:
|
||||
|
||||
- Setters
|
||||
|
||||
[source, java]
|
||||
----
|
||||
|
||||
@ClassRule
|
||||
public static BrokerRunning brokerRunning = BrokerRunning.isRunningWithEmptyQueues("foo", "bar");
|
||||
|
||||
static {
|
||||
brokerRunning.setHostName("10.0.0.1")
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
brokerRunning.removeTestQueues("some.other.queue.too") // removes foo, bar as well
|
||||
}
|
||||
----
|
||||
|
||||
- Environment Variables
|
||||
|
||||
The following environment variables are provided:
|
||||
|
||||
[source, java]
|
||||
----
|
||||
public static final String BROKER_ADMIN_URI = "RABBITMQ_TEST_ADMIN_URI";
|
||||
public static final String BROKER_HOSTNAME = "RABBITMQ_TEST_HOSTNAME";
|
||||
public static final String BROKER_PORT = "RABBITMQ_TEST_PORT";
|
||||
public static final String BROKER_USER = "RABBITMQ_TEST_USER";
|
||||
public static final String BROKER_PW = "RABBITMQ_TEST_PASSWORD";
|
||||
public static final String BROKER_ADMIN_USER = "RABBITMQ_TEST_ADMIN_USER";
|
||||
public static final String BROKER_ADMIN_PW = "RABBITMQ_TEST_ADMIN_PASSWORD";
|
||||
----
|
||||
|
||||
These will override the default settings (`localhost:5672` for amqp and `http://localhost:15672/api/` for the management REST API).
|
||||
|
||||
Changing the host name affects both the amqp and management REST API connection (unless the admin uri is explicitly set).
|
||||
|
||||
`BrokerRunning` also provides a `static` method: `setEnvironmentVariableOverrides` where you can pass in a map containing these variables; they override system environment variables.
|
||||
This might be useful if you wish to use different configuration for tests in multiple test suites.
|
||||
IMPORTANT: The method must be called before invoking any of the `isRunning()` static methods that create the rule instance.
|
||||
Variable values will be applied to all instances created after this.
|
||||
Invoke `clearEnvironmentVariableOverrides()` to reset the rule to use defaults (including any actual environment variables).
|
||||
|
||||
In your test cases, you can use those properties when creating the connection factory:
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@Bean
|
||||
public ConnectionFactory rabbitConnectionFactory() {
|
||||
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
|
||||
connectionFactory.setHost(brokerRunning.getHostName());
|
||||
connectionFactory.setPort(brokerRunning.getPort());
|
||||
connectionFactory.setUsername(brokerRunning.getUser());
|
||||
connectionFactory.setPassword(brokerRunning.getPassword());
|
||||
return connectionFactory;
|
||||
}
|
||||
----
|
||||
|
||||
===== LongRunningIntegrationTest
|
||||
|
||||
`LongRunningIntegrationTest` is a rule that disables long running tests; you might want to use this on a developer system but ensure that the rule is disabled on, for example, nightly CI builds.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user