-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Using TestContainers for Arquillian Remote
- Loading branch information
Showing
13 changed files
with
285 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/main/docker/integration-tests/scripts/create-stomp-test.cli
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package x1.arquillian; | ||
|
||
import java.util.List; | ||
|
||
import org.jboss.arquillian.container.spi.ContainerRegistry; | ||
import org.testcontainers.containers.GenericContainer; | ||
|
||
/** | ||
* implementation must have a no-arg constructor and must be annotated | ||
* with @ContainerDefinition | ||
*/ | ||
public interface ArquillianTestContainers { | ||
List<GenericContainer<?>> instances(); | ||
|
||
default void configureAfterStart(ContainerRegistry registry) { | ||
}; | ||
|
||
default boolean followLog(GenericContainer<?> container) { | ||
return true; | ||
} | ||
|
||
default boolean simpleLog(GenericContainer<?> container) { | ||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package x1.arquillian; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Inherited; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Inherited | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.TYPE }) | ||
public @interface ContainerDefinition { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package x1.arquillian; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
import org.jboss.arquillian.config.descriptor.api.ContainerDef; | ||
import org.jboss.arquillian.container.spi.Container; | ||
import org.jboss.arquillian.container.spi.ContainerRegistry; | ||
import org.testcontainers.containers.GenericContainer; | ||
import org.testcontainers.containers.Network; | ||
import org.testcontainers.containers.wait.strategy.Wait; | ||
import org.testcontainers.utility.DockerImageName; | ||
|
||
import jakarta.ws.rs.core.Response.Status; | ||
|
||
@ContainerDefinition | ||
public final class Containers implements ArquillianTestContainers { | ||
private Network network = Network.newNetwork(); | ||
|
||
private GenericContainer<?> database = new GenericContainer<>( | ||
DockerImageName.parse("registry.x1/j7beck/x1-postgres-stomp-test:1.8")).withNetwork(network) | ||
.withNetworkAliases("db"); | ||
|
||
private GenericContainer<?> etcd = new GenericContainer<>(DockerImageName.parse("quay.io/coreos/etcd:v3.5.11")) | ||
.withEnv("ETCD_ENABLE_V2", "true").withNetwork(network).withNetworkAliases("etcd").withCommand("etcd", | ||
"--listen-client-urls", "http://0.0.0.0:2379", "--advertise-client-urls", "http://etcd:2379"); | ||
|
||
private GenericContainer<?> wildfly = new GenericContainer<>( | ||
DockerImageName.parse("registry.x1/j7beck/x1-wildfly-stomp-test-it:1.8")).dependsOn(database).dependsOn(etcd) | ||
.withNetwork(network).withEnv("DB_SERVER", "db").withEnv("DB_PORT", "5432").withEnv("DB_USER", "stocks") | ||
.withEnv("DB_PASSWORD", "stocks").withEnv("ETCD_SERVER", "etcd").withEnv("ETCD_PORT", "2379") | ||
.withEnv("X1_SERVICE_REGISTRY_STAGE", "docker").withExposedPorts(8080, 9990) | ||
.waitingFor(Wait.forHttp("/health/ready").forStatusCode(Status.OK.getStatusCode())); | ||
|
||
private final List<GenericContainer<?>> instances = Arrays.asList(etcd, database, wildfly); | ||
|
||
@Override | ||
public List<GenericContainer<?>> instances() { | ||
return instances; | ||
} | ||
|
||
@Override | ||
public void configureAfterStart(ContainerRegistry registry) { | ||
Container arquillianContainer = registry.getContainers().iterator().next(); | ||
ContainerDef containerConfiguration = arquillianContainer.getContainerConfiguration(); | ||
containerConfiguration.property("managementPort", Integer.toString(wildfly.getMappedPort(9990))); | ||
|
||
// if we would run the test as client, we would need to access the servlet from the host | ||
// ProtocolDef protocolConfiguration = arquillianContainer.getProtocolConfiguration(new ProtocolDescription(ServletProtocolDefinition.NAME)); | ||
// protocolConfiguration.property("port", Integer.toString(wildfly.getMappedPort(8080))); | ||
} | ||
|
||
@Override | ||
public boolean followLog(GenericContainer<?> container) { | ||
if (container == etcd) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
@Override | ||
public boolean simpleLog(GenericContainer<?> container) { | ||
if (container == wildfly) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package x1.arquillian; | ||
|
||
import org.testcontainers.containers.output.BaseConsumer; | ||
import org.testcontainers.containers.output.OutputFrame; | ||
|
||
public class SimpleLogConsumer extends BaseConsumer<SimpleLogConsumer> { | ||
|
||
@Override | ||
public void accept(OutputFrame outputFrame) { | ||
var outputType = outputFrame.getType(); | ||
var utf8String = outputFrame.getUtf8StringWithoutLineEnding(); | ||
|
||
switch (outputType) { | ||
case END -> {} | ||
case STDOUT -> System.out.println(utf8String); | ||
case STDERR -> System.err.println(utf8String); | ||
default -> throw new IllegalArgumentException("Unexpected outputType " + outputType); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package x1.arquillian; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Collectors; | ||
|
||
import org.jboss.arquillian.container.spi.ContainerRegistry; | ||
import org.jboss.arquillian.container.spi.event.container.AfterStop; | ||
import org.jboss.arquillian.core.api.annotation.Observes; | ||
import org.jboss.arquillian.core.spi.LoadableExtension; | ||
import org.jboss.arquillian.core.spi.ServiceLoader; | ||
import org.reflections.Reflections; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.testcontainers.containers.output.Slf4jLogConsumer; | ||
|
||
public class TestContainersExtension implements LoadableExtension { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(TestContainersExtension.class); | ||
private static final String PACKAGE_NAME = "x1.arquillian"; | ||
|
||
public static boolean isRemoteArquillian() { | ||
return System.getProperty("arquillian.launch").equals("remote"); | ||
} | ||
|
||
@Override | ||
public void register(ExtensionBuilder builder) { | ||
if (isRemoteArquillian()) { | ||
findArquillianTestContainers().ifPresent(containerDefinition -> { | ||
LoadContainerConfiguration.containerDefinition = containerDefinition; | ||
builder.observer(LoadContainerConfiguration.class); | ||
}); | ||
} | ||
} | ||
|
||
public static final class LoadContainerConfiguration { | ||
private static ArquillianTestContainers containerDefinition; | ||
|
||
public void registerInstance(@Observes ContainerRegistry registry, ServiceLoader serviceLoader) { | ||
containerDefinition.instances().forEach(container -> { | ||
container.start(); | ||
if (containerDefinition.followLog(container)) { | ||
var logConsumer = containerDefinition.simpleLog(container) ? new SimpleLogConsumer() | ||
: new Slf4jLogConsumer(LOGGER).withSeparateOutputStreams(); | ||
container.followOutput(logConsumer); | ||
} | ||
}); | ||
LOGGER.info("Started {}", getImageNames()); | ||
containerDefinition.configureAfterStart(registry); | ||
} | ||
|
||
public void stopInstance(@Observes AfterStop event) { | ||
containerDefinition.instances().forEach(container -> container.stop()); | ||
LOGGER.info("Stopped {}", getImageNames()); | ||
} | ||
|
||
private List<String> getImageNames() { | ||
return containerDefinition.instances().stream().map(instance -> instance.getDockerImageName()) | ||
.collect(Collectors.toList()); | ||
} | ||
} | ||
|
||
private Optional<ArquillianTestContainers> findArquillianTestContainers() { | ||
var classes = new Reflections(PACKAGE_NAME).getTypesAnnotatedWith(ContainerDefinition.class); | ||
if (classes.isEmpty()) { | ||
return Optional.empty(); | ||
} else if (classes.size() > 1) { | ||
throw new IllegalArgumentException( | ||
"Found more than one ContainerDefinition under " + PACKAGE_NAME + ": " + classes); | ||
} | ||
try { | ||
LOGGER.debug("Found ContainerDefinition in {}", classes); | ||
return Optional.of((ArquillianTestContainers) classes.iterator().next().getDeclaredConstructor().newInstance()); | ||
} catch (Exception e) { | ||
LOGGER.warn("Could not create ContainerDefinition", e); | ||
return Optional.empty(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
x1.arquillian.TestContainersExtension |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_2_2.xsd" | ||
version="2.2"> | ||
<persistence-unit name="stomp-test"> | ||
<jta-data-source>java:jboss/datasources/stocksDS</jta-data-source> | ||
<properties> | ||
<property name="hibernate.hbm2ddl.auto" value="update" /> | ||
<property name="hibernate.show_sql" value="false" /> | ||
<property name="hibernate.default_schema" value="stocks" /> | ||
<property name="hibernate.cache.use_query_cache" value="true" /> | ||
<property name="hibernate.cache.use_second_level_cache" value="true" /> | ||
</properties> | ||
</persistence-unit> | ||
</persistence> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
org.slf4j.simpleLogger.defaultLogLevel=info | ||
org.slf4j.simpleLogger.log.x1=debug | ||
org.slf4j.simpleLogger.log.org.hibernate=warn | ||
org.slf4j.simpleLogger.log.org.hibernate=warn | ||
org.slf4j.simpleLogger.log.x1.arquillian=info |