#5 - Refactoring and documentation
This commit is contained in:
parent
5e1655e154
commit
647d4fe441
4 changed files with 236 additions and 39 deletions
202
README.md
202
README.md
|
|
@ -10,17 +10,211 @@ This library does not provide tools to include testcontainers in your testing li
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
The library provides a set of functions to interact with the testcontainers. A simple exampe could look like this:
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(require '[clj-test-containers.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]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "verysecret"}}))
|
:env-vars {"POSTGRES_PASSWORD" "verysecret"}})
|
||||||
|
(tc/configure-volume! {:file-system-bind {:host-path "/tmp"
|
||||||
|
:container-path "/opt"
|
||||||
|
:mode :read-only}})))
|
||||||
|
|
||||||
(tc/start postgres)
|
(do-database-testing (:host container)
|
||||||
|
(get (:mapped-ports container) 5432))
|
||||||
|
|
||||||
(tc/stop postgres)
|
(tc/stop! container)
|
||||||
```
|
```
|
||||||
|
## Functions and Properties
|
||||||
|
|
||||||
|
### create
|
||||||
|
Creates a testcontainers instance and returns them
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| `: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 |
|
||||||
|
| `:env-vars` | Map | A map with environment variables|
|
||||||
|
| `:command` | Vector with strings | Environment Variables to be set in the container|
|
||||||
|
|
||||||
|
#### 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 |
|
||||||
|
| `:env-vars` | Map | Value of the same input parameter|
|
||||||
|
| `:host` | String | The host for the Docker Container|
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(create {:image-name "alpine:3.2"
|
||||||
|
:exposed-ports [80]
|
||||||
|
:env-vars {"MAGIC_NUMBER" "42"
|
||||||
|
:command ["/bin/sh"
|
||||||
|
"-c"
|
||||||
|
"while true; do echo \"$MAGIC_NUMBER\" | nc -l -p 80; done"]})
|
||||||
|
```
|
||||||
|
|
||||||
|
### start!
|
||||||
|
Starts the Testcontainer, which was defined by `create`
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| First parameter: | | |
|
||||||
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
|
|
||||||
|
#### Result:
|
||||||
|
The `container-config`
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(def container (create {:image-name "alpine:3.2"
|
||||||
|
:exposed-ports [80]
|
||||||
|
:env-vars {"MAGIC_NUMBER" "42"})
|
||||||
|
|
||||||
|
(start! container)
|
||||||
|
```
|
||||||
|
|
||||||
|
### stop!
|
||||||
|
Stops the Testcontainer, which was defined by `create`
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| First parameter: | | |
|
||||||
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
|
|
||||||
|
#### Result:
|
||||||
|
The `container-config`
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(def container (create {:image-name "alpine:3.2"
|
||||||
|
:exposed-ports [80]
|
||||||
|
:env-vars {"MAGIC_NUMBER" "42"})
|
||||||
|
|
||||||
|
(start! container)
|
||||||
|
(stop! container)
|
||||||
|
```
|
||||||
|
|
||||||
|
### map-classpath-resource!
|
||||||
|
Maps a resource from your classpath into the containers file system
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| First parameter: | | |
|
||||||
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
|
| Second parameter: | | |
|
||||||
|
| `:resource-path` | String, mandatory | Path of your classpath resource |
|
||||||
|
| `:container-path` | String, mandatory | Path, to which the resource should be mapped |
|
||||||
|
| `:mode` | Keyword, mandatory | `:read-only` or `:read-write` |
|
||||||
|
|
||||||
|
|
||||||
|
#### Result:
|
||||||
|
The `container-config`
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(map-classpath-resource! container {:resource-path "test.sql"
|
||||||
|
:container-path "/opt/test.sql"
|
||||||
|
:mode :read-only})
|
||||||
|
```
|
||||||
|
|
||||||
|
### bind-filesystem!
|
||||||
|
Binds a path from your local filesystem into the Docker container as a volume
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| First parameter: | | |
|
||||||
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
|
| Second parameter: | | |
|
||||||
|
| `:host-path` | String , mandatory | Path on your local filesystem |
|
||||||
|
| `:container-path` | String, mandatory | Path, to which the resource should be mapped |
|
||||||
|
| `:mode` | Keyword, mandatory | `:read-only` or `:read-write` |
|
||||||
|
|
||||||
|
|
||||||
|
#### Result:
|
||||||
|
The `container-config`
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(bind-filesystem! container {:host-path "."
|
||||||
|
:container-path "/opt"
|
||||||
|
:mode :read-only})
|
||||||
|
```
|
||||||
|
|
||||||
|
### copy-file-to-container!
|
||||||
|
Copies a file from your filesystem or classpath into the running container
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| First parameter: | | |
|
||||||
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
|
| Second parameter: | | |
|
||||||
|
| `:path` | String, mandatory | Path to a classpath resource *or* file on your filesystem |
|
||||||
|
| `:host-path` | String, mandatory | Path, to which the file should be copied |
|
||||||
|
| `:type` | Keyword, mandatory | `:classpath-resource` or `:host-path` |
|
||||||
|
|
||||||
|
|
||||||
|
#### Result:
|
||||||
|
The `container-config`
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(copy-file-to-container! container {:path "test.sql"
|
||||||
|
:container-path "/opt/test.sql"
|
||||||
|
:type :host-path})
|
||||||
|
```
|
||||||
|
|
||||||
|
### execute-command!
|
||||||
|
Executes a command in the running container, and returns the result
|
||||||
|
|
||||||
|
#### Config parameters:
|
||||||
|
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| First parameter: | | |
|
||||||
|
| `container-config`| Map, mandatory | Return value of the `create` function |
|
||||||
|
| Second parameter: | | |
|
||||||
|
| `command` | Vector with Strings, mandatory | A vector containing the command and its parameters |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### Result:
|
||||||
|
| Key | Type | Description |
|
||||||
|
| ------------- |:------------- | :-----|
|
||||||
|
| `:exit-code` | int | Exit code of the executed command |
|
||||||
|
| `:stdout` | String | Content of stdout |
|
||||||
|
| `:stdin` | String | Content of stdin |
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(execute-command! container ["tail" "/opt/test.sql"])
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
(defproject clj-test-containers "0.1.0-SNAPSHOT"
|
(defproject clj-test-containers "0.1.0"
|
||||||
:description "A lightweight, unofficial wrapper around the Testcontainers Java library"
|
:description "A lightweight, unofficial wrapper around the Testcontainers Java library"
|
||||||
:url "https://github.com/javahippie/clj-test-containers"
|
:url "https://github.com/javahippie/clj-test-containers"
|
||||||
:license {:name "Eclipse Public License"
|
:license {:name "Eclipse Public License"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
5(ns clj-test-containers.core)
|
(ns clj-test-containers.core)
|
||||||
|
|
||||||
(defn- resolve-bind-mode [bind-mode]
|
(defn- resolve-bind-mode [bind-mode]
|
||||||
(if (= :read-write bind-mode)
|
(if (= :read-write bind-mode)
|
||||||
|
|
@ -29,27 +29,29 @@
|
||||||
:host (.getHost container)}))
|
:host (.getHost container)}))
|
||||||
|
|
||||||
|
|
||||||
(defn configure-volume! [container-config
|
(defn map-classpath-resource!
|
||||||
{classpath-resource-mapping :classpath-resource-mapping
|
"Maps a resource in the classpath to the given container path. Should be called before starting the container!"
|
||||||
file-system-bind :file-system-bind}]
|
[container-config
|
||||||
|
{resource-path :resource-path
|
||||||
(when-let [{resource-path :resource-path
|
|
||||||
container-path :container-path
|
container-path :container-path
|
||||||
mode :mode} classpath-resource-mapping]
|
mode :mode}]
|
||||||
(.withClasspathResourceMapping (:container container-config)
|
|
||||||
|
(assoc container-config :container (.withClasspathResourceMapping (:container container-config)
|
||||||
resource-path
|
resource-path
|
||||||
container-path
|
container-path
|
||||||
(resolve-bind-mode mode)))
|
(resolve-bind-mode mode))))
|
||||||
|
|
||||||
|
(defn bind-filesystem!
|
||||||
(when-let [{host-path :host-path
|
"Binds a source from the filesystem to the given container path. Should be called before starting the container!"
|
||||||
|
[container-config
|
||||||
|
{host-path :host-path
|
||||||
container-path :container-path
|
container-path :container-path
|
||||||
mode :mode} file-system-bind]
|
mode :mode}]
|
||||||
(.withFileSystemBind (:container container-config)
|
|
||||||
host-path
|
|
||||||
container-path))
|
|
||||||
|
|
||||||
container-config)
|
(assoc container-config :container (.withFileSystemBind (:container container-config)
|
||||||
|
host-path
|
||||||
|
container-path
|
||||||
|
(resolve-bind-mode mode))))
|
||||||
|
|
||||||
(defn copy-file-to-container!
|
(defn copy-file-to-container!
|
||||||
"Copies a file into the running container"
|
"Copies a file into the running container"
|
||||||
|
|
@ -67,7 +69,8 @@
|
||||||
mountable-file
|
mountable-file
|
||||||
container-path))))
|
container-path))))
|
||||||
|
|
||||||
(defn execute-command
|
(defn execute-command!
|
||||||
|
"Executes a command in the container, and returns the result"
|
||||||
[container-conf command]
|
[container-conf command]
|
||||||
(let [container (:container container-conf)
|
(let [container (:container container-conf)
|
||||||
result (.execInContainer container
|
result (.execInContainer container
|
||||||
|
|
|
||||||
|
|
@ -22,22 +22,22 @@
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
initialized-container (start! container)
|
initialized-container (start! container)
|
||||||
result (execute-command initialized-container ["whoami"])
|
result (execute-command! initialized-container ["whoami"])
|
||||||
stopped-container (stop! container)]
|
stopped-container (stop! container)]
|
||||||
(is (= 0 (:exit-code result)))
|
(is (= 0 (:exit-code result)))
|
||||||
(is (= "root\n" (:stdout result))))))
|
(is (= "root\n" (:stdout result))))))
|
||||||
|
|
||||||
(deftest init-with-volume-test
|
(deftest init-volume-test
|
||||||
|
|
||||||
(testing "Testing mapping of a classpath resource"
|
(testing "Testing mapping of a classpath resource"
|
||||||
(let [container (-> (create {:image-name "postgres:12.2"
|
(let [container (-> (create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
(configure-volume! {:classpath-resource-mapping {:resource-path "test.sql"
|
(map-classpath-resource! {:resource-path "test.sql"
|
||||||
:container-path "/opt/test.sql"
|
:container-path "/opt/test.sql"
|
||||||
:mode :read-only}}))
|
:mode :read-only}))
|
||||||
initialized-container (start! container)
|
initialized-container (start! container)
|
||||||
file-check (execute-command initialized-container ["tail" "/opt/test.sql"])
|
file-check (execute-command! initialized-container ["tail" "/opt/test.sql"])
|
||||||
stopped-container (stop! container)]
|
stopped-container (stop! container)]
|
||||||
(is (some? (:id initialized-container)))
|
(is (some? (:id initialized-container)))
|
||||||
(is (some? (:mapped-ports initialized-container)))
|
(is (some? (:mapped-ports initialized-container)))
|
||||||
|
|
@ -50,11 +50,11 @@
|
||||||
(let [container (-> (create {:image-name "postgres:12.2"
|
(let [container (-> (create {:image-name "postgres:12.2"
|
||||||
:exposed-ports [5432]
|
:exposed-ports [5432]
|
||||||
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
:env-vars {"POSTGRES_PASSWORD" "pw"}})
|
||||||
(configure-volume! {:file-system-bind {:host-path "."
|
(bind-filesystem! {:host-path "."
|
||||||
:container-path "/opt"
|
:container-path "/opt"
|
||||||
:mode :read-only}}))
|
:mode :read-only}))
|
||||||
initialized-container (start! container)
|
initialized-container (start! container)
|
||||||
file-check (execute-command initialized-container ["tail" "/opt/README.md"])
|
file-check (execute-command! initialized-container ["tail" "/opt/README.md"])
|
||||||
stopped-container (stop! container)]
|
stopped-container (stop! container)]
|
||||||
(is (some? (:id initialized-container)))
|
(is (some? (:id initialized-container)))
|
||||||
(is (some? (:mapped-ports initialized-container)))
|
(is (some? (:mapped-ports initialized-container)))
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
:container-path "/opt/test.sql"
|
:container-path "/opt/test.sql"
|
||||||
:type :host-path}))
|
:type :host-path}))
|
||||||
initialized-container (start! container)
|
initialized-container (start! container)
|
||||||
file-check (execute-command initialized-container ["tail" "/opt/test.sql"])
|
file-check (execute-command! initialized-container ["tail" "/opt/test.sql"])
|
||||||
stopped-container (stop! container)]
|
stopped-container (stop! container)]
|
||||||
(is (some? (:id initialized-container)))
|
(is (some? (:id initialized-container)))
|
||||||
(is (some? (:mapped-ports initialized-container)))
|
(is (some? (:mapped-ports initialized-container)))
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
:container-path "/opt/test.sql"
|
:container-path "/opt/test.sql"
|
||||||
:type :classpath-resource}))
|
:type :classpath-resource}))
|
||||||
initialized-container (start! container)
|
initialized-container (start! container)
|
||||||
file-check (execute-command initialized-container ["tail" "/opt/test.sql"])
|
file-check (execute-command! initialized-container ["tail" "/opt/test.sql"])
|
||||||
stopped-container (stop! container)]
|
stopped-container (stop! container)]
|
||||||
(is (some? (:id initialized-container)))
|
(is (some? (:id initialized-container)))
|
||||||
(is (some? (:mapped-ports initialized-container)))
|
(is (some? (:mapped-ports initialized-container)))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue