Skip to content

Commit

Permalink
Merge pull request #7 from xdev-software/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
AB-xdev authored May 8, 2024
2 parents b7b0f25 + a9e4c2d commit f0fd305
Show file tree
Hide file tree
Showing 36 changed files with 731 additions and 45 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# 1.0.1
* Make it possible to disable agents
* Improved D&D (docs and demo)

# 1.0.0
_Initial release_
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
[![Latest version](https://img.shields.io/maven-central/v/software.xdev/tci-base?logo=apache%20maven)](https://mvnrepository.com/artifact/software.xdev/tci-base)
[![Build](https://img.shields.io/github/actions/workflow/status/xdev-software/tci-base/checkBuild.yml?branch=develop)](https://github.com/xdev-software/tci-base/actions/workflows/checkBuild.yml?query=branch%3Adevelop)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=xdev-software_tci-base&metric=alert_status)](https://sonarcloud.io/dashboard?id=xdev-software_tci-base)
[![javadoc](https://javadoc.io/badge2/software.xdev/tci-base/javadoc.svg)](https://javadoc.io/doc/software.xdev/tci-base)

# <img src="./assets/logo.png" height=28 > Testcontainers Infrastructure (TCI) Framework Base

Basis Module for XDEV's Testcontainer Infrastructure Framework

## Features
* Easily create infrastructure using - TCI (TestContainer Infrastructure) templating + Factories for that
* [PreStarting mechanism](./tci-base/src/main/java/software/xdev/tci/factory/prestart/) for [additional performance](./PERFORMANCE.md)
* An optimized [implementation of Network](./tci-base/src/main/java/software/xdev/tci/network/)
* [Safe starting of named containers](./tci-base/src/main/java/software/xdev/tci/safestart/)
* [Container Leak detection](./tci-base/src/main/java/software/xdev/tci/leakdetection/)
* [Tracing](./tci-base/src/main/java/software/xdev/tci/tracing/)
| Feature | Why? | Demo |
| --- | --- | --- |
| Easily create infrastructure using TCI<sup>[JD](https://javadoc.io/doc/software.xdev/tci-base/latest/software/xdev/tci/TCI.html)</sup> (TestContainer Infrastructure) templating + Factories for that | Makes writing and designing tests easier | [here](./tci-base-demo/src/test/java/software/xdev/tci/dummyinfra/) |
| [PreStarting mechanism](./tci-base/src/main/java/software/xdev/tci/factory/prestart/)<sup>[JD](https://javadoc.io/doc/software.xdev/tci-base/latest/software/xdev/tci/factory/prestart/PreStartableTCIFactory.html)</sup> for [additional performance](./PERFORMANCE.md) | Tries to run tests as fast as possible - with a few trade-offs | [here](./tci-base-demo/src/test/java/software/xdev/tci/factory/prestart/) |
| All started containers have a unique human-readable name | Easier identification when tracing or debugging | [here](./tci-base-demo/src/test/java/software/xdev/tci/safestart/) |
| An optimized [implementation of Network](./tci-base/src/main/java/software/xdev/tci/network/)<sup>[JD](https://javadoc.io/doc/software.xdev/tci-base/latest/software/xdev/tci/network/LazyNetwork.html)</sup> | Addresses various problems of the original implementation to speed up tests | [here](./tci-base-demo/src/test/java/software/xdev/tci/network/) |
| [Safe starting of named containers](./tci-base/src/main/java/software/xdev/tci/safestart/) | Ensures that a container doesn't enter a crash loop during retried startups | [here](./tci-base-demo/src/test/java/software/xdev/tci/safestart/) |
| [Container Leak detection](./tci-base/src/main/java/software/xdev/tci/leakdetection/)¹ | Prevents you from running out of resources | [here](./tci-base-demo/src/test/java/software/xdev/tci/leak/) |
| [Tracing](./tci-base/src/main/java/software/xdev/tci/tracing/)¹ | Makes finding bottlenecks and similar problems easier | |

¹ = Active by default due to service loading

## Usage
This module has many different components that can be used in different situations in different ways.
Take a look at the [minimalistic demo](./tci-base-demo/) that showcases the components individually.

Checkout the [advanced demo](./tci-advanced-demo/) as a reference to get a feeling how this can be done.
You may also checkout the [advanced demo](./tci-advanced-demo/) - a reference implementation of all features in a realistic project - to get a better feeling how this can be done.

> [!TIP]
> More detailed documentation is usually available in the corresponding JavaDocs.
> More detailed documentation is usually available in the corresponding [JavaDocs](https://javadoc.io/doc/software.xdev/tci-base).
## Installation
[Installation guide for the latest release](https://github.com/xdev-software/tci-base/releases/latest#Installation)
Expand Down
4 changes: 4 additions & 0 deletions assets/Advanced-Demo-Overview.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

<modules>
<module>tci-base</module>
<module>tci-base-demo</module>
<module>tci-advanced-demo</module>
</modules>

Expand Down
8 changes: 8 additions & 0 deletions renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"rebaseWhen": "behind-base-branch",
"packageRules": [
{
"description": "Ignore project internal dependencies",
"packagePattern": "^software.xdev.tci.demo",
"datasources": [
"maven"
],
"enabled": false
},
{
"description": "Ignore dependencies for JDK8",
"packagePattern": "^org.bsc.maven:maven-processor-plugin",
Expand Down
18 changes: 16 additions & 2 deletions tci-advanced-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@

This demo is a reference implementation for TCI.

It represents a Spring Boot Application with a Database and OIDC authentication that is tested using Selenium.
There are also test that validate the database migrations and queries.
It represents a Spring Boot Application with a Database and OIDC authentication that [is tested](./webapp-it/) using Selenium.
There are also test that [validate the database migrations and queries](./persistence-it/).

![Overview](../assets/Advanced-Demo-Overview.drawio.svg)

The most interesting project is probably [webapp-it](./webapp-it/) which contains the integration tests for the WebApp.

> [!TIP]
> Pre defined launchers exist for running the app and the integration tests.
## Module naming
* ``tci-*`` are TestContainer Infrastructure projects (used inside the integration tests)
* ``*-it`` are IntegrationTest projects
* All other projects are used for the webapp at compile time

## Features showcase
* PreStarting:<br/> Can be seen when enabling it using ``-Dinfra-pre-start.enabled=1`` or by running the corresponding launchers
* LazyNetwork:<br/> Search for it inside ``BaseTest``. Can also be observed using ``docker network ls`` while running tests.
* Safe starting of named containers:<br/> Is integrated inside ``TCI``. Parts of it only kick in on unexpected container start errors. Can also be observed during tests (with e.g. ``docker stats``) as it names the containers.
* Container leak detection:<br/> Only kicks in when you forget to stop infrastructure after a test. Can be manually reproduced by commenting out the corresponding ``TCI#stop`` methods.
* Tracing:<br/> Seen at the end of each test inside the logs.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public OIDCServerContainer withDefaultEnvConfig()
"ClientSecrets": [
"%s"
],
"Description": "TimelineDesc",
"Description": "Desc",
"AllowedGrantTypes": [
"authorization_code",
"refresh_token"
Expand Down
6 changes: 2 additions & 4 deletions tci-advanced-demo/tci-webapp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,10 @@ RUN mkdir -p ${APP_DIR} \
&& addgroup -g ${gid} ${group} \
&& adduser -h "$APP_DIR" -u ${uid} -G ${group} -s /bin/sh -D ${user}

# MinRAMPercentage: Default value is 50% -> may reserve memory that it doesn't need -> decreased
# MaxRAMPercentage: Default value is 25% -> we want to use available memory optimal -> increased, but
# enough is left for other RAM usages like e.g. Metaspace
# MaxRAMPercentage: Default value is 25% -> we want to use available memory optimal -> increased, but enough is left for other RAM usages like e.g. Metaspace
# Min/MaxHeapFreeRatio: Default values cause container reserved memory not to shrink properly/waste memory -> decreased
# https://stackoverflow.com/questions/16058250/what-is-the-purpose-of-xxminheapfreeratio-and-xxmaxheapfreeratio
ENV JAVA_OPTS "-XX:MinRAMPercentage=20 -XX:MaxRAMPercentage=75 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 -Djava.awt.headless=true"
ENV JAVA_OPTS "-XX:MaxRAMPercentage=75 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 -Djava.awt.headless=true"

EXPOSE 8080

Expand Down
9 changes: 9 additions & 0 deletions tci-advanced-demo/webapp-it/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
This module contains the integrations test for the WebApp using Selenium.

## Design
The project contains the following major packages:
* [cases](./src/test/java/software/xdev/tci/demo/webapp/cases/) contains the testcases
* [datageneration](./src/test/java/software/xdev/tci/demo/webapp/datageneration/) contains project specific datageneration logic
* [base](./src/test/java/software/xdev/tci/demo/webapp/base/) contains the basics that the testcases have in common. This includes:
* ``BaseTest``: Contains the logic how the app server and it's underlying infrastructure is started, how videos are recorded and so on (most of the TCI features). Every test extends from this class
* ``IntegrationTestDefaults`` (implemented by ``BaseTest``): An interface with common workflows that every test needs. For example: login, logout, waitUntil, ...
* ``InfraPerCase/ClassTest``: Lifecycle specific implementations of ``BaseTest`` - either for starting all infrastructure per case or once per class
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ abstract class BaseTest implements IntegrationTestDefaults<BaseTest>

protected static final String DNS_NAME_DB = "db";
protected static final String DNS_NAME_OIDC = "oidc";
protected static final String DNS_NAME_TIMELINE = "webapp";
protected static final String DNS_NAME_WEBAPP = "webapp";

protected static final DBTCIFactory DB_INFRA_FACTORY = new DBTCIFactory();
protected static final OIDCTCIFactory OIDC_INFRA_FACTORY = new OIDCTCIFactory();
Expand Down Expand Up @@ -111,7 +111,7 @@ protected void startBaseInfrastructure(final Consumer<DBTCI> onDataBaseMigrated)
CompletableFuture.supplyAsync(() -> OIDC_INFRA_FACTORY.getNew(this.network, DNS_NAME_OIDC));

final CompletableFuture<WebAppTCI> cfApp =
CompletableFuture.supplyAsync(() -> APP_INFRA_FACTORY.getNew(this.network, DNS_NAME_TIMELINE));
CompletableFuture.supplyAsync(() -> APP_INFRA_FACTORY.getNew(this.network, DNS_NAME_WEBAPP));

this.dbInfra = DB_INFRA_FACTORY.getNew(this.network, DNS_NAME_DB);
Optional.ofNullable(onDataBaseMigrated).ifPresent(c -> c.accept(this.dbInfra));
Expand Down
6 changes: 2 additions & 4 deletions tci-advanced-demo/webapp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ RUN mkdir -p ${APP_DIR} \
&& addgroup -g ${gid} ${group} \
&& adduser -h "$APP_DIR" -u ${uid} -G ${group} -s /bin/sh -D ${user}

# MinRAMPercentage: Default value is 50% -> may reserve memory that it doesn't need -> decreased
# MaxRAMPercentage: Default value is 25% -> we want to use available memory optimal -> increased, but
# enough is left for other RAM usages like e.g. Metaspace
# MaxRAMPercentage: Default value is 25% -> we want to use available memory optimal -> increased, but enough is left for other RAM usages like e.g. Metaspace
# Min/MaxHeapFreeRatio: Default values cause container reserved memory not to shrink properly/waste memory -> decreased
# https://stackoverflow.com/questions/16058250/what-is-the-purpose-of-xxminheapfreeratio-and-xxmaxheapfreeratio
ENV JAVA_OPTS "-XX:MinRAMPercentage=20 -XX:MaxRAMPercentage=75 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 -Djava.awt.headless=true"
ENV JAVA_OPTS "-XX:MaxRAMPercentage=75 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 -Djava.awt.headless=true"

EXPOSE 8080

Expand Down
5 changes: 5 additions & 0 deletions tci-base-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Minimalistic demo

This demo contains [test classes](./src/test/java/software/xdev/tci/) for the individual components.

Simply run the corresponding test from within your IDE.
107 changes: 107 additions & 0 deletions tci-base-demo/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>software.xdev</groupId>
<artifactId>tci-base-demo</artifactId>
<version>1.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<organization>
<name>XDEV Software</name>
<url>https://xdev.software</url>
</organization>

<properties>
<javaVersion>17</javaVersion>
<maven.compiler.release>${javaVersion}</maven.compiler.release>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

<dependencies>
<dependency>
<groupId>software.xdev</groupId>
<artifactId>tci-base</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<finalName>${project.artifactId}</finalName>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>${maven.compiler.release}</release>
<compilerArgs>
<arg>-proc:none</arg>
</compilerArgs>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<!-- Test need to be executed individually -->
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>checkstyle</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.16.0</version>
</dependency>
</dependencies>
<configuration>
<configLocation>../.config/checkstyle/checkstyle.xml</configLocation>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package software.xdev.tci.dummyinfra;

import software.xdev.tci.TCI;
import software.xdev.tci.dummyinfra.containers.DummyContainer;


public class DummyTCI extends TCI<DummyContainer>
{
public DummyTCI(final DummyContainer container, final String networkAlias)
{
super(container, networkAlias);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package software.xdev.tci.dummyinfra.containers;

import org.testcontainers.containers.GenericContainer;


public class DummyContainer extends GenericContainer<DummyContainer>
{
public static final int PORT = 80;

public DummyContainer()
{
super("nginx:stable-alpine");
this.addExposedPort(PORT);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package software.xdev.tci.dummyinfra.factory;

import software.xdev.tci.dummyinfra.DummyTCI;
import software.xdev.tci.dummyinfra.containers.DummyContainer;
import software.xdev.tci.factory.prestart.PreStartableTCIFactory;


public class DummyTCIFactory extends PreStartableTCIFactory<DummyContainer, DummyTCI>
{
public DummyTCIFactory()
{
super(
DummyTCI::new,
DummyContainer::new,
"dummy",
"container.dummy",
"Dummy");
}
}
Loading

0 comments on commit f0fd305

Please sign in to comment.