go.dedis.ch/onet/v3@v3.2.11-0.20210930124529-e36530bca7ef/tracing/trace_test.go (about) 1 package tracing 2 3 import ( 4 "context" 5 "fmt" 6 "sort" 7 "strings" 8 "testing" 9 10 "go.dedis.ch/onet/v3/log" 11 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestNewStackEntry(t *testing.T) { 16 for i, test := range []struct { 17 method string 18 file string 19 se stackEntry 20 err bool 21 }{ 22 {"runtime/debug.Stack(0x11953ba, 0x1089998, 0xad8eee637bfa)", 23 "/usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/stack." + 24 "go:24 +0xab", 25 stackEntry{ 26 24, "/usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/", 27 "stack.go", 28 "runtime/debug", "Stack", 29 "(0x11953ba, 0x1089998, 0xad8eee637bfa)", "", false, 30 }, false, 31 }, {"go.dedis.ch/onet/v3/log.Stack(...)", 32 "/home/foo/onet/log/testutil.go:105", 33 stackEntry{ 34 105, "/home/foo/onet/log/", 35 "testutil.go", 36 "go.dedis.ch/onet/v3/log", "Stack", 37 "(...)", "", false, 38 }, false, 39 }, {"go.dedis.ch/onet/v3/honeycomb.TestNewTrace(0xc0001b2200)", 40 "/home/foo/onet/honeycomb/trace_test.go:19", 41 stackEntry{ 42 line: 19, path: "/home/foo/onet" + 43 "/honeycomb/", file: "trace_test.go", 44 pkgPath: "go.dedis.ch/onet/v3/honeycomb", method: "TestNewTrace", 45 params: "(0xc0001b2200)", 46 }, false, 47 }, {"testing.tRunner", 48 "/usr/local/Cellar/go/1.13.3/libexec/src/testing/testing.go:909 +0x19a", 49 stackEntry{ 50 line: 909, path: "/usr/local/Cellar/go/1.13.3/libexec/src/testing/", 51 file: "testing.go", 52 pkgPath: "testing", method: "tRunner", params: "", 53 }, false, 54 }, {"created by testing.(*T).Run", 55 "/usr/local/Cellar/go/1.13.3/libexec/src/testing/testing.go:960 +0x652", 56 stackEntry{ 57 line: 960, path: "/usr/local/Cellar/go/1.13.3/libexec/src/testing/", 58 file: "testing.go", 59 pkgPath: "testing.(*T)", method: "Run", 60 params: "", createdBy: true, 61 }, false, 62 }, 63 {"created by testing.(*T).Run", 64 "/usr/local/Cellar/go/1.13.3/libexec/src/testing/testing.go:960 +0x652", 65 stackEntry{ 66 line: 960, path: "/usr/local/Cellar/go/1.13.3/libexec/src/testing/", 67 file: "testing.go", 68 pkgPath: "testing.(*T)", method: "Run", params: "", 69 createdBy: true, 70 }, false, 71 }, 72 {"created by testing.(*T).Run", 73 "/usr/local/Cellar/go/1.13.3/libexec/src/testing/testing.go", 74 stackEntry{createdBy: true}, true, 75 }, 76 {"created by testing", 77 "/usr/local/Cellar/go/1.13.3/libexec/src/testing/testing.go:960 +0x652", 78 stackEntry{createdBy: true}, true, 79 }, 80 { 81 "go.dedis.ch/onet/v3/honeycomb.(*oneStr).more.(*another).one(" + 82 "0x58fe970, 0xc0001f0410, 0x14)", 83 "/home/foo/onet/honeycomb/stack_test.go:32 +0x34", 84 stackEntry{32, "/home/foo/onet/honeycomb/", "stack_test.go", 85 "go.dedis.ch/onet/v3/honeycomb.(*oneStr).more.(*another)", 86 "one", "(0x58fe970, 0xc0001f0410, 0x14)", "", false, 87 }, false, 88 }, 89 } { 90 se, err := newStackEntry(test.method, test.file, "") 91 if test.err { 92 require.Error(t, err) 93 } else { 94 require.NoError(t, err) 95 require.Equal(t, test.se, se, fmt.Sprint("Failed for: ", i)) 96 } 97 } 98 } 99 100 func TestParseLogs(t *testing.T) { 101 for _, test := range []struct { 102 logs string 103 ses []stackEntry 104 }{ 105 { 106 `runtime/debug.Stack(0x11953ba, 0x1009c10, 0xc00004ff18) 107 /usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/stack.go:24 +0xab 108 go.dedis.ch/onet/v3/log.Stack(...) 109 /home/foo//onet/log/testutil.go:105`, 110 []stackEntry{ 111 {line: 105, path: "/home/foo//onet/log/", 112 file: "testutil.go", 113 pkgPath: "go.dedis.ch/onet/v3/log", method: "Stack", params: "(...)"}, 114 {line: 24, path: "/usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/", 115 file: "stack.go", 116 pkgPath: "runtime/debug", method: "Stack", 117 params: "(0x11953ba, 0x1009c10, 0xc00004ff18)"}, 118 }, 119 }, 120 { 121 `runtime/debug.Stack(0x11953ba, 0x1009c10, 0xc00004ff18) 122 /usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/stack.go:24 +0xab 123 /home/foo//onet/log/testutil.go:105`, 124 []stackEntry{ 125 {line: 24, path: "/usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/", 126 file: "stack.go", 127 pkgPath: "runtime/debug", method: "Stack", 128 params: "(0x11953ba, 0x1009c10, 0xc00004ff18)"}, 129 }, 130 }, 131 { 132 `runtime/debug.Stack(0x11953ba, 0x1009c10, 0xc00004ff18) 133 /usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/stack.go`, 134 nil, 135 }, 136 } { 137 ses := parseLogs("goroutine t [test]\n"+test.logs, map[string]string{}) 138 for s := range test.ses { 139 test.ses[s].traceID = "go_t" 140 } 141 require.Equal(t, test.ses, ses, fmt.Sprintf("logs: %s\nses: %+v", 142 test.logs, test.ses)) 143 } 144 } 145 146 func simpleSe(path ...string) (ses []stackEntry) { 147 for _, p := range path { 148 ses = append(ses, stackEntry{method: p}) 149 } 150 return 151 } 152 153 func TestNewStacked(t *testing.T) { 154 ctx, hcTr := newSimulTrace(context.TODO(), "") 155 tr, _ := newTraceWrapper(ctx, hcTr, simpleSe("root")) 156 stack1 := simpleSe("root", "one") 157 stack12 := simpleSe("root", "one", "two") 158 stack2 := simpleSe("root", "two") 159 stack23 := simpleSe("root", "two", "three") 160 stack234 := simpleSe("root", "two", "three", "four") 161 tr.stackToSpan(stack1).log(1, "one-1") 162 tr.stackToSpan(stack12).log(1, "one/two-1") 163 tr.stackToSpan(stack12).log(1, "one/two-2") 164 tr.stackToSpan(stack1).log(1, "one-2") 165 tr.stackToSpan(stack2).log(1, "two-1") 166 tr.stackToSpan(stack23).log(1, "two/three-1") 167 tr.stackToSpan(stack2).log(1, "two-2") 168 tr.stackToSpan(stack23).log(1, "two/three-2") 169 tr.stackToSpan(stack234).log(1, "two/three-2/four") 170 tr.stackToSpan(stack2).log(1, "two-3") 171 tr.send() 172 testSentTrace(t, tr, 173 `log.Lvl:1;log.Msg:"one-1";method:"one"`, 174 `log.Lvl:1;log.Msg:"one/two-1";method:"two"`, 175 `log.Lvl:1;log.Msg:"one/two-2";method:"two"`, 176 `method:"two"`, 177 `log.Lvl:1;log.Msg:"one-2";method:"one"`, 178 `log.Lvl:1;log.Msg:"two-1";method:"two"`, 179 `log.Lvl:1;log.Msg:"two/three-1";method:"three"`, 180 `method:"three"`, 181 `log.Lvl:1;log.Msg:"two-2";method:"two"`, 182 `log.Lvl:1;log.Msg:"two/three-2";method:"three"`, 183 `log.Lvl:1;log.Msg:"two/three-2/four";method:"four"`, 184 `method:"four"`, 185 `method:"three"`, 186 `log.Lvl:1;log.Msg:"two-3";method:"two"`, 187 `method:"two"`, `method:"root"`) 188 } 189 190 func TestTraceWrapper_Add(t *testing.T) { 191 skv := &storeKVs{} 192 for _, test := range []struct { 193 val interface{} 194 kv map[string]string 195 }{ 196 {1, map[string]string{"base": "1"}}, 197 {ab{`"AA"`, 2}, 198 map[string]string{"base.A": `"AA"`, "base.B": "2"}}, 199 {struct { 200 C ab 201 D int 202 }{ab{"E", 3}, 2}, 203 map[string]string{ 204 "base.C.A": `"E"`, 205 "base.C.B": "3", 206 "base.D": "2"}}, 207 {struct{ D cab }{ 208 cab{ab{"CAB", 3}}}, 209 map[string]string{ 210 "base.D.C.A": `"CAB"`, 211 "base.D.C.B": "3"}}, 212 } { 213 skv.kvs = map[string]string{} 214 structToFields(skv.AddField, "base", test.val) 215 require.Equal(t, test.kv, skv.kvs) 216 } 217 } 218 219 type ab struct { 220 A string 221 B int 222 } 223 224 type cab struct { 225 C ab 226 } 227 228 func TestMerge(t *testing.T) { 229 for _, tms := range testMergeStack[1:] { 230 ctx, hcTr := newSimulTrace(context.TODO(), "") 231 ses := parseLogs(tms[1], map[string]string{}) 232 known, _ := newTraceWrapper(ctx, hcTr, ses) 233 sesNew := known.findGoroutine(parseLogs(tms[0], map[string]string{})) 234 require.NotNil(t, sesNew) 235 require.NotEqual(t, 0, len(sesNew)) 236 require.Equal(t, ses[0].traceID, sesNew[0].traceID) 237 } 238 } 239 240 var testMergeStack = [][]string{{`goroutine 2 [running]: 241 go.dedis.ch/onet/v3/tracing.tg() 242 /home/foo//onet/tracing/logger_test.go:116 +0x44 243 created by go.dedis.ch/onet/v3/tracing.TestGor 244 /home/foo//onet/tracing/logger_test.go:108 +0x68 245 `, `goroutine 1 [runnable]: 246 sync.(*WaitGroup).Wait(0xc0001ce070) 247 /usr/local/Cellar/go/1.13.3/libexec/src/sync/waitgroup.go:103 +0x148 248 go.dedis.ch/onet/v3/tracing.tg() 249 /home/foo//onet/tracing/logger_test.go:136 +0x183 250 created by go.dedis.ch/onet/v3/tracing.TestGor 251 /home/foo//onet/tracing/logger_test.go:107 +0x50 252 `}, 253 { 254 `goroutine 2 [running]: 255 runtime/debug.Stack(0x3, 0x3, 0xc00042dfb8) 256 /usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/stack.go:24 +0xab 257 go.dedis.ch/onet/v3/log.Stack(...) 258 /home/foo//onet/log/testutil.go:105 259 go.dedis.ch/onet/v3/tracing.subgo(0xc000388410) 260 /home/foo//onet/tracing/logger_test.go:85 +0x87 261 created by go.dedis.ch/onet/v3/tracing.goroutines 262 /home/foo//onet/tracing/logger_test.go:78 +0x209`, 263 `goroutine 1 [running]: 264 runtime/debug.Stack(0x2, 0x3, 0xc0000c7f80) 265 /usr/local/Cellar/go/1.13.3/libexec/src/runtime/debug/stack.go:24 +0xab 266 go.dedis.ch/onet/v3/log.Stack(...) 267 /home/foo//onet/log/testutil.go:105 268 go.dedis.ch/onet/v3/tracing.goroutines(0x0) 269 /home/foo//onet/tracing/logger_test.go:74 +0xc7 270 go.dedis.ch/onet/v3/tracing.TestGoroutines.func1(0xc0001e8620, 0x0) 271 /home/foo//onet/tracing/logger_test.go:56 +0x39 272 created by go.dedis.ch/onet/v3/tracing.TestGoroutines 273 /home/foo//onet/tracing/logger_test.go:55 +0x1eb`, 274 }} 275 276 func TestTraceID(t *testing.T) { 277 sc, tr := newSimulLogger() 278 defer log.UnregisterLogger(tr.loggerID) 279 if testing.Verbose() { 280 tr.PrintSingleSpans = 10 281 tr.Debug = true 282 } 283 tr.AddEntryPoints("go.dedis.ch/onet/v3/tracing.setTraceID") 284 tr.AddDoneMsgs("done trace") 285 syncTrace[0] = make(chan bool, 2) 286 syncTrace[1] = make(chan bool, 2) 287 setTraceID(0, "get") 288 setTraceID(1, "set") 289 290 setTraceID(0, "set") 291 setTraceID(1, "get") 292 293 setTraceID(0, "done") 294 setTraceID(1, "done") 295 sc.Wg.Wait() 296 sc.waitAndPrint() 297 require.Equal(t, 2, len(sc.Traces)) 298 } 299 300 // used to make sure that the 'done' comes _after_ the get and set method 301 var syncTrace [2]chan bool 302 303 func setTraceID(id int, cmd string) { 304 log.TraceID([]byte{byte(id)}) 305 log.Lvl2("adding traceID") 306 go traceCmd(id, cmd) 307 } 308 309 func traceCmd(id int, cmd string) { 310 log.TraceID([]byte{byte(id)}) 311 log.Lvl2("cmd:", cmd) 312 if cmd == "done" { 313 <-syncTrace[id] 314 <-syncTrace[id] 315 log.Lvl2("done trace") 316 } else { 317 syncTrace[id] <- true 318 } 319 } 320 321 type storeKVs struct { 322 kvs map[string]string 323 } 324 325 func (s *storeKVs) AddField(key string, val interface{}) { 326 s.kvs[key] = valToJSON(val) 327 } 328 329 func testSentTrace(t *testing.T, tr *traceWrapper, exp ...string) { 330 testSent(t, tr.hcTrace.(*simulTrace).sent, exp...) 331 } 332 333 func testSent(t *testing.T, sent []map[string]string, exp ...string) { 334 var sentStr []string 335 for _, cl := range sent { 336 var keys []string 337 for k := range cl { 338 keys = append(keys, k) 339 } 340 sort.Strings(keys) 341 var s []string 342 for _, k := range keys { 343 s = append(s, fmt.Sprintf("%s:%s", k, strings.TrimSpace(cl[k]))) 344 } 345 sentStr = append(sentStr, strings.Join(s, ";")) 346 } 347 sentNice := strings.Join(sentStr, "\n") 348 require.Equal(t, len(exp), len(sent), sentNice) 349 require.Equal(t, exp, sentStr, sentNice) 350 }