Skip to content

Commit

Permalink
fix(influxdb): Respect custom waitStrategy (testcontainers#2845)
Browse files Browse the repository at this point in the history
* Respect custom waitStrategy for InfluxDB (#1)

fix(influxdb): Respect passed waitStrategy

* Refactor test to use require for container state assertion

Co-authored-by: Steven Hartland <[email protected]>

* Change default wait strategy from checking logs to health check for influxdb2 (#2)

* /health check waitStrategy for influx1 and influx2

* Undo health endpoint test after default strategy was changed

* Update http health check to verify JSON status value (#3)

* Move Shutdown check to WithInitDb (#4)

Move Shutdown check to WithInitDb

* Remove slice

Co-authored-by: Steven Hartland <[email protected]>

* Simplify comment

Co-authored-by: Steven Hartland <[email protected]>

* More precise WitInitDb domment

---------

Co-authored-by: Steven Hartland <[email protected]>
  • Loading branch information
marcinmilewski93 and stevenh authored Nov 20, 2024
1 parent 1b26907 commit 83b47ca
Showing 1 changed file with 24 additions and 37 deletions.
61 changes: 24 additions & 37 deletions modules/influxdb/influxdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package influxdb

import (
"context"
"encoding/json"
"fmt"
"io"
"path"
"strings"

"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
Expand Down Expand Up @@ -34,7 +35,7 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
"INFLUXDB_HTTP_HTTPS_ENABLED": "false",
"INFLUXDB_HTTP_AUTH_ENABLED": "false",
},
WaitingFor: wait.ForListeningPort("8086/tcp"),
WaitingFor: waitForHttpHealth(),
}
genericContainerReq := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Expand All @@ -47,38 +48,6 @@ func Run(ctx context.Context, img string, opts ...testcontainers.ContainerCustom
}
}

hasInitDb := false

for _, f := range genericContainerReq.Files {
if f.ContainerFilePath == "/" && strings.HasSuffix(f.HostFilePath, "docker-entrypoint-initdb.d") {
// Init service in container will start influxdb, run scripts in docker-entrypoint-initdb.d and then
// terminate the influxdb server, followed by restart of influxdb. This is tricky to wait for, and
// in this case, we are assuming that data was added by init script, so we then look for an
// "Open shard" which is the last thing that happens before the server is ready to accept connections.
// This is probably different for InfluxDB 2.x, but that is left as an exercise for the reader.
strategies := []wait.Strategy{
genericContainerReq.WaitingFor,
wait.ForLog("influxdb init process in progress..."),
wait.ForLog("Server shutdown completed"),
wait.ForLog("Opened shard"),
}
genericContainerReq.WaitingFor = wait.ForAll(strategies...)
hasInitDb = true
break
}
}

if !hasInitDb {
if lastIndex := strings.LastIndex(genericContainerReq.Image, ":"); lastIndex != -1 {
tag := genericContainerReq.Image[lastIndex+1:]
if tag == "latest" || tag[0] == '2' {
genericContainerReq.WaitingFor = wait.ForLog(`Listening log_id=[0-9a-zA-Z_~]+ service=tcp-listener transport=http`).AsRegexp()
}
} else {
genericContainerReq.WaitingFor = wait.ForLog("Listening for signals")
}
}

container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
var c *InfluxDbContainer
if container != nil {
Expand Down Expand Up @@ -147,9 +116,8 @@ func WithConfigFile(configFile string) testcontainers.CustomizeRequestOption {
}
}

// WithInitDb will copy a 'docker-entrypoint-initdb.d' directory to the container.
// The secPath is the path to the directory on the host machine.
// The directory will be copied to the root of the container.
// WithInitDb returns a request customizer that initialises the database using the file `docker-entrypoint-initdb.d`
// located in `srcPath` directory.
func WithInitDb(srcPath string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) error {
cf := testcontainers.ContainerFile{
Expand All @@ -158,6 +126,25 @@ func WithInitDb(srcPath string) testcontainers.CustomizeRequestOption {
FileMode: 0o755,
}
req.Files = append(req.Files, cf)

req.WaitingFor = wait.ForAll(
wait.ForLog("Server shutdown completed"),
waitForHttpHealth(),
)
return nil
}
}

func waitForHttpHealth() *wait.HTTPStrategy {
return wait.ForHTTP("/health").
WithResponseMatcher(func(body io.Reader) bool {
decoder := json.NewDecoder(body)
r := struct {
Status string `json:"status"`
}{}
if err := decoder.Decode(&r); err != nil {
return false
}
return r.Status == "pass"
})
}

0 comments on commit 83b47ca

Please sign in to comment.