diff options
author | Sami Hiltunen <shiltunen@gitlab.com> | 2023-10-31 15:15:10 +0300 |
---|---|---|
committer | Sami Hiltunen <shiltunen@gitlab.com> | 2023-10-31 15:18:32 +0300 |
commit | 372615000b33841360d85651722d2069128d7290 (patch) | |
tree | 067793067227e016023b89ede47310b79282f609 | |
parent | 1a46729b8560f5092c4b46de9a1ed7d8b3baec8e (diff) |
Implement general ticker factory helpers
Gitaly's code is using tickers in multiple places. They make it easier
to test code that runs on an interval. The tickers are generally
constructed using a factory method injected into the type using the
ticker. This makes it easier to mock out the timer based tickers in
tests. We'll soon need this in the PartitionManager tests. This commit
implements factory methods for timer ticker and a ticker that never
ticks. The timer tickers can be used to configure the production code,
and the null tickers can be used to disable the ticking for example in
tests. If the tests need to manually control the ticking, they can
do so by passing a custom TickerFactoryFunc into the type under test.
-rw-r--r-- | internal/helper/ticker_factory.go | 29 | ||||
-rw-r--r-- | internal/helper/ticker_factory_test.go | 47 |
2 files changed, 76 insertions, 0 deletions
diff --git a/internal/helper/ticker_factory.go b/internal/helper/ticker_factory.go new file mode 100644 index 000000000..3b06d2667 --- /dev/null +++ b/internal/helper/ticker_factory.go @@ -0,0 +1,29 @@ +package helper + +import "time" + +// TickerFactory constructs a new ticker. +type TickerFactory interface { + // NewTicker returns a new Ticker. + NewTicker() Ticker +} + +// TickerFactoryFunc is a function that implements TickerFactory +type TickerFactoryFunc func() Ticker + +// NewTicker returns a new ticker. +func (fn TickerFactoryFunc) NewTicker() Ticker { return fn() } + +// NewNullTickerFactory returns new tickers that don't tick. +func NewNullTickerFactory() TickerFactory { + return TickerFactoryFunc(func() Ticker { + return NewManualTicker() + }) +} + +// NewTimerTickerFactory returns new tickers that tick after the given interval. +func NewTimerTickerFactory(interval time.Duration) TickerFactory { + return TickerFactoryFunc(func() Ticker { + return NewTimerTicker(interval) + }) +} diff --git a/internal/helper/ticker_factory_test.go b/internal/helper/ticker_factory_test.go new file mode 100644 index 000000000..193d5e4fa --- /dev/null +++ b/internal/helper/ticker_factory_test.go @@ -0,0 +1,47 @@ +package helper + +import ( + "testing" + "time" +) + +func TestNullTickerFactory(t *testing.T) { + ticker := NewNullTickerFactory().NewTicker() + + select { + case <-ticker.C(): + t.Fatal("unexpected tick received before reset") + default: + } + + ticker.Reset() + + select { + case <-ticker.C(): + t.Fatal("unexpected tick received after reset") + default: + } +} + +func TestNewTimerTickerFactory(t *testing.T) { + tickerFactory := NewTimerTickerFactory(time.Nanosecond) + + ticker1 := tickerFactory.NewTicker() + ticker2 := tickerFactory.NewTicker() + + select { + case <-ticker1.C(): + t.Fatal("unexpected tick received from ticker1 before reset") + case <-ticker2.C(): + t.Fatal("unexpected tick received from ticker2 before reset") + default: + } + + ticker1.Reset() + + select { + case <-ticker1.C(): + case <-ticker2.C(): + t.Fatal("unexpected tick received from ticker2 after resetting ticker1") + } +} |