Git Product home page Git Product logo

microshed-testing's Introduction

MicroShed

microshed-testing's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

microshed-testing's Issues

Requires MP Health 2.0 / MicroProfile 3.0 runtime

According to the readme, the goal is

  • Work with any JavaEE or MicroProfile runtime

But it requires MP Health 2.0 due to the fact that it checks for readiness of the container using /health/ready

So the goals must be adjusted, or the check must be made configurable.

Add getReadinessPath() also to ServerAdapter

Since a ServerAdapter is defined for a specific runtime, the withReadinessPath() can be specified in the adapter so that the developer doesn't need to specify it in each test.

Requiered "typ" header of token was missed

Describe the bug
There is no "typ": "JWT" in header

To Reproduce
Try to use RESTClient with @JwtConfig for application secured by "MP-JWT"

Expected behavior
JwtBuilder should add typ header in buildJwt method
builder.jws.setHeader("typ", "JWT");

LogMessageWaitStrategy fails in hollow mode with NPE, assuming a container log

Describe the bug

In "hollow" mode, using a config like:

   public class BonusPayoutITContainerConfig implements SharedContainerConfiguration {

    @Container
    public static ApplicationContainer inventory = new ApplicationContainer()
                    .withAppContextRoot("/")
                    .withExposedPorts(9443)
                    .waitingFor(
                            Wait.forLogMessage(".*CWWKF0011I.*\\n", 1)
                        );
   }

fails with:

java.util.concurrent.CompletionException: java.lang.NullPointerException: containerId was not specified
Caused by: java.lang.NullPointerException: containerId was not specified

with stack trace:

Preconditions.checkNotNull(T, Object) line: 228
LogContainerCmdImpl.withContainerId(String) line: 78
LogContainerCmdImpl.(LogContainerCmd$Exec, String) line: 38
DockerClientImpl.logContainerCmd(String) line: 380
AuditLoggingDockerClient.logContainerCmd(String) line: 26
LogUtils.attachConsumer(DockerClient, String, Consumer, boolean, OutputType...) line: 88
LogUtils.followOutput(DockerClient, String, Consumer, OutputType...) line: 36
LogUtils.followOutput(DockerClient, String, Consumer) line: 51
LogMessageWaitStrategy.waitUntilReady() line: 22
LogMessageWaitStrategy(AbstractWaitStrategy).waitUntilReady(WaitStrategyTarget) line: 35
ApplicationContainer(GenericContainer).waitUntilContainerStarted() line: 879
ApplicationContainer.doStart() line: 296
ApplicationContainer(GenericContainer).start() line: 300

Assuming we probably need to either:

  • figure we don't need to wait, because it's hollow mode, and things are already started.
    OR
  • use the "hollow" JVM's log stream to search for the log message.

To Reproduce
Using Open Liberty with the v0.9 adapater, using a config like above, run: mvn liberty:dev

Expected behavior
Either no-op the wait, or execute wait based on the "hollow" JVM which doesn't need to be started.

System information:

  • OS: Windows
  • Java Version: 11
  • MicroShed Testing Version: org.microshed:microshed-testing-liberty:jar:0.9:

Allow the injection of any bean

Is your feature request related to a problem? Please describe.
As a developer I want to test both my APIs and the schedulers I had in my application. At this point if you try to inject a resource that is not a RESTClient it is null.

Describe the solution you'd like
I would like this resource to be injected in order to be able to test my entire application with MicroShed.

Describe alternatives you've considered
I tried to use Quarkus with microshed but they don't support querydsl.

Additional context
N/A

Running unit and integration tests side by side

As a user of the system-test package, I want to be able to run integration tests (using system-test) and unit tests (using junit) against a single application at the same time.

This functionally already works, but it is easy to configure incorrectly. Therefore, additional documentation / examples may be necessary.

  • Create sample application (gradle or maven)
  • Distinguish between it and unit test directories
  • Distinguish between org.junit.jupiter.api.Test and org.junit.Test imports
  • Write accompanying documentation.

Hook to purge connection pool between test runs

For hollow mode, connection pools may be unable to cope with DBs being replaced underneath them.

We should add a hook to purge connection pools before tests start so that connection pools start with a clean state and do not have stale connection references in them.

Test an app that uses JDBC

User story:

As a user of this test framework, I want to test an app that uses JDBC.

Additional detail:

It is very common for microservice applications to persist data to a database. Relational databases are commonly used for microservices. Some databases we should consider testing with are:

  • PostgreSQL
  • MySQL
  • Microsoft SQLServer
  • Oracle XE
  • IBM DB2

Recommend that developers use Testcontainers to create an instance of their DB using a Docker container.
Since container start can be expensive, it would be best if we can keep the same database up for all tests, and just wipe the DB clean after every test method and/or class. This behavior should have a reasonable default, and other options should be easily configurable. If users want a more fine-grained direct control over how data is managed between tests, there should be a way that users can plug-in their own pre-populating/clearing logic.

Coordinate design with testing NoSQL databases.

Test an app that uses messaging

User story:

As a user of this test framework, I want to test an app that uses messaging (JMS, MP Reactive Messaging, or Kafka)

Additional detail:

It is common for applications to communicate via some sort of messaging. Initially we could try and implement support for JMS or Kafka, but MP Reactive Messaging will hopefully gain a lot of traction once released and will influence the design of testing messaging apps. Wait until MP Reactive Messaging is stable/released before investigating this further.

Test an app with simulated network instability

User story:

As a user of this test framework, I want to test an app that simulates network instability.

Additional detail:

Applications should be resilient to failures in infrastructure such as excessive latency or cut connections. MicroProfile Fault Tolerance was created for this reason, but it can be difficult to test in an automated fashion. Use the toxiproxy module to simulate network instability with applications and ensure they recover properly.

Create a CONTRIBUTING.md

  • Describes how one can contribute to the project with DCO signoff.
  • Enable DCO app for appropriate branches.

Support for Quarkus Kafka Streams

Is your feature request related to a problem? Please describe.
The Quarkus Kafka Streams extension use different properties to configure e.g. Kafka bootstrap servers. We would like to use MST to test Kafka Streams applications. Without the correct settings the Kafka Streams application can't be bootstrapped.

https://quarkus.io/guides/kafka-streams#configuration-reference

Describe the solution you'd like
My quick and dirty solution was to simply add the proper property to QuarkusConfiguration.java:
System.setProperty("quarkus.kafka-streams.bootstrap-servers", bootstrapServers);

Additional context

  • OS: macOS 10.15.3
  • Java Version: 11
  • MicroShed Testing Version: 0.8.1-SNAPSHOT
  • Qarkus 1.3.2.Final

Test an app that uses a NoSQL database

User story:

As a user of this test framework, I want to test an app that that communicates with a NoSQL database.

Additional detail:

It is very common for microservice applications to persist data to a database. NoSQL databases are commonly used for microservices. Some databases we should consider testing with are:

  • MongoDB
  • Cassandra
  • Couchbase
  • Redis

If the DB provides a mock driver that can be used with their client API, we can use it. Otherwise, users can use Testcontainers to create an instance of their DB using a Docker container.
Since container start can be expensive, it would be best if we can keep the same database up for all tests, and just wipe the DB clean after every test method and/or class. This behavior should have a reasonable default, and other options should be easily configurable. If users want a more fine-grained direct control over how data is managed between tests, there should be a way that users can plug-in their own pre-populating/clearing logic.

Coordinate design with testing relational databases.

@QuarkusTest collides with @KafkaConsumerConfig/@KafkaProducerConfig

Describe the bug
Kafka consumer and producer will not be injected into @QuarkusTest annotated tests. Fields are null.

To Reproduce

@MicroShedTest
@QuarkusTest
@SharedContainerConfig(KafkaTestResourceConfig.class)
public class MyTest {

  @KafkaConsumerConfig(groupId = "my-consumer")
  public static KafkaConsumer<String, String> consumer;

  @KafkaProducerConfig
  public static KafkaProducer<String, String> producer;

  @Test
  public void myTest() {
    // producer.send(...)
    // consumer.poll(...)
  }
}

public class KafkaTestResourceConfig implements SharedContainerConfiguration {

  private static Network network = Network.newNetwork();

  @Container
  public static KafkaContainer kafka = new KafkaContainer("5.0.1")
    .withNetwork(network);
}

Expected behavior
Injection should work the way it does if you remove @QuarkusTest annotation.

System information:

  • OS: macOS 10.15.3
  • Java Version: 11
  • MicroShed Testing Version: 0.8.1-SNAPSHOT
  • Qarkus 1.3.2.Final

Access the response status and headers of the Client Response

Is your feature request related to a problem? Please describe.

Right now we can only write assertions based on the response type of the JAX-RS method class. It would be nice if we can access the actual JAX-RS Response to inspect HTTP headers & the response status.

Describe the solution you'd like

Maybe reconsider the solution with the injection of the JAX-RS resources class to a static field using @RESTClient PersonResource personResource (which is also not that intuitive IMHO). It would be nice to just inject a prepared JAX-RS Client which is already bound to the application context, has some default provider (e.g. JSON/XML) and can be further configured if required. The Spring framework, for example, provides a WebTestClient during a test execution with the described setup.

I wouldn't go that far as the Spring Framework and also add assertion methods on the client class and just prepare it to be used by the developer like in his production code.

The downside of this idea: The user has to enter the actual path for the JAX-RS resource he/she wants to access, which is currently not required. This might also be a small plus, as with the current solution your integration test would never recognize a URL change in the API e.g. /resources/persons to /api/persons.

Describe alternatives you've considered

  • Enhance the current solution with @RESTClient
  • Don't prepare anything for accessing the JAX-RS resources and let the developer pick and setup whatever he wants

Additional context

none

Test an app that communicates with external HTTP service

User story:

As a user of this test framework, I want to test an app that communicates with an external HTTP service

Additional detail:

A very common thing for a microservice application to do is communicate with some sort of external HTTP service. Typically this is might be an external REST API, but it could also be a Servlet endpoint. It should be easy for users to mock out and control external HTTP services that their application may need to communicate with.

Create hosted documentation

User story:

As a user of this test framework, I want to be able to view documentation examples for each of the key aspects of the test framework

Additional detail:

Consider using github pages to host documentation, so that source and docs can be kept in the same repository.

Would like the ability to calculate a base path from a JAX-RS Application type in a specific package, unrelated to @RESTClient type

I'd like to be able to use:

@RESTClient
public static StarterResource appService;

but to use an Application from some other package.

import javax.ws.rs.core.Application;

@ApplicationPath("/api")
public class StarterApplication extends Application {

At the moment, MST will start from the Resource class and look for an Application in the same package, (understandably not wanting to scan the whole classloader tree).

Interested to hear ideas here on how this could fit into MST config or extension.

This basic mapping strikes me as maybe one that could have come up in other JAX-RS-related contexts, but admit I haven't done much resource to see if there's something already to build off of (completely separate from MST).

Standard JavaEE/MicroProfile app and tests should be portable

User story:

As a user of this test framework, I want my MP/JEE standard application and tests to work on different app servers without needing to change a significant amount of my test code.

Additional detail:

One important aspect about standards like JavaEE and MicroProfile is that they are portable across multiple implementations. This is currently true for application code, and should also be true for test code as well. Arquillian currently provides this fairly well -- each vendor has implemented an adapter with instructions on how to start/stop containers, and deploy/undeploy apps from each.

With this test framework, the start/stop deploy/undeploy gets handled by Docker. However, other aspects to consider may be:

  • getting default container ports (optional)
  • getting default app start timeout (optional)
  • composition of default Docker image

Important: There should be as little vendor-specific function required in the adapters. The less code vendors have to implement/maintain, the more likely we are to get wide adoption.

Use dedicated annotation for REST Client instead of @Inject

Is your feature request related to a problem? Please describe.
It is important for users to understand how REST Clients work (and that they are being used in the first place). However, the current approach with @Inject MyService svc; does not make it very obvious that a REST client is being injected. Instead, users may think that the actual server-side instance of MyService is being injected, or that the test code is running inside the container -- neither of which is the case. Also, users may think that CDI is being used to inject the annotation, which is not the case.

Describe the solution you'd like
We should introduce a new annotation that makes it more obvious that a REST Client is being used, and that CDI is NOT being used to inject it.

For example:

import org.microshed.testing.jupiter.RestClient;

@RestClient
public static MyService myService;

Additional context
We should keep in mind that MicroProfile REST Client has an @org.eclipse.microprofile.rest.client.inject.RestClient annotation, which will commonly be on the build path. It may be confusing to users having to know which package to import @RestClient from and I expect many users may import the MP annotation and wonder why the fields are not being injected in the test. For this reason, we should consider alternative names such as @MicroShedRestClient or @RESTClient

RESTClient Host is null (UnknownHostException)

Describe the bug
Hi there. I am new to microshed, it is a very promising project, so I tried to code some tests.
Currently I have the problem, that the applications is starting in docker but it seems, that the host is not set in the Object annotated by '@restclient'.
Plz see the attached Project. this results in a
'UnknownHostException: UnknownHostException invoking http://null:0/myapp/myresource/dosth: null'

To Reproduce
see project zip

System information:

  • OS: [e.g. Linux, Windows, Mac]: windows 10
  • Java Version: [e.g. 8, 11]: 8
  • MicroShed Testing Version: [e.g. 0.4.2]: 0.6.2

Additional context
IDE: Netbeans 11.2
mavenproject7.zip

Thanks for your help. And thanks for your work :)

Test an application that uses MP JWT

User story:

As a user of this test framework, I want to test an app that uses MP JWT

Additional detail:

JWT (Json Web Tokens) are a widely used auth protocol that has been officially adopted as the security mechanism of choice for MP apps. This test framework should make it easy to create test JWTs that can be invoked from the test client to test auth behavior of the application

Error if org.microshed.testing.jaxrs.RESTClient return CompletionStage

Describe the bug
A service provides a REST api return CompletionStage<>.
Used MST RESTClient to test it, got following error:

javax.ws.rs.client.ResponseProcessingException: Problem with reading the data, class java.util.concurrent.CompletionStage, ContentType: application/json.

To Reproduce

[ERROR] Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 41.349 s <<< FAILURE! - in it.io.openliberty.guides.inventory.InventoryServiceIT
[ERROR] testGetProperty  Time elapsed: 0.937 s  <<< ERROR!
javax.ws.rs.client.ResponseProcessingException: Problem with reading the data, class java.util.concurrent.CompletionStage, ContentType: application/json.
	at it.io.openliberty.guides.inventory.InventoryServiceIT.testGetProperty(InventoryServiceIT.java:96)
Caused by: javax.json.bind.JsonbException: Internal error: Unexpected char 82 at (line no=1, column no=1, offset=0)
	at it.io.openliberty.guides.inventory.InventoryServiceIT.testGetProperty(InventoryServiceIT.java:96)
Caused by: javax.json.stream.JsonParsingException: Unexpected char 82 at (line no=1, column no=1, offset=0)
	at it.io.openliberty.guides.inventory.InventoryServiceIT.testGetProperty(InventoryServiceIT.java:96)

Expected behavior
No error and test can be passed

System information:

  • OS: Linux, Mac
  • Java Version: 8
  • MicroShed Testing Version: 0.9

Additional context
MicroProfile rest client supports to return CompletionStage

add cookies/headers to the RESTClient decorator

I have a lot of tests that use the RESTClient decorator.

Due to some security concerns, now we need to exchange a session cookie.
This cookie must remain the same between requests on some operations.

It would be nice if we can use something like
RESTClient(headers = {header1, header2}) public static MyService myService;

I know it is possible to use the RestClientBuilder, but I do prefer the decorator approach!

Hook to recycle application before test begins

Sometimes an app may be written assuming that it will outlive the lifecycle of its external resources, for example an app may assume a DB will already exist, and it may not be able to cope with a DB restarting during its activation.

To resolve this, we should recycle applications (if supported by the runtimes) in hollow mode so that each test run starts with a fresh application state.

Test an app that uses JPA

User story:

As a user of this test framework, I want to test an app that uses JPA

Additional detail:

This story should be worked on after the JDBC story: #13

Docker daemon caching does not work

Describe the bug
When running with one of the server adapters where Dockerfiles are generated, layers that include a COPY or ADD step are never cached, resulting in later steps never being cached.

To Reproduce
Add configure.sh to the LibertyAdapter default image, notice that configure.sh runs every time and is never cached.

Expected behavior
Layers should be cached

Test an app that uses HTTPS

User story:

As a user of this test framework, I want to test an app that uses HTTPS

Additional detail:

The easiest way to test an HTTP service is using unsecured applications, but in production applications should be communicating via HTTPS, which requires client/server certificates. The test framework should make it easy to drive HTTPS requests to the server.

Test apps/repos that have no knowledge of Docker

User story:

As a user of this test framework, I want to test an app that just builds a war and does not use Docker or have a Dockerfile

Additional detail:

Not all apps use Docker in production, or may not have a Dockerfile written. For these cases, we can still provide easy setup/run through Docker if we build a Docker image for them automatically using a vendor-specific standard Dockerfile.
For example, the standard OpenLiberty Dockerfile looks like:

FROM open-liberty:<PROFILE>
ADD build/libs/<USER_APP>.war /config/dropins
COPY src/main/liberty/config /config/

Access the container from the SharedContainerConfig

I would like to test the logs from a container I defined in the SharedContainerConfig class. Testcontainers provides the WaitingConsumer class, which allows me to follow and read the logs from my tests.

Is there a way to get the shared container defined in the SharedContainerConfig class?

Communications link failure (MySQL)

I'm getting Communications link failure exception when my test class use the persistence context. The ApplicationContainer cannot communicate with the database(MySQL) container.

151656 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDERR: [ERROR ] CWWJP9992E: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.6.v20200131-b7c997804f): org.eclipse.persistence.exceptions.DatabaseException
151657 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDERR: Internal Exception: java.sql.SQLRecoverableException: Communications link failure
151657 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDERR:
151657 INFO org.microshed.testing.testcontainers.ApplicationContainer - STDERR: The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. DSRA0010E: SQL State = 08S01, Error Code = 0

public class AppConfig implements SharedContainerConfiguration {

    @Container
    public static MySQLContainer<?> mysqlContainer = new MySQLContainer<>()
            .withNetworkAliases("mysqlhost")
            .withExposedPorts(3306)
            .withUsername("root")
            .withPassword("root")
            .withDatabaseName("testdb");

    @Container
    public static ApplicationContainer app = new ApplicationContainer()
            .withEnv("MYSQL_HOST", "mysqlhost")
            .withEnv("MYSQL_TCP_PORT", "3306")
            .withEnv("MYSQL_USERNAME", "root")
            .withEnv("MYSQL_PASSWORD", "root")
            .withExposedPorts(9082)
            .withAppContextRoot("/management-service")
            .withReadinessPath("/health/ready")
            .dependsOn(mysqlContainer);
}

I using openliberty, the datasource definition in the server.xml file is as follows

<dataSource id="mySqlDataSource" jndiName="jdbc/scoreManagementDataSource">
        <jdbcDriver libraryRef="mySqlLib"/>
        <properties databaseName="testdb" createDatabaseIfNotExist="true"
                    serverName="${MYSQL_HOST}" portNumber="${MYSQL_TCP_PORT}"
                    user="${MYSQL_USERNAME}" password="${MYSQL_PASSWORD}"/>
    </dataSource>

My dependencies are

<dependency>
            <groupId>org.microshed</groupId>
            <artifactId>microshed-testing-liberty</artifactId>
            <version>0.9</version>
            <scope>test</scope>
</dependency>
<dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mysql</artifactId>
            <version>1.14.2</version>
            <scope>test</scope>
</dependency>

I think this issue is due to the host parameter in the jdbc url. I examined many examples and your documentation, everything looks correct but there must be something I missed.

Readiness of application reported too early

Describe the bug

Hey @aguibert, I wanted to create a blog post about this nice technology and started with a sample application (Jakarta EE + MP + PostgreSQL). The container setup is the following:

public class SampleApplicationConfig implements SharedContainerConfiguration {

    @Container
    public static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>()
            .withNetworkAliases("mypostgres")
            .withUsername("duke")
            .withPassword("duke42")
            .withDatabaseName("users");

    @Container
    public static MicroProfileApplication app = new MicroProfileApplication()
            .withEnv("POSTGRES_HOSTNAME", "mypostgres")
            .withEnv("POSTGRES_PORT", "5432")
            .withEnv("POSTGRES_USERNAME", "duke")
            .withEnv("POSTGRES_PASSWORD", "duke42")
            .withEnv("message", "Hello World from MicroShed Testing")
            .withAppContextRoot("/")
            .withReadinessPath("/resources/sample")
            //.withReadinessPath("/health/ready") reports readiness too early
            .dependsOn(postgres);

    @Override
    public void startContainers() {
        postgres.start();
        app.start();
    }

}

With the setup above it waits until the application is "ready" and my tests are green. But once I want to use the MicroProfile Health API to check readiness with .withReadinessPath("/health/ready") it reports readiness way too early right after:

15692 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKI0001I: The CORBA name server is now available at corbaloc:iiop:localhost:2809/NameService.
16716 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/metrics/
16716 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/openapi/ui/
16716 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/ibm/api/
16718 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/jwt/
16718 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/health/
16870 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/openapi/
20940 INFO org.microshed.testing.testcontainers.MicroProfileApplication  - STDOUT: [AUDIT   ] CWWKT0016I: Web application available (default_host): http://29f2c873a699:9080/

I'm not sure whether the setup is wrong or this is something with OpenLiberty and not your library. It seems like once the application starts the sequence of request "/health/ready" is the following: CONNECTION REFUSED -> 404 Liberty Page -> 200 OK (this is too early as the application is not ready) -> 200 OK with custom Health API check

To Reproduce

Find the project here and execute the SampleApplicationIntegrationTest

Expected behavior

It should wait until the application is started.

System information:

  • OS: Linux
  • Java Version: 11
  • MicroShed Testing Version: 0.5

Additional context

Inject REST clients into utility classes

After discussing with @sdaschner at EclipseCon, he said it was important to be able to wrap logic for the individual REST Client operations into helper methods in other classes. Currently it is only possible to @Inject a REST Client into test classes.

For example, today we can do this:

@MicroShedTest
public class SomeIT {

  @Inject
  public static MyService myService;

  @Test
  public void testCreateThing() {
    Thing t = new Thing();
     long id = myService.create(t);
     Thing result = myService.get(id);
     // verify result
  }
}

It would be nice to be able to encapsulate such logic into helper classes like so:

// Just a regular java class, not a test class
public class ServiceHelper {

  @Inject
  public static MyService myService;

  public static void createAndVerify(Thing t) {
     long id = myService.create(t);
     Thing result = myService.get(id);
     // verify result
  }
}

@MicroShedTest
public class SomeIT {

  @Test
  public void testCreateThing() {
    ServiceHelper.createAndVerify(new Thing());
  }
}

Create Wildfly adapter module

Describe the solution you'd like
Currently the OpenLiberty and Payara runtimes have dedicated modules that provide some helpful default configuration like:

  • default ports
  • default dockerfile instructions

It would be nice if Wildfly also had a default module so users are not required to have a Dockerfile

Describe alternatives you've considered
It is still possible to use MicroShed Testing on a Wildfly app without a dedicated Wildfly adapter module, but this relies on:

  • Inspecting the docker container for exposed port on each run (adds about a second to the test runtime)
  • the user having a Dockerfile in their repo (if building the app from source)

Additional context
Write an adapter involves implementing the org.microshed.testing.testcontainers.spi.ServerAdapter interface in a new module. See the Payara micro adapter for a minimal example

Ensure ordering to containers

User Story

As a user of this test framework, I want to be able to pass information from my test-container to my app container during the setup process. This would require a way to define what order containers should be created.

Additional information

If I am using a database test-container:

    @Container
    public static OracleContainer oracle = new OracleContainer();

When I set up my application I want to be able to grab the data-source configuration information from this container.

    @Container
    public static MicroProfileApplication<?> app = new MicroProfileApplication<>()
        .withEnv("NAME", oracle.getUsername())
        .withEnv("PASSWORD", oracle.getPassword())
        .withEnv("URL", oracle.getJdbcUrl())
        .dependsOn(oracle);

In this case the following error is thrown -
[ERROR] it.io.openliberty.guides.event.EventEntityTest Time elapsed: 2.823 s <<< ERROR! java.lang.ExceptionInInitializerError Caused by: java.lang.IllegalStateException: Mapped port can only be obtained after the container is started

There is a .dependsOn() method in the test-container spec. But it does not seem to work in some cases. Possibly related to issue: testcontainers/testcontainers-java#1722

allow basic authentication header on injected @RESTClients

Is your feature request related to a problem? Please describe.

We already support attaching JWTs to RESTClient instances. Allow another type in that same vein, for setting HTTP Basic Authentication header.

Describe the solution you'd like

@RESTClient
@BasicAuthConfig(username = "user", password="pass")
MyClientResource myClient;

Describe alternatives you've considered

The only alternative is to completely change my application to use JWTs instead of in-container basic authentication.

Additional context

Open Liberty 19 with standard LDAP registry and web.xml with ALL_CONFIDENTIAL protecting /*

Test an application using JUnit 4

User story:

As a user of this test framework, I want to test my application using JUnit 4 because I already have significant investment in JUnit 4 and do not wish to migrate to JUnit Jupiter.

Additional detail:

JUnit Jupiter is the newest version of JUnit and has a good amount of adoption. From a test framework implementor perspective, Jupiter is far more flexible and powerful than previous versions of JUnit. By default, we will use Jupiter in implementation and examples, but it should also be possible for users to use JUnit 4 (although it may be a bit clunkier).

Need custom header / authorization support

Is your feature request related to a problem? Please describe.
Our system relies on an authorization mechanism that isn't either basic auth or JWT. If you are using something other than those two methods then unless the Authorization parameter is a named method parameter then there's currently no way to set it to anything other than either a username / password or a JWT.

Describe the solution you'd like
It would be great if it was possible to specify some HTTP headers when calling a test or be able to specify a handler method that gets called just before the REST call so that it was possible to manipulate the request headers etc. Ideally this would work for dynamic values where they are generated at test time rather than being static as per the current @BasicAuthConfig and the @JwtConfig.
Describe alternatives you've considered
The only way that I can currently get this to work is to add a header parameter onto each of my REST methods so that I can pass this value in on calling the test e.g. public Response getAccount(@HeaderParam("Authorization") String authorisationParameter).

Additional context
We are using a ContainerRequestFilter to process the authorization header and check the value which means that we don't have to handle this in each specific method. See example code below:

@Provider
@Priority(Priorities.AUTHENTICATION)
public class SecurityFilter implements ContainerRequestFilter {

   @Override
    public void filter(ContainerRequestContext requestContext) throws IOException
    {
        Method method = resourceInfo.getResourceMethod();
        // access allowed for all methods that @PermitAll
        if( ! method.isAnnotationPresent(PermitAll.class))
        {
            // access denied for all methods that @DenyAll
            if (method.isAnnotationPresent(DenyAll.class))
            {
                requestContext.abortWith(Response.status(Response.Status.FORBIDDEN)
                        .entity("Access denied").build());
                return;
            }

            // for any others that have the @RolesAllowed annotation then check the token

            // fetch authorization header which should contain the bearer token
            final MultivaluedMap<String, String> headers = requestContext.getHeaders();
            final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
            ....

Expose multiple ports for testing other than the default set on the container

Is your feature request related to a problem? Please describe.
I am trying to expose two ports, one http and one https that are different from those set on the container. I am trying to use this method: .withExposedPorts() that allows you to set multiple ports but when you do the first port is no longer used as the default. Only when I specify one port does it work.

Describe the solution you'd like
To be able to set two ports in the above mentioned method with it having the same outcome as having one port set

Describe alternatives you've considered
I have not bothered using the https port and have just used the http one. By only setting one port I am then able to set the default testing port that is different to the default for my container.

Additional context
This works in regards to setting the defualt port

.withExposedPorts(9081)

where if I use this, the default port then gets set to that of the default port on the image/container:

.withExposedPorts(9081, 9443)

Your .dependabot/config.yml contained invalid details

Dependabot encountered the following error when parsing your .dependabot/config.yml:

The property '#/update_configs/5' did not contain a required property of 'directory'
The property '#/update_configs/5' did not contain a required property of 'update_schedule'

Please update the config file to conform with Dependabot's specification using our docs and online validator.

Create TomEE adapter module

Describe the solution you'd like
Currently the OpenLiberty and Payara runtimes have dedicated modules that provide some helpful default configuration like:

  • default ports
  • default dockerfile instructions

It would be nice if TomEE also had a default module so users are not required to have a Dockerfile

Describe alternatives you've considered
It is still possible to use MicroShed Testing on a TomEE app without a dedicated TomEE adapter module, but this relies on:

  • Inspecting the docker container for exposed port on each run (adds about a second to the test runtime)
  • the user having a Dockerfile in their repo (if building the app from source)

Additional context
Write an adapter involves implementing the org.microshed.testing.testcontainers.spi.ServerAdapter interface in a new module. See the Payara micro adapter for a minimal example

Remove left over docker images

As a user of the system-test package, I would like to use the integration test capabilities of this package for test driven development. However, after performing an integration test, there is an un-tagged docker image left over (in this case liberty). These images should be cleaned up after tests are done.

kyleaure $  docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
<none>                            <none>              4f9beb902785        27 seconds ago      454MB
<none>                            <none>              92665d6533e9        About an hour ago   454MB
<none>                            <none>              4bb455866900        About an hour ago   454MB
<none>                            <none>              0a836e010c64        About an hour ago   454MB
<none>                            <none>              610d278151d9        About an hour ago   454MB

JWT keygen slow - consider triggering with something other than use of SharedContainerConfiguration

I'm noticing that, the math involved to do keygen in JwtBuilder.getPublicKey() can be slow, especially when a debugger is attached.

Since shared container config is fundamentally about reuse of config across test classes (rather than JWT), maybe there's a better way to decide we should do keygen than just looking for the presence of SharedContainerConfiguration ?

private boolean isJwtNeeded() {
if (containers.hasSharedConfig())
return true;

My last run was with an IBM V8 JDK, but haven't been carefully keeping track.

Maybe we could leave this open and see how big a deal it is, and see if there's a motivation to address.

Application on non-default port fails to start

Describe the bug
ApplicationContainer startup fails because readiness endpoint never returns HTTP 200. Using the container configuration:

    @Container
    public static ApplicationContainer app = new ApplicationContainer()
                    .withReadinessPath("/kitchen/foodMessaging")
                    .withExposedPorts(9083);

Fails with the error:

56540 ERROR ๐Ÿณ [testcontainers/mpapp-ehcgnhgpmt:latest]  - Could not start container
org.testcontainers.containers.ContainerLaunchException: Timed out waiting for URL to be accessible (http://localhost:32975/kitchen/foodMessaging should return HTTP 200)

Expected behavior
ApplicationContainer should start successfully.

System information:

  • OS: [e.g. Linux, Windows, Mac] Any
  • Java Version: [e.g. 8, 11] Any
  • MicroShed Testing Version: [e.g. 0.4.2] 0.7.1

Update Quarkus 1.6.1.Final makes @RESTClient be null

Describe the bug
At this point after downloading the microshed quarkus-app and updating quarkus to the latest version, it will result in an NPE in all tests that include the @restclient annotation.

To Reproduce

  1. Download latest version of microshed quarkus-app (https://github.com/MicroShed/microshed-testing/tree/master/sample-apps/quarkus-app)
  2. Update the quarkus-plugin.version and quarkus.platform.version properties to 1.6.1.Final.
  3. Run 'mvn verify'

Expected behavior
Should run without NPE errors.

System information:

  • OS:Mac
  • Java Version: 11
  • MicroShed Testing Version: 0.9

Additional context
I use the @Inject annotation as workaround and seems fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.