Utility for using Solace PubSub+ in JUnit Jupiter.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.solace.test.integration</groupId>
<artifactId>solace-integration-test-support-bom</artifactId>
<version>${solace.integration.test.support.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.solace.test.integration</groupId>
<artifactId>pubsubplus-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>The PubSubPlusExtension is the Junit 5 extension for using Solace PubSub+.
By default a Solace PubSub+ container will be auto-provisioned only if necessary.
The lifecycle of resources (e.g. sessions and endpoints) created through this extension are bound to the earliest JUnit context that they were defined in.
e.g.:
- If a resource was only defined as a parameter of a
@Testmethod, then that resource's lifecycle is bound to the test, and will be cleaned up after the test completes. - If a resource was only defined as a parameter of a
@BeforeAllmethod, then the resource's lifecycle is bound to the class, and will be cleaned up after the test class completes. - If you had the same resource defined as parameters of both
@BeforeAlland@Test, then both methods will use the same resource, and its lifecycle would be bound to the test class (i.e. the earliest definition of the resource).
Note that the only exception to this is the PubSub+ broker container. Which, if created, is bound to JUnit's root context. i.e. it will be cleaned up with the JVM.
@ExtendWith(PubSubPlusExtension.class)
public class Test {
// At least one of these arguments must be defined on the test function for the session and broker to be
// provisioned.
@Test
public void testMethod(JCSMPSession session, SempV2Api sempV2Api, Queue queue, JCSMPProperties properties) {
// Test logic using JCSMP
}
}JCSMPProperties & JCSMPSession parameters can be annotated with @JCSMPProperty to override individual JCSMP properties.
If a test needs multiple parameters of the same type (e.g. 2 JCSMPSessions), use the @Store annotation. This parameter annotation defines which store the parameter's resources belongs to.
If one resource is needed to create another (e.g. JCSMPSession is needed to create a Queue), then this extension will retrieve that resource's required resource from the same store.
e.g. In the following code snippet, defaultQueue will be created using defaultSession, while otherQueue will be created using otherSession:
@ExtendWith(PubSubPlusExtension.class)
public class Test {
@Test
public void testMethod(JCSMPSession defaultSession, @Store("other") otherSession,
Queue defaultQueue, @Store("other") Queue otherQueue) {
}
}First, implement the PubSubPlusExtension.ExternalProvider interface. e.g.:
public class OtherExternalProvider PubSubPlusExtension.ExternalProvider {
@Override
public boolean isValid(ExtensionContext extensionContext) {
// Return true to inform the PubSub+ extension if it can use this external
// provider to get its test broker
}
@Override
public void init(ExtensionContext extensionContext) {
// Initialize this external provider. Is only invoked once
}
@Override
public JCSMPProperties createJCSMPProperties(ExtensionContext extensionContext) {
// Create a new JCSMPProperties instance pointing to your externally managed broker
}
@Override
public SempV2Api createSempV2Api(ExtensionContext extensionContext) {
// Create a new SempV2API instance pointing to your externally managed broker
}
}Then add the META-INF/services/com.solace.test.integration.junit.jupiter.extension.PubSubPlusExtension$ExternalProvider resource file to configure external PubSub+ providers:
com.test.OtherExternalProvider
com.solace.test.integration.junit.jupiter.extension.pubsubplus.provider.PubSubPlusFileProvider
Note: Providers are resolved in order of top-to-bottom.
By default, PubSubPlusFileProvider is enabled as the only external provider.
Either extend SimpleContainerProvider or implement PubSubPlusExtension.ContainerProvider. e.g.:
public class OtherContainerProvider implements PubSubPlusExtension.ContainerProvider {
@Override
public Supplier<PubSubPlusContainer> containerSupplier(ExtensionContext extensionContext) {
// return a supplier which creates a new PubSubPlusContainer
return PubSubPlusContainer::new;
}
@Override
public void containerPostStart(ExtensionContext extensionContext, PubSubPlusContainer container) {
// optionally do something after the container starts
}
@Override
public JCSMPProperties createJcsmpProperties(ExtensionContext extensionContext, PubSubPlusContainer container) {
// create a new JCSMPProperties instance for the given PubSub+ container
}
@Override
public SempV2Api createSempV2Api(ExtensionContext extensionContext, PubSubPlusContainer container) {
// create a new SempV2API instance for the given PubSub+ container
}
}Then add the META-INF/services/com.solace.test.integration.junit.jupiter.extension.PubSubPlusExtension$ContainerProvider resource file that contains the full reference to your new ContainerProvider class:
com.test.OtherContainerProvider
Note: Only one container provider is supported. If multiple are detected, the first found provider will be used.
By default, SimpleContainerProvider is enabled as the container provider.
To integrate this extension into other extensions, use this extension's static getters. e.g.:
public class SomeNewExtension implements ParameterResolver {
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
...
}
public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
JCSMPSession jcsmpSession = PubSubPlusExtension.getJCSMPSession(extensionContext);
}
}Note: Resources created through these methods follows the PubSub+ Resource Lifecycle.
To retrieve a proxied JCSMP session, annotate your JCSMPSession parameter with @JCSMPProxy. To get the proxy itself, add the ToxiproxyContext parameter that's also annotated with @JCSMPProxy:
@ExtendWith(PubSubPlusExtension.class)
public class Test {
@Test
public void testMethod(@JCSMPProxy JCSMPSession jcsmpSession, @JCSMPProxy ToxiproxyContext jcsmpProxyContext) {
// add a toxic to the JCSMP proxy
Latency toxic = jcsmpProxyContext.getProxy().toxics()
.latency("lag", ToxicDirection.UPSTREAM, TimeUnit.SECONDS.toMillis(5));
// get a host that a container within the docker network can use to access the proxy
String toxicJCSMPNetworkHost = String.format("tcp://%s:%s", jcsmpProxyContext.getDockerNetworkAlias(),
jcsmpProxyContext.getProxy().getOriginalProxyPort())
// Test logic using toxic JCSMP session.
// Is already preconfigured to use the proxy since the parameter is annotated by @JCSMPProxy.
}
}This project provides a number of JUnit extensions: