111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package runtimeinfo
|
|
|
|
import (
|
|
"runtime/debug"
|
|
"sync"
|
|
"sync/atomic"
|
|
"testing"
|
|
)
|
|
|
|
func TestVersion(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
injected string
|
|
info *debug.BuildInfo
|
|
ok bool
|
|
want string
|
|
}{
|
|
{
|
|
name: "injected version takes precedence",
|
|
injected: "v1.2.3",
|
|
info: &debug.BuildInfo{Main: debug.Module{Version: "v4.5.6"}},
|
|
ok: true,
|
|
want: "v1.2.3",
|
|
},
|
|
{
|
|
name: "main module version",
|
|
info: &debug.BuildInfo{Main: debug.Module{Version: "v4.5.6"}},
|
|
ok: true,
|
|
want: "v4.5.6",
|
|
},
|
|
{
|
|
name: "missing build information",
|
|
want: "dev",
|
|
},
|
|
{
|
|
name: "development main module",
|
|
info: &debug.BuildInfo{Main: debug.Module{Version: "(devel)"}},
|
|
ok: true,
|
|
want: "dev",
|
|
},
|
|
{
|
|
name: "empty main module version",
|
|
info: &debug.BuildInfo{Main: debug.Module{}},
|
|
ok: true,
|
|
want: "dev",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
got := version(test.injected, func() (*debug.BuildInfo, bool) {
|
|
return test.info, test.ok
|
|
})
|
|
if got != test.want {
|
|
t.Fatalf("version() = %q, want %q", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFallbackVersionReadsMetadataOnceConcurrently(t *testing.T) {
|
|
var reads atomic.Int32
|
|
fallback := newFallbackVersion(func() (*debug.BuildInfo, bool) {
|
|
reads.Add(1)
|
|
return &debug.BuildInfo{Main: debug.Module{Version: "v4.5.6"}}, true
|
|
})
|
|
|
|
const callers = 32
|
|
results := make(chan string, callers)
|
|
var workers sync.WaitGroup
|
|
workers.Add(callers)
|
|
for i := 0; i < callers; i++ {
|
|
go func() {
|
|
defer workers.Done()
|
|
results <- fallback()
|
|
}()
|
|
}
|
|
workers.Wait()
|
|
close(results)
|
|
for result := range results {
|
|
if result != "v4.5.6" {
|
|
t.Errorf("fallback() = %q, want stable version", result)
|
|
}
|
|
}
|
|
if got := reads.Load(); got != 1 {
|
|
t.Fatalf("metadata reader called %d times, want once", got)
|
|
}
|
|
}
|
|
|
|
func TestFallbackVersionCachesUnavailableAndDevelopmentMetadata(t *testing.T) {
|
|
for _, test := range []struct {
|
|
name string
|
|
read func() (*debug.BuildInfo, bool)
|
|
}{
|
|
{name: "unavailable", read: func() (*debug.BuildInfo, bool) { return nil, false }},
|
|
{name: "development", read: func() (*debug.BuildInfo, bool) {
|
|
return &debug.BuildInfo{Main: debug.Module{Version: "(devel)"}}, true
|
|
}},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
fallback := newFallbackVersion(test.read)
|
|
if got := fallback(); got != "dev" {
|
|
t.Fatalf("fallback() = %q, want dev", got)
|
|
}
|
|
if got := fallback(); got != "dev" {
|
|
t.Fatalf("repeated fallback() = %q, want dev", got)
|
|
}
|
|
})
|
|
}
|
|
}
|