|
|
|
package trace
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestSpan(t *testing.T) {
|
|
|
|
report := &mockReport{}
|
|
|
|
t1 := NewTracer("service1", report, true)
|
|
|
|
t.Run("test span string", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfinish").(*Span)
|
|
|
|
assert.NotEmpty(t, fmt.Sprint(sp1))
|
|
|
|
})
|
|
|
|
t.Run("test fork", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfork").(*Span)
|
|
|
|
sp2 := sp1.Fork("xxx", "opt_2").(*Span)
|
|
|
|
assert.Equal(t, sp1.context.TraceID, sp2.context.TraceID)
|
|
|
|
assert.Equal(t, sp1.context.SpanID, sp2.context.ParentID)
|
|
|
|
t.Run("test max fork", func(t *testing.T) {
|
|
|
|
sp3 := sp2.Fork("xx", "xxx")
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
sp3 = sp3.Fork("", "xxx")
|
|
|
|
}
|
|
|
|
assert.Equal(t, noopspan{}, sp3)
|
|
|
|
})
|
|
|
|
t.Run("test max childs", func(t *testing.T) {
|
|
|
|
sp3 := sp2.Fork("xx", "xxx")
|
|
|
|
for i := 0; i < 4096; i++ {
|
|
|
|
sp3.Fork("", "xxx")
|
|
|
|
}
|
|
|
|
assert.Equal(t, noopspan{}, sp3.Fork("xx", "xx"))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
t.Run("test finish", func(t *testing.T) {
|
|
|
|
t.Run("test finish ok", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfinish").(*Span)
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
sp1.Finish(nil)
|
|
|
|
assert.True(t, sp1.startTime.Unix() > 0)
|
|
|
|
assert.True(t, sp1.duration > time.Microsecond)
|
|
|
|
})
|
|
|
|
t.Run("test finish error", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfinish").(*Span)
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
err := fmt.Errorf("🍻")
|
|
|
|
sp1.Finish(&err)
|
|
|
|
assert.True(t, sp1.startTime.Unix() > 0)
|
|
|
|
assert.True(t, sp1.duration > time.Microsecond)
|
|
|
|
errorTag := false
|
|
|
|
for _, tag := range sp1.tags {
|
|
|
|
if tag.Key == TagError && tag.Value != nil {
|
|
|
|
errorTag = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert.True(t, errorTag)
|
|
|
|
messageLog := false
|
|
|
|
for _, log := range sp1.logs {
|
|
|
|
assert.True(t, log.Timestamp != 0)
|
|
|
|
for _, field := range log.Fields {
|
|
|
|
if field.Key == LogMessage && len(field.Value) != 0 {
|
|
|
|
messageLog = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert.True(t, messageLog)
|
|
|
|
})
|
|
|
|
t.Run("test finish error stack", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfinish").(*Span)
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
err := fmt.Errorf("🍻")
|
|
|
|
err = errors.WithStack(err)
|
|
|
|
sp1.Finish(&err)
|
|
|
|
ok := false
|
|
|
|
for _, log := range sp1.logs {
|
|
|
|
for _, field := range log.Fields {
|
|
|
|
if field.Key == LogStack && len(field.Value) != 0 {
|
|
|
|
ok = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert.True(t, ok, "LogStack set")
|
|
|
|
})
|
|
|
|
t.Run("test too many tags", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfinish").(*Span)
|
|
|
|
for i := 0; i < 1024; i++ {
|
|
|
|
sp1.SetTag(Tag{Key: strconv.Itoa(i), Value: "hello"})
|
|
|
|
}
|
|
|
|
assert.Len(t, sp1.tags, _maxTags+1)
|
|
|
|
assert.Equal(t, sp1.tags[_maxTags].Key, "trace.error")
|
|
|
|
assert.Equal(t, sp1.tags[_maxTags].Value, "too many tags")
|
|
|
|
})
|
|
|
|
t.Run("test too many logs", func(t *testing.T) {
|
|
|
|
sp1 := t1.New("testfinish").(*Span)
|
|
|
|
for i := 0; i < 1024; i++ {
|
|
|
|
sp1.SetLog(LogField{Key: strconv.Itoa(i), Value: "hello"})
|
|
|
|
}
|
|
|
|
assert.Len(t, sp1.logs, _maxLogs+1)
|
|
|
|
assert.Equal(t, sp1.logs[_maxLogs].Fields[0].Key, "trace.error")
|
|
|
|
assert.Equal(t, sp1.logs[_maxLogs].Fields[0].Value, []byte("too many logs"))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|