Skip to content

Commit

Permalink
pkg/core/services/servicetest: add TestRunHealthy
Browse files Browse the repository at this point in the history
  • Loading branch information
jmank88 committed Nov 27, 2023
1 parent e6c73fd commit 81a045a
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 7 deletions.
22 changes: 16 additions & 6 deletions pkg/services/servicetest/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ package servicetest
import (
"context"
"errors"
"testing"
"fmt"
"time"

"golang.org/x/exp/maps"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand All @@ -20,8 +18,14 @@ type Runnable interface {
Close() error
}

type TestingT interface {
require.TestingT
Helper()
Cleanup(func())
}

// Run fails tb if the service fails to start or close.
func Run(tb testing.TB, s Runnable) {
func Run(tb TestingT, s Runnable) {
tb.Helper()
require.NoError(tb, s.Start(tests.Context(tb)), "service failed to start")
tb.Cleanup(func() { assert.NoError(tb, s.Close(), "error closing service") })
Expand All @@ -30,7 +34,7 @@ func Run(tb testing.TB, s Runnable) {
// RunHealthy fails tb if the service fails to start, close, is never ready, or is ever unhealthy (based on periodic checks).
// - after starting, readiness will always be checked at least once, before closing
// - if ever ready, then health will be checked at least once, before closing
func RunHealthy(tb testing.TB, s services.Service) {
func RunHealthy(tb TestingT, s services.Service) {
tb.Helper()
Run(tb, s)

Expand All @@ -41,7 +45,13 @@ func RunHealthy(tb testing.TB, s services.Service) {
})
go func() {
defer close(done)
hp := func() error { return errors.Join(maps.Values(s.HealthReport())...) }
hp := func() (err error) {
for k, v := range s.HealthReport() {
err = errors.Join(err, fmt.Errorf("%s: %w", k, v))
}
fmt.Println("Health report: ", err)
return
}
for s.Ready() != nil {
select {
case <-done:
Expand Down
99 changes: 99 additions & 0 deletions pkg/services/servicetest/run_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package servicetest

import (
"context"
"errors"
"fmt"
"testing"

"github.com/stretchr/testify/assert"

"github.com/smartcontractkit/chainlink-common/pkg/services"
)

func TestRunHealthy(t *testing.T) {
for _, test := range []struct {
name string
s services.Service
expFail bool
}{
{name: "healty", s: &fakeService{}},
{name: "start", s: &fakeService{start: errors.New("test")}, expFail: true},
{name: "close", s: &fakeService{close: errors.New("test")}, expFail: true},
{name: "unready", s: &fakeService{ready: errors.New("test")}, expFail: true},
{name: "unhealthy", s: &fakeService{healthReport: map[string]error{
"foo.bar": errors.New("baz"),
}}, expFail: true},
} {
t.Run(test.name, func(t *testing.T) {
_, failed := runFake(func(t TestingT) {
RunHealthy(t, test.s)
})
assert.Equal(t, test.expFail, failed)
})
}

}

func runFake(fn func(t TestingT)) ([]string, bool) {
var t fakeTest
func() {
defer func() {
for i := len(t.cleanup) - 1; i >= 0; i-- {
t.cleanup[i]()
}
if r := recover(); r != nil {
if _, ok := r.(failNow); ok {
return
}
panic(r)
}
}()
fn(&t)
}()
return t.errors, t.failed
}

type failNow struct{}

type fakeTest struct {
cleanup []func()
errors []string
failed bool
}

func (f *fakeTest) Cleanup(fn func()) {
f.cleanup = append(f.cleanup, fn)
}

func (f *fakeTest) Errorf(format string, args ...interface{}) {
f.errors = append(f.errors, fmt.Sprintf(format, args...))
f.failed = true
}

func (f *fakeTest) FailNow() {
if f.failed == true {
return // only panic the first time
}
f.failed = true
panic(failNow{})
}

func (f *fakeTest) Helper() {}

type fakeService struct {
start error
close error
ready error
healthReport map[string]error
}

func (h *fakeService) Name() string { return "fakeService" }

func (h *fakeService) Start(ctx context.Context) error { return h.start }

func (h *fakeService) Close() error { return h.close }

func (h *fakeService) Ready() error { return h.ready }

func (h *fakeService) HealthReport() map[string]error { return h.healthReport }
9 changes: 8 additions & 1 deletion pkg/utils/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Context(tb testing.TB) (ctx context.Context) {
type TestingT interface {
require.TestingT
Helper()
Cleanup(func())
}

func Context(tb TestingT) (ctx context.Context) {
ctx = context.Background()
var cancel func()

Expand Down

0 comments on commit 81a045a

Please sign in to comment.