Skip to content

Commit

Permalink
Merge pull request #1 from testcontainers/first-working-version
Browse files Browse the repository at this point in the history
  • Loading branch information
rnorth authored Sep 26, 2020
2 parents 086e4ab + 4d7268e commit e2c56a0
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
helloworld
11 changes: 11 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM golang:alpine3.12 AS builder
WORKDIR /go/src/github.com/testcontainers/helloworld
COPY go.mod go.sum ./
RUN go mod download
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
ENTRYPOINT ["/helloworld"]
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

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
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.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# 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 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
* 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 testcontainers/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.
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/testcontainers/helloworld

go 1.15

require (
github.com/google/uuid v1.1.2
github.com/gorilla/handlers v1.5.1
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
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=
51 changes: 51 additions & 0 deletions internal/server/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package server

import (
"fmt"
"log"
"net/http"
"os"
"time"

"github.com/google/uuid"
"github.com/gorilla/handlers"
"github.com/testcontainers/helloworld/internal/util"
)

// StartServing starts serving content on ports 8080 and 8081
func StartServing() {

// 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)

// Create a UUID for this container instance
instanceUUID := uuid.New().String()

// start both servers, with delay before each
startServerOnPort(8080, instanceUUID, delayStart)
startServerOnPort(8081, instanceUUID, delayStart)
}

func startServerOnPort(port int, instanceUUID string, delayStart int) {
fs := http.FileServer(http.Dir("./static"))

server := http.NewServeMux()
server.Handle("/", fs)
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)
time.Sleep(time.Duration(delayStart) * time.Millisecond)

log.Printf("Starting server on port %d", port)
portName := fmt.Sprintf(":%d", port)
go func() {
log.Fatal(http.ListenAndServe(portName, handlers.LoggingHandler(os.Stdout, server)))
}()
}
19 changes: 19 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
@@ -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
}
19 changes: 19 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -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
}
Binary file added static/favicon.ico
Binary file not shown.
37 changes: 37 additions & 0 deletions static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello world</title>
<style>
body {
font-family: sans-serif;
max-width: 38rem;
padding: 2rem;
margin: auto;
}

* {
max-width: 100%;
}
</style>
</head>

<body>
<h1>Hello world</h1>
<img src="logo.png" alt="Testcontainers logo"/>
<p>
This is a test server used for Testcontainers' own self-tests. Find out more about this image on <a href="https://github.com/testcontainers/helloworld">GitHub</a>.
</p>
<p>
Find out more about Testcontainers at <a href="https://www.testcontainers.org">www.testcontainers.org</a>.
</p>
<p>
Hit <a href="/ping"><code>/ping</code></a> for a simple test response.
</p>
<p>
Hit <a href="/uuid"><code>/uuid</code></a> for a UUID that is unique to this running instance of the container.
</p>
</body>
</html>
Binary file added static/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e2c56a0

Please sign in to comment.