Skip to content

Commit

Permalink
Add k6 module (#8318)
Browse files Browse the repository at this point in the history
Co-authored-by: Eddú Meléndez <eddu.melendez@gmail.com>
  • Loading branch information
javaducky and eddumelendez committed Feb 28, 2024
1 parent fdcc31c commit baa8770
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ body:
- HiveMQ
- InfluxDB
- K3S
- K6
- Kafka
- LocalStack
- MariaDB
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/enhancement.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ body:
- HiveMQ
- InfluxDB
- K3S
- K6
- Kafka
- LocalStack
- MariaDB
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ body:
- HiveMQ
- InfluxDB
- K3S
- K6
- Kafka
- LocalStack
- MariaDB
Expand Down
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,14 @@ updates:
ignore:
- dependency-name: "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml"
update-types: [ "version-update:semver-minor", "version-update:semver-patch" ]
- package-ecosystem: "gradle"
directory: "/modules/k6"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
ignore:
- dependency-name: "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml"
update-types: [ "version-update:semver-minor", "version-update:semver-patch" ]
- package-ecosystem: "gradle"
directory: "/modules/kafka"
schedule:
Expand Down
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@
- changed-files:
- any-glob-to-any-file:
- modules/k3s/**/*
"modules/k6":
- changed-files:
- any-glob-to-any-file:
- modules/k6/**/*
"modules/kafka":
- changed-files:
- any-glob-to-any-file:
Expand Down
3 changes: 3 additions & 0 deletions .github/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ labels:
- name: modules/k3s
color: '#006b75'

- name: modules/k6
color: '#006b75'

- name: modules/kafka
color: '#006b75'

Expand Down
39 changes: 39 additions & 0 deletions docs/modules/k6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# k6 Module

!!! note
This module is INCUBATING.
While it is ready for use and operational in the current version of Testcontainers, it is possible that it may receive breaking changes in the future.
See [our contributing guidelines](/contributing/#incubating-modules) for more information on our incubating modules policy.

Testcontainers module for [k6](https://registry.hub.docker.com/r/grafana/k6).

[k6](https://k6.io/) is an extensible reliability testing tool built for developer happiness.

## Basic script execution

Execute a simple k6 test script, `test.js`, with commandline options and injected script variable.

Create a simple k6 test script to be executed as part of your tests:

<!--codeinclude-->
[Setup the container](../../modules/k6/src/test/java/org/testcontainers/k6/K6ContainerTests.java) inside_block:standard_k6
[Content of `scripts/test.js`](../../modules/k6/src/test/resources/scripts/test.js) inside_block:access_script_vars
<!--/codeinclude-->

## Adding this module to your project dependencies

Add the following dependency to your `pom.xml`/`build.gradle` file:

=== "Gradle"
```groovy
testImplementation "org.testcontainers:k6:{{latest_version}}"
```
=== "Maven"
```xml
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>k6</artifactId>
<version>{{latest_version}}</version>
<scope>test</scope>
</dependency>
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ nav:
- modules/gcloud.md
- modules/hivemq.md
- modules/k3s.md
- modules/k6.md
- modules/kafka.md
- modules/localstack.md
- modules/milvus.md
Expand Down
7 changes: 7 additions & 0 deletions modules/k6/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
description = "Testcontainers :: k6"

dependencies {
api project(':testcontainers')

testImplementation 'org.assertj:assertj-core:3.25.2'
}
88 changes: 88 additions & 0 deletions modules/k6/src/main/java/org/testcontainers/k6/K6Container.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.testcontainers.k6;

import org.apache.commons.io.FilenameUtils;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class K6Container extends GenericContainer<K6Container> {

/** Standard image for k6, as provided by Grafana. */
private static final DockerImageName K6_IMAGE = DockerImageName.parse("grafana/k6");

private String testScript;

private List<String> cmdOptions = new ArrayList<>();

private Map<String, String> scriptVars = new HashMap<>();

/**
* Creates a new container instance based upon the provided image name.
*/
public K6Container(String dockerImageName) {
this(DockerImageName.parse(dockerImageName));
}

/**
* Creates a new container instance based upon the provided image.
*/
public K6Container(DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(K6_IMAGE);
}

/**
* Specifies the test script to be executed within the container.
* @param testScript file to be copied into the container
* @return the builder
*/
public K6Container withTestScript(MountableFile testScript) {
this.testScript = "/home/k6/" + FilenameUtils.getName(testScript.getResolvedPath());
withCopyFileToContainer(testScript, this.testScript);
return self();
}

/**
* Specifies additional command line options to be provided to the k6 command.
* @param options command line options
* @return the builder
*/
public K6Container withCmdOptions(String... options) {
cmdOptions.addAll(Arrays.asList(options));
return self();
}

/**
* Adds a key-value pair for access within test scripts as an environment variable.
* @param key unique identifier for the variable
* @param value value of the variable
* @return the builder
*/
public K6Container withScriptVar(String key, String value) {
scriptVars.put(key, value);
return self();
}

/**
* {@inheritDoc}
*/
@Override
protected void configure() {
List<String> commandParts = new ArrayList<>();
commandParts.add("run");
commandParts.addAll(cmdOptions);
for (Map.Entry<String, String> entry : scriptVars.entrySet()) {
commandParts.add("--env");
commandParts.add(String.format("%s=%s", entry.getKey(), entry.getValue()));
}
commandParts.add(testScript);

setCommand(commandParts.toArray(new String[] {}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.testcontainers.k6;

import org.junit.Test;
import org.testcontainers.containers.output.WaitingConsumer;
import org.testcontainers.utility.MountableFile;

import java.util.concurrent.TimeUnit;

import static org.assertj.core.api.Assertions.assertThat;

public class K6ContainerTests {

@Test
public void k6StandardTest() throws Exception {
try (
// standard_k6 {
K6Container container = new K6Container("grafana/k6:0.49.0")
.withTestScript(MountableFile.forClasspathResource("scripts/test.js"))
.withScriptVar("MY_SCRIPT_VAR", "are cool!")
.withScriptVar("AN_UNUSED_VAR", "unused")
.withCmdOptions("--quiet", "--no-usage-report")
// }
) {
container.start();

WaitingConsumer consumer = new WaitingConsumer();
container.followOutput(consumer);

// Wait for test script results to be collected
consumer.waitUntil(
frame -> {
return frame.getUtf8String().contains("iteration_duration");
},
3,
TimeUnit.SECONDS
);

assertThat(container.getLogs()).contains("k6 tests are cool!");
}
}
}
16 changes: 16 additions & 0 deletions modules/k6/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
</encoder>
</appender>

<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>

<logger name="org.testcontainers" level="INFO"/>
</configuration>
6 changes: 6 additions & 0 deletions modules/k6/src/test/resources/scripts/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// access_script_vars {
// The most basic of k6 scripts.
export default function(){
console.log(`k6 tests ${__ENV.MY_SCRIPT_VAR}`)
}
// }

0 comments on commit baa8770

Please sign in to comment.