trpc.group/trpc-go/trpc-go@v1.0.3/rpcz/config_test.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 package rpcz_test 15 16 import ( 17 "errors" 18 "testing" 19 "time" 20 21 "github.com/stretchr/testify/require" 22 23 "trpc.group/trpc-go/trpc-go/rpcz" 24 ) 25 26 func TestRPCZ_ShouldRecord(t *testing.T) { 27 t.Run("checking ID", func(t *testing.T) { 28 r := rpcz.NewRPCZ(&rpcz.Config{ 29 Fraction: 1.0, 30 Capacity: 1, 31 ShouldRecord: func(s rpcz.Span) bool { 32 return s.ID()%2 == 0 33 }, 34 }) 35 s, ender := r.NewChild("") 36 id := s.ID() 37 ender.End() 38 readOnlySpan, ok := r.Query(id) 39 if id%2 == 0 { 40 require.True(t, ok) 41 require.Equal(t, id, readOnlySpan.ID) 42 } else { 43 require.False(t, ok) 44 } 45 }) 46 t.Run("checking Attribute", func(t *testing.T) { 47 const attributeName = "Error" 48 attributeValue := errors.New("test error") 49 r := rpcz.NewRPCZ(&rpcz.Config{ 50 Fraction: 1.0, 51 Capacity: 1, 52 ShouldRecord: func(s rpcz.Span) bool { 53 if err, ok := s.Attribute(attributeName); ok { 54 err, ok := err.(error) 55 return ok && err != nil 56 } 57 return false 58 }, 59 }) 60 s, ender := r.NewChild("") 61 id := s.ID() 62 s.SetAttribute(attributeName, attributeValue) 63 ender.End() 64 readOnlySpan, _ := r.Query(id) 65 require.Contains(t, readOnlySpan.Attributes, rpcz.Attribute{Name: attributeName, Value: attributeValue}) 66 67 s, ender = r.NewChild("") 68 id = s.ID() 69 ender.End() 70 _, ok := r.Query(id) 71 require.False(t, ok) 72 }) 73 t.Run("checking StartTime and EndTime", func(t *testing.T) { 74 const maxDuration = 100 * time.Millisecond 75 r := rpcz.NewRPCZ(&rpcz.Config{ 76 Fraction: 1.0, 77 Capacity: 1, 78 ShouldRecord: func(s rpcz.Span) bool { 79 return s.EndTime().Sub(s.StartTime()) > maxDuration 80 }, 81 }) 82 s, ender := r.NewChild("slow one") 83 id := s.ID() 84 // to mimic some time-consuming operation. 85 time.Sleep(150 * time.Millisecond) 86 ender.End() 87 readOnlySpan, _ := r.Query(id) 88 require.Contains(t, readOnlySpan.Name, "slow one") 89 90 s, ender = r.NewChild("fast one") 91 id = s.ID() 92 ender.End() 93 _, ok := r.Query(id) 94 require.False(t, ok) 95 }) 96 t.Run("checking Events", func(t *testing.T) { 97 const specialEvent = "leave func" 98 r := rpcz.NewRPCZ(&rpcz.Config{ 99 Fraction: 1.0, 100 Capacity: 1, 101 ShouldRecord: func(s rpcz.Span) bool { 102 _, ok := s.Event(specialEvent) 103 return ok 104 }, 105 }) 106 s, ender := r.NewChild("doesn't contain special event") 107 id := s.ID() 108 s.AddEvent("enter func") 109 ender.End() 110 _, ok := r.Query(id) 111 require.False(t, ok) 112 113 s, ender = r.NewChild("contain special event") 114 id = s.ID() 115 s.AddEvent(specialEvent) 116 ender.End() 117 readOnlySpan, _ := r.Query(id) 118 require.Equal(t, specialEvent, readOnlySpan.Events[0].Name) 119 }) 120 }