Skip to content

Commit

Permalink
setectest: add a Ticker type implementing a fake setec.Ticker
Browse files Browse the repository at this point in the history
Move the unexported utility type into the shared test package.
Update the tests to use the test package version instead.
  • Loading branch information
creachadair committed Sep 23, 2024
1 parent f63dc91 commit 4af0470
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 23 deletions.
27 changes: 4 additions & 23 deletions client/setec/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func TestCachedStore(t *testing.T) {
const cacheData = `{"alpha":{"secret":{"Value":"Zm9vYmFy","Version":1},"lastAccess":"0"}}`

// Make a poll ticker so we can control the poll schedule.
pollTicker := newFakeTicker()
pollTicker := setectest.NewFakeTicker()

// Populate a memory cache with an "old" value of a secret.
mc := setec.NewMemCache(cacheData)
Expand Down Expand Up @@ -303,7 +303,7 @@ func TestWatcher(t *testing.T) {
ctx := context.Background()
cli := setec.Client{Server: hs.URL, DoHTTP: hs.Client().Do}

pollTicker := newFakeTicker()
pollTicker := setectest.NewFakeTicker()
st, err := setec.NewStore(ctx, setec.StoreConfig{
Client: cli,
Secrets: []string{"green"},
Expand Down Expand Up @@ -368,7 +368,7 @@ func TestUpdater(t *testing.T) {
ctx := context.Background()
cli := setec.Client{Server: hs.URL, DoHTTP: hs.Client().Do}

pollTicker := newFakeTicker()
pollTicker := setectest.NewFakeTicker()
st, err := setec.NewStore(ctx, setec.StoreConfig{
Client: cli,
Secrets: []string{"label"},
Expand Down Expand Up @@ -521,7 +521,7 @@ func TestCacheExpiry(t *testing.T) {
})

t.Run("Probe", func(t *testing.T) {
pt := newFakeTicker()
pt := setectest.NewFakeTicker()

st, err := setec.NewStore(ctx, setec.StoreConfig{
Client: cli,
Expand Down Expand Up @@ -642,22 +642,3 @@ type badCache struct{}

func (badCache) Write([]byte) error { return errors.New("write failed") }
func (badCache) Read() ([]byte, error) { return nil, errors.New("read failed") }

func newFakeTicker() *fakeTicker {
return &fakeTicker{ch: make(chan time.Time), done: make(chan struct{})}
}

type fakeTicker struct {
ch chan time.Time
done chan struct{}
}

func (fakeTicker) Stop() {}
func (f fakeTicker) Chan() <-chan time.Time { return f.ch }
func (f *fakeTicker) Done() { f.done <- struct{}{} }

// Poll signals the ticker, then waits for Done to be invoked.
func (f *fakeTicker) Poll() {
f.ch <- time.Now()
<-f.done
}
27 changes: 27 additions & 0 deletions setectest/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package setectest

import "time"

// NewFakeTicker constructs a test-controled instance of the [setec.Ticker]
// interface that can be used by tests to control the advancement of updates to
// a [setec.Store].
func NewFakeTicker() *Ticker {
return &Ticker{ch: make(chan time.Time), done: make(chan struct{})}
}

// Ticker implements the [setec.Ticker] interface allowing a test to control
// the advancement of time to exercise polling.
type Ticker struct {
ch chan time.Time
done chan struct{}
}

func (Ticker) Stop() {}
func (f Ticker) Chan() <-chan time.Time { return f.ch }
func (f *Ticker) Done() { f.done <- struct{}{} }

// Poll signals the ticker, then waits for Done to be invoked.
func (f *Ticker) Poll() {
f.ch <- time.Now()
<-f.done
}

0 comments on commit 4af0470

Please sign in to comment.