Of possible interest to anyone testing concurrent Go code in general and time in particular, a proposed standard library package: <a href="https://go.dev/issue/67434" rel="nofollow">https://go.dev/issue/67434</a>
At the risk of appearing low-tech, a much more simple, Goroutine-safe solution for dealing with "now-dependent" code:<p>type NowFunc func() time.Time<p>func getGreeting(nowFunc NowFunc) string {<p><pre><code> now := nowFunc()
if now.Hour() < 12 {
return "Good Morning"
}
return "Good day"
</code></pre>
}<p>And just pass in `time.Now` in for live code, and your own inline function for simulating a time in tests.
I think <a href="https://pkg.go.dev/k8s.io/utils/clock" rel="nofollow">https://pkg.go.dev/k8s.io/utils/clock</a> and <a href="https://pkg.go.dev/k8s.io/utils/clock/testing" rel="nofollow">https://pkg.go.dev/k8s.io/utils/clock/testing</a> is already doing these?
I have a fair bit of experience writing tests for concurrent code that uses timers on Go. We started with an open source test library ( <a href="https://pkg.go.dev/github.com/benbjohnson/clock" rel="nofollow">https://pkg.go.dev/github.com/benbjohnson/clock</a> ). It had a lot of problems. This was many years ago, looks like it's seen some maintenance since so maybe it's better? Then we tried to fix it. Fixed all the obvious bugs but still had a lot of problems using it in practice. It's not enough to just handle the calls without context of who is calling them in concurrent code. Then we switched to using gomock which ended up also being hard to use.<p>It's quite tricky is sort of the bottom line. It's not enough to just create fake time there's a lot more to it.
For linux, there is faketime, which will set a specific date and time for all child processes. This enables you to test software you don't even compile for time-based problems, e.g. logic around Feb 29th or daylight saving time.