Compare commits

..

1 commit

Author SHA1 Message Date
Eddú Meléndez Gonzales
802f18af55
Update GHA versions (#80)
* actions/setup-java@v4
* actions/cache@v4
* actions/checkout@v4
2024-04-16 07:53:09 -05:00
11 changed files with 40 additions and 82 deletions

View file

@ -3,12 +3,12 @@ description: Sets up Build
runs: runs:
using: "composite" using: "composite"
steps: steps:
- uses: actions/setup-java@v3 - uses: actions/setup-java@v4
with: with:
java-version: '8' java-version: '8'
distribution: temurin distribution: temurin
- name: Cache dependencies - name: Cache dependencies
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: ~/.m2/repository path: ~/.m2/repository
key: ${{ runner.os }}-lein-${{ hashFiles('**/project.clj') }} key: ${{ runner.os }}-lein-${{ hashFiles('**/project.clj') }}

View file

@ -6,9 +6,6 @@ on:
pull_request: pull_request:
branches: [ main ] branches: [ main ]
env:
TESTCONTAINERS_REUSE_ENABLE: true
permissions: permissions:
contents: read contents: read
@ -16,7 +13,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Setup Build - name: Setup Build
uses: ./.github/actions/setup-build uses: ./.github/actions/setup-build
- name: Install dependencies - name: Install dependencies

View file

@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Code - name: Checkout Code
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Setup Build - name: Setup Build

View file

@ -1,4 +1,4 @@
# testcontainers-clj # clj-test-containers
[![Clojars Project](http://clojars.org/clj-test-containers/latest-version.svg)](http://clojars.org/clj-test-containers) [![Clojars Project](http://clojars.org/clj-test-containers/latest-version.svg)](http://clojars.org/clj-test-containers)
@ -11,13 +11,17 @@ 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 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. 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 ## Usage
The library provides a set of functions to interact with the testcontainers. A simple example, how to create a container 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: with a Docker label, could look like this:
```clojure ```clojure
(require '[testcontainers-clj.core :as tc]) (require '[clj-test-containers.core :as tc])
(def container (-> (tc/create {:image-name "postgres:12.1" (def container (-> (tc/create {:image-name "postgres:12.1"
:exposed-ports [5432] :exposed-ports [5432]
@ -37,7 +41,7 @@ If you'd rather create a container from a Dockerfile in your project, it could l
```clojure ```clojure
(require '[testcontainers-clj.core :as tc]) (require '[clj-test-containers.core :as tc])
(def container (-> (tc/create-from-docker-file {:env-vars {"FOO" "bar"} (def container (-> (tc/create-from-docker-file {:env-vars {"FOO" "bar"}
:exposed-ports [80] :exposed-ports [80]
@ -48,7 +52,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 If you prefer to use prebuilt containers from the Testcontainers project, you can do it like this
```clojure ```clojure
(require '[testcontainers-clj.core :as tc]) (require '[clj-test-containers.core :as tc])
(:import [org.testcontainers.containers PostgreSQLContainer]) (:import [org.testcontainers.containers PostgreSQLContainer])
(def container (-> (tc/init {:container (PostgreSQLContainer. "postgres:12.2") (def container (-> (tc/init {:container (PostgreSQLContainer. "postgres:12.2")
@ -68,21 +72,19 @@ 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` | | `: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 | | `: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 | | `:env-vars` | Map | A map with environment variables |
| `:command` | Vector with strings | The start command of the container | | `: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` | 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 | | `: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 | | `: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: #### Result:
| Key | Type | Description | | Key | Type | Description |
|------------------|:------------------------------------------|:------------------------------------------------------------------------------------------| | ------------- | :------------- | :----- |
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) | | `: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 | | `: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 | | `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container | | `:host` | String | The host for the Docker Container |
| `:network` | Map | The network configuration of the Container, if provided | | `:network` | Map | The network configuration of the Container, if provided |
@ -101,20 +103,6 @@ Creates a testcontainers instance from a given Docker label and returns them
"while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"]}) "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: #### Example using wait-for and healthcheck:
```clojure ```clojure
@ -135,18 +123,17 @@ Initializes a given Testcontainer, which was e.g. provided by a library
#### Config parameters: #### Config parameters:
| Key | Type | Description | | Key | Type | Description |
|--------------------|:------------------------------------------------------------|:---------------------------------------------------------------------------------------------------| | ------------- | :------------- |:----------------------------------------------------------------------------------------------------|
| `:container` | `org.testcontainers.containers.GenericContainer`, mandatory | The name and label of an image, e.g. `postgres:12.2` | | `: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 | | `: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 |
| `:env-vars` | Map | A map with environment variables | | `:command` | Vector with strings | The start command of the container |
| `: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` | 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 |
| `: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 | | `: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: #### Result:
@ -154,7 +141,6 @@ Initializes a given Testcontainer, which was e.g. provided by a library
| ------------- | :------------- |:------------------------------------------------------------------------------------------| | ------------- | :------------- |:------------------------------------------------------------------------------------------|
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) | | `: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 | | `: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 | | `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container | | `:host` | String | The host for the Docker Container |
| `:network` | Map | The network configuration of the Container, if provided | | `:network` | Map | The network configuration of the Container, if provided |
@ -195,7 +181,6 @@ Creates a testcontainer from a Dockerfile
| ------------- | :------------- | :----- | | ------------- | :------------- | :----- |
| `:docker-file` | String, mandatory | String containing a path to 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 | | `: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 | | `:env-vars` | Map | A map with environment variables |
| `:command` | Vector with strings | The start command of the container | | `: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` | Map | A map containing the configuration of a Docker Network (see: `create-network`) |
@ -210,7 +195,6 @@ Creates a testcontainer from a Dockerfile
| ------------- | :------------- | :----- | | ------------- | :------------- | :----- |
| `:container` | `org.testcontainers.containers.Container` | The Testcontainers instance, accessible for everything this library doesn't provide (yet) | | `: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 | | `: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 | | `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container | | `:host` | String | The host for the Docker Container |
| `:network` | Map | The network configuration of the Container, if provided | | `:network` | Map | The network configuration of the Container, if provided |
@ -247,7 +231,6 @@ 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) | | `: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 | | `: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 | | `:env-vars` | Map | Value of the same input parameter |
| `:host` | String | The host for the Docker Container | | `:host` | String | The host for the Docker Container |
| `:id` | String | The ID of the started docker container | | `:id` | String | The ID of the started docker container |

View file

@ -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: consistent way. The example shown with Java Interop above would look like this, when using the wrapped functions:
```clojure ```clojure
(require '[testcontainers-clj.core :as tc]) (require '[clj-test-containers.core :as tc])
(deftest db-integration-test (deftest db-integration-test
(testing "A simple PostgreSQL integration test" (testing "A simple PostgreSQL integration test"

View file

@ -1,4 +1,4 @@
(defproject org.testcontainers/testcontainers-clj "unspecified" (defproject testcontainers-clj "unspecified"
:description "A lightweight, official wrapper around the Testcontainers Java library" :description "A lightweight, official wrapper around the Testcontainers Java library"
:url "https://github.com/testcontainers/testcontainers-clj" :url "https://github.com/testcontainers/testcontainers-clj"

View file

@ -1,6 +1,6 @@
(ns testcontainers-clj.core (ns clj-test-containers.core
(:require (:require
[testcontainers-clj.spec.core :as cs] [clj-test-containers.spec.core :as cs]
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[clojure.string]) [clojure.string])
(:import (:import
@ -183,7 +183,6 @@
"Sets the properties for a testcontainer instance" "Sets the properties for a testcontainer instance"
[{:keys [^GenericContainer container [{:keys [^GenericContainer container
exposed-ports exposed-ports
reuse
env-vars env-vars
command command
network network
@ -195,9 +194,6 @@
(doseq [[k v] env-vars] (doseq [[k v] env-vars]
(.addEnv container k v)) (.addEnv container k v))
(when reuse
(.withReuse container true))
(when command (when command
(.setCommand container ^"[Ljava.lang.String;" (into-array String command))) (.setCommand container ^"[Ljava.lang.String;" (into-array String command)))
@ -429,6 +425,5 @@
;; REPL Helpers ;; REPL Helpers
(comment (comment
(start! (create {:image-name "postgres:12.1" :reuse true})) (start! (create {:image-name "postgres:12.1"}))
(perform-cleanup!) (perform-cleanup!))
)

View file

@ -1,4 +1,4 @@
(ns testcontainers-clj.spec.container (ns clj-test-containers.spec.container
(:require (:require
[clojure.spec.alpha :as s] [clojure.spec.alpha :as s]
[clojure.spec.gen.alpha :as gen]) [clojure.spec.gen.alpha :as gen])
@ -14,9 +14,6 @@
(s/def ::exposed-ports (s/def ::exposed-ports
(s/coll-of (s/int-in 1 65535))) (s/coll-of (s/int-in 1 65535)))
(s/def ::reuse
boolean?)
(s/def ::env-vars (s/def ::env-vars
(s/map-of string? string?)) (s/map-of string? string?))

View file

@ -1,7 +1,7 @@
(ns testcontainers-clj.spec.core (ns clj-test-containers.spec.core
(:require (:require
[testcontainers-clj.spec.container :as csc] [clj-test-containers.spec.container :as csc]
[testcontainers-clj.spec.network :as csn] [clj-test-containers.spec.network :as csn]
[clojure.spec.alpha :as s])) [clojure.spec.alpha :as s]))
(s/def ::wait-for (s/def ::wait-for
@ -25,15 +25,13 @@
::csc/exposed-ports ::csc/exposed-ports
::csc/env-vars ::csc/env-vars
::csc/host] ::csc/host]
:opt-un [::csc/reuse :opt-un [::network
::network
::wait-for ::wait-for
::log-to])) ::log-to]))
(s/def ::init-options (s/def ::init-options
(s/keys :req-un [::csc/container] (s/keys :req-un [::csc/container]
:opt-un [::csc/exposed-ports :opt-un [::csc/exposed-ports
::csc/reuse
::csc/env-vars ::csc/env-vars
::csc/command ::csc/command
::network ::network

View file

@ -1,4 +1,4 @@
(ns testcontainers-clj.spec.network (ns clj-test-containers.spec.network
(:require (:require
[clojure.spec.alpha :as s]) [clojure.spec.alpha :as s])
(:import (:import

View file

@ -1,6 +1,6 @@
(ns testcontainers-clj.core-test (ns clj-test-containers.core-test
(:require (:require
[testcontainers-clj.core :as sut] [clj-test-containers.core :as sut]
[clojure.string :refer [includes?]] [clojure.string :refer [includes?]]
[clojure.test :refer [deftest is testing]]) [clojure.test :refer [deftest is testing]])
(:import (:import
@ -115,19 +115,7 @@
result (sut/execute-command! initialized-container ["whoami"]) result (sut/execute-command! initialized-container ["whoami"])
_stopped-container (sut/stop! container)] _stopped-container (sut/stop! container)]
(is (= 0 (:exit-code result))) (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 (deftest execute-command-in-container