github.com/matrixorigin/matrixone@v1.2.0/pkg/util/trace/impl/motrace/buffer_pipe_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 motrace 16 17 import ( 18 "bytes" 19 "context" 20 "fmt" 21 "io" 22 "strings" 23 "testing" 24 "time" 25 26 "github.com/google/gops/agent" 27 "github.com/google/uuid" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 "go.uber.org/zap" 31 "go.uber.org/zap/zapcore" 32 33 "github.com/matrixorigin/matrixone/pkg/common/moerr" 34 "github.com/matrixorigin/matrixone/pkg/common/mpool" 35 "github.com/matrixorigin/matrixone/pkg/config" 36 "github.com/matrixorigin/matrixone/pkg/util/batchpipe" 37 "github.com/matrixorigin/matrixone/pkg/util/errutil" 38 "github.com/matrixorigin/matrixone/pkg/util/export/etl" 39 "github.com/matrixorigin/matrixone/pkg/util/export/table" 40 "github.com/matrixorigin/matrixone/pkg/util/internalExecutor" 41 "github.com/matrixorigin/matrixone/pkg/util/trace" 42 ) 43 44 var buf = new(bytes.Buffer) 45 var err1 = moerr.NewInternalError(context.Background(), "test1") 46 var err2 = errutil.Wrapf(err1, "test2") 47 var traceIDSpanIDColumnStr string 48 var traceIDSpanIDCsvStr string 49 50 func noopReportError(context.Context, error, int) {} 51 52 var dummyBaseTime time.Time 53 54 func init() { 55 time.Local = time.FixedZone("CST", 0) // set time-zone +0000 56 dummyBaseTime = time.Unix(0, 0) 57 SV := config.ObservabilityParameters{} 58 SV.SetDefaultValues("v0.test.0") 59 SV.TraceExportInterval = 15 60 SV.LongQueryTime = 0 61 SV.EnableTraceDebug = true 62 if err, _ := InitWithConfig( 63 context.Background(), 64 &SV, 65 EnableTracer(true), 66 withMOVersion("v0.test.0"), 67 WithNode("node_uuid", trace.NodeTypeStandalone), 68 WithFSWriterFactory(&dummyFSWriterFactory{}), 69 WithSQLExecutor(func() internalExecutor.InternalExecutor { 70 return nil 71 }), 72 ); err != nil { 73 panic(err) 74 } 75 errutil.SetErrorReporter(noopReportError) 76 77 sc := trace.SpanFromContext(DefaultContext()).SpanContext() 78 traceIDSpanIDColumnStr = fmt.Sprintf(`"%s", "%s"`, sc.TraceID.String(), sc.SpanID.String()) 79 traceIDSpanIDCsvStr = fmt.Sprintf(`%s,%s`, sc.TraceID.String(), sc.SpanID.String()) 80 81 if err := agent.Listen(agent.Options{}); err != nil { 82 _ = moerr.NewInternalError(DefaultContext(), "listen gops agent failed: %s", err) 83 panic(err) 84 } 85 fmt.Println("Finish tests init.") 86 } 87 88 type dummyStringWriter struct{} 89 90 func (w *dummyStringWriter) WriteString(s string) (n int, err error) { 91 return fmt.Printf("dummyStringWriter: %s\n", s) 92 } 93 func (w *dummyStringWriter) WriteRow(row *table.Row) error { 94 fmt.Printf("dummyStringWriter: %v\n", row.ToStrings()) 95 return nil 96 } 97 func (w *dummyStringWriter) FlushAndClose() (int, error) { 98 return 0, nil 99 } 100 func (w *dummyStringWriter) GetContent() string { return "" } 101 102 func (w *dummyStringWriter) Write(p []byte) (n int, err error) { 103 return fmt.Printf("dummyStringWriter: %s\n", p) 104 } 105 106 func (w *dummyStringWriter) Close() error { return nil } 107 108 type dummyFSWriterFactory struct{} 109 110 func (f *dummyFSWriterFactory) GetRowWriter(ctx context.Context, account string, tbl *table.Table, ts time.Time) table.RowWriter { 111 return &dummyStringWriter{} 112 } 113 func (f *dummyFSWriterFactory) GetWriter(ctx context.Context, fp string) io.WriteCloser { 114 return &dummyStringWriter{} 115 } 116 117 func Test_newBuffer2Sql_base(t *testing.T) { 118 119 buf := NewItemBuffer() 120 byteBuf := new(bytes.Buffer) 121 assert.Equal(t, true, buf.IsEmpty()) 122 buf.Add(&MOSpan{}) 123 assert.Equal(t, false, buf.IsEmpty()) 124 assert.Equal(t, false, buf.ShouldFlush()) 125 assert.Equal(t, "", buf.GetBatch(context.TODO(), byteBuf)) 126 buf.Reset() 127 assert.Equal(t, true, buf.IsEmpty()) 128 } 129 130 func Test_buffer2Sql_IsEmpty(t *testing.T) { 131 type fields struct { 132 Reminder batchpipe.Reminder 133 buf []IBuffer2SqlItem 134 sizeThreshold int64 135 batchFunc genBatchFunc 136 } 137 tests := []struct { 138 name string 139 fields fields 140 want bool 141 }{ 142 { 143 name: "empty", 144 fields: fields{ 145 Reminder: batchpipe.NewConstantClock(time.Hour), 146 buf: []IBuffer2SqlItem{}, 147 sizeThreshold: mpool.GB, 148 batchFunc: nil, 149 }, 150 want: true, 151 }, 152 { 153 name: "not_empty", 154 fields: fields{ 155 Reminder: batchpipe.NewConstantClock(time.Hour), 156 buf: []IBuffer2SqlItem{&MOZapLog{}}, 157 sizeThreshold: mpool.GB, 158 batchFunc: nil, 159 }, 160 want: false, 161 }, 162 } 163 for _, tt := range tests { 164 t.Run(tt.name, func(t *testing.T) { 165 b := &itemBuffer{ 166 Reminder: tt.fields.Reminder, 167 buf: tt.fields.buf, 168 sizeThreshold: tt.fields.sizeThreshold, 169 genBatchFunc: tt.fields.batchFunc, 170 } 171 if got := b.IsEmpty(); got != tt.want { 172 t.Errorf("IsEmpty() = %v, want %v", got, tt.want) 173 } 174 }) 175 } 176 } 177 178 func Test_buffer2Sql_Reset(t *testing.T) { 179 type fields struct { 180 Reminder batchpipe.Reminder 181 buf []IBuffer2SqlItem 182 sizeThreshold int64 183 batchFunc genBatchFunc 184 } 185 tests := []struct { 186 name string 187 fields fields 188 want bool 189 }{ 190 { 191 name: "empty", 192 fields: fields{ 193 Reminder: batchpipe.NewConstantClock(time.Hour), 194 buf: []IBuffer2SqlItem{}, 195 sizeThreshold: mpool.GB, 196 batchFunc: nil, 197 }, 198 want: true, 199 }, 200 { 201 name: "not_empty", 202 fields: fields{ 203 Reminder: batchpipe.NewConstantClock(time.Hour), 204 buf: []IBuffer2SqlItem{&MOZapLog{}}, 205 sizeThreshold: mpool.GB, 206 batchFunc: nil, 207 }, 208 want: true, 209 }, 210 } 211 for _, tt := range tests { 212 t.Run(tt.name, func(t *testing.T) { 213 b := &itemBuffer{ 214 Reminder: tt.fields.Reminder, 215 buf: tt.fields.buf, 216 sizeThreshold: tt.fields.sizeThreshold, 217 genBatchFunc: tt.fields.batchFunc, 218 } 219 b.Reset() 220 if got := b.IsEmpty(); got != tt.want { 221 t.Errorf("IsEmpty() = %v, want %v", got, tt.want) 222 } 223 }) 224 } 225 } 226 227 func Test_withSizeThreshold(t *testing.T) { 228 type args struct { 229 size int64 230 } 231 tests := []struct { 232 name string 233 args args 234 want int64 235 }{ 236 {name: "1 B", args: args{size: 1}, want: 1}, 237 {name: "1 KB", args: args{size: mpool.KB}, want: 1 << 10}, 238 {name: "1 MB", args: args{size: mpool.MB}, want: 1 << 20}, 239 {name: "1 GB", args: args{size: mpool.GB}, want: 1 << 30}, 240 {name: "1.001 GB", args: args{size: mpool.GB + mpool.MB}, want: 1<<30 + 1<<20}, 241 } 242 buf := &itemBuffer{} 243 for _, tt := range tests { 244 t.Run(tt.name, func(t *testing.T) { 245 BufferWithSizeThreshold(tt.args.size).apply(buf) 246 if got := buf.sizeThreshold; got != tt.want { 247 t.Errorf("BufferWithSizeThreshold() = %v, want %v", got, tt.want) 248 } 249 }) 250 } 251 } 252 253 /* 254 var gCtrlSqlCh = make(chan struct{}, 1) 255 func Test_batchSqlHandler_NewItemBatchHandler(t1 *testing.T) { 256 gCtrlSqlCh <- struct{}{} 257 type fields struct { 258 defaultOpts []BufferOption 259 ch chan string 260 } 261 type args struct { 262 batch string 263 } 264 265 tests := []struct { 266 name string 267 fields fields 268 args args 269 want func(batch any) 270 }{ 271 { 272 name: "nil", 273 fields: fields{ 274 defaultOpts: []BufferOption{BufferWithSizeThreshold(GB)}, 275 ch: make(chan string, 10), 276 }, 277 args: args{ 278 batch: "batch", 279 }, 280 want: func(batch any) {}, 281 }, 282 } 283 for _, tt := range tests { 284 t1.Run(tt.name, func(t1 *testing.T) { 285 WithSQLExecutor(newDummyExecutorFactory(tt.fields.ch)).apply(&GetTracerProvider().tracerProviderConfig) 286 t := batchSqlHandler{ 287 defaultOpts: tt.fields.defaultOpts, 288 } 289 290 got := t.NewItemBatchHandler(context.TODO()) 291 go got(tt.args.batch) 292 batch, ok := <-tt.fields.ch 293 if ok { 294 require.Equal(t1, tt.args.batch, batch) 295 } else { 296 t1.Log("exec sql Done.") 297 } 298 //close(tt.fields.ch) 299 }) 300 } 301 WithSQLExecutor(func() internalExecutor.InternalExecutor { return nil }).apply(&GetTracerProvider().tracerProviderConfig) 302 <-gCtrlSqlCh 303 }*/ 304 305 var genFactory = func() table.WriterFactory { 306 return table.NewWriterFactoryGetter( 307 func(ctx context.Context, account string, tbl *table.Table, ts time.Time) table.RowWriter { 308 return etl.NewCSVWriter(ctx, &dummyStringWriter{}) 309 }, 310 nil, 311 ) 312 } 313 314 func Test_genCsvData(t *testing.T) { 315 errorFormatter.Store("%v") 316 logStackFormatter.Store("%n") 317 type args struct { 318 in []IBuffer2SqlItem 319 buf *bytes.Buffer 320 } 321 sc := trace.SpanContextWithIDs(_1TraceID, _1SpanID) 322 tests := []struct { 323 name string 324 args args 325 want any 326 }{ 327 { 328 name: "single_span", 329 args: args{ 330 in: []IBuffer2SqlItem{ 331 &MOSpan{ 332 SpanConfig: trace.SpanConfig{SpanContext: trace.SpanContext{TraceID: _1TraceID, SpanID: _1SpanID}, Parent: trace.NoopSpan{}}, 333 Name: "span1", 334 StartTime: dummyBaseTime, 335 EndTime: dummyBaseTime.Add(time.Microsecond), 336 Duration: time.Microsecond, 337 tracer: gTracer.(*MOTracer), 338 }, 339 }, 340 buf: buf, 341 }, 342 want: `span_info,node_uuid,Standalone,0000000000000001,00000000-0000-0000-0000-000000000001,,1970-01-01 00:00:00.000001,,,,{},0,,,span1,0,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000001,1000,"{""Node"":{""node_uuid"":""node_uuid"",""node_type"":""Standalone""},""version"":""v0.test.0""}",internal,, 343 `, 344 }, 345 { 346 name: "multi_span", 347 args: args{ 348 in: []IBuffer2SqlItem{ 349 &MOSpan{ 350 SpanConfig: trace.SpanConfig{SpanContext: trace.SpanContext{TraceID: _1TraceID, SpanID: _1SpanID, Kind: trace.SpanKindStatement}, Parent: trace.NoopSpan{}}, 351 Name: "span1", 352 StartTime: dummyBaseTime, 353 EndTime: dummyBaseTime.Add(time.Microsecond), 354 Duration: time.Microsecond, 355 tracer: gTracer.(*MOTracer), 356 }, 357 &MOSpan{ 358 SpanConfig: trace.SpanConfig{SpanContext: trace.SpanContext{TraceID: _1TraceID, SpanID: _2SpanID, Kind: trace.SpanKindRemote}, Parent: trace.NoopSpan{}}, 359 Name: "span2", 360 StartTime: dummyBaseTime.Add(time.Microsecond), 361 EndTime: dummyBaseTime.Add(time.Millisecond), 362 Duration: time.Millisecond - time.Microsecond, 363 tracer: gTracer.(*MOTracer), 364 }, 365 &MOSpan{ 366 SpanConfig: trace.SpanConfig{SpanContext: trace.SpanContext{TraceID: _1TraceID, SpanID: _2SpanID, Kind: trace.SpanKindRemote}, Parent: trace.NoopSpan{}}, 367 Name: "empty_end", 368 StartTime: dummyBaseTime.Add(time.Microsecond), 369 Duration: 0, 370 tracer: gTracer.(*MOTracer), 371 //EndTime: table.ZeroTime, 372 ExtraFields: []zap.Field{zap.String("str", "field"), zap.Int64("int", 0)}, 373 }, 374 }, 375 buf: buf, 376 }, 377 want: `span_info,node_uuid,Standalone,0000000000000001,00000000-0000-0000-0000-000000000001,,1970-01-01 00:00:00.000001,,,,{},0,,,span1,0,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000001,1000,"{""Node"":{""node_uuid"":""node_uuid"",""node_type"":""Standalone""},""version"":""v0.test.0""}",statement,, 378 span_info,node_uuid,Standalone,0000000000000002,00000000-0000-0000-0000-000000000001,,1970-01-01 00:00:00.001000,,,,{},0,,,span2,0,1970-01-01 00:00:00.000001,1970-01-01 00:00:00.001000,999000,"{""Node"":{""node_uuid"":""node_uuid"",""node_type"":""Standalone""},""version"":""v0.test.0""}",remote,, 379 span_info,node_uuid,Standalone,0000000000000002,00000000-0000-0000-0000-000000000001,,0001-01-01 00:00:00.000000,,,,"{""str"":""field"",""int"":0}",0,,,empty_end,0,1970-01-01 00:00:00.000001,0001-01-01 00:00:00.000000,0,"{""Node"":{""node_uuid"":""node_uuid"",""node_type"":""Standalone""},""version"":""v0.test.0""}",remote,, 380 `, 381 }, 382 { 383 name: "single_zap", 384 args: args{ 385 in: []IBuffer2SqlItem{ 386 &MOZapLog{ 387 Level: zapcore.InfoLevel, 388 SpanContext: &sc, 389 Timestamp: dummyBaseTime, 390 Caller: "trace/buffer_pipe_sql_test.go:912", 391 Message: "info message", 392 Extra: "{}", 393 }, 394 }, 395 buf: buf, 396 }, 397 want: `log_info,node_uuid,Standalone,0000000000000001,00000000-0000-0000-0000-000000000001,,1970-01-01 00:00:00.000000,info,trace/buffer_pipe_sql_test.go:912,info message,{},0,,,,0,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,0,{},internal,, 398 `, 399 }, 400 { 401 name: "multi_zap", 402 args: args{ 403 in: []IBuffer2SqlItem{ 404 &MOZapLog{ 405 Level: zapcore.InfoLevel, 406 SpanContext: &sc, 407 Timestamp: dummyBaseTime, 408 Caller: "trace/buffer_pipe_sql_test.go:939", 409 Message: "info message", 410 Extra: "{}", 411 }, 412 &MOZapLog{ 413 Level: zapcore.DebugLevel, 414 SpanContext: &sc, 415 Timestamp: dummyBaseTime.Add(time.Microsecond + time.Millisecond), 416 Caller: "trace/buffer_pipe_sql_test.go:939", 417 Message: "debug message", 418 Extra: "{}", 419 }, 420 }, 421 buf: buf, 422 }, 423 want: `log_info,node_uuid,Standalone,0000000000000001,00000000-0000-0000-0000-000000000001,,1970-01-01 00:00:00.000000,info,trace/buffer_pipe_sql_test.go:939,info message,{},0,,,,0,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,0,{},internal,, 424 log_info,node_uuid,Standalone,0000000000000001,00000000-0000-0000-0000-000000000001,,1970-01-01 00:00:00.001001,debug,trace/buffer_pipe_sql_test.go:939,debug message,{},0,,,,0,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,0,{},internal,, 425 `, 426 }, 427 { 428 name: "single_statement", 429 args: args{ 430 in: []IBuffer2SqlItem{ 431 &StatementInfo{ 432 StatementID: _1TraceID, 433 TransactionID: _1TxnID, 434 SessionID: _1SesID, 435 Account: "MO", 436 User: "moroot", 437 Database: "system", 438 Statement: "show tables", 439 StatementFingerprint: "show tables", 440 StatementTag: "", 441 ExecPlan: nil, 442 RequestAt: dummyBaseTime, 443 ResponseAt: dummyBaseTime, 444 }, 445 }, 446 buf: buf, 447 }, 448 want: `00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show tables,,show tables,node_uuid,Standalone,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000000,0,Running,0,,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,0 449 `, 450 }, 451 { 452 name: "multi_statement", 453 args: args{ 454 in: []IBuffer2SqlItem{ 455 &StatementInfo{ 456 StatementID: _1TraceID, 457 TransactionID: _1TxnID, 458 SessionID: _1SesID, 459 Account: "MO", 460 User: "moroot", 461 Database: "system", 462 Statement: "show tables", 463 StatementFingerprint: "show tables", 464 StatementTag: "", 465 ExecPlan: nil, 466 RequestAt: dummyBaseTime, 467 ResponseAt: dummyBaseTime, 468 }, 469 &StatementInfo{ 470 StatementID: _2TraceID, 471 TransactionID: _1TxnID, 472 SessionID: _1SesID, 473 Account: "MO", 474 User: "moroot", 475 Database: "system", 476 Statement: "show databases", 477 StatementFingerprint: "show databases", 478 StatementTag: "dcl", 479 RequestAt: dummyBaseTime.Add(time.Microsecond), 480 ResponseAt: dummyBaseTime.Add(time.Microsecond + time.Second), 481 Duration: time.Microsecond + time.Second, 482 Status: StatementStatusFailed, 483 Error: moerr.NewInternalError(DefaultContext(), "test error"), 484 ExecPlan: nil, 485 }, 486 }, 487 buf: buf, 488 }, 489 want: `00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show tables,,show tables,node_uuid,Standalone,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000000,0,Running,0,,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,0 490 00000000-0000-0000-0000-000000000002,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show databases,dcl,show databases,node_uuid,Standalone,1970-01-01 00:00:00.000001,1970-01-01 00:00:01.000001,1000001000,Failed,20101,internal error: test error,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,0 491 `, 492 }, 493 { 494 name: "single_error", 495 args: args{ 496 in: []IBuffer2SqlItem{ 497 &MOErrorHolder{Error: err1, Timestamp: dummyBaseTime}, 498 }, 499 buf: buf, 500 }, 501 want: `error_info,node_uuid,Standalone,0,,,1970-01-01 00:00:00.000000,,,,{},20101,internal error: test1,internal error: test1,,0,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,0,{},,, 502 `, 503 }, 504 { 505 name: "multi_error", 506 args: args{ 507 in: []IBuffer2SqlItem{ 508 &MOErrorHolder{Error: err1, Timestamp: dummyBaseTime}, 509 &MOErrorHolder{Error: err2, Timestamp: dummyBaseTime.Add(time.Millisecond + time.Microsecond)}, 510 }, 511 buf: buf, 512 }, 513 want: `error_info,node_uuid,Standalone,0,,,1970-01-01 00:00:00.000000,,,,{},20101,internal error: test1,internal error: test1,,0,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,0,{},,, 514 error_info,node_uuid,Standalone,0,,,1970-01-01 00:00:00.001001,,,,{},20101,test2: internal error: test1,test2: internal error: test1,,0,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,0,{},,, 515 `, 516 }, 517 } 518 519 for _, tt := range tests { 520 t.Run(tt.name, func(t *testing.T) { 521 got := genETLData(context.TODO(), tt.args.in, tt.args.buf, genFactory()) 522 require.NotEqual(t, nil, got) 523 req, ok := got.(table.ExportRequests) 524 require.Equal(t, true, ok) 525 require.Equal(t, 1, len(req)) 526 batch := req[0].(*table.RowRequest) 527 content := batch.GetContent() 528 assert.Equalf(t, tt.want, content, "genETLData(%v, %v)", content, tt.args.buf) 529 t.Logf("%s", tt.want) 530 }) 531 } 532 } 533 534 func Test_genCsvData_diffAccount(t *testing.T) { 535 type args struct { 536 in []IBuffer2SqlItem 537 buf *bytes.Buffer 538 } 539 tests := []struct { 540 name string 541 args args 542 wantReqCnt int 543 want []string 544 }{ 545 { 546 name: "single_statement", 547 args: args{ 548 in: []IBuffer2SqlItem{ 549 &StatementInfo{ 550 StatementID: _1TraceID, 551 TransactionID: _1TxnID, 552 SessionID: _1SesID, 553 Account: "MO", 554 User: "moroot", 555 Database: "system", 556 Statement: "show tables", 557 StatementFingerprint: "show tables", 558 StatementTag: "", 559 ExecPlan: nil, 560 RequestAt: dummyBaseTime, 561 ResponseAt: dummyBaseTime, 562 }, 563 }, 564 buf: buf, 565 }, 566 wantReqCnt: 1, 567 want: []string{`00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show tables,,show tables,node_uuid,Standalone,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000000,0,Running,0,,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,0 568 `}, 569 }, 570 { 571 name: "multi_statement", 572 args: args{ 573 in: []IBuffer2SqlItem{ 574 &StatementInfo{ 575 StatementID: _1TraceID, 576 TransactionID: _1TxnID, 577 SessionID: _1SesID, 578 Account: "MO", 579 User: "moroot", 580 Database: "system", 581 Statement: "show tables", 582 StatementFingerprint: "show tables", 583 StatementTag: "", 584 ExecPlan: nil, 585 RequestAt: dummyBaseTime, 586 ResponseAt: dummyBaseTime, 587 }, 588 &StatementInfo{ 589 StatementID: _2TraceID, 590 TransactionID: _1TxnID, 591 SessionID: _1SesID, 592 Account: "sys", 593 User: "moroot", 594 Database: "system", 595 Statement: "show databases", 596 StatementFingerprint: "show databases", 597 StatementTag: "dcl", 598 RequestAt: dummyBaseTime.Add(time.Microsecond), 599 ResponseAt: dummyBaseTime.Add(time.Microsecond + time.Second), 600 Duration: time.Microsecond + time.Second, 601 Status: StatementStatusFailed, 602 Error: moerr.NewInternalError(DefaultContext(), "test error"), 603 ExecPlan: nil, 604 }, 605 }, 606 buf: buf, 607 }, 608 wantReqCnt: 1, 609 want: []string{`00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show tables,,show tables,node_uuid,Standalone,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000000,0,Running,0,,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,0 610 `, `00000000-0000-0000-0000-000000000002,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,sys,moroot,,system,show databases,dcl,show databases,node_uuid,Standalone,1970-01-01 00:00:00.000001,1970-01-01 00:00:01.000001,1000001000,Failed,20101,internal error: test error,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,0 611 `}, 612 }, 613 } 614 for _, tt := range tests { 615 t.Run(tt.name, func(t *testing.T) { 616 got := genETLData(DefaultContext(), tt.args.in, tt.args.buf, genFactory()) 617 require.NotEqual(t, nil, got) 618 reqs, ok := got.(table.ExportRequests) 619 require.Equal(t, true, ok) 620 require.Equal(t, tt.wantReqCnt, len(reqs)) 621 require.Equal(t, len(tt.args.in), len(tt.want)) 622 for _, req := range reqs { 623 found := false 624 batch := req.(*table.RowRequest) 625 for idx, w := range tt.want { 626 if strings.Contains(batch.GetContent(), w) { 627 found = true 628 t.Logf("idx %d: %s", idx, w) 629 } 630 } 631 assert.Equalf(t, true, found, "genETLData: %v", batch.GetContent()) 632 } 633 }) 634 } 635 } 636 637 func Test_genCsvData_LongQueryTime(t *testing.T) { 638 errorFormatter.Store("%v") 639 logStackFormatter.Store("%n") 640 type args struct { 641 preapre func([]IBuffer2SqlItem) 642 643 in []IBuffer2SqlItem 644 buf *bytes.Buffer 645 queryT int64 646 } 647 tests := []struct { 648 name string 649 args args 650 want any 651 }{ 652 { 653 name: "multi_statement", 654 args: args{ 655 preapre: func(in []IBuffer2SqlItem) { 656 for _, item := range in { 657 item.(*StatementInfo).ExecPlan2Stats(context.TODO()) 658 } 659 }, 660 in: []IBuffer2SqlItem{ 661 &StatementInfo{ 662 StatementID: _1TraceID, 663 TransactionID: _1TxnID, 664 SessionID: _1SesID, 665 Account: "MO", 666 User: "moroot", 667 Database: "system", 668 Statement: "show tables", 669 StatementFingerprint: "show tables", 670 StatementTag: "", 671 ExecPlan: nil, 672 Duration: time.Second - time.Nanosecond, 673 ResultCount: 1, 674 }, 675 &StatementInfo{ 676 StatementID: _1TraceID, 677 TransactionID: _1TxnID, 678 SessionID: _1SesID, 679 Account: "MO", 680 User: "moroot", 681 Database: "system", 682 Statement: "show tables", 683 StatementFingerprint: "show tables", 684 StatementTag: "", 685 ExecPlan: NewDummySerializableExecPlan(nil, dummySerializeExecPlan, uuid.UUID(_1TraceID)), 686 Duration: time.Second - time.Nanosecond, 687 ResultCount: 2, 688 RequestAt: dummyBaseTime, 689 ResponseAt: dummyBaseTime, 690 }, 691 &StatementInfo{ 692 StatementID: _2TraceID, 693 TransactionID: _1TxnID, 694 SessionID: _1SesID, 695 Account: "MO", 696 User: "moroot", 697 Database: "system", 698 Statement: "show databases", 699 StatementFingerprint: "show databases", 700 StatementTag: "dcl", 701 RequestAt: dummyBaseTime.Add(time.Microsecond), 702 ResponseAt: dummyBaseTime.Add(time.Microsecond + time.Second), 703 Duration: time.Second, 704 Status: StatementStatusFailed, 705 Error: moerr.NewInternalError(DefaultContext(), "test error"), 706 ExecPlan: NewDummySerializableExecPlan(map[string]string{"key": "val"}, dummySerializeExecPlan, uuid.UUID(_2TraceID)), 707 SqlSourceType: "internal", 708 ResultCount: 3, 709 }, 710 }, 711 buf: buf, 712 queryT: int64(time.Second), 713 }, 714 want: `00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show tables,,show tables,node_uuid,Standalone,0001-01-01 00:00:00.000000,0001-01-01 00:00:00.000000,999999999,Running,0,,{},0,0,"[0,0,0,0,0,0,0,0,0]",,,0,,0,1 715 00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show tables,,show tables,node_uuid,Standalone,1970-01-01 00:00:00.000000,1970-01-01 00:00:00.000000,999999999,Running,0,,"{""code"":200,""message"":""no exec plan""}",0,0,"[4,0,0,0,0,0,0,0,0]",,,0,,0,2 716 00000000-0000-0000-0000-000000000002,00000000-0000-0000-0000-000000000001,00000000-0000-0000-0000-000000000001,MO,moroot,,system,show databases,dcl,show databases,node_uuid,Standalone,1970-01-01 00:00:00.000001,1970-01-01 00:00:01.000001,1000000000,Failed,20101,internal error: test error,"{""key"":""val""}",1,1,"[4,1,2.000,3,4,5,0,0,44.0161]",,,0,internal,0,3 717 `, 718 }, 719 } 720 for _, tt := range tests { 721 t.Run(tt.name, func(t *testing.T) { 722 GetTracerProvider().longQueryTime = tt.args.queryT 723 if tt.args.preapre != nil { 724 tt.args.preapre(tt.args.in) 725 } 726 got := genETLData(DefaultContext(), tt.args.in, tt.args.buf, genFactory()) 727 require.NotEqual(t, nil, got) 728 req, ok := got.(table.ExportRequests) 729 require.Equal(t, true, ok) 730 require.Equal(t, 1, len(req)) 731 batch := req[0].(*table.RowRequest) 732 content := batch.GetContent() 733 assert.Equalf(t, tt.want, content, "genETLData(%v, %v)", content, tt.args.buf) 734 t.Logf("%s", tt.want) 735 GetTracerProvider().longQueryTime = 0 736 }) 737 } 738 }