Add support for a container wait strategy. (#31)

For review.

-=david=-
This commit is contained in:
David Harrigan 2020-09-24 18:23:12 +01:00 committed by GitHub
parent 76359eec37
commit ea854767ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 8 deletions

View file

@ -13,7 +13,9 @@
(org.testcontainers.images.builder (org.testcontainers.images.builder
ImageFromDockerfile) ImageFromDockerfile)
(org.testcontainers.utility (org.testcontainers.utility
MountableFile))) MountableFile)
(org.testcontainers.containers.wait.strategy
Wait)))
(defn- resolve-bind-mode (defn- resolve-bind-mode
[bind-mode] [bind-mode]
@ -21,13 +23,33 @@
BindMode/READ_WRITE BindMode/READ_WRITE
BindMode/READ_ONLY)) BindMode/READ_ONLY))
(defmulti wait :strategy)
(defmethod wait :http
[{:keys [path]} container]
(.waitingFor container (Wait/forHttp path))
{:wait-for-http path})
(defmethod wait :health
[_ container]
(.waitingFor container (Wait/forHealthcheck))
{:wait-for-healthcheck true})
(defmethod wait :log
[{:keys [message]} container]
(let [log-message (str ".*" message ".*\\n")]
(.waitingFor container (Wait/forLogMessage log-message 1))
{:wait-for-log-message log-message}))
(defmethod wait :default [_ _] nil)
(s/fdef init (s/fdef init
:args (s/cat :init-options ::cs/init-options) :args (s/cat :init-options ::cs/init-options)
:ret ::cs/container) :ret ::cs/container)
(defn init (defn init
"Sets the properties for a testcontainer instance" "Sets the properties for a testcontainer instance"
[{:keys [container exposed-ports env-vars command network network-aliases]}] [{:keys [container exposed-ports env-vars command network network-aliases wait-for]}]
(.setExposedPorts container (map int exposed-ports)) (.setExposedPorts container (map int exposed-ports))
@ -42,11 +64,11 @@
(when network-aliases (when network-aliases
(.setNetworkAliases container (java.util.ArrayList. network-aliases))) (.setNetworkAliases container (java.util.ArrayList. network-aliases)))
{:container container (merge {:container container
:exposed-ports (vec (.getExposedPorts container)) :exposed-ports (vec (.getExposedPorts container))
:env-vars (into {} (.getEnvMap container)) :env-vars (into {} (.getEnvMap container))
:host (.getHost container) :host (.getHost container)
:network network}) :network network} (wait wait-for container)))
(s/fdef create (s/fdef create
:args (s/cat :create-options ::cs/create-options) :args (s/cat :create-options ::cs/create-options)

View file

@ -25,3 +25,23 @@
(s/def ::image-name (s/def ::image-name
string?) string?)
(s/def ::http
keyword?)
(s/def ::health
keyword?)
(s/def ::log
keyword?)
(s/def ::strategy #{:http :health :log})
(s/def ::path
string?)
(s/def ::message
string?)
(s/def ::check
boolean?)

View file

@ -4,6 +4,12 @@
[clj-test-containers.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/keys :req-un [::csc/strategy]
:opt-un [::csc/path
::csc/message
::csc/check]))
(s/def ::network (s/def ::network
(s/nilable (s/keys :req-un [::csn/network (s/nilable (s/keys :req-un [::csn/network
::csn/name ::csn/name
@ -15,7 +21,8 @@
::csc/exposed-ports ::csc/exposed-ports
::csc/env-vars ::csc/env-vars
::csc/host] ::csc/host]
:opt-un [::network])) :opt-un [::network
::wait-for]))
(s/def ::init-options (s/def ::init-options
(s/keys :req-un [::csc/container] (s/keys :req-un [::csc/container]
@ -23,6 +30,7 @@
::csc/env-vars ::csc/env-vars
::csc/command ::csc/command
::network ::network
::wait-for
::csc/network-aliases])) ::csc/network-aliases]))
(s/def ::create-options (s/def ::create-options
@ -31,6 +39,7 @@
::csc/env-vars ::csc/env-vars
::csc/command ::csc/command
::network ::network
::wait-for
::csc/network-aliases])) ::csc/network-aliases]))
(s/def ::create-network-options (s/def ::create-network-options

View file

@ -19,6 +19,20 @@
(is (nil? (:id stopped-container))) (is (nil? (:id stopped-container)))
(is (nil? (:mapped-ports stopped-container))))) (is (nil? (:mapped-ports stopped-container)))))
(testing "Testing basic testcontainer generic image initialisation with wait for log message"
(let [container (sut/create {:image-name "postgres:12.2"
:exposed-ports [5432]
:env-vars {"POSTGRES_PASSWORD" "pw"}
:wait-for {:strategy :log :message "accept connections"}})
initialized-container (sut/start! container)
stopped-container (sut/stop! container)]
(is (some? (:id initialized-container)))
(is (some? (:mapped-ports initialized-container)))
(is (some? (get (:mapped-ports initialized-container) 5432)))
(is (= (:wait-for-log-message initialized-container) ".*accept connections.*\\n"))
(is (nil? (:id stopped-container)))
(is (nil? (:mapped-ports stopped-container)))))
(testing "Testing basic testcontainer image creation from docker file" (testing "Testing basic testcontainer image creation from docker file"
(let [container (sut/create-from-docker-file {:exposed-ports [80] (let [container (sut/create-from-docker-file {:exposed-ports [80]
:docker-file "test/resources/Dockerfile"}) :docker-file "test/resources/Dockerfile"})