aboutsummaryrefslogtreecommitdiffstats
path: root/modules/gtprof/trace_test.go
blob: 0f4e3facba0e11ec3b6dfc8c4eb6528ca410db2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gtprof

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
)

// "vendor span" is a simple demo for a span from a vendor library

var vendorContextKey any = "vendorContextKey"

type vendorSpan struct {
	name     string
	children []*vendorSpan
}

func vendorTraceStart(ctx context.Context, name string) (context.Context, *vendorSpan) {
	span := &vendorSpan{name: name}
	parentSpan, ok := ctx.Value(vendorContextKey).(*vendorSpan)
	if ok {
		parentSpan.children = append(parentSpan.children, span)
	}
	ctx = context.WithValue(ctx, vendorContextKey, span)
	return ctx, span
}

// below "testTrace*" integrate the vendor span into our trace system

type testTraceSpan struct {
	vendorSpan *vendorSpan
}

func (t *testTraceSpan) addEvent(name string, cfg *EventConfig) {}

func (t *testTraceSpan) recordError(err error, cfg *EventConfig) {}

func (t *testTraceSpan) end() {}

type testTraceStarter struct{}

func (t *testTraceStarter) start(ctx context.Context, traceSpan *TraceSpan, internalSpanIdx int) (context.Context, traceSpanInternal) {
	ctx, span := vendorTraceStart(ctx, traceSpan.name)
	return ctx, &testTraceSpan{span}
}

func TestTraceStarter(t *testing.T) {
	globalTraceStarters = []traceStarter{&testTraceStarter{}}

	ctx := t.Context()
	ctx, span := GetTracer().Start(ctx, "root")
	defer span.End()

	func(ctx context.Context) {
		ctx, span := GetTracer().Start(ctx, "span1")
		defer span.End()
		func(ctx context.Context) {
			_, span := GetTracer().Start(ctx, "spanA")
			defer span.End()
		}(ctx)
		func(ctx context.Context) {
			_, span := GetTracer().Start(ctx, "spanB")
			defer span.End()
		}(ctx)
	}(ctx)

	func(ctx context.Context) {
		_, span := GetTracer().Start(ctx, "span2")
		defer span.End()
	}(ctx)

	var spanFullNames []string
	var collectSpanNames func(parentFullName string, s *vendorSpan)
	collectSpanNames = func(parentFullName string, s *vendorSpan) {
		fullName := parentFullName + "/" + s.name
		spanFullNames = append(spanFullNames, fullName)
		for _, c := range s.children {
			collectSpanNames(fullName, c)
		}
	}
	collectSpanNames("", span.internalSpans[0].(*testTraceSpan).vendorSpan)
	assert.Equal(t, []string{
		"/root",
		"/root/span1",
		"/root/span1/spanA",
		"/root/span1/spanB",
		"/root/span2",
	}, spanFullNames)
}