1
0
mirror of https://github.com/distribution/distribution synced 2024-11-12 05:45:51 +01:00
distribution/internal/dcontext/trace_test.go
Milos Gajdos b3681c4cd3
feat: add tparallel linter to improve handling parallel tests
This linter both prevents parallel test races as well as
suggests parallel tests where appropriate:
See: https://github.com/moricho/tparallel

Signed-off-by: Milos Gajdos <milosthegajdos@gmail.com>
2023-11-29 21:40:20 +00:00

104 lines
2.1 KiB
Go

package dcontext
import (
"runtime"
"testing"
"time"
)
// TestWithTrace ensures that tracing has the expected values in the context.
func TestWithTrace(t *testing.T) {
t.Parallel()
pc, file, _, _ := runtime.Caller(0) // get current caller.
f := runtime.FuncForPC(pc)
base := []valueTestCase{
{
key: "trace.id",
notnilorempty: true,
},
{
key: "trace.file",
expected: file,
notnilorempty: true,
},
{
key: "trace.line",
notnilorempty: true,
},
{
key: "trace.start",
notnilorempty: true,
},
}
ctx, done := WithTrace(Background())
t.Cleanup(func() { done("this will be emitted at end of test") })
tests := append(base, valueTestCase{
key: "trace.func",
expected: f.Name(),
})
for _, tc := range tests {
tc := tc
t.Run(tc.key, func(t *testing.T) {
t.Parallel()
v := ctx.Value(tc.key)
if tc.notnilorempty {
if v == nil || v == "" {
t.Fatalf("value was nil or empty: %#v", v)
}
return
}
if v != tc.expected {
t.Fatalf("unexpected value: %v != %v", v, tc.expected)
}
})
}
tracedFn := func() {
parentID := ctx.Value("trace.id") // ensure the parent trace id is correct.
pc, _, _, _ := runtime.Caller(0) // get current caller.
f := runtime.FuncForPC(pc)
ctx, done := WithTrace(ctx)
defer done("this should be subordinate to the other trace")
time.Sleep(time.Second)
tests := append(base, valueTestCase{
key: "trace.func",
expected: f.Name(),
}, valueTestCase{
key: "trace.parent.id",
expected: parentID,
})
for _, tc := range tests {
tc := tc
t.Run(tc.key, func(t *testing.T) {
t.Parallel()
v := ctx.Value(tc.key)
if tc.notnilorempty {
if v == nil || v == "" {
t.Fatalf("value was nil or empty: %#v", v)
}
return
}
if v != tc.expected {
t.Fatalf("unexpected value: %v != %v", v, tc.expected)
}
})
}
}
tracedFn()
time.Sleep(time.Second)
}
type valueTestCase struct {
key string
expected interface{}
notnilorempty bool // just check not empty/not nil
}