Skip to content

Commit dff0bd6

Browse files
huhong-webhao022
authored andcommitted
test(pkg/tracing): add unit testing
1 parent e93aa37 commit dff0bd6

File tree

3 files changed

+646
-0
lines changed

3 files changed

+646
-0
lines changed

pkg/tracing/manager_test.go

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
// Copyright 2026 The HuaTuo Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package tracing
16+
17+
import (
18+
"context"
19+
"strings"
20+
"sync"
21+
"testing"
22+
"time"
23+
24+
pkgtypes "huatuo-bamai/pkg/types"
25+
)
26+
27+
type stubEvent struct {
28+
startFunc func(ctx context.Context) error
29+
}
30+
31+
func (s *stubEvent) Start(ctx context.Context) error {
32+
return s.startFunc(ctx)
33+
}
34+
35+
func waitCancelReady(te *EventTracing) bool {
36+
for range 50 {
37+
if te.cancelCtx != nil {
38+
return true
39+
}
40+
time.Sleep(5 * time.Millisecond)
41+
}
42+
return false
43+
}
44+
45+
func TestNewMgrTracingEvent(t *testing.T) {
46+
resetRegisterState()
47+
t.Cleanup(resetRegisterState)
48+
49+
newAttr := func(flag uint32) *EventTracingAttr {
50+
return &EventTracingAttr{
51+
Flag: flag,
52+
Interval: 1,
53+
TracingData: &stubEvent{startFunc: func(context.Context) error { return nil }},
54+
}
55+
}
56+
57+
RegisterEventTracing("trace_only", func() (*EventTracingAttr, error) {
58+
return newAttr(FlagTracing), nil
59+
})
60+
RegisterEventTracing("metric_only", func() (*EventTracingAttr, error) {
61+
return newAttr(FlagMetric), nil
62+
})
63+
64+
mgr, err := NewMgrTracingEvent(nil)
65+
if err != nil {
66+
t.Errorf("NewMgrTracingEvent() error=%v", err)
67+
return
68+
}
69+
70+
if got, want := len(mgr.tracingEvents), 1; got != want {
71+
t.Errorf("tracingEvents len=%d, want %d", got, want)
72+
return
73+
}
74+
75+
if _, ok := mgr.tracingEvents["trace_only"]; !ok {
76+
t.Errorf("trace_only should be included in manager")
77+
return
78+
}
79+
80+
if _, ok := mgr.tracingEvents["metric_only"]; ok {
81+
t.Errorf("metric_only should not be included in tracing manager")
82+
}
83+
}
84+
85+
func TestMgrTracingEventStart(t *testing.T) {
86+
tests := []struct {
87+
name string
88+
setup func() (*MgrTracingEvent, string)
89+
validate func(*testing.T, error)
90+
}{
91+
{
92+
name: "not found",
93+
setup: func() (*MgrTracingEvent, string) {
94+
return &MgrTracingEvent{tracingEvents: map[string]*EventTracing{}, blackListed: nil}, "trace-not-found"
95+
},
96+
validate: func(t *testing.T, err error) {
97+
if err == nil {
98+
t.Errorf("MgrTracingEventStart() error=nil, want non-nil")
99+
return
100+
}
101+
if !strings.Contains(err.Error(), "not found") {
102+
t.Errorf("MgrTracingEventStart() error=%q, want contain %q", err.Error(), "not found")
103+
}
104+
},
105+
},
106+
{
107+
name: "blacklisted",
108+
setup: func() (*MgrTracingEvent, string) {
109+
return &MgrTracingEvent{
110+
tracingEvents: map[string]*EventTracing{
111+
"trace-2026": {name: "trace-2026"},
112+
},
113+
blackListed: []string{"trace-2026"},
114+
}, "trace-2026"
115+
},
116+
validate: func(t *testing.T, err error) {
117+
if err == nil {
118+
t.Errorf("MgrTracingEventStart() error=nil, want non-nil")
119+
return
120+
}
121+
if !strings.Contains(err.Error(), "blackListed") {
122+
t.Errorf("MgrTracingEventStart() error=%q, want contain %q", err.Error(), "blackListed")
123+
}
124+
},
125+
},
126+
{
127+
name: "already running",
128+
setup: func() (*MgrTracingEvent, string) {
129+
return &MgrTracingEvent{
130+
tracingEvents: map[string]*EventTracing{
131+
"trace-2026": {name: "trace-2026", isRunning: true},
132+
},
133+
blackListed: nil,
134+
}, "trace-2026"
135+
},
136+
validate: func(t *testing.T, err error) {
137+
if err == nil {
138+
t.Errorf("MgrTracingEventStart() error=nil, want non-nil")
139+
return
140+
}
141+
if !strings.Contains(err.Error(), "already running") {
142+
t.Errorf("MgrTracingEventStart() error=%q, want contain %q", err.Error(), "already running")
143+
}
144+
},
145+
},
146+
}
147+
148+
for i := range tests {
149+
t.Run(tests[i].name, func(t *testing.T) {
150+
mgr, targetName := tests[i].setup()
151+
err := mgr.MgrTracingEventStart(targetName)
152+
tests[i].validate(t, err)
153+
})
154+
}
155+
}
156+
157+
func TestMgrTracingEventStartAndStopSuccess(t *testing.T) {
158+
te := &EventTracing{
159+
ic: &stubEvent{
160+
startFunc: func(ctx context.Context) error {
161+
<-ctx.Done()
162+
return pkgtypes.ErrExitByCancelCtx
163+
},
164+
},
165+
name: "trace-2026",
166+
interval: 1,
167+
}
168+
mgr := &MgrTracingEvent{
169+
tracingEvents: map[string]*EventTracing{"trace-2026": te},
170+
blackListed: nil,
171+
mu: sync.Mutex{},
172+
}
173+
174+
startErr := mgr.MgrTracingEventStart("trace-2026")
175+
if startErr != nil {
176+
t.Errorf("MgrTracingEventStart() error=%v", startErr)
177+
return
178+
}
179+
180+
if !waitCancelReady(te) {
181+
t.Errorf("cancelCtx was not initialized in time")
182+
return
183+
}
184+
185+
stopErr := mgr.MgrTracingEventStop("trace-2026")
186+
if stopErr != nil {
187+
t.Errorf("MgrTracingEventStop() error=%v", stopErr)
188+
}
189+
}
190+
191+
func TestMgrTracingEventStop(t *testing.T) {
192+
tests := []struct {
193+
name string
194+
setup func() (*MgrTracingEvent, string)
195+
validate func(*testing.T, error)
196+
}{
197+
{
198+
name: "not found",
199+
setup: func() (*MgrTracingEvent, string) {
200+
return &MgrTracingEvent{tracingEvents: map[string]*EventTracing{}}, "trace-not-found"
201+
},
202+
validate: func(t *testing.T, err error) {
203+
if err == nil {
204+
t.Errorf("MgrTracingEventStop() error=nil, want non-nil")
205+
return
206+
}
207+
if !strings.Contains(err.Error(), "not found") {
208+
t.Errorf("MgrTracingEventStop() error=%q, want contain %q", err.Error(), "not found")
209+
}
210+
},
211+
},
212+
{
213+
name: "not running",
214+
setup: func() (*MgrTracingEvent, string) {
215+
return &MgrTracingEvent{
216+
tracingEvents: map[string]*EventTracing{
217+
"trace-2026": {name: "trace-2026", isRunning: false},
218+
},
219+
}, "trace-2026"
220+
},
221+
validate: func(t *testing.T, err error) {
222+
if err == nil {
223+
t.Errorf("MgrTracingEventStop() error=nil, want non-nil")
224+
return
225+
}
226+
if !strings.Contains(err.Error(), "not running") {
227+
t.Errorf("MgrTracingEventStop() error=%q, want contain %q", err.Error(), "not running")
228+
}
229+
},
230+
},
231+
{
232+
name: "running",
233+
setup: func() (*MgrTracingEvent, string) {
234+
return &MgrTracingEvent{
235+
tracingEvents: map[string]*EventTracing{
236+
"trace-2026": {name: "trace-2026", isRunning: true, cancelCtx: func() {}},
237+
},
238+
}, "trace-2026"
239+
},
240+
validate: func(t *testing.T, err error) {
241+
if err != nil {
242+
t.Errorf("MgrTracingEventStop() error=%v, want nil", err)
243+
}
244+
},
245+
},
246+
}
247+
248+
for i := range tests {
249+
t.Run(tests[i].name, func(t *testing.T) {
250+
mgr, targetName := tests[i].setup()
251+
err := mgr.MgrTracingEventStop(targetName)
252+
tests[i].validate(t, err)
253+
})
254+
}
255+
}
256+
257+
func TestMgrTracingInfoDump(t *testing.T) {
258+
tests := []struct {
259+
nameKey string
260+
wantName string
261+
wantRun bool
262+
wantHit int
263+
wantIntvl int
264+
wantFlag uint32
265+
}{
266+
{nameKey: "trace-2026", wantName: "trace-2026", wantRun: true, wantHit: 3, wantIntvl: 2, wantFlag: FlagTracing},
267+
{nameKey: "trace-2027", wantName: "trace-2027", wantRun: false, wantHit: 1, wantIntvl: 5, wantFlag: FlagMetric | FlagTracing},
268+
}
269+
270+
mgr := &MgrTracingEvent{
271+
tracingEvents: map[string]*EventTracing{},
272+
}
273+
for i := range tests {
274+
mgr.tracingEvents[tests[i].nameKey] = &EventTracing{
275+
name: tests[i].wantName,
276+
isRunning: tests[i].wantRun,
277+
hitCount: tests[i].wantHit,
278+
interval: tests[i].wantIntvl,
279+
flag: tests[i].wantFlag,
280+
}
281+
}
282+
283+
info := mgr.MgrTracingInfoDump()
284+
if len(info) != len(tests) {
285+
t.Errorf("MgrTracingInfoDump len=%d, want %d", len(info), len(tests))
286+
return
287+
}
288+
289+
for i := range tests {
290+
t.Run(tests[i].nameKey, func(t *testing.T) {
291+
got := info[tests[i].nameKey]
292+
if got == nil {
293+
t.Errorf("info[%q]=nil, want non-nil", tests[i].nameKey)
294+
return
295+
}
296+
if got.Name != tests[i].wantName {
297+
t.Errorf("info[%q].Name=%q, want %q", tests[i].nameKey, got.Name, tests[i].wantName)
298+
}
299+
if got.Running != tests[i].wantRun {
300+
t.Errorf("info[%q].Running=%v, want %v", tests[i].nameKey, got.Running, tests[i].wantRun)
301+
}
302+
if got.HitCount != tests[i].wantHit {
303+
t.Errorf("info[%q].HitCount=%d, want %d", tests[i].nameKey, got.HitCount, tests[i].wantHit)
304+
}
305+
if got.Interval != tests[i].wantIntvl {
306+
t.Errorf("info[%q].Interval=%d, want %d", tests[i].nameKey, got.Interval, tests[i].wantIntvl)
307+
}
308+
if got.Flag != tests[i].wantFlag {
309+
t.Errorf("info[%q].Flag=%d, want %d", tests[i].nameKey, got.Flag, tests[i].wantFlag)
310+
}
311+
})
312+
}
313+
}

0 commit comments

Comments
 (0)