#5 - Refactoring and documentation

This commit is contained in:
Tim Zöller 2020-06-06 17:30:00 +02:00
parent 5e1655e154
commit 647d4fe441
4 changed files with 236 additions and 39 deletions

204
README.md
View file

@ -10,17 +10,211 @@ This library does not provide tools to include testcontainers in your testing li
## Usage
The library provides a set of functions to interact with the testcontainers. A simple exampe could look like this:
```clojure
(require '[clj-test-containers.core :as tc])
(def container (tc/create {:image-name "postgres:12.1"
:exposed-ports [5432]
:env-vars {"POSTGRES_PASSWORD" "verysecret"}}))
(def container (-> (tc/create {:image-name "postgres:12.1"
:exposed-ports [5432]
: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

View file

@ -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"
:url "https://github.com/javahippie/clj-test-containers"
:license {:name "Eclipse Public License"

View file

@ -1,4 +1,4 @@
5(ns clj-test-containers.core)
(ns clj-test-containers.core)
(defn- resolve-bind-mode [bind-mode]
(if (= :read-write bind-mode)
@ -29,27 +29,29 @@
:host (.getHost container)}))
(defn configure-volume! [container-config
{classpath-resource-mapping :classpath-resource-mapping
file-system-bind :file-system-bind}]
(defn map-classpath-resource!
"Maps a resource in the classpath to the given container path. Should be called before starting the container!"
[container-config
{resource-path :resource-path
container-path :container-path
mode :mode}]
(when-let [{resource-path :resource-path
container-path :container-path
mode :mode} classpath-resource-mapping]
(.withClasspathResourceMapping (:container container-config)
resource-path
container-path
(resolve-bind-mode mode)))
(assoc container-config :container (.withClasspathResourceMapping (:container container-config)
resource-path
container-path
(resolve-bind-mode mode))))
(defn bind-filesystem!
"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
mode :mode}]
(when-let [{host-path :host-path
container-path :container-path
mode :mode} file-system-bind]
(.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!
"Copies a file into the running container"
@ -67,7 +69,8 @@
mountable-file
container-path))))
(defn execute-command
(defn execute-command!
"Executes a command in the container, and returns the result"
[container-conf command]
(let [container (:container container-conf)
result (.execInContainer container

View file

@ -22,22 +22,22 @@
:exposed-ports [5432]
:env-vars {"POSTGRES_PASSWORD" "pw"}})
initialized-container (start! container)
result (execute-command initialized-container ["whoami"])
result (execute-command! initialized-container ["whoami"])
stopped-container (stop! container)]
(is (= 0 (:exit-code result)))
(is (= "root\n" (:stdout result))))))
(deftest init-with-volume-test
(deftest init-volume-test
(testing "Testing mapping of a classpath resource"
(let [container (-> (create {:image-name "postgres:12.2"
:exposed-ports [5432]
:env-vars {"POSTGRES_PASSWORD" "pw"}})
(configure-volume! {:classpath-resource-mapping {:resource-path "test.sql"
:container-path "/opt/test.sql"
:mode :read-only}}))
(map-classpath-resource! {:resource-path "test.sql"
:container-path "/opt/test.sql"
:mode :read-only}))
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)]
(is (some? (:id initialized-container)))
(is (some? (:mapped-ports initialized-container)))
@ -50,11 +50,11 @@
(let [container (-> (create {:image-name "postgres:12.2"
:exposed-ports [5432]
:env-vars {"POSTGRES_PASSWORD" "pw"}})
(configure-volume! {:file-system-bind {:host-path "."
:container-path "/opt"
:mode :read-only}}))
(bind-filesystem! {:host-path "."
:container-path "/opt"
:mode :read-only}))
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)]
(is (some? (:id initialized-container)))
(is (some? (:mapped-ports initialized-container)))
@ -71,7 +71,7 @@
:container-path "/opt/test.sql"
:type :host-path}))
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)]
(is (some? (:id initialized-container)))
(is (some? (:mapped-ports initialized-container)))
@ -88,7 +88,7 @@
:container-path "/opt/test.sql"
:type :classpath-resource}))
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)]
(is (some? (:id initialized-container)))
(is (some? (:mapped-ports initialized-container)))