Merged in feature/stabilisetimeNow (pull request #125)

inject time.now for tesability

* inject
This commit is contained in:
Michael McGuinness
2025-04-29 14:11:10 +00:00
parent 28b24a33fd
commit 76cc547bd6
2 changed files with 31 additions and 11 deletions
+4 -4
View File
@@ -25,16 +25,16 @@ var startupTime time.Time
var startupTimeOnce sync.Once var startupTimeOnce sync.Once
func GetVersionTimestamp() time.Time { func GetVersionTimestamp() time.Time {
startupTimeOnce.Do(getStartTime(&startupTime, debug.ReadBuildInfo)) startupTimeOnce.Do(getStartTime(&startupTime, debug.ReadBuildInfo, time.Now))
return startupTime return startupTime
} }
func getStartTime(startupTime *time.Time, readBuildInfo func() (info *debug.BuildInfo, ok bool)) func() { func getStartTime(startupTime *time.Time, readBuildInfo func() (info *debug.BuildInfo, ok bool), clock func() time.Time) func() {
return func() { return func() {
info, ok := readBuildInfo() info, ok := readBuildInfo()
if !ok { if !ok {
*startupTime = time.Now().UTC() *startupTime = clock()
return return
} }
@@ -52,7 +52,7 @@ func getStartTime(startupTime *time.Time, readBuildInfo func() (info *debug.Buil
} }
// Return current time if no build time found // Return current time if no build time found
*startupTime = time.Now().UTC() *startupTime = clock()
} }
} }
+27 -7
View File
@@ -51,27 +51,30 @@ func TestGetVersionTimestamp(t *testing.T) {
} }
func TestGetStartTime(t *testing.T) { func TestGetStartTime(t *testing.T) {
injectedTime := time.Now().UTC()
injectTime := func() time.Time {
return injectedTime
}
vcsTime := time.Now().UTC()
t.Run("vcs time", func(t *testing.T) { t.Run("vcs time", func(t *testing.T) {
var tt time.Time var tt time.Time
expectedTime := time.Now().UTC()
f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) { f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) {
return &debug.BuildInfo{ return &debug.BuildInfo{
Settings: []debug.BuildSetting{ Settings: []debug.BuildSetting{
{ {
Key: "vcs.time", Key: "vcs.time",
Value: expectedTime.Format(time.RFC3339), Value: vcsTime.Format(time.RFC3339),
}, },
}, },
}, true }, true
}) }, injectTime)
assert.NotNil(t, f) assert.NotNil(t, f)
f() f()
assert.Equal(t, expectedTime.Truncate(time.Second), tt) assert.Equal(t, vcsTime.Truncate(time.Second), tt)
}) })
t.Run("vcs time - invalid format", func(t *testing.T) { t.Run("vcs time - invalid format", func(t *testing.T) {
var tt time.Time var tt time.Time
// to make the test less likely to fail due to non deterministic temporal issues. // to make the test less likely to fail due to non deterministic temporal issues.
expectedTime := time.Now().UTC().Add(-time.Millisecond)
f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) { f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) {
return &debug.BuildInfo{ return &debug.BuildInfo{
Settings: []debug.BuildSetting{ Settings: []debug.BuildSetting{
@@ -81,10 +84,27 @@ func TestGetStartTime(t *testing.T) {
}, },
}, },
}, true }, true
}) }, injectTime)
assert.NotNil(t, f) assert.NotNil(t, f)
f() f()
assert.True(t, expectedTime.Before(tt)) assert.Equal(t, injectedTime, tt)
})
t.Run("vcs time - not available", func(t *testing.T) {
var tt time.Time
// to make the test less likely to fail due to non deterministic temporal issues.
f := getStartTime(&tt, func() (info *debug.BuildInfo, ok bool) {
return &debug.BuildInfo{
Settings: []debug.BuildSetting{
{
Key: "vcs.time",
Value: "invalid",
},
},
}, true
}, injectTime)
assert.NotNil(t, f)
f()
assert.Equal(t, injectedTime, tt)
}) })
} }