From 8b02c94c0981dd61c509d541733d95f982986b93 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 09:44:12 +0100 Subject: [PATCH 01/14] First working version --- .gitignore | 1 + Dockerfile | 9 ++++++ LICENSE | 21 ++++++++++++++ README.md | 36 ++++++++++++++++++++++++ go.mod | 8 ++++++ go.sum | 4 +++ internal/server/server.go | 57 ++++++++++++++++++++++++++++++++++++++ internal/util/util.go | 19 +++++++++++++ main.go | 19 +++++++++++++ static/index.html | 34 +++++++++++++++++++++++ static/logo.png | Bin 0 -> 51964 bytes 11 files changed, 208 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/server/server.go create mode 100644 internal/util/util.go create mode 100644 main.go create mode 100644 static/index.html create mode 100644 static/logo.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31e0fce --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +helloworld diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2654ea6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM golang:alpine AS builder +WORKDIR /go/src/github.com/testcontainers/helloworld +COPY . ./ +RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o /helloworld . + +FROM scratch +COPY static /static +COPY --from=builder /helloworld /helloworld +CMD ["/helloworld"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2e38890 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-2019 Richard North + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..3de2162 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +# Testcontainers Helloworld Docker Image + +This is a Docker image for use by Testcontainers' own self-test suites. It is not intended for use outside of the Testcontainers project. + +It features a small HTTP server with the following characteristics: + +* It serves content on two ports (8080 and 8081) to enable testing that multiple Docker container ports can be exposed. +* It serves an HTML root page, with a few basic elements, to enable verification that browser-based test tools can access the container. +* It servers a non-HTML endpoint at `/ping` +* It implements a configurable delay at startup before each port's server is started, to enable testing of startup wait strategies (TCP or HTTP-based). Setting the environment variable `DELAY_START_MSEC` to a non-zero number will: + * wait for the defined duration + * start the port 8080 server + * wait again for the same duration + * start the port 8081 server +* It emits a basic log message after starting which can be used to test log-based wait strategies. + +## Example usage + +``` +$ docker run -p 8080:8080 -p 8081:8081 -e DELAY_START_MSEC=2000 helloworld + +2020/09/26 08:50:55 DELAY_START_MSEC: 2000 +2020/09/26 08:50:55 Sleeping for 2000 ms +2020/09/26 08:50:57 Starting server on port 8080 +2020/09/26 08:50:57 Sleeping for 2000 ms +2020/09/26 08:50:59 Starting server on port 8081 +2020/09/26 08:50:59 Ready, listening on 8080 and 8081 +``` + +## License + +See [LICENSE](./LICENSE). + +## Copyright + +Copyright (c) 2020 Richard North and other authors. \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..dde80b2 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module github.com/testcontainers/helloworld + +go 1.14 + +require ( + github.com/google/uuid v1.1.1 + github.com/gorilla/handlers v1.4.2 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..44ada22 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= +github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..f941339 --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,57 @@ +package server + +import ( + "fmt" + "log" + "net/http" + "os" + "time" + + "github.com/google/uuid" + "github.com/gorilla/handlers" + "github.com/testcontainers/helloworld/internal/util" +) + +func pingHandler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "PONG") +} + +func uuidHandler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, uuid.New().String()) +} + +func StartServing() { + fs := http.FileServer(http.Dir("./static")) + + server8080 := http.NewServeMux() + server8080.Handle("/", fs) + server8080.HandleFunc("/ping", pingHandler) + server8080.HandleFunc("/uuid", uuidHandler) + + server8081 := http.NewServeMux() + server8081.Handle("/", fs) + server8081.HandleFunc("/ping", pingHandler) + server8081.HandleFunc("/uuid", uuidHandler) + + // Delay, if configured to do so with an environment variable + delayStart := util.GetEnvInt("DELAY_START_MSEC", 0) + log.Printf("DELAY_START_MSEC: %d\n", delayStart) + + // Delay once before the server on port 8080 starts + log.Printf("Sleeping for %d ms", delayStart) + time.Sleep(time.Duration(delayStart) * time.Millisecond) + + log.Println("Starting server on port 8080") + go func() { + log.Fatal(http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, server8080))) + }() + + // Delay again before the server on port 8081 starts + log.Printf("Sleeping for %d ms", delayStart) + time.Sleep(time.Duration(delayStart) * time.Millisecond) + + log.Println("Starting server on port 8081") + go func() { + log.Fatal(http.ListenAndServe(":8081", handlers.LoggingHandler(os.Stdout, server8081))) + }() +} diff --git a/internal/util/util.go b/internal/util/util.go new file mode 100644 index 0000000..5213032 --- /dev/null +++ b/internal/util/util.go @@ -0,0 +1,19 @@ +package util + +import ( + "log" + "os" + "strconv" +) + +func GetEnvInt(key string, fallback int) int { + if valueString, ok := os.LookupEnv(key); ok { + value, err := strconv.Atoi(valueString) + if err != nil { + log.Fatalf("Environment variable %s could not be parsed as an integer. Found value: %s. Will use default value: %d\n", key, valueString, fallback) + return fallback + } + return value + } + return fallback +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..413230b --- /dev/null +++ b/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "log" + + "github.com/testcontainers/helloworld/internal/server" +) + +func main() { + // Use a channel to wait indefinitely once running + finish := make(chan bool) + + server.StartServing() + + log.Println("Ready, listening on 8080 and 8081") + + // Wait + <-finish +} diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..2c33594 --- /dev/null +++ b/static/index.html @@ -0,0 +1,34 @@ + + + + + + Hello world + + + + +

Hello world

+Testcontainers logo +

+ This is a test server used for Testcontainers' own self-tests. +

+

+ Find out more about Testcontainers at www.testcontainers.org. +

+

+ Hit /ping for a simple test response. +

+ + diff --git a/static/logo.png b/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..696e03ad6ff360ce03647928910996169e329b4f GIT binary patch literal 51964 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 Gg8vr^t7`)Q literal 0 HcmV?d00001 From eeba2b9073785c17a90166d2c756cc900cc93b55 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:00:56 +0100 Subject: [PATCH 02/14] Fix punctuation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3de2162..96b6837 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ It features a small HTTP server with the following characteristics: * It serves content on two ports (8080 and 8081) to enable testing that multiple Docker container ports can be exposed. * It serves an HTML root page, with a few basic elements, to enable verification that browser-based test tools can access the container. -* It servers a non-HTML endpoint at `/ping` +* It servers a non-HTML endpoint at `/ping`. * It implements a configurable delay at startup before each port's server is started, to enable testing of startup wait strategies (TCP or HTTP-based). Setting the environment variable `DELAY_START_MSEC` to a non-zero number will: * wait for the defined duration * start the port 8080 server From cd66dec91a35163b7319bb95026170c5f75b320b Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:08:09 +0100 Subject: [PATCH 03/14] Simplify code --- internal/server/server.go | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/internal/server/server.go b/internal/server/server.go index f941339..5d5c8fa 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -20,38 +20,33 @@ func uuidHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, uuid.New().String()) } +// StartServing starts serving content on ports 8080 and 8081 func StartServing() { - fs := http.FileServer(http.Dir("./static")) - - server8080 := http.NewServeMux() - server8080.Handle("/", fs) - server8080.HandleFunc("/ping", pingHandler) - server8080.HandleFunc("/uuid", uuidHandler) - - server8081 := http.NewServeMux() - server8081.Handle("/", fs) - server8081.HandleFunc("/ping", pingHandler) - server8081.HandleFunc("/uuid", uuidHandler) - // Delay, if configured to do so with an environment variable + // We will delay, if configured to do so with an environment variable delayStart := util.GetEnvInt("DELAY_START_MSEC", 0) log.Printf("DELAY_START_MSEC: %d\n", delayStart) - // Delay once before the server on port 8080 starts - log.Printf("Sleeping for %d ms", delayStart) - time.Sleep(time.Duration(delayStart) * time.Millisecond) + // start both servers, with delay before each + startServerOnPort(8080, delayStart) + startServerOnPort(8081, delayStart) +} - log.Println("Starting server on port 8080") - go func() { - log.Fatal(http.ListenAndServe(":8080", handlers.LoggingHandler(os.Stdout, server8080))) - }() +func startServerOnPort(port int, delayStart int) { + fs := http.FileServer(http.Dir("./static")) + + server := http.NewServeMux() + server.Handle("/", fs) + server.HandleFunc("/ping", pingHandler) + server.HandleFunc("/uuid", uuidHandler) - // Delay again before the server on port 8081 starts + // Delay before the server starts log.Printf("Sleeping for %d ms", delayStart) time.Sleep(time.Duration(delayStart) * time.Millisecond) - log.Println("Starting server on port 8081") + log.Printf("Starting server on port %d", port) + portName := fmt.Sprintf(":%d", port) go func() { - log.Fatal(http.ListenAndServe(":8081", handlers.LoggingHandler(os.Stdout, server8081))) + log.Fatal(http.ListenAndServe(portName, handlers.LoggingHandler(os.Stdout, server))) }() } From 5a2cee57768a159b3ff0041e71eb805c58ad22fa Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:08:14 +0100 Subject: [PATCH 04/14] Add favicon --- static/favicon.ico | Bin 0 -> 15086 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 static/favicon.ico diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..004282385c3e9b51ece573d194b64693145dc2e1 GIT binary patch literal 15086 zcmeHOe{2)i9Y30_tZETd>N;uKL?%|PTO}4dAy9@0q8e+rL6bPyTA+-wt%FVdqusQP zNgdwQLE}3okOFNOA@QB>Y)pu4g_SXlQMDawV;lMdI%wJwC@pk_62bz3B))x~ojWeh z`T3oFNuz2fUEbZj?|Yxm_r2%$y?^0LU!{K`c3pgmFdb#Q(|<37y)Qkp;U z!EsR%91l)JA0i3ilBd-9N%|1(^pt?-agD24C<$ffvhXK$aTRs(n5v?SALlC)7k&=D{brnv-^BW| z|4{g++LOdPonb(B$Rx6EPVja*(moDG`^W} z;D3gZKdFnP#5+ArO{Jf;(+^cuCq?3(UxC}TOn$lErG{DWTi~B+Pq2@*dP-;5;X_AU zxD6ctl8a}yc(K0xbRPWShqKqmJC_&YL-dd^AG}UyHjKDL#ae~jN@ zg(J;Y+BE0g@#Y^+2+cH3R^p_McfT{<{Lxqb*$PLRt+Z+G+vCsw`uv^7jU`TMoZB_t z{G%~X6AL#M8|mqJ$L-)x=G@G`-vs|G3pc9Gzn;7j2rfOY_^Jk_hS|po^}$O26OHp* zsoaLwhS_X(@Bj4)MXI@|NG?^orDqnB-$8%AepulTUR$zpqkivvYAD#Y@`%PcGn98M z?h(DEr}FW^691U6nab0o{CB_b#D|Jp`#~n>QSV~4Dm8xVs8t`V@DC^Wr2f zA<4vp^1Ee8FF(7GjM-O>epulT?)v<{{YCeMfc%4#EVy>s$UDA&K@>{$wVNgWG2TPU zf7jke{|!!8?c`-CFN_ub#<@pGJy_w7GWVwDE(Nv&OI#^f{-#AI(9il<=WlKD(mODJ z*>4xV4fz}n_*@QF{=|-GlCtD_1lS|yVK#8l=X4Bt4Je}P4^2&v1N zvcfC3t>1M-mTQ?chg@}|_+884!?|(rV-RJ&;km~9Cg#e-FD~uY03|K zbGXQSO$(D1>G%HW>9A*NI_xe=hwe$~Fg3^H)Fj7Mko5f=H=Tq%95QzVSnJ?R79#UO!*6k){%D@s;Th#;d1JkoPO8J zQ7cy!7qL%=_|$gl}LSn>vq^ItRr& z&a`^Ixk!s2%Md=V0=9mh2Kv3G6^_XsyXH&urMfA=mC5?ucmw}}QP040r(JvG8g@tA zQGox^Xnb9#@`bkCbxS_@dtTpg zD}0V{UTm_HE(LYho6QSptggu(I z$bZ0yL3@_GWme8{?A@{6@%e1^5sC3XqhXoFN%gaIEsW9*biER1CRb;}A8uprqKrYO#2KvM+&}``VYVSr@r9M zWv|Pv_n*gafPEj6f*(!rKQ;Q6?YV9LZ@UzK&H3x=nd&6=gJbY9sr#vwcV?0cTl<|CR-Zfq!ij2MT^9=2>CH4`MP4oBO$M`(*oEQZk`gd^QvAB6ntPWjdVVB zEx2pNYoqe9f@xywf94*te{`AF{@VV&wi5eTXYIz;^J`grUTU1TB3u7Yz89by<Pav@5 zi)MM|^DRR+p<(x+uX;Eij9h6_x(D_>P`;*pA@t6Dfx!J=&XrH0@ruti6CC1(dhR8A zLWSmQB|XZbNS11TgR$rIJ_bET{mi+qlfCsGSg}AChPcAK7Oxrj+Q?d98sRe z^h8HUrH^?ALg7{aME_yBui@XiuoGo>ndD&I2aR~b__-ZNs{bi3U*ApPU$?`UV7a_&zDTPtTEp97<~SlAyX z>v`;Ju0|fcxQ9>|b@}Yik})IK{wUEllk1@CPUpBD>=<+xaoqEiy9c|(#5P$$G*OQG EAH!e_G5`Po literal 0 HcmV?d00001 From fff9d94a42b06d0a97fe2953c8547454d11e7bd9 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:21:27 +0100 Subject: [PATCH 05/14] Run `go get` before build for dependency caching --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 2654ea6..e73d2a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM golang:alpine AS builder WORKDIR /go/src/github.com/testcontainers/helloworld COPY . ./ +RUN go get . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o /helloworld . FROM scratch From 5a72ba4b0c530ef029bb4c9707e8a77eb647707a Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:31:37 +0100 Subject: [PATCH 06/14] Use pinned alpine image for builder Co-authored-by: Kevin Wittek --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e73d2a6..cd3a244 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:alpine AS builder +FROM golang:alpine3.12 AS builder WORKDIR /go/src/github.com/testcontainers/helloworld COPY . ./ RUN go get . From 1e09c1fc54133ce38e079bf05f78e0dd78fd93ef Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:33:50 +0100 Subject: [PATCH 07/14] Use ENTRYPOINT, as the binary is not changeable --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index cd3a244..7d6fca7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,4 +7,4 @@ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflag FROM scratch COPY static /static COPY --from=builder /helloworld /helloworld -CMD ["/helloworld"] +ENTRYPOINT ["/helloworld"] From 61c2a6d7a8f2bce3ad918f9964445f2c067cd131 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:36:46 +0100 Subject: [PATCH 08/14] Fix LICENSE date --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 2e38890..7582fdf 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015-2019 Richard North +Copyright (c) 2020 Richard North Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From c9e5039bc638f1df4bb8dcdd319588c0b450dda1 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:38:06 +0100 Subject: [PATCH 09/14] Add link to repo in HTML page --- static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.html b/static/index.html index 2c33594..5640c68 100644 --- a/static/index.html +++ b/static/index.html @@ -22,7 +22,7 @@

Hello world

Testcontainers logo

- This is a test server used for Testcontainers' own self-tests. + This is a test server used for Testcontainers' own self-tests. Find out more about this image on GitHub.

Find out more about Testcontainers at www.testcontainers.org. From b8a768e733d44c712134197f7b476638c6f19d09 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:54:50 +0100 Subject: [PATCH 10/14] Update image name in example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 96b6837..b042638 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ It features a small HTTP server with the following characteristics: ## Example usage ``` -$ docker run -p 8080:8080 -p 8081:8081 -e DELAY_START_MSEC=2000 helloworld +$ docker run -p 8080:8080 -p 8081:8081 -e DELAY_START_MSEC=2000 testcontainers/helloworld 2020/09/26 08:50:55 DELAY_START_MSEC: 2000 2020/09/26 08:50:55 Sleeping for 2000 ms From 6e2065ea346d097c72862390cc89e9227ab1b3c2 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 10:59:05 +0100 Subject: [PATCH 11/14] Bump dependency versions --- go.mod | 6 +++--- go.sum | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index dde80b2..298d74a 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/testcontainers/helloworld -go 1.14 +go 1.15 require ( - github.com/google/uuid v1.1.1 - github.com/gorilla/handlers v1.4.2 + github.com/google/uuid v1.1.2 + github.com/gorilla/handlers v1.5.1 ) diff --git a/go.sum b/go.sum index 44ada22..2c192ef 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ -github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg= -github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= From a8b0683f458adb0b1b3e44ae8f7b25fe9c7a54fe Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 11:05:28 +0100 Subject: [PATCH 12/14] Properly implement `/uuid` --- README.md | 3 ++- internal/server/server.go | 25 ++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index b042638..5f152ec 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ It features a small HTTP server with the following characteristics: * It serves content on two ports (8080 and 8081) to enable testing that multiple Docker container ports can be exposed. * It serves an HTML root page, with a few basic elements, to enable verification that browser-based test tools can access the container. -* It servers a non-HTML endpoint at `/ping`. +* It serves a non-HTML endpoint at `/ping`, to enable plain HTTP testing. +* It serves a UUID unique to this running instance of the container, at `/uuid`, to enable testing of multiple container instances or testing of stop/start behaviour. * It implements a configurable delay at startup before each port's server is started, to enable testing of startup wait strategies (TCP or HTTP-based). Setting the environment variable `DELAY_START_MSEC` to a non-zero number will: * wait for the defined duration * start the port 8080 server diff --git a/internal/server/server.go b/internal/server/server.go index 5d5c8fa..74c6a8a 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -12,14 +12,6 @@ import ( "github.com/testcontainers/helloworld/internal/util" ) -func pingHandler(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "PONG") -} - -func uuidHandler(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, uuid.New().String()) -} - // StartServing starts serving content on ports 8080 and 8081 func StartServing() { @@ -27,18 +19,25 @@ func StartServing() { delayStart := util.GetEnvInt("DELAY_START_MSEC", 0) log.Printf("DELAY_START_MSEC: %d\n", delayStart) + // Create a UUID for this container instance + instanceUUID := uuid.New().String() + // start both servers, with delay before each - startServerOnPort(8080, delayStart) - startServerOnPort(8081, delayStart) + startServerOnPort(8080, instanceUUID, delayStart) + startServerOnPort(8081, instanceUUID, delayStart) } -func startServerOnPort(port int, delayStart int) { +func startServerOnPort(port int, instanceUUID string, delayStart int) { fs := http.FileServer(http.Dir("./static")) server := http.NewServeMux() server.Handle("/", fs) - server.HandleFunc("/ping", pingHandler) - server.HandleFunc("/uuid", uuidHandler) + server.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "PONG") + }) + server.HandleFunc("/uuid", func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, instanceUUID) + }) // Delay before the server starts log.Printf("Sleeping for %d ms", delayStart) From 4a92d1bb8c5ccb1ff89df12b3f6f633dbf510788 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 11:08:38 +0100 Subject: [PATCH 13/14] Mention /uuid endpoint in index page --- static/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/static/index.html b/static/index.html index 5640c68..a972908 100644 --- a/static/index.html +++ b/static/index.html @@ -30,5 +30,8 @@

Hello world

Hit /ping for a simple test response.

+

+ Hit /uuid for a UUID that is unique to this running instance of the container. +

From 4d7268e9364965be015c2d7271a8f79a9a626bd5 Mon Sep 17 00:00:00 2001 From: Richard North Date: Sat, 26 Sep 2020 21:02:02 +0100 Subject: [PATCH 14/14] Improve dependency caching on build --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 7d6fca7..ec4f390 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,8 @@ FROM golang:alpine3.12 AS builder WORKDIR /go/src/github.com/testcontainers/helloworld +COPY go.mod go.sum ./ +RUN go mod download COPY . ./ -RUN go get . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o /helloworld . FROM scratch