Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.7.5 #79

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/clojure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
pull_request:
branches: [ main ]

env:
TESTCONTAINERS_REUSE_ENABLE: true

permissions:
contents: read

Expand Down
59 changes: 38 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# clj-test-containers
# testcontainers-clj

[![Clojars Project](http://clojars.org/clj-test-containers/latest-version.svg)](http://clojars.org/clj-test-containers)

Expand All @@ -11,17 +11,13 @@ This library is a lightweight wrapper around the [Testcontainers Java library](h
This library does not provide tools to include testcontainers in your testing lifecycle. As there are many different
test tools with different approaches to testing in the clojure world, handling the lifecycle is up to you.

## Integration with test runners

There is an [experimental kaocha plugin](https://github.com/lambdaschmiede/kaocha-testcontainers-plugin) you can try out

## Usage

The library provides a set of functions to interact with the testcontainers. A simple example, how to create a container
with a Docker label, could look like this:

```clojure
(require '[clj-test-containers.core :as tc])
(require '[testcontainers-clj.core :as tc])

(def container (-> (tc/create {:image-name "postgres:12.1"
:exposed-ports [5432]
Expand All @@ -41,7 +37,7 @@ If you'd rather create a container from a Dockerfile in your project, it could l

```clojure

(require '[clj-test-containers.core :as tc])
(require '[testcontainers-clj.core :as tc])

(def container (-> (tc/create-from-docker-file {:env-vars {"FOO" "bar"}
:exposed-ports [80]
Expand All @@ -52,7 +48,7 @@ If you'd rather create a container from a Dockerfile in your project, it could l
If you prefer to use prebuilt containers from the Testcontainers project, you can do it like this

```clojure
(require '[clj-test-containers.core :as tc])
(require '[testcontainers-clj.core :as tc])
(:import [org.testcontainers.containers PostgreSQLContainer])

(def container (-> (tc/init {:container (PostgreSQLContainer. "postgres:12.2")
Expand All @@ -72,19 +68,21 @@ Creates a testcontainers instance from a given Docker label and returns them
| ------------- | :------------- |:----------------------------------------------------------------------------------------------------|
| `:image-name` | String, mandatory | The name and label of an image, e.g. `postgres:12.2` |
| `:exposed-ports` | Vector with ints, mandatory | All ports which should be exposed and mapped to a local port |
| `:reuse` | Boolean | Should the container be reused, if another Testcontainer with identical config is started? |
| `:env-vars` | Map | A map with environment variables |
| `:command` | Vector with strings | The start command of the container |
| `:network` | Map | A map containing the configuration of a Docker Network (see: `create-network`) |
| `:network-aliases` | Map | A list of alias names for the container on the network |
| `:wait-for` | Map | A map containing the [wait strategy](doc/wait-strategies.md) to use and the condition to check for |
| `:log-to` | Map | A map containing the [log strategy](doc/log-strategies.md) to use, e.g. {:log-strategy string} |
| `:wait-for` | Map | A map containing the [wait strategy](doc/wait-strategies.md) to use and the condition to check for |
| `:log-to` | Map | A map containing the [log strategy](doc/log-strategies.md) to use, e.g. {:log-strategy string} |

#### Result:

| Key | Type | Description |
| ------------- | :------------- | :----- |
|------------------|:------------------------------------------|:------------------------------------------------------------------------------------------|
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) |
| `:exposed-ports` | Vector with ints | Value of the same input parameter |
| `:reuse` | Boolean | Is this container reusable? |
| `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container |
| `:network` | Map | The network configuration of the Container, if provided |
Expand All @@ -103,6 +101,20 @@ Creates a testcontainers instance from a given Docker label and returns them
"while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"]})
```

#### Example with reuse

```clojure
(create {:image-name "alpine:3.2"
:exposed-ports [80]
:reuse true
:env-vars {"MAGIC_NUMBER" "42"}
:network (create-network)
:network-aliases ["api-server"]
:command ["/bin/sh"
"-c"
"while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"]})
```

#### Example using wait-for and healthcheck:

```clojure
Expand All @@ -123,24 +135,26 @@ Initializes a given Testcontainer, which was e.g. provided by a library

#### Config parameters:

| Key | Type | Description |
| ------------- | :------------- |:----------------------------------------------------------------------------------------------------|
| `:container` | `org.testcontainers.containers.GenericContainer`, mandatory | The name and label of an image, e.g. `postgres:12.2` |
| `:exposed-ports` | Vector with ints, mandatory | All ports which should be exposed and mapped to a local port |
| `:env-vars` | Map | A map with environment variables |
| `:command` | Vector with strings | The start command of the container |
| `:network` | Map | A map containing the configuration of a Docker Network (see: `create-network`) |
| `:network-aliases` | Map | A list of alias names for the container on the network |
| Key | Type | Description |
|--------------------|:------------------------------------------------------------|:---------------------------------------------------------------------------------------------------|
| `:container` | `org.testcontainers.containers.GenericContainer`, mandatory | The name and label of an image, e.g. `postgres:12.2` |
| `:exposed-ports` | Vector with ints, mandatory | All ports which should be exposed and mapped to a local port |
| `:reuse` | Boolean | Should the container be reused, if another Testcontainer with identical config is started? |
| `:env-vars` | Map | A map with environment variables |
| `:command` | Vector with strings | The start command of the container |
| `:network` | Map | A map containing the configuration of a Docker Network (see: `create-network`) |
| `:network-aliases` | Map | A list of alias names for the container on the network |
| `:wait-for` | Map | A map containing the [wait strategy](doc/wait-strategies.md) to use and the condition to check for |
| `:log-to` | Map | A map containing the [log strategy](doc/log-strategies.md) to use, e.g. {:log-strategy string} |
| | | |
| `:log-to` | Map | A map containing the [log strategy](doc/log-strategies.md) to use, e.g. {:log-strategy string} |
| | | |

#### Result:

| Key | Type | Description |
| ------------- | :------------- |:------------------------------------------------------------------------------------------|
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) |
| `:exposed-ports` | Vector with ints | Value of the same input parameter |
| `:reuse` | Boolean | Is this container reusable? |
| `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container |
| `:network` | Map | The network configuration of the Container, if provided |
Expand Down Expand Up @@ -181,6 +195,7 @@ Creates a testcontainer from a Dockerfile
| ------------- | :------------- | :----- |
| `:docker-file` | String, mandatory | String containing a path to a Dockerfile |
| `:exposed-ports` | Vector with ints, mandatory | All ports which should be exposed and mapped to a local port |
| `:reuse` | Boolean | Should the container be reused, if another Testcontainer with identical config is started? |
| `:env-vars` | Map | A map with environment variables |
| `:command` | Vector with strings | The start command of the container |
| `:network` | Map | A map containing the configuration of a Docker Network (see: `create-network`) |
Expand All @@ -195,6 +210,7 @@ Creates a testcontainer from a Dockerfile
| ------------- | :------------- | :----- |
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) |
| `:exposed-ports` | Vector with ints | Value of the same input parameter |
| `:reuse` | Boolean | Is this container reusable? |
| `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container |
| `:network` | Map | The network configuration of the Container, if provided |
Expand Down Expand Up @@ -231,6 +247,7 @@ Starts the Testcontainer, which was defined by `create`
| ------------- | :------------- | :----- |
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) |
| `:exposed-ports` | Vector with ints | Value of the same input parameter |
| `:reuse` | Boolean | Is this container reusable? |
| `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container |
| `:id` | String | The ID of the started docker container |
Expand Down
2 changes: 1 addition & 1 deletion doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The functions accept and return a map structure, which enables us to operate the
consistent way. The example shown with Java Interop above would look like this, when using the wrapped functions:

```clojure
(require '[clj-test-containers.core :as tc])
(require '[testcontainers-clj.core :as tc])

(deftest db-integration-test
(testing "A simple PostgreSQL integration test"
Expand Down
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(defproject testcontainers-clj "unspecified"
(defproject org.testcontainers/testcontainers-clj "unspecified"
:description "A lightweight, official wrapper around the Testcontainers Java library"

:url "https://github.com/testcontainers/testcontainers-clj"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns clj-test-containers.core
(ns testcontainers-clj.core
(:require
[clj-test-containers.spec.core :as cs]
[testcontainers-clj.spec.core :as cs]
[clojure.spec.alpha :as s]
[clojure.string])
(:import
Expand Down Expand Up @@ -183,6 +183,7 @@
"Sets the properties for a testcontainer instance"
[{:keys [^GenericContainer container
exposed-ports
reuse
env-vars
command
network
Expand All @@ -194,6 +195,9 @@
(doseq [[k v] env-vars]
(.addEnv container k v))

(when reuse
(.withReuse container true))

(when command
(.setCommand container ^"[Ljava.lang.String;" (into-array String command)))

Expand Down Expand Up @@ -425,5 +429,6 @@

;; REPL Helpers
(comment
(start! (create {:image-name "postgres:12.1"}))
(perform-cleanup!))
(start! (create {:image-name "postgres:12.1" :reuse true}))
(perform-cleanup!)
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(ns clj-test-containers.spec.container
(ns testcontainers-clj.spec.container
(:require
[clojure.spec.alpha :as s]
[clojure.spec.gen.alpha :as gen])
Expand All @@ -14,6 +14,9 @@
(s/def ::exposed-ports
(s/coll-of (s/int-in 1 65535)))

(s/def ::reuse
boolean?)

(s/def ::env-vars
(s/map-of string? string?))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(ns clj-test-containers.spec.core
(ns testcontainers-clj.spec.core
(:require
[clj-test-containers.spec.container :as csc]
[clj-test-containers.spec.network :as csn]
[testcontainers-clj.spec.container :as csc]
[testcontainers-clj.spec.network :as csn]
[clojure.spec.alpha :as s]))

(s/def ::wait-for
Expand All @@ -25,13 +25,15 @@
::csc/exposed-ports
::csc/env-vars
::csc/host]
:opt-un [::network
:opt-un [::csc/reuse
::network
::wait-for
::log-to]))

(s/def ::init-options
(s/keys :req-un [::csc/container]
:opt-un [::csc/exposed-ports
::csc/reuse
::csc/env-vars
::csc/command
::network
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(ns clj-test-containers.spec.network
(ns testcontainers-clj.spec.network
(:require
[clojure.spec.alpha :as s])
(:import
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(ns clj-test-containers.core-test
(ns testcontainers-clj.core-test
(:require
[clj-test-containers.core :as sut]
[testcontainers-clj.core :as sut]
[clojure.string :refer [includes?]]
[clojure.test :refer [deftest is testing]])
(:import
Expand Down Expand Up @@ -115,7 +115,19 @@
result (sut/execute-command! initialized-container ["whoami"])
_stopped-container (sut/stop! container)]
(is (= 0 (:exit-code result)))
(is (= "root\n" (:stdout result))))))
(is (= "root\n" (:stdout result)))))

(testing "Reusing a container with the :reuse flag"
(let [container-1 (sut/init {:container (PostgreSQLContainer. "postgres:15.3")
:exposed-ports [5432]
:reuse true})
container-2 (sut/init {:container (PostgreSQLContainer. "postgres:15.3")
:exposed-ports [5432]
:reuse true})
initialized-container-1 (sut/start! container-1)
initialized-container-2 (sut/start! container-2)]
(is (= (.getContainerId (:container initialized-container-1))
(.getContainerId (:container initialized-container-2)))))))

(deftest execute-command-in-container

Expand Down
Loading