Skip to content

Commit

Permalink
Merge pull request #83 from GaruGaru/master
Browse files Browse the repository at this point in the history
Multiple wait strategy
  • Loading branch information
gianarb authored Sep 2, 2019
2 parents 290309f + 9e86f45 commit 1637080
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
77 changes: 77 additions & 0 deletions docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,3 +592,80 @@ func TestContainerCreationWaitsForLog(t *testing.T) {
t.Errorf("error creating table: %+v\n", err)
}
}

func TestContainerCreationWaitsForLogAndPortContextTimeout(t *testing.T) {
ctx := context.Background()
req := ContainerRequest{
Image: "mysql:latest",
ExposedPorts: []string{"3306/tcp", "33060/tcp"},
Env: map[string]string{
"MYSQL_ROOT_PASSWORD": "password",
"MYSQL_DATABASE": "database",
},
WaitingFor: wait.ForAll(
wait.ForLog("I love testcontainers-go"),
wait.ForListeningPort("3306/tcp"),
),
}
_, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Started: true,
})

if err == nil {
t.Fatal("Expected timeout")
}

}

func TestContainerCreationWaitsForLogAndPort(t *testing.T) {
ctx := context.Background()
req := ContainerRequest{
Image: "mysql:latest",
ExposedPorts: []string{"3306/tcp", "33060/tcp"},
Env: map[string]string{
"MYSQL_ROOT_PASSWORD": "password",
"MYSQL_DATABASE": "database",
},
WaitingFor: wait.ForAll(
wait.ForLog("port: 3306 MySQL Community Server - GPL"),
wait.ForListeningPort("3306/tcp"),
),
}

mysqlC, err := GenericContainer(ctx, GenericContainerRequest{
ContainerRequest: req,
Started: true,
})

if err != nil {
t.Fatal(err)
}

defer func() {
t.Log("terminating container")
err := mysqlC.Terminate(ctx)
if err != nil {
t.Fatal(err)
}
}()

host, _ := mysqlC.Host(ctx)
p, _ := mysqlC.MappedPort(ctx, "3306/tcp")
port := p.Int()
connectionString := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?tls=skip-verify",
"root", "password", host, port, "database")

db, err := sql.Open("mysql", connectionString)

if err != nil {
t.Fatal(err)
}

defer db.Close()

if err = db.Ping(); err != nil {
t.Errorf("error pinging db: %+v\n", err)
}

}
47 changes: 47 additions & 0 deletions wait/multi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package wait

import (
"context"
"fmt"
"time"
)

// Implement interface
var _ Strategy = (*MultiStrategy)(nil)

type MultiStrategy struct {
// all Strategies should have a startupTimeout to avoid waiting infinitely
startupTimeout time.Duration

// additional properties
Strategies []Strategy
}

func (ms *MultiStrategy) WithStartupTimeout(startupTimeout time.Duration) *MultiStrategy {
ms.startupTimeout = startupTimeout
return ms
}

func ForAll(strategies ...Strategy) *MultiStrategy {
return &MultiStrategy{
startupTimeout: defaultStartupTimeout(),
Strategies: strategies,
}
}

func (ms *MultiStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget) (err error) {
ctx, cancelContext := context.WithTimeout(ctx, ms.startupTimeout)
defer cancelContext()

if len(ms.Strategies) == 0 {
return fmt.Errorf("no wait strategy supplied")
}

for _, strategy := range ms.Strategies {
err := strategy.WaitUntilReady(ctx, target)
if err != nil {
return err
}
}
return nil
}

0 comments on commit 1637080

Please sign in to comment.