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