github.com/matrixorigin/matrixone@v1.2.0/pkg/util/trace/config_test.go (about) 1 // Copyright 2022 Matrix Origin 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 trace 16 17 import ( 18 "testing" 19 "time" 20 21 "github.com/stretchr/testify/assert" 22 "github.com/stretchr/testify/require" 23 ) 24 25 var _1TraceID TraceID = [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1} 26 var _1SpanID SpanID = [8]byte{0, 0, 0, 0, 0, 0, 0, 1} 27 28 func TestTraceID_IsZero(t *testing.T) { 29 tests := []struct { 30 name string 31 t TraceID 32 want bool 33 }{ 34 { 35 name: "normal", 36 t: _1TraceID, 37 want: false, 38 }, 39 { 40 name: "nil", 41 t: NilTraceID, 42 want: true, 43 }, 44 } 45 for _, tt := range tests { 46 t.Run(tt.name, func(t *testing.T) { 47 assert.Equalf(t, tt.want, tt.t.IsZero(), "IsZero()") 48 }) 49 } 50 } 51 52 func TestSpanID_SetByUUID_IsZero(t *testing.T) { 53 type args struct { 54 id string 55 } 56 tests := []struct { 57 name string 58 s SpanID 59 args args 60 wantZero bool 61 }{ 62 { 63 name: "normal", 64 args: args{id: "node_uuid"}, 65 wantZero: false, 66 }, 67 { 68 name: "short", 69 args: args{id: "1234"}, 70 wantZero: false, 71 }, 72 { 73 name: "nil", 74 args: args{id: "00000000-0000-0000-0000-000000000000"}, 75 wantZero: true, 76 }, 77 } 78 for _, tt := range tests { 79 t.Run(tt.name, func(t *testing.T) { 80 tt.s.SetByUUID(tt.args.id) 81 t.Logf("SpanID: %s", tt.s.String()) 82 require.Equal(t, tt.wantZero, tt.s.IsZero()) 83 }) 84 } 85 } 86 87 func TestSpanContext_IsEmpty(t *testing.T) { 88 type fields struct { 89 TraceID TraceID 90 SpanID SpanID 91 } 92 tests := []struct { 93 name string 94 fields fields 95 want bool 96 }{ 97 { 98 name: "normal", 99 fields: fields{ 100 TraceID: _1TraceID, 101 SpanID: _1SpanID, 102 }, 103 want: false, 104 }, 105 { 106 name: "nilTraceID", 107 fields: fields{ 108 TraceID: NilTraceID, 109 SpanID: _1SpanID, 110 }, 111 want: false, 112 }, 113 { 114 name: "nilSpanID", 115 fields: fields{ 116 TraceID: _1TraceID, 117 SpanID: NilSpanID, 118 }, 119 want: false, 120 }, 121 { 122 name: "nil", 123 fields: fields{ 124 TraceID: NilTraceID, 125 SpanID: NilSpanID, 126 }, 127 want: true, 128 }, 129 } 130 for _, tt := range tests { 131 t.Run(tt.name, func(t *testing.T) { 132 c := &SpanContext{ 133 TraceID: tt.fields.TraceID, 134 SpanID: tt.fields.SpanID, 135 } 136 assert.Equalf(t, tt.want, c.IsEmpty(), "IsEmpty()") 137 }) 138 } 139 } 140 141 func TestSpanConfig_ProfileRuntime(t *testing.T) { 142 type fields struct { 143 goroutine bool 144 heap bool 145 alloc bool 146 threadCreate bool 147 block bool 148 mutex bool 149 } 150 tests := []struct { 151 name string 152 fields fields 153 prepare func(*SpanConfig) 154 need bool 155 }{ 156 { 157 name: "goroutinue", 158 fields: fields{goroutine: true, heap: false, alloc: false, threadCreate: false, block: false, mutex: false}, 159 need: true, 160 }, 161 { 162 name: "heap", 163 fields: fields{goroutine: false, heap: true, alloc: false, threadCreate: false, block: false, mutex: false}, 164 need: true, 165 }, 166 { 167 name: "alloc", 168 fields: fields{goroutine: false, heap: false, alloc: true, threadCreate: false, block: false, mutex: false}, 169 need: true, 170 }, 171 { 172 name: "threadcreate", 173 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: true, block: false, mutex: false}, 174 need: true, 175 }, 176 { 177 name: "block", 178 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: false, block: true, mutex: false}, 179 need: true, 180 }, 181 { 182 name: "mutex", 183 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: false, block: false, mutex: true}, 184 need: true, 185 }, 186 { 187 name: "cpu", 188 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: false, block: false, mutex: false}, 189 prepare: func(c *SpanConfig) { 190 WithProfileCpuSecs(time.Millisecond).ApplySpanStart(c) 191 }, 192 need: true, 193 }, 194 { 195 name: "trace", 196 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: false, block: false, mutex: false}, 197 prepare: func(c *SpanConfig) { 198 WithProfileTraceSecs(time.Millisecond).ApplySpanStart(c) 199 }, 200 need: true, 201 }, 202 { 203 name: "trace_cpu", 204 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: false, block: false, mutex: false}, 205 prepare: func(c *SpanConfig) { 206 WithProfileTraceSecs(time.Millisecond).ApplySpanStart(c) 207 WithProfileCpuSecs(time.Millisecond).ApplySpanStart(c) 208 }, 209 need: true, 210 }, 211 { 212 name: "no_need", 213 fields: fields{goroutine: false, heap: false, alloc: false, threadCreate: false, block: false, mutex: false}, 214 prepare: nil, 215 need: false, 216 }, 217 } 218 for _, tt := range tests { 219 t.Run(tt.name, func(t *testing.T) { 220 c := &SpanConfig{} 221 if tt.fields.goroutine { 222 WithProfileGoroutine().ApplySpanStart(c) 223 } 224 if tt.fields.heap { 225 WithProfileHeap().ApplySpanStart(c) 226 } 227 if tt.fields.alloc { 228 WithProfileAllocs().ApplySpanStart(c) 229 } 230 if tt.fields.threadCreate { 231 WithProfileThreadCreate().ApplySpanStart(c) 232 } 233 if tt.fields.block { 234 WithProfileBlock().ApplySpanStart(c) 235 } 236 if tt.fields.mutex { 237 WithProfileMutex().ApplySpanStart(c) 238 } 239 if tt.prepare != nil { 240 tt.prepare(c) 241 } 242 assert.Equal(t, tt.fields.goroutine, c.ProfileGoroutine()) 243 assert.Equal(t, tt.fields.heap, c.ProfileHeap()) 244 assert.Equal(t, tt.fields.alloc, c.ProfileAllocs()) 245 assert.Equal(t, tt.fields.threadCreate, c.ProfileThreadCreate()) 246 assert.Equal(t, tt.fields.block, c.ProfileBlock()) 247 assert.Equal(t, tt.fields.mutex, c.ProfileMutex()) 248 assert.Equal(t, tt.need, c.NeedProfile()) 249 }) 250 } 251 } 252 253 func TestSpanConfig_Reset(t *testing.T) { 254 type fields struct { 255 SpanContext SpanContext 256 NewRoot bool 257 Parent Span 258 LongTimeThreshold time.Duration 259 profileFlag uint64 260 profileCpuDur time.Duration 261 profileTraceDur time.Duration 262 hungThreshold time.Duration 263 } 264 tests := []struct { 265 name string 266 fields fields 267 }{ 268 { 269 name: "reset", 270 fields: fields{ 271 SpanContext: SpanContext{ 272 TraceID: TraceID{}, 273 SpanID: SpanID{}, 274 Kind: 1, 275 }, 276 NewRoot: false, 277 Parent: NoopSpan{}, 278 LongTimeThreshold: 1, 279 profileFlag: 2, 280 profileCpuDur: 3, 281 profileTraceDur: 4, 282 hungThreshold: 5, 283 }, 284 }, 285 } 286 for _, tt := range tests { 287 t.Run(tt.name, func(t *testing.T) { 288 c := &SpanConfig{ 289 SpanContext: tt.fields.SpanContext, 290 NewRoot: tt.fields.NewRoot, 291 Parent: tt.fields.Parent, 292 LongTimeThreshold: tt.fields.LongTimeThreshold, 293 profileFlag: tt.fields.profileFlag, 294 profileCpuDur: tt.fields.profileCpuDur, 295 profileTraceDur: tt.fields.profileTraceDur, 296 hungThreshold: tt.fields.hungThreshold, 297 } 298 c.Reset() 299 require.Equal(t, &SpanConfig{}, c) 300 }) 301 } 302 }