Open KyleAure opened 1 year ago
Thanks for raising the issue, Kyle! Can you elaborate more about applicationPackages
and applicationArchives
, please?
@kiview and I were experimenting a little bit yesterday. There are different ways to build the artifact:
static InvocationResult buildWar() {
try {
DefaultInvocationRequest defaultInvocationRequest = new DefaultInvocationRequest();
defaultInvocationRequest.setMavenHome(new File(System.getenv("MAVEN_HOME")));
defaultInvocationRequest.setJavaHome(new File(System.getenv("JAVA_HOME")));
defaultInvocationRequest.setPomFile(Paths.get("pom.xml").toFile());
defaultInvocationRequest.setGoals(Collections.singletonList("war:war"));
Invoker appInvoker = new DefaultInvoker();
return appInvoker.execute(defaultInvocationRequest);
} catch (MavenInvocationException e) {
throw new RuntimeException("Could not build war", e);
}
}
static GenericContainer<?> jakartaApp = new GenericContainer<>("payara/micro:5.2021.9-jdk11")
.withExposedPorts(8080)
.withCopyFileToContainer(MountableFile.forHostPath("target/jakarta-tc.war"), "/opt/payara/deployments/jakarta-tc.war")
.waitingFor(Wait.forLogMessage(".* Payara Micro .* ready in .*\\s", 1));
File[] deps = Maven.resolver().loadPomFromFile("pom.xml").importCompileAndRuntimeDependencies().resolve().withTransitivity().asFile();
WebArchive archive = ShrinkWrap.create(WebArchive.class,"jakarta-tc.war")
.addClass(App.class)
.addPackages(true,
"dev.wittek.tc.jakarta.book",
"dev.wittek.tc.jakarta.dice",
"dev.wittek.tc.jakarta.time",
"dev.wittek.tc.jakarta.turing")
.addAsResource("META-INF/persistence.xml")
.addAsResource("META-INF/init.sql")
.addAsResource("turing.csv")
.addAsLibraries(deps);
archive.as(ZipExporter.class).exportTo(Paths.get("target/jakarta-tc.war").toFile(), true);
IDK if there is a better way to do this with ShrinkWrap, that's how I remember I did in a project some years ago. Any suggestion is welcome.
We were thinking about adding the ApplicationServer support such as PayaraMicroContainer
, TomcatContainer
and so on, with proper documentation about how can be used with Maven invoker, Gradle TestKit and ShrinkWrap. Thoughts?
If I think about the possible projects an ApplicationContainer
could be used in I can think of two distinct use cases:
ApplicationContainer
(integration testing)When performing these types of tests I have the following project structure:
target || build
- libs/
- app.war
src/
- main/
- java/
- resources/
- test/
- java/
- resources/
pom.xml || build.gradle
I can configure maven/gradle to build the .war
prior to running my tests.
Thus an ApplicationContainer
would look something like this:
@Container
static final ApplicationContainer<?> liberty = new LibertyContainer<>("open-liberty:23.0.0.4-full-java11-openj9")
.withApplicationPackages(MountableFile.forHostPath("build/libs/testapp.war"))
.waitingFor(Wait.forLogMessage(".*CWWKZ0001I: Application .* started in .* seconds.*", 1))
.withLogConsumer(new LogConsumer(Test.class, "liberty"));
When performing these types of tests I have the following project structure:
target || build
- libs
- library.jar
src/
- main/
- java/
- resources/
- test/
- java/
- webApp1/
- webApp2/
- test.java
- resources/
pom.xml || build.gradle
In this case, the applications I want to deploy are within my test directory itself, so I'm not able to rely on maven/gradle to have built and packaged them already.
Therefore, I need a runtime method to achieve this (Shrinkwrap being an existing library that allows me to do this).
Thus an ApplicationContainer
would look something like this:
@Container
static final ApplicationContainer<?> liberty = new LibertyContainer<>("open-liberty:23.0.0.4-full-java11-openj9")
.withApplicationArchvies(getApp1(), getApp2())
.waitingFor(Wait.forLogMessage(".*CWWKZ0001I: Application .* started in .* seconds.*", 2))
.withLogConsumer(new LogConsumer(Test.class, "liberty"));
static WebArchive getApp1() {
return ShrinkWrap.create(WebArchive.class, "app1.war")
.addPackage("webApp1");
}
static WebArchive getApp2() {
return ShrinkWrap.create(WebArchive.class, "app2.war")
.addPackage("webApp1");
}
Obviously withApplicationArchvies
and withApplicationPackages
are just what I came up with on the spot. Maybe we don't need to differentiate between the two and just use: withApplicationArchvies
and overload the method.
Maybe we don't need to differentiate between the two and just use: withApplicationArchvies and overload the method.
I like it! looking forward to it 🤗
Also, I saw that Glasshfish is going to be available at DockerHub. We should consider it when it's back again. WDYT?
@eddumelendez @kiview I created a draft PR to put together most of what we have talked about in this issue.
Module
New Module
Problem
As a Java test framework, it would be great for the Testcontainers project to expand into the Jakarta EE space by offering an application platform module with application containers.
This would allow application developers the ability to perform functional tests on their applications. This would allow platform developers the ability to perform integration tests on their platform.
Solution
The solution I am proposing would be to have a new module named
application-platform
With an abstract container type of
ApplicationContainer
Implementations of this container would come from vendors, for example:
[WIP] An ApplicationContainer would contain:
Benefit
The benefit of having this feature would be to streamline the process of performing functional and integration testing on Jakarta EE platforms.
Alternatives
The direct alternative would be to use a generic container with a bespoke configuration.
The comprehensive alternative would be to use Microshed Testing which isn't being maintained.
The other alternative is Arquillian which has its own concept of "containers" which doesn't use docker as the underlying technology.
Would you like to help contributing this feature?
Yes