Skip to content

Commit 50c17ea

Browse files
garyrussellartembilan
authored andcommitted
GH-1071: JUnit 5 Support Improvements
Resolves #1071 - Remove JUnit4 dependency from `RabbitAvailableCondition` (minor breaking API change) - Add `purgeAfterEach` to `@RabbitAvailable` - tabs not spaces in `RabbitAvailableCondition` (review with `?w=1`) - `@LogLevels` now requires `level` * Sonar, javadoc fixes; default log level, per review comments; convert more tests. * Remove unnecessary `defaultPort` field; 2 more conversions
1 parent 3d5fe16 commit 50c17ea

File tree

53 files changed

+1071
-818
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1071
-818
lines changed

spring-rabbit-junit/src/main/java/org/springframework/amqp/rabbit/junit/BrokerRunning.java

Lines changed: 38 additions & 333 deletions
Large diffs are not rendered by default.

spring-rabbit-junit/src/main/java/org/springframework/amqp/rabbit/junit/BrokerRunningSupport.java

Lines changed: 622 additions & 0 deletions
Large diffs are not rendered by default.

spring-rabbit-junit/src/main/java/org/springframework/amqp/rabbit/junit/LogLevels.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353

5454
/**
5555
* The Log4j level name to switch the categories to during the test.
56-
* @return the level.
56+
* @return the level (default DEBUG).
5757
*/
58-
String level() default "";
58+
String level() default "DEBUG";
5959

6060
}

spring-rabbit-junit/src/main/java/org/springframework/amqp/rabbit/junit/LogLevelsCondition.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,12 @@ public void beforeEach(ExtensionContext context) {
7474
store = parent.getStore(Namespace.create(getClass(), parent));
7575
logLevels = store.get(STORE_ANNOTATION_KEY, LogLevels.class);
7676
}
77-
store.put(STORE_CONTAINER_KEY, JUnitUtils.adjustLogLevels(context.getDisplayName(),
78-
Arrays.asList((logLevels.classes())),
79-
Arrays.asList(logLevels.categories()),
80-
Level.toLevel(logLevels.level())));
77+
if (logLevels != null) {
78+
store.put(STORE_CONTAINER_KEY, JUnitUtils.adjustLogLevels(context.getDisplayName(),
79+
Arrays.asList((logLevels.classes())),
80+
Arrays.asList(logLevels.categories()),
81+
Level.toLevel(logLevels.level())));
82+
}
8183
}
8284

8385
@Override
@@ -91,10 +93,12 @@ public void afterEach(ExtensionContext context) {
9193
container = store.get(STORE_CONTAINER_KEY, LevelsContainer.class);
9294
parentStore = true;
9395
}
94-
JUnitUtils.revertLevels(context.getDisplayName(), container);
95-
store.remove(STORE_CONTAINER_KEY);
96-
if (!parentStore) {
97-
store.remove(STORE_ANNOTATION_KEY);
96+
if (container != null) {
97+
JUnitUtils.revertLevels(context.getDisplayName(), container);
98+
store.remove(STORE_CONTAINER_KEY);
99+
if (!parentStore) {
100+
store.remove(STORE_ANNOTATION_KEY);
101+
}
98102
}
99103
}
100104

spring-rabbit-junit/src/main/java/org/springframework/amqp/rabbit/junit/RabbitAvailable.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,11 @@
6262
*/
6363
boolean management() default false;
6464

65+
/**
66+
* Purge the test queues after each test.
67+
* @return true to purge (default).
68+
* @since 2.2
69+
*/
70+
boolean purgeAfterEach() default true;
71+
6572
}

spring-rabbit-junit/src/main/java/org/springframework/amqp/rabbit/junit/RabbitAvailableCondition.java

Lines changed: 101 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Optional;
2121

2222
import org.junit.jupiter.api.extension.AfterAllCallback;
23+
import org.junit.jupiter.api.extension.AfterEachCallback;
2324
import org.junit.jupiter.api.extension.ConditionEvaluationResult;
2425
import org.junit.jupiter.api.extension.ExecutionCondition;
2526
import org.junit.jupiter.api.extension.ExtensionContext;
@@ -35,100 +36,110 @@
3536
import com.rabbitmq.client.ConnectionFactory;
3637

3738
/**
38-
* JUnit5 {@link ExecutionCondition}.
39-
* Looks for {@code @RabbitAvailable} annotated classes and disables
40-
* if found the broker is not available.
39+
* JUnit5 {@link ExecutionCondition}. Looks for {@code @RabbitAvailable} annotated classes
40+
* and disables if found the broker is not available.
4141
*
4242
* @author Gary Russell
4343
* @since 2.0.2
4444
*
4545
*/
46-
public class RabbitAvailableCondition implements ExecutionCondition, AfterAllCallback, ParameterResolver {
47-
48-
private static final String BROKER_RUNNING_BEAN = "brokerRunning";
49-
50-
private static final ConditionEvaluationResult ENABLED = ConditionEvaluationResult.enabled(
51-
"@RabbitAvailable is not present");
52-
53-
private static final ThreadLocal<BrokerRunning> brokerRunningHolder = new ThreadLocal<>(); // NOSONAR - lower case
54-
55-
@Override
56-
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
57-
Optional<AnnotatedElement> element = context.getElement();
58-
MergedAnnotations annotations = MergedAnnotations.from(element.get(),
59-
MergedAnnotations.SearchStrategy.TYPE_HIERARCHY);
60-
if (annotations.get(RabbitAvailable.class).isPresent()) {
61-
RabbitAvailable rabbit = annotations.get(RabbitAvailable.class).synthesize();
62-
try {
63-
String[] queues = rabbit.queues();
64-
BrokerRunning brokerRunning = getStore(context).get(BROKER_RUNNING_BEAN, BrokerRunning.class);
65-
if (brokerRunning == null) {
66-
if (rabbit.management()) {
67-
brokerRunning = BrokerRunning.isBrokerAndManagementRunningWithEmptyQueues(queues);
68-
}
69-
else {
70-
brokerRunning = BrokerRunning.isRunningWithEmptyQueues(queues);
71-
}
72-
}
73-
brokerRunning.isUp();
74-
brokerRunningHolder.set(brokerRunning);
75-
Store store = getStore(context);
76-
store.put(BROKER_RUNNING_BEAN, brokerRunning);
77-
store.put("queuesToDelete", queues);
78-
return ConditionEvaluationResult.enabled("RabbitMQ is available");
79-
}
80-
catch (Exception e) {
81-
if (BrokerRunning.fatal()) {
82-
throw new IllegalStateException("Required RabbitMQ is not available", e);
83-
}
84-
return ConditionEvaluationResult.disabled("RabbitMQ is not available");
85-
}
86-
}
87-
return ENABLED;
88-
}
89-
90-
@Override
91-
public void afterAll(ExtensionContext context) {
92-
brokerRunningHolder.remove();
93-
Store store = getStore(context);
94-
BrokerRunning brokerRunning = store.remove(BROKER_RUNNING_BEAN, BrokerRunning.class);
95-
if (brokerRunning != null) {
96-
brokerRunning.removeTestQueues();
97-
}
98-
}
99-
100-
@Override
101-
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
102-
throws ParameterResolutionException {
103-
Class<?> type = parameterContext.getParameter().getType();
104-
return type.equals(ConnectionFactory.class) || type.equals(BrokerRunning.class);
105-
}
106-
107-
@Override
108-
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext context)
109-
throws ParameterResolutionException {
110-
// in parent for method injection, Composite key causes a store miss
111-
BrokerRunning brokerRunning =
112-
getParentStore(context).get(BROKER_RUNNING_BEAN, BrokerRunning.class) == null
113-
? getStore(context).get(BROKER_RUNNING_BEAN, BrokerRunning.class)
114-
: getParentStore(context).get(BROKER_RUNNING_BEAN, BrokerRunning.class);
115-
Assert.state(brokerRunning != null, "Could not find brokerRunning instance");
116-
Class<?> type = parameterContext.getParameter().getType();
117-
return type.equals(ConnectionFactory.class) ? brokerRunning.getConnectionFactory()
118-
: brokerRunning;
119-
}
120-
121-
private Store getStore(ExtensionContext context) {
122-
return context.getStore(Namespace.create(getClass(), context));
123-
}
124-
125-
private Store getParentStore(ExtensionContext context) {
126-
ExtensionContext parent = context.getParent().get();
127-
return parent.getStore(Namespace.create(getClass(), parent));
128-
}
129-
130-
public static BrokerRunning getBrokerRunning() {
131-
return brokerRunningHolder.get();
132-
}
46+
public class RabbitAvailableCondition
47+
implements ExecutionCondition, AfterEachCallback, AfterAllCallback, ParameterResolver {
48+
49+
private static final String BROKER_RUNNING_BEAN = "brokerRunning";
50+
51+
private static final ConditionEvaluationResult ENABLED = ConditionEvaluationResult.enabled(
52+
"@RabbitAvailable is not present");
53+
54+
private static final ThreadLocal<BrokerRunningSupport> BROKER_RUNNING_HOLDER = new ThreadLocal<>();
55+
56+
@Override
57+
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
58+
Optional<AnnotatedElement> element = context.getElement();
59+
MergedAnnotations annotations = MergedAnnotations.from(element.get(),
60+
MergedAnnotations.SearchStrategy.TYPE_HIERARCHY);
61+
if (annotations.get(RabbitAvailable.class).isPresent()) {
62+
RabbitAvailable rabbit = annotations.get(RabbitAvailable.class).synthesize();
63+
try {
64+
String[] queues = rabbit.queues();
65+
BrokerRunningSupport brokerRunning = getStore(context).get(BROKER_RUNNING_BEAN,
66+
BrokerRunningSupport.class);
67+
if (brokerRunning == null) {
68+
if (rabbit.management()) {
69+
brokerRunning = BrokerRunningSupport.isBrokerAndManagementRunningWithEmptyQueues(queues);
70+
}
71+
else {
72+
brokerRunning = BrokerRunningSupport.isRunningWithEmptyQueues(queues);
73+
}
74+
}
75+
brokerRunning.setPurgeAfterEach(rabbit.purgeAfterEach());
76+
brokerRunning.test();
77+
BROKER_RUNNING_HOLDER.set(brokerRunning);
78+
Store store = getStore(context);
79+
store.put(BROKER_RUNNING_BEAN, brokerRunning);
80+
store.put("queuesToDelete", queues);
81+
return ConditionEvaluationResult.enabled("RabbitMQ is available");
82+
}
83+
catch (Exception e) {
84+
if (BrokerRunningSupport.fatal()) {
85+
throw new IllegalStateException("Required RabbitMQ is not available", e);
86+
}
87+
return ConditionEvaluationResult.disabled("RabbitMQ is not available");
88+
}
89+
}
90+
return ENABLED;
91+
}
92+
93+
@Override
94+
public void afterEach(ExtensionContext context) {
95+
BrokerRunningSupport brokerRunning = BROKER_RUNNING_HOLDER.get();
96+
if (brokerRunning != null && brokerRunning.isPurgeAfterEach()) {
97+
brokerRunning.purgeTestQueues();
98+
}
99+
}
100+
101+
@Override
102+
public void afterAll(ExtensionContext context) {
103+
BROKER_RUNNING_HOLDER.remove();
104+
Store store = getStore(context);
105+
BrokerRunningSupport brokerRunning = store.remove(BROKER_RUNNING_BEAN, BrokerRunningSupport.class);
106+
if (brokerRunning != null) {
107+
brokerRunning.removeTestQueues();
108+
}
109+
}
110+
111+
@Override
112+
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
113+
throws ParameterResolutionException {
114+
Class<?> type = parameterContext.getParameter().getType();
115+
return type.equals(ConnectionFactory.class) || type.equals(BrokerRunningSupport.class);
116+
}
117+
118+
@Override
119+
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext context)
120+
throws ParameterResolutionException {
121+
// in parent for method injection, Composite key causes a store miss
122+
BrokerRunningSupport brokerRunning = getParentStore(context).get(BROKER_RUNNING_BEAN,
123+
BrokerRunningSupport.class) == null
124+
? getStore(context).get(BROKER_RUNNING_BEAN, BrokerRunningSupport.class)
125+
: getParentStore(context).get(BROKER_RUNNING_BEAN, BrokerRunningSupport.class);
126+
Assert.state(brokerRunning != null, "Could not find brokerRunning instance");
127+
Class<?> type = parameterContext.getParameter().getType();
128+
return type.equals(ConnectionFactory.class) ? brokerRunning.getConnectionFactory()
129+
: brokerRunning;
130+
}
131+
132+
private Store getStore(ExtensionContext context) {
133+
return context.getStore(Namespace.create(getClass(), context));
134+
}
135+
136+
private Store getParentStore(ExtensionContext context) {
137+
ExtensionContext parent = context.getParent().get();
138+
return parent.getStore(Namespace.create(getClass(), parent));
139+
}
140+
141+
public static BrokerRunningSupport getBrokerRunning() {
142+
return BROKER_RUNNING_HOLDER.get();
143+
}
133144

134145
}

spring-rabbit-junit/src/test/java/org/springframework/amqp/rabbit/junit/BrokerRunningTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ public void testEnvironmentVars() {
7272
assertThat(connectionFactory.getUsername()).isEqualTo("FIZ");
7373
assertThat(connectionFactory.getPassword()).isEqualTo("QUX");
7474
DirectFieldAccessor dfa = new DirectFieldAccessor(brokerRunning);
75-
assertThat(dfa.getPropertyValue("adminUser")).isEqualTo("BAR");
76-
assertThat(dfa.getPropertyValue("adminPassword")).isEqualTo("FOO");
75+
assertThat(dfa.getPropertyValue("brokerRunning.adminUser")).isEqualTo("BAR");
76+
assertThat(dfa.getPropertyValue("brokerRunning.adminPassword")).isEqualTo("FOO");
7777

7878
BrokerRunning.clearEnvironmentVariableOverrides();
7979
}

spring-rabbit-junit/src/test/java/org/springframework/amqp/rabbit/junit/RabbitAvailableCTORInjectionTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public class RabbitAvailableCTORInjectionTests {
3535

3636
private final ConnectionFactory connectionFactory;
3737

38-
public RabbitAvailableCTORInjectionTests(BrokerRunning brokerRunning) {
38+
public RabbitAvailableCTORInjectionTests(BrokerRunningSupport brokerRunning) {
3939
this.connectionFactory = brokerRunning.getConnectionFactory();
4040
}
4141

spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/AbstractConnectionFactoryTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import java.util.concurrent.atomic.AtomicInteger;
3737

3838
import org.apache.commons.logging.Log;
39-
import org.junit.Test;
39+
import org.junit.jupiter.api.Test;
4040
import org.mockito.ArgumentCaptor;
4141

4242
import org.springframework.amqp.utils.test.TestUtils;

spring-rabbit/src/test/java/org/springframework/amqp/rabbit/connection/CachePropertiesTests.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,15 @@
2121
import java.util.Properties;
2222
import java.util.concurrent.atomic.AtomicInteger;
2323

24-
import org.junit.ClassRule;
25-
import org.junit.Test;
26-
import org.junit.runner.RunWith;
24+
import org.junit.jupiter.api.Test;
2725

2826
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory.CacheMode;
29-
import org.springframework.amqp.rabbit.junit.BrokerRunning;
27+
import org.springframework.amqp.rabbit.junit.RabbitAvailable;
3028
import org.springframework.beans.factory.annotation.Autowired;
3129
import org.springframework.context.annotation.Bean;
3230
import org.springframework.context.annotation.Configuration;
3331
import org.springframework.test.annotation.DirtiesContext;
34-
import org.springframework.test.context.ContextConfiguration;
35-
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
32+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
3633

3734
import com.rabbitmq.client.Channel;
3835

@@ -41,14 +38,11 @@
4138
* @since 1.6
4239
*
4340
*/
44-
@ContextConfiguration
45-
@RunWith(SpringJUnit4ClassRunner.class)
41+
@SpringJUnitConfig
4642
@DirtiesContext
43+
@RabbitAvailable
4744
public class CachePropertiesTests {
4845

49-
@ClassRule
50-
public static BrokerRunning br = BrokerRunning.isRunning();
51-
5246
@Autowired
5347
private CachingConnectionFactory channelCf;
5448

0 commit comments

Comments
 (0)