mirror of
https://github.com/hanzoai/oxy.git
synced 2026-09-30 23:42:31 +00:00
106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
//go:build !holster_test_mode
|
|
|
|
// Package clock provides the same functions as the system package time. In
|
|
// production it forwards all calls to the system time package, but in tests
|
|
// the time can be frozen by calling Freeze function and from that point it has
|
|
// to be advanced manually with Advance function making all scheduled calls
|
|
// deterministic.
|
|
//
|
|
// The functions provided by the package have the same parameters and return
|
|
// values as their system counterparts with a few exceptions. Where either
|
|
// *time.Timer or *time.Ticker is returned by a system function, the clock
|
|
// package counterpart returns clock.Timer or clock.Ticker interface
|
|
// respectively. The interfaces provide API as respective structs except C is
|
|
// not a channel, but a function that returns <-chan time.Time.
|
|
package clock
|
|
|
|
import "time"
|
|
|
|
var (
|
|
frozenAt time.Time
|
|
realtime = &systemTime{}
|
|
provider Clock = realtime
|
|
)
|
|
|
|
// Freeze after this function is called all time related functions start
|
|
// generate deterministic timers that are triggered by Advance function. It is
|
|
// supposed to be used in tests only. Returns an Unfreezer so it can be a
|
|
// one-liner in tests: defer clock.Freeze(clock.Now()).Unfreeze()
|
|
func Freeze(now time.Time) Unfreezer {
|
|
frozenAt = now.UTC()
|
|
provider = &frozenTime{now: now}
|
|
return Unfreezer{}
|
|
}
|
|
|
|
type Unfreezer struct{}
|
|
|
|
func (u Unfreezer) Unfreeze() {
|
|
Unfreeze()
|
|
}
|
|
|
|
// Unfreeze reverses effect of Freeze.
|
|
func Unfreeze() {
|
|
provider = realtime
|
|
}
|
|
|
|
// Realtime returns a clock provider wrapping the SDK's time package. It is
|
|
// supposed to be used in tests when time is frozen to schedule test timeouts.
|
|
func Realtime() Clock {
|
|
return realtime
|
|
}
|
|
|
|
// Makes the deterministic time move forward by the specified duration, firing
|
|
// timers along the way in the natural order. It returns how much time has
|
|
// passed since it was frozen. So you can assert on the return value in tests
|
|
// to make it explicit where you stand on the deterministic time scale.
|
|
func Advance(d time.Duration) time.Duration {
|
|
ft, ok := provider.(*frozenTime)
|
|
if !ok {
|
|
panic("Freeze time first!")
|
|
}
|
|
ft.advance(d)
|
|
return Now().UTC().Sub(frozenAt)
|
|
}
|
|
|
|
// Wait4Scheduled blocks until either there are n or more scheduled events, or
|
|
// the timeout elapses. It returns true if the wait condition has been met
|
|
// before the timeout expired, false otherwise.
|
|
func Wait4Scheduled(count int, timeout time.Duration) bool {
|
|
return provider.Wait4Scheduled(count, timeout)
|
|
}
|
|
|
|
// Now see time.Now.
|
|
func Now() time.Time {
|
|
return provider.Now()
|
|
}
|
|
|
|
// Sleep see time.Sleep.
|
|
func Sleep(d time.Duration) {
|
|
provider.Sleep(d)
|
|
}
|
|
|
|
// After see time.After.
|
|
func After(d time.Duration) <-chan time.Time {
|
|
return provider.After(d)
|
|
}
|
|
|
|
// NewTimer see time.NewTimer.
|
|
func NewTimer(d time.Duration) Timer {
|
|
return provider.NewTimer(d)
|
|
}
|
|
|
|
// AfterFunc see time.AfterFunc.
|
|
func AfterFunc(d time.Duration, f func()) Timer {
|
|
return provider.AfterFunc(d, f)
|
|
}
|
|
|
|
// NewTicker see time.Ticker.
|
|
func NewTicker(d time.Duration) Ticker {
|
|
return provider.NewTicker(d)
|
|
}
|
|
|
|
// Tick see time.Tick.
|
|
func Tick(d time.Duration) <-chan time.Time {
|
|
return provider.Tick(d)
|
|
}
|