Skip to content

Commit

Permalink
Added occurrence for the WaitLogStrategy
Browse files Browse the repository at this point in the history
This is related to the work @giorgioazzinnaro is doing here
#98 .

Now you can declare how many times a log line should appear before
having the container declared as ready.

Signed-off-by: Gianluca Arbezzano <[email protected]>
  • Loading branch information
Gianluca Arbezzano committed Oct 2, 2019
1 parent de4c7e2 commit 4f7b7c1
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ require (
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gotest.tools v0.0.0-20181223230014-1083505acf35 // indirect
)

go 1.13
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
17 changes: 16 additions & 1 deletion wait/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type LogStrategy struct {
// additional properties
Log string
PollInterval time.Duration
Occurence int
}

// NewLogStrategy constructs a HTTP strategy waiting on port 80 and status code 200
Expand All @@ -26,6 +27,7 @@ func NewLogStrategy(log string) *LogStrategy {
startupTimeout: defaultStartupTimeout(),
Log: log,
PollInterval: 100 * time.Millisecond,
Occurence: 1,
}

}
Expand All @@ -46,6 +48,15 @@ func (ws *LogStrategy) WithPollInterval(pollInterval time.Duration) *LogStrategy
return ws
}

func (ws *LogStrategy) WithOccurence(o int) *LogStrategy {
// the number of occurence needs to be positive
if o <= 0 {
o = 1
}
ws.Occurence = o
return ws
}

// ForLog is the default construction for the fluid interface.
//
// For Example:
Expand All @@ -61,6 +72,7 @@ func (ws *LogStrategy) WaitUntilReady(ctx context.Context, target StrategyTarget
// limit context to startupTimeout
ctx, cancelContext := context.WithTimeout(ctx, ws.startupTimeout)
defer cancelContext()
currentOccurence := 0

LOOP:
for {
Expand All @@ -77,7 +89,10 @@ LOOP:
b, err := ioutil.ReadAll(reader)
logs := string(b)
if strings.Contains(logs, ws.Log) {
break LOOP
currentOccurence++
if ws.Occurence == 0 || currentOccurence >= ws.Occurence-1 {
break LOOP
}
} else {
time.Sleep(ws.PollInterval)
continue
Expand Down
65 changes: 65 additions & 0 deletions wait/log_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package wait

import (
"bytes"
"context"
"io"
"io/ioutil"
"testing"
"time"

"github.com/docker/go-connections/nat"
)

type noopStrategyTarget struct {
ioReaderCloser io.ReadCloser
}

func (st noopStrategyTarget) Host(ctx context.Context) (string, error) {
return "", nil
}

func (st noopStrategyTarget) MappedPort(ctx context.Context, n nat.Port) (nat.Port, error) {
return n, nil
}

func (st noopStrategyTarget) Logs(ctx context.Context) (io.ReadCloser, error) {
return st.ioReaderCloser, nil
}

func TestWaitForLog(t *testing.T) {
target := noopStrategyTarget{
ioReaderCloser: ioutil.NopCloser(bytes.NewReader([]byte("dude"))),
}
wg := NewLogStrategy("dude").WithStartupTimeout(100 * time.Microsecond)
err := wg.WaitUntilReady(context.Background(), target)
if err != nil {
t.Fatal(err)
}
}

func TestWaitWithMaxOccurence(t *testing.T) {
target := noopStrategyTarget{
ioReaderCloser: ioutil.NopCloser(bytes.NewReader([]byte("hello\r\ndude\n\rdude"))),
}
wg := NewLogStrategy("dude").
WithStartupTimeout(100 * time.Microsecond).
WithOccurence(2)
err := wg.WaitUntilReady(context.Background(), target)
if err != nil {
t.Fatal(err)
}
}

func TestWaitWithMaxOccurenceButItWillNeverHappen(t *testing.T) {
target := noopStrategyTarget{
ioReaderCloser: ioutil.NopCloser(bytes.NewReader([]byte("hello\r\ndude"))),
}
wg := NewLogStrategy("blaaa").
WithStartupTimeout(100 * time.Microsecond).
WithOccurence(2)
err := wg.WaitUntilReady(context.Background(), target)
if err == nil {
t.Fatal("expected error")
}
}

0 comments on commit 4f7b7c1

Please sign in to comment.