Complex KIE server tests automation part 2: Deadline notifications after KIE server restart

“Deadlines keep you on track for success” (Timothy Dalton)

Motivation: shouldn’t we automate resilience testing as well?

This article follows the series of easing test automation in complex KIE server setups. In this ocasion, we will cover how to test deadline notifications after KIE server restart.

With human task deadlines, you can set a time limit for that task, when not started or completed. Therefore, the KIE server will send a notification (by default, an automated email) to the target people defined for that task as managers, administrators, other team members.

Here, we will focus on resilience testing. If the KIE server crashes, as there is a mechanism to persist the timer in a database, the KIE server will recover it after restarting. Consequently, the failover mechanism allows sending the deadline notification (triggered before crashing) at the right timing.

The following figure depicts this scenario:

This flow involves multiple system testing components: KIE Server, database, and SMTP server for mailing. We might be tempted to do a one-time setup instead of creating an automated test for our CI/CD pipelines.

But, in the spirit of Martin Fowler’s soundbite “if it hurts, do it more often” (reduces pain drastically), we will follow the automated approach. This way we will exercise the failover scenario regularly, taking advantage of containers. 

First of all, we have to select our tools wisely, as the SMTP server.

One SMTP Server to track them all

The purpose of notification testing is to ensure that:

  • right inbox receives the expected emails (no more, no less).
  • the received emails have the right content for headers and body.

So, we need a containerized SMTP server with the following requirements:

  • Easy to configure: minimum setup for required operations (e.g., authentication is useless to check testing emails)
  • Fast bootstrap: not too long to be up and running
  • Clear API to assist test automation: documented REST APIs to retrieve and clear emails.

In our case, we have chosen “Mailhog”, an open-source SMTP server, as it fulfills these expectations and also has a docker image published in docker hub.

We use the following REST APIs in our automation. Respectively, they retrieve all the messages from the inbox and delete all the messages after each test:

Notice that they belong to different versions of the API (there is no DELETE operation at v2). Therefore, two different basePaths (/api/v2, /api/v1) will be set up for each endpoint in the REST-assured RequestSpecification.

Fitting containers together

Once we have defined our testing approach with self-unit independent pieces (containers) and the testing frameworks (Junit5 with REST-assured and testcontainers), it is time to write our tests that will be the glue for fitting all the components together. 

Our system-under-test -the main component- is the KIE Server. From version 7.61.0.Final, we can download it from the Red Hay Quay repository.

From a Multistage Dockerfile, a temporary image on-the-fly will be created containing the business application (kjar) for exercising test scenarios. Therefore:

  • First stage, it will pull the slim maven image and install the kjars tailored for our tests.
  • Second stage, it will pull the KIE server image (in this case, kie-server-showcase) with any additional configuration (jboss-cli scripts for configuring persistence and logging).

The mailhog container is a testcontainers GenericContainer (that internally pulls the latest image from docker hub). It is exposing their SMTP and HTTP ports. Notice that it shares the same network as the rest of the containers: communication can occur among them without the need of exposing ports through the host.

@Container
public static GenericContainer<?> mailhog = new GenericContainer<>("mailhog/mailhog:latest")
        .withExposedPorts(PORT_SMTP, PORT_HTTP)
        .withNetwork(network)
        .withNetworkAliases("mailhog")
        .withLogConsumer(new Slf4jLogConsumer(logger))
        .waitingFor(Wait.forHttp("/"));

Finally, the PostgreSQL container is one of the out-of-the-box testcontainers database modules. We will use the initialization script under /docker-entrypoint-initdb.d containing postgresql-jbpm-schema.sql as explained here.

Maven build-tool pulls the schema from GitHub sources, from the same branch as the system-under-test. It is automatically downloaded using the download-maven-plugin at generate-sources phase, as it is shown in this snippet taken from the pom.xml:

<configuration>
  <url>http://raw.githubusercontent.com/kiegroup/jbpm/${version.org.kie}/jbpm-db-scripts/src/main/resources/db/ddl-scripts/postgresql/postgresql-jbpm-schema.sql</url>
  <outputFileName>postgresql-jbpm-schema.sql</outputFileName>
  <unpack>false</unpack>
  <outputDirectory>${project.build.directory}/postgresql</outputDirectory>
</configuration>

Testing deadline notifications after KIE server restart

This scenario (deadline notifications after KIE server restart) in former releases of KIE Server contained a bug tracked by jbpm#9920:  duplicated emails were received in the target inboxes.

The root cause was that the initialization of the human task service occurred before the deployment (upon server restart). Therefore, the timer service was not available at the moment of starting deadlines, provoking the problem of double notification.

Let’s try to verify that, after fixing, it is working properly.

First of all, we need a kjar containing a simple process with a human task with this deadline configuration:

We can easily stop the KIE Server container after deploying the kjar and start it again to simulate a crash with a reboot. 

And then, after deadlines timeout, we will check the expected outcome by means of REST-assured utils. We can connect to Mailhog to assure that the received emails match the expected ones:

given()
     .spec(specV2)
     .when()
     .get("/messages")
     .then()
     .body("total", equalTo(3))
     .assertThat().body("items[0].Content.Headers.To", hasItem("administrator@jbpm.org"))
     .assertThat().body("items[0].Content.Headers.From", hasItem("john@jbpm.org"))
     .assertThat().body("items[0].Content.Headers.Subject", hasItem("foo"))
     .assertThat().body("items[0].Content.Body", is("bar"));

We also have another test for checking the case when a different kjar is deployed after the KIE server restart, then, no notification is sent because the kjar that triggered the deadline is not deployed again.

Finally, you can find the code and configuration for this example here.

Conclusion: automated tests for deadline notifications after KIE server restart

Automated Tests are also a good option to make resilience and integration testing less painful.

We can combine different dockerized components (from the system-under-test -KIE server- to external databases -PostgreSQL- or SMTP servers -Mailhog-) into JUnit tests. As we control the containers’ lifecycle, it is easy to stop/start them to check failover mechanisms.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments