Compare commits
No commits in common. "main" and "0.7.0" have entirely different histories.
12 changed files with 188 additions and 299 deletions
18
.github/actions/setup-build/action.yml
vendored
18
.github/actions/setup-build/action.yml
vendored
|
|
@ -1,18 +0,0 @@
|
||||||
name: Set up Build
|
|
||||||
description: Sets up Build
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '8'
|
|
||||||
distribution: temurin
|
|
||||||
- name: Cache dependencies
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: ~/.m2/repository
|
|
||||||
key: ${{ runner.os }}-lein-${{ hashFiles('**/project.clj') }}
|
|
||||||
restore-keys: ${{ runner.os }}-lein-
|
|
||||||
- name: Clear existing docker image cache
|
|
||||||
shell: bash
|
|
||||||
run: docker image prune -af
|
|
||||||
21
.github/workflows/clojure.yml
vendored
21
.github/workflows/clojure.yml
vendored
|
|
@ -2,21 +2,18 @@ name: Clojure CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ main ]
|
branches: [ master ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ main ]
|
branches: [ master ]
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
- name: Setup Build
|
- name: Install dependencies
|
||||||
uses: ./.github/actions/setup-build
|
run: lein deps
|
||||||
- name: Install dependencies
|
- name: Run tests
|
||||||
run: lein deps
|
run: lein test
|
||||||
- name: Run tests
|
|
||||||
run: lein test
|
|
||||||
|
|
|
||||||
28
.github/workflows/release.yml
vendored
28
.github/workflows/release.yml
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup Build
|
|
||||||
uses: ./.github/actions/setup-build
|
|
||||||
- name: Set version
|
|
||||||
run: |
|
|
||||||
lein change version set '"${{github.event.release.tag_name}}"'
|
|
||||||
- name: Release ${{github.event.release.tag_name}}
|
|
||||||
run: lein with-profile release deploy maven
|
|
||||||
env:
|
|
||||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
|
||||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
|
||||||
26
CHANGELOG.md
26
CHANGELOG.md
|
|
@ -1,32 +1,6 @@
|
||||||
# Change Log
|
# Change Log
|
||||||
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
|
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
|
||||||
|
|
||||||
## [0.7.4] - 2022-11-16
|
|
||||||
### Changed
|
|
||||||
- [#64](https://github.com/javahippie/clj-test-containers/pull/64): Fix container path parameter for copy-file-to-container! in README
|
|
||||||
- [#65](https://github.com/javahippie/clj-test-containers/issues/65): Upgrade to testcontainers-java 1.17.6
|
|
||||||
- [#66](https://github.com/javahippie/clj-test-containers/issues/66): Remove usage of deprecated API calls for cleanup
|
|
||||||
- [#67](https://github.com/javahippie/clj-test-containers/issues/67): Update Dependencies
|
|
||||||
|
|
||||||
## [0.7.3] - 2202-09-30
|
|
||||||
### Changed
|
|
||||||
- [#63](https://github.com/javahippie/clj-test-containers/issues/63): Upgrade to testcontainers-java 1.17.4
|
|
||||||
|
|
||||||
## [0.7.2] - 2202-07-03
|
|
||||||
### Changed
|
|
||||||
- [#61](https://github.com/javahippie/clj-test-containers/issues/61): Upgrade to testcontainers-java 1.17.3
|
|
||||||
|
|
||||||
## [0.7.1] - 2202-06-12
|
|
||||||
### Added
|
|
||||||
- [#58](https://github.com/javahippie/clj-test-containers/issues/58): Add new `allowInsecure` flag to the HTTP wait strategy
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- [#57](https://github.com/javahippie/clj-test-containers/issues/57): Upgrade to testcontainers-java 1.17.2
|
|
||||||
|
|
||||||
## [0.7.0] - 2022-04-23
|
|
||||||
### Changed
|
|
||||||
- [#56](https://github.com/javahippie/clj-test-containers/issues/56): Update to Testcontainers 1.17.1
|
|
||||||
|
|
||||||
## [0.6.0] - 2022-03-26
|
## [0.6.0] - 2022-03-26
|
||||||
### Changed
|
### Changed
|
||||||
- [#55](https://github.com/javahippie/clj-test-containers/issues/55): Upgrade to latest Testcontainers version
|
- [#55](https://github.com/javahippie/clj-test-containers/issues/55): Upgrade to latest Testcontainers version
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ Copies a file from your filesystem or classpath into the running container
|
||||||
| `container-config`| Map, mandatory | Return value of the `create` function |
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
| Second parameter: | | |
|
| Second parameter: | | |
|
||||||
| `:path` | String, mandatory | Path to a classpath resource *or* file on your filesystem |
|
| `:path` | String, mandatory | Path to a classpath resource *or* file on your filesystem |
|
||||||
| `:container-path` | String, mandatory | Path, to which the file should be copied |
|
| `:host-path` | String, mandatory | Path, to which the file should be copied |
|
||||||
| `:type` | Keyword, mandatory | `:classpath-resource` or `:host-path` |
|
| `:type` | Keyword, mandatory | `:classpath-resource` or `:host-path` |
|
||||||
|
|
||||||
#### Result:
|
#### Result:
|
||||||
|
|
|
||||||
22
deps.edn
22
deps.edn
|
|
@ -1,27 +1,27 @@
|
||||||
{:paths ["src" "resources"]
|
{:paths ["src" "resources"]
|
||||||
|
|
||||||
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
|
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
|
||||||
org.testcontainers/testcontainers {:mvn/version "1.19.7"}}
|
org.testcontainers/testcontainers {:mvn/version "1.16.3"}}
|
||||||
|
|
||||||
:aliases {:dev {:extra-paths "dev-src"}
|
:aliases {:dev {:extra-paths "dev-src"}
|
||||||
:test {:extra-paths ["test" "test/resources"]
|
:test {:extra-paths ["test" "test/resources"]
|
||||||
:extra-deps {expound/expound {:mvn/version "0.9.0"}
|
:extra-deps {expound/expound {:mvn/version "0.9.0"}
|
||||||
lambdaisland/kaocha {:mvn/version "1.88.1376"}
|
lambdaisland/kaocha {:mvn/version "1.63.998"}
|
||||||
lambdaisland/kaocha-cloverage {:mvn/version "1.1.89"}
|
lambdaisland/kaocha-cloverage {:mvn/version "1.0.75"}
|
||||||
lambdaisland/kaocha-junit-xml {:mvn/version "1.17.101"}
|
lambdaisland/kaocha-junit-xml {:mvn/version "0.0.76"}
|
||||||
org.clojure/test.check {:mvn/version "1.1.1"}
|
org.clojure/test.check {:mvn/version "1.1.1"}
|
||||||
org.testcontainers/postgresql {:mvn/version "1.19.7"}}}
|
org.testcontainers/postgresql {:mvn/version "1.16.3"}}}
|
||||||
|
|
||||||
:test-runner {:extra-paths ["test" "test/resources"]
|
:test-runner {:extra-paths ["test" "test/resources"]
|
||||||
:extra-deps {expound/expound {:mvn/version "0.9.0"}
|
:extra-deps {expound/expound {:mvn/version "0.8.5"}
|
||||||
lambdaisland/kaocha {:mvn/version "1.88.1376"}
|
lambdaisland/kaocha {:mvn/version "1.0.700"}
|
||||||
lambdaisland/kaocha-cloverage {:mvn/version "1.1.89"}
|
lambdaisland/kaocha-cloverage {:mvn/version "1.0.63"}
|
||||||
lambdaisland/kaocha-junit-xml {:mvn/version "1.17.101"}
|
lambdaisland/kaocha-junit-xml {:mvn/version "0.0.76"}
|
||||||
org.clojure/test.check {:mvn/version "1.1.1"}
|
org.clojure/test.check {:mvn/version "1.1.1"}
|
||||||
orchestra {:mvn/version "2021.01.01-1"}
|
orchestra {:mvn/version "2021.01.01-1"}
|
||||||
org.testcontainers/postgresql {:mvn/version "1.19.7"}}
|
org.testcontainers/postgresql {:mvn/version "1.16.3"}}
|
||||||
:main-opts ["-m" "kaocha.runner" "--reporter" "kaocha.report/documentation"]}
|
:main-opts ["-m" "kaocha.runner" "--reporter" "kaocha.report/documentation"]}
|
||||||
|
|
||||||
:cljstyle {:extra-deps {mvxcvi/cljstyle {:mvn/version "0.16.630"
|
:cljstyle {:extra-deps {mvxcvi/cljstyle {:mvn/version "0.15.0"
|
||||||
:exclusions [org.clojure/clojure]}}
|
:exclusions [org.clojure/clojure]}}
|
||||||
:main-opts ["-m" "cljstyle.main" "check"]}}}
|
:main-opts ["-m" "cljstyle.main" "check"]}}}
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@ This library offers two ways to access the logs of the running container: The :s
|
||||||
|
|
||||||
## String Strategy
|
## String Strategy
|
||||||
|
|
||||||
The `:string` strategy sets up a function in the returned map, under the `:log` key. This function enables the
|
The `:string` strategy sets up a function in the returned map, under the `string-log` key. This function enables the
|
||||||
dumping of the logs when passed to the `dump-logs` function.
|
dumping of the logs when passed to the `dump-logs` function.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
{:log-to {:log-strategy :string}}
|
{:log-strategy :string}
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, later in your program, you can access the logs thus:
|
Then, later in your program, you can access the logs thus:
|
||||||
|
|
@ -29,6 +29,6 @@ This way you can pass the container logging on to the logging library of your ch
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
{:log-to {:log-strategy :fn
|
{:log-strategy :fn
|
||||||
:function (fn [log-line] (println "From Container: " log-line))}}
|
:function (fn [log-line] (println "From Container: " log-line)}
|
||||||
```
|
```
|
||||||
|
|
@ -89,10 +89,10 @@ atom, a fixture for Testcontainers could look like this:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(use-fixtures :once (fn [f]
|
(use-fixtures :once (fn [f]
|
||||||
(let [pw "apassword"
|
(let [{pw "apassword"
|
||||||
postgres (tc/start! (tc/create {:image-name "postgres:12.2"
|
postgres (tc/start! (tc/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" pw}}))]
|
:env-vars {"POSTGRES_PASSWORD" pw}}))}]
|
||||||
(my-app/initialize-db! {:dbtype "postgresql"
|
(my-app/initialize-db! {:dbtype "postgresql"
|
||||||
:dbname "postgres"
|
:dbname "postgres"
|
||||||
:user "postgres"
|
:user "postgres"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ criteria is met.
|
||||||
| method | String | The HTTP method to use (get, post, put...) |
|
| method | String | The HTTP method to use (get, post, put...) |
|
||||||
| status-codes | seq of int | The status codes which mark a successful request |
|
| status-codes | seq of int | The status codes which mark a successful request |
|
||||||
| tls | boolean | Should TLS be used? |
|
| tls | boolean | Should TLS be used? |
|
||||||
| allow-insecure | boolean | Should insecure HTTP endpoints be trusted? |
|
|
||||||
| read-timeout | long | The duration in seconds the HTTP may take |
|
| read-timeout | long | The duration in seconds the HTTP may take |
|
||||||
| basic-credentials | Map | {:username "User" :password "Password"} |
|
| basic-credentials | Map | {:username "User" :password "Password"} |
|
||||||
| headers | Map | HTTP Headers, e.g. {"Accept" "application/json"} |
|
| headers | Map | HTTP Headers, e.g. {"Accept" "application/json"} |
|
||||||
|
|
|
||||||
30
project.clj
30
project.clj
|
|
@ -1,13 +1,13 @@
|
||||||
(defproject testcontainers-clj "unspecified"
|
(defproject clj-test-containers "0.7.0"
|
||||||
:description "A lightweight, official wrapper around the Testcontainers Java library"
|
:description "A lightweight, unofficial wrapper around the Testcontainers Java library"
|
||||||
|
|
||||||
:url "https://github.com/testcontainers/testcontainers-clj"
|
:url "https://github.com/javahippie/clj-test-containers"
|
||||||
|
|
||||||
:license {:name "Eclipse Public License"
|
:license {:name "Eclipse Public License"
|
||||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||||
|
|
||||||
:dependencies [[org.clojure/clojure "1.10.3"]
|
:dependencies [[org.clojure/clojure "1.10.3"]
|
||||||
[org.testcontainers/testcontainers "1.19.7"]]
|
[org.testcontainers/testcontainers "1.17.1"]]
|
||||||
|
|
||||||
:aliases {"test" ["run" "-m" "kaocha.runner"]
|
:aliases {"test" ["run" "-m" "kaocha.runner"]
|
||||||
"cljstyle" ["run" "-m" "cljstyle.main"]}
|
"cljstyle" ["run" "-m" "cljstyle.main"]}
|
||||||
|
|
@ -15,20 +15,16 @@
|
||||||
:plugins [[jainsahab/lein-githooks "1.0.0"]]
|
:plugins [[jainsahab/lein-githooks "1.0.0"]]
|
||||||
|
|
||||||
:profiles {:dev {:dependencies [[expound "0.9.0"]
|
:profiles {:dev {:dependencies [[expound "0.9.0"]
|
||||||
[lambdaisland/kaocha "1.88.1376"]
|
[lambdaisland/kaocha "1.65.1029"]
|
||||||
[lambdaisland/kaocha-cloverage "1.1.89"]
|
[lambdaisland/kaocha-cloverage "1.0.75"]
|
||||||
[lambdaisland/kaocha-junit-xml "1.17.101"]
|
[lambdaisland/kaocha-junit-xml "0.0.76"]
|
||||||
[mvxcvi/cljstyle "0.16.630" :exclusions [org.clojure/clojure]]
|
[mvxcvi/cljstyle "0.15.0" :exclusions [org.clojure/clojure]]
|
||||||
[org.clojure/test.check "1.1.1"]
|
[org.clojure/test.check "1.1.1"]
|
||||||
[orchestra "2021.01.01-1"]
|
[orchestra "2021.01.01-1"]
|
||||||
[org.clojure/tools.namespace "1.5.0"]
|
[org.clojure/tools.namespace "1.2.0"]
|
||||||
[org.testcontainers/postgresql "1.19.7"]
|
[org.testcontainers/postgresql "1.16.3"]
|
||||||
[com.fzakaria/slf4j-timbre "0.4.1"]
|
[com.fzakaria/slf4j-timbre "0.3.21"]
|
||||||
[nrepl "1.0.0"]]
|
[nrepl "0.9.0"]]
|
||||||
:source-paths ["dev-src"]}
|
:source-paths ["dev-src"]}}
|
||||||
:release {:deploy-repositories [["maven" {:url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
|
|
||||||
:username :env/ossrh_username
|
|
||||||
:password :env/ossrh_password
|
|
||||||
:sign-releases false}]]}}
|
|
||||||
|
|
||||||
:target-path "target/%s")
|
:target-path "target/%s")
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
(ns clj-test-containers.core
|
(ns clj-test-containers.core
|
||||||
(:require
|
(:require
|
||||||
[clj-test-containers.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
|
||||||
(java.nio.file
|
(java.nio.file
|
||||||
Paths)
|
Paths)
|
||||||
(java.time
|
(java.time
|
||||||
Duration)
|
Duration)
|
||||||
(org.testcontainers DockerClientFactory)
|
(org.testcontainers.containers
|
||||||
(org.testcontainers.containers
|
BindMode
|
||||||
BindMode
|
GenericContainer
|
||||||
GenericContainer
|
Network)
|
||||||
Network)
|
(org.testcontainers.containers.output
|
||||||
(org.testcontainers.containers.output
|
BaseConsumer
|
||||||
BaseConsumer
|
OutputFrame
|
||||||
OutputFrame
|
ToStringConsumer)
|
||||||
ToStringConsumer)
|
(org.testcontainers.containers.wait.strategy
|
||||||
(org.testcontainers.containers.wait.strategy
|
Wait)
|
||||||
Wait)
|
(org.testcontainers.images.builder
|
||||||
(org.testcontainers.images.builder
|
ImageFromDockerfile)
|
||||||
ImageFromDockerfile)
|
(org.testcontainers.utility
|
||||||
(org.testcontainers.utility
|
MountableFile
|
||||||
MountableFile)))
|
ResourceReaper)))
|
||||||
|
|
||||||
(defn- resolve-bind-mode
|
(defn- resolve-bind-mode
|
||||||
(^BindMode [bind-mode]
|
(^BindMode [bind-mode]
|
||||||
|
|
@ -30,69 +30,71 @@
|
||||||
BindMode/READ_WRITE
|
BindMode/READ_WRITE
|
||||||
BindMode/READ_ONLY)))
|
BindMode/READ_ONLY)))
|
||||||
|
|
||||||
(defonce started-instances (atom #{}))
|
(defn- reaper-instance
|
||||||
|
[]
|
||||||
|
(ResourceReaper/instance))
|
||||||
|
|
||||||
(defmulti wait
|
(defmulti wait
|
||||||
"Sets a wait strategy to the container. Supports :http, :health and :log as
|
"Sets a wait strategy to the container. Supports :http, :health and :log as
|
||||||
strategies.
|
strategies.
|
||||||
|
|
||||||
## HTTP Strategy
|
## HTTP Strategy
|
||||||
The :http strategy will only accept the container as initialized if it can be
|
The :http strategy will only accept the container as initialized if it can be
|
||||||
accessed via HTTP. It accepts a path, a port, a vector of status codes, a
|
accessed via HTTP. It accepts a path, a port, a vector of status codes, a
|
||||||
boolean that specifies if TLS is enabled, a read timeout in seconds and a map
|
boolean that specifies if TLS is enabled, a read timeout in seconds and a map
|
||||||
with basic credentials, containing username and password. Only the path is
|
with basic credentials, containing username and password. Only the path is
|
||||||
required, all others are optional.
|
required, all others are optional.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(wait {:wait-strategy :http
|
(wait {:wait-strategy :http
|
||||||
:port 80
|
:port 80
|
||||||
:path \"/\"
|
:path \"/\"
|
||||||
:status-codes [200 201]
|
:status-codes [200 201]
|
||||||
:tls true
|
:tls true
|
||||||
:read-timeout 5
|
:read-timeout 5
|
||||||
:basic-credentials {:username \"user\"
|
:basic-credentials {:username \"user\"
|
||||||
:password \"password\"
|
:password \"password\"
|
||||||
:startup-timeout 60}}
|
:startup-timeout 60}}
|
||||||
container)
|
container)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Health Strategy
|
## Health Strategy
|
||||||
The :health strategy enables support for Docker's healthcheck feature,
|
The :health strategy enables support for Docker's healthcheck feature,
|
||||||
whereby you can directly leverage the healthy state of your container as your wait condition.
|
whereby you can directly leverage the healthy state of your container as your wait condition.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(wait {:wait-strategy :health
|
(wait {:wait-strategy :health
|
||||||
:startup-timeout 60} container)
|
:startup-timeout 60} container)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Log Strategy
|
## Log Strategy
|
||||||
The :log strategy accepts a message which simply causes the output of your
|
The :log strategy accepts a message which simply causes the output of your
|
||||||
container's log to be used in determining if the container is ready or not.
|
container's log to be used in determining if the container is ready or not.
|
||||||
The output is `grepped` against the log message.
|
The output is `grepped` against the log message.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(wait {:wait-strategy :log
|
(wait {:wait-strategy :log
|
||||||
:message \"accept connections\"
|
:message \"accept connections\"
|
||||||
:startup-timeout 60} container)
|
:startup-timeout 60} container)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Port Strategy
|
## Port Strategy
|
||||||
The port strategy waits for the first of the mapped ports to be opened. It only accepts the startup-timeout
|
The port strategy waits for the first of the mapped ports to be opened. It only accepts the startup-timeout
|
||||||
value as a parameter.
|
value as a parameter.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(wait {:wait-strategy :port
|
(wait {:wait-strategy :port
|
||||||
:startup-timeout 60} container
|
:startup-timeout 60} container
|
||||||
```"
|
```"
|
||||||
:wait-strategy)
|
:wait-strategy)
|
||||||
|
|
||||||
(defmethod wait :http
|
(defmethod wait :http
|
||||||
[{:keys [path
|
[{:keys [path
|
||||||
|
|
@ -100,7 +102,6 @@
|
||||||
method
|
method
|
||||||
status-codes
|
status-codes
|
||||||
tls
|
tls
|
||||||
allow-insecure
|
|
||||||
read-timeout
|
read-timeout
|
||||||
basic-credentials
|
basic-credentials
|
||||||
headers
|
headers
|
||||||
|
|
@ -119,9 +120,6 @@
|
||||||
(when tls
|
(when tls
|
||||||
(.usingTls for-http))
|
(.usingTls for-http))
|
||||||
|
|
||||||
(when allow-insecure
|
|
||||||
(.allowInsecure for-http))
|
|
||||||
|
|
||||||
(when read-timeout
|
(when read-timeout
|
||||||
(.withReadTimeout for-http (Duration/ofSeconds read-timeout)))
|
(.withReadTimeout for-http (Duration/ofSeconds read-timeout)))
|
||||||
|
|
||||||
|
|
@ -235,11 +233,11 @@
|
||||||
[{:keys [^GenericContainer container] :as container-config}
|
[{:keys [^GenericContainer container] :as container-config}
|
||||||
{:keys [^String resource-path ^String container-path mode]}]
|
{:keys [^String resource-path ^String container-path mode]}]
|
||||||
(assoc container-config
|
(assoc container-config
|
||||||
:container
|
:container
|
||||||
(.withClasspathResourceMapping container
|
(.withClasspathResourceMapping container
|
||||||
resource-path
|
resource-path
|
||||||
container-path
|
container-path
|
||||||
(resolve-bind-mode mode))))
|
(resolve-bind-mode mode))))
|
||||||
|
|
||||||
(defn bind-filesystem!
|
(defn bind-filesystem!
|
||||||
"Binds a source from the filesystem to the given container path. Should be
|
"Binds a source from the filesystem to the given container path. Should be
|
||||||
|
|
@ -247,11 +245,11 @@
|
||||||
[{:keys [^GenericContainer container] :as container-config}
|
[{:keys [^GenericContainer container] :as container-config}
|
||||||
{:keys [^String host-path ^String container-path mode]}]
|
{:keys [^String host-path ^String container-path mode]}]
|
||||||
(assoc container-config
|
(assoc container-config
|
||||||
:container
|
:container
|
||||||
(.withFileSystemBind container
|
(.withFileSystemBind container
|
||||||
host-path
|
host-path
|
||||||
container-path
|
container-path
|
||||||
(resolve-bind-mode mode))))
|
(resolve-bind-mode mode))))
|
||||||
|
|
||||||
(defn copy-file-to-container!
|
(defn copy-file-to-container!
|
||||||
"If a container is not yet started, adds a mapping from mountable file to
|
"If a container is not yet started, adds a mapping from mountable file to
|
||||||
|
|
@ -268,10 +266,10 @@
|
||||||
(.copyFileToContainer container mountable-file container-path)
|
(.copyFileToContainer container mountable-file container-path)
|
||||||
container-config)
|
container-config)
|
||||||
(assoc container-config
|
(assoc container-config
|
||||||
:container
|
:container
|
||||||
(.withCopyFileToContainer container
|
(.withCopyFileToContainer container
|
||||||
mountable-file
|
mountable-file
|
||||||
container-path)))))
|
container-path)))))
|
||||||
|
|
||||||
(defn execute-command!
|
(defn execute-command!
|
||||||
"Executes a command in the container, and returns the result"
|
"Executes a command in the container, and returns the result"
|
||||||
|
|
@ -282,39 +280,39 @@
|
||||||
:stderr (.getStderr result)}))
|
:stderr (.getStderr result)}))
|
||||||
|
|
||||||
(defmulti log
|
(defmulti log
|
||||||
"Sets a log strategy on the container as a means of accessing the container logs.
|
"Sets a log strategy on the container as a means of accessing the container logs.
|
||||||
|
|
||||||
## String Strategy
|
## String Strategy
|
||||||
The `:string` strategy sets up a function in the returned map, under the
|
The `:string` strategy sets up a function in the returned map, under the
|
||||||
`string-log` key. This function enables the dumping of the logs when passed to
|
`string-log` key. This function enables the dumping of the logs when passed to
|
||||||
the `dump-logs` function.
|
the `dump-logs` function.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
{:log-strategy :string}
|
{:log-strategy :string}
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, later in your program, you can access the logs thus:
|
Then, later in your program, you can access the logs thus:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(def container-config (tc/start! container))
|
(def container-config (tc/start! container))
|
||||||
(tc/dump-logs container-config)
|
(tc/dump-logs container-config)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Function Strategy
|
## Function Strategy
|
||||||
The `:fn` strategy accepts an additional parameter `:function` in the configuration
|
The `:fn` strategy accepts an additional parameter `:function` in the configuration
|
||||||
map, which allows you to pass a function to the Testcontainers log mechanism
|
map, which allows you to pass a function to the Testcontainers log mechanism
|
||||||
which accepts a single String parameter and gets called for every log line. This
|
which accepts a single String parameter and gets called for every log line. This
|
||||||
way you can pass the container logging on to the logging library of your choice.
|
way you can pass the container logging on to the logging library of your choice.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```clojure
|
```clojure
|
||||||
{:log-strategy :fn
|
{:log-strategy :fn
|
||||||
:function (fn [log-line] (println \"From Container: \" log-line)}
|
:function (fn [log-line] (println \"From Container: \" log-line)}
|
||||||
```
|
```
|
||||||
"
|
"
|
||||||
:log-strategy)
|
:log-strategy)
|
||||||
|
|
||||||
(defmethod log :string
|
(defmethod log :string
|
||||||
[_ ^GenericContainer container]
|
[_ ^GenericContainer container]
|
||||||
|
|
@ -334,10 +332,7 @@
|
||||||
(defn dump-logs
|
(defn dump-logs
|
||||||
"Dumps the logs found by invoking the function on the :string-log key"
|
"Dumps the logs found by invoking the function on the :string-log key"
|
||||||
[container-config]
|
[container-config]
|
||||||
(let [log-fn (:log container-config)]
|
((:log container-config)))
|
||||||
(if (some? log-fn)
|
|
||||||
(log-fn)
|
|
||||||
(throw (IllegalStateException. "You are trying to access the container logs, but have not configured a log configuration with :log-to")))))
|
|
||||||
|
|
||||||
(defn start!
|
(defn start!
|
||||||
"Starts the underlying testcontainer instance and adds new values to the
|
"Starts the underlying testcontainer instance and adds new values to the
|
||||||
|
|
@ -353,7 +348,9 @@
|
||||||
container-id ^String (.getContainerId container)
|
container-id ^String (.getContainerId container)
|
||||||
image-name ^String (.getDockerImageName container)
|
image-name ^String (.getDockerImageName container)
|
||||||
logger (log log-to container)]
|
logger (log log-to container)]
|
||||||
(swap! started-instances conj {:type :container :id container-id})
|
(.registerContainerForCleanup ^ResourceReaper (reaper-instance)
|
||||||
|
container-id
|
||||||
|
image-name)
|
||||||
(-> container-config
|
(-> container-config
|
||||||
(merge {:id container-id
|
(merge {:id container-id
|
||||||
:mapped-ports mapped-ports
|
:mapped-ports mapped-ports
|
||||||
|
|
@ -387,7 +384,7 @@
|
||||||
|
|
||||||
(let [network (.build builder)
|
(let [network (.build builder)
|
||||||
network-name (.getName network)]
|
network-name (.getName network)]
|
||||||
(swap! started-instances conj {:type :network :id :network-name})
|
(.registerNetworkIdForCleanup ^ResourceReaper (reaper-instance) network-name)
|
||||||
{:network network
|
{:network network
|
||||||
:name network-name
|
:name network-name
|
||||||
:ipv6 (.getEnableIpv6 network)
|
:ipv6 (.getEnableIpv6 network)
|
||||||
|
|
@ -395,32 +392,10 @@
|
||||||
|
|
||||||
(def ^:deprecated init-network create-network)
|
(def ^:deprecated init-network create-network)
|
||||||
|
|
||||||
(defn- remove-network! [instance]
|
|
||||||
(-> (DockerClientFactory/instance)
|
|
||||||
(.client)
|
|
||||||
(.removeNetworkCmd (:id instance))
|
|
||||||
(.exec))
|
|
||||||
instance)
|
|
||||||
|
|
||||||
(defn- stop-and-remove-container! [instance]
|
|
||||||
(let [docker-client (DockerClientFactory/instance)]
|
|
||||||
(-> docker-client
|
|
||||||
(.client)
|
|
||||||
(.stopContainerCmd (:id instance))
|
|
||||||
(.exec))
|
|
||||||
(-> docker-client
|
|
||||||
(.client)
|
|
||||||
(.removeContainerCmd (:id instance))
|
|
||||||
(.exec)))
|
|
||||||
instance)
|
|
||||||
|
|
||||||
(defn perform-cleanup!
|
(defn perform-cleanup!
|
||||||
"Stops and removes all container instances which were created in the active JVM or REPL session"
|
"Stops and removes all container instances which were created in the active JVM or REPL session"
|
||||||
[]
|
[]
|
||||||
(for [instance @started-instances]
|
(.performCleanup ^ResourceReaper (reaper-instance)))
|
||||||
(swap! started-instances disj (case (:type instance)
|
|
||||||
:container (stop-and-remove-container! instance)
|
|
||||||
:network (remove-network! instance)))))
|
|
||||||
|
|
||||||
|
|
||||||
;; REPL Helpers
|
;; REPL Helpers
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
(deftest create-test
|
(deftest create-test
|
||||||
(testing "Testing basic testcontainer generic image initialisation"
|
(testing "Testing basic testcontainer generic image initialisation"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
|
|
@ -21,33 +21,25 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Testing log access to the container with string logs"
|
(testing "Testing log access to the container with string logs"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/init {:container (PostgreSQLContainer. "postgres:12.2")
|
||||||
:exposed-ports [5432]
|
:log-to {:log-strategy :string}})
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}
|
|
||||||
:log-to {:log-strategy :string}})
|
|
||||||
initialized-container (sut/start! container)]
|
initialized-container (sut/start! container)]
|
||||||
(Thread/sleep 500)
|
(Thread/sleep 500)
|
||||||
(is (includes? (sut/dump-logs initialized-container) "database system is ready to accept connections"))))
|
(is (includes? (sut/dump-logs initialized-container) "database system is ready to accept connections"))))
|
||||||
|
|
||||||
(testing "Testing log access to the container with function logs"
|
(testing "Testing log access to the container with function logs"
|
||||||
(let [logs (atom [])]
|
(let [logs (atom [])]
|
||||||
(sut/start! (sut/init {:container (PostgreSQLContainer. "postgres:15.3")
|
(sut/start! (sut/init {:container (PostgreSQLContainer. "postgres:12.2")
|
||||||
:exposed-ports [5432]
|
|
||||||
:log-to {:log-strategy :fn
|
:log-to {:log-strategy :fn
|
||||||
:function #(swap! logs conj %)}}))
|
:function #(swap! logs conj %)}}))
|
||||||
(is (filter #(includes? "database system is ready to accept connections" %) @logs))))
|
(is (filter #(includes? "database system is ready to accept connections" %) @logs))))
|
||||||
|
|
||||||
(testing "Testing log access to the container with unconfigured logger"
|
|
||||||
(let [container (sut/start! (sut/init {:container (PostgreSQLContainer. "postgres:15.3")
|
|
||||||
:exposed-ports [5432]}))]
|
|
||||||
(is (thrown? IllegalStateException (sut/dump-logs container)))))
|
|
||||||
|
|
||||||
(testing "Testing basic testcontainer generic image initialisation with wait for log message"
|
(testing "Testing basic testcontainer generic image initialisation with wait for log message"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}
|
:env-vars {"POSTGRES_PASSWORD" "pw"}
|
||||||
:wait-for {:wait-strategy :log
|
:wait-for {:wait-strategy :log
|
||||||
:message "accept connections"
|
:message "accept connections"
|
||||||
:startup-timeout 10}})
|
:startup-timeout 10}})
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
stopped-container (sut/stop! container)]
|
stopped-container (sut/stop! container)]
|
||||||
|
|
@ -59,7 +51,7 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Testing basic testcontainer generic image initialisation with wait for host port"
|
(testing "Testing basic testcontainer generic image initialisation with wait for host port"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}
|
:env-vars {"POSTGRES_PASSWORD" "pw"}
|
||||||
:wait-for {:wait-strategy :port}})
|
:wait-for {:wait-strategy :port}})
|
||||||
|
|
@ -73,15 +65,18 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Testing basic testcontainer generic image initialisation with wait for http"
|
(testing "Testing basic testcontainer generic image initialisation with wait for http"
|
||||||
(let [container (sut/create {:image-name "bitnami/nginx:1.22"
|
(let [container (sut/create {:image-name "alpine:3.5"
|
||||||
:network-aliases ["foo"]
|
:network-aliases ["foo"]
|
||||||
|
:command ["/bin/sh"
|
||||||
|
"-c"
|
||||||
|
"while true ; do printf 'HTTP/1.1 200 OK\\n\\nyay' | nc -l -p 8080; done"]
|
||||||
:exposed-ports [8080]
|
:exposed-ports [8080]
|
||||||
:wait-for {:wait-strategy :http
|
:wait-for {:wait-strategy :http
|
||||||
:path "/"
|
:path "/"
|
||||||
:port 8080
|
:port 8080
|
||||||
:method "GET"
|
:method "GET"
|
||||||
:status-codes [200]
|
:status-codes [200]
|
||||||
:headers {"Accept" "text/plain"}}})
|
:headers {"Accept" "text/plain"}}})
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
stopped-container (sut/stop! container)]
|
stopped-container (sut/stop! container)]
|
||||||
(is (some? (:id initialized-container)))
|
(is (some? (:id initialized-container)))
|
||||||
|
|
@ -109,8 +104,7 @@
|
||||||
|
|
||||||
|
|
||||||
(testing "Executing a command in the running Docker container with a custom container"
|
(testing "Executing a command in the running Docker container with a custom container"
|
||||||
(let [container (sut/init {:container (PostgreSQLContainer. "postgres:15.3")
|
(let [container (sut/init {:container (PostgreSQLContainer. "postgres:12.2")})
|
||||||
:exposed-ports [5432]})
|
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
result (sut/execute-command! initialized-container ["whoami"])
|
result (sut/execute-command! initialized-container ["whoami"])
|
||||||
_stopped-container (sut/stop! container)]
|
_stopped-container (sut/stop! container)]
|
||||||
|
|
@ -120,7 +114,7 @@
|
||||||
(deftest execute-command-in-container
|
(deftest execute-command-in-container
|
||||||
|
|
||||||
(testing "Executing a command in the running Docker container"
|
(testing "Executing a command in the running Docker container"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
|
|
@ -132,7 +126,7 @@
|
||||||
(deftest init-volume-test
|
(deftest init-volume-test
|
||||||
|
|
||||||
(testing "Testing mapping of a classpath resource"
|
(testing "Testing mapping of a classpath resource"
|
||||||
(let [container (-> (sut/create {:image-name "postgres:15.3"
|
(let [container (-> (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
(sut/map-classpath-resource! {:resource-path "test.sql"
|
(sut/map-classpath-resource! {:resource-path "test.sql"
|
||||||
|
|
@ -149,7 +143,7 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Testing mapping of a filesystem-binding"
|
(testing "Testing mapping of a filesystem-binding"
|
||||||
(let [container (-> (sut/create {:image-name "postgres:15.3"
|
(let [container (-> (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
(sut/bind-filesystem! {:host-path "."
|
(sut/bind-filesystem! {:host-path "."
|
||||||
|
|
@ -166,7 +160,7 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Copying a file from the host into the container"
|
(testing "Copying a file from the host into the container"
|
||||||
(let [container (-> (sut/create {:image-name "postgres:15.3"
|
(let [container (-> (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
(sut/copy-file-to-container! {:path "test.sql"
|
(sut/copy-file-to-container! {:path "test.sql"
|
||||||
|
|
@ -184,7 +178,7 @@
|
||||||
|
|
||||||
|
|
||||||
(testing "Copying a file from the classpath into the container"
|
(testing "Copying a file from the classpath into the container"
|
||||||
(let [container (-> (sut/create {:image-name "postgres:15.3"
|
(let [container (-> (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
(sut/copy-file-to-container! {:path "test.sql"
|
(sut/copy-file-to-container! {:path "test.sql"
|
||||||
|
|
@ -201,7 +195,7 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Copying a file from the host into a running container"
|
(testing "Copying a file from the host into a running container"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
|
|
@ -220,7 +214,7 @@
|
||||||
(is (nil? (:mapped-ports stopped-container)))))
|
(is (nil? (:mapped-ports stopped-container)))))
|
||||||
|
|
||||||
(testing "Copying a file from the classpath into a running container"
|
(testing "Copying a file from the classpath into a running container"
|
||||||
(let [container (sut/create {:image-name "postgres:15.3"
|
(let [container (sut/create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
initialized-container (sut/start! container)
|
initialized-container (sut/start! container)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue