github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/explain_unit_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 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 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package interlock 15 16 import ( 17 "context" 18 "errors" 19 "testing" 20 21 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 22 "github.com/whtcorpsinc/milevadb/memex" 23 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 24 "github.com/whtcorpsinc/milevadb/types" 25 "github.com/whtcorpsinc/milevadb/soliton/chunk" 26 "github.com/whtcorpsinc/milevadb/soliton/mock" 27 ) 28 29 var ( 30 _ InterlockingDirectorate = &mockErrorOperator{} 31 ) 32 33 type mockErrorOperator struct { 34 baseInterlockingDirectorate 35 toPanic bool 36 closed bool 37 } 38 39 func (e *mockErrorOperator) Open(ctx context.Context) error { 40 return nil 41 } 42 43 func (e *mockErrorOperator) Next(ctx context.Context, req *chunk.Chunk) error { 44 if e.toPanic { 45 panic("next panic") 46 } else { 47 return errors.New("next error") 48 } 49 } 50 51 func (e *mockErrorOperator) Close() error { 52 e.closed = true 53 return errors.New("close error") 54 } 55 56 func getDeferredCausets() []*memex.DeferredCauset { 57 return []*memex.DeferredCauset{ 58 {Index: 1, RetType: types.NewFieldType(allegrosql.TypeLonglong)}, 59 } 60 } 61 62 // close() must be called after next() to avoid goroutines leak 63 func TestExplainAnalyzeInvokeNextAndClose(t *testing.T) { 64 ctx := mock.NewContext() 65 ctx.GetStochastikVars().InitChunkSize = variable.DefInitChunkSize 66 ctx.GetStochastikVars().MaxChunkSize = variable.DefMaxChunkSize 67 schemaReplicant := memex.NewSchema(getDeferredCausets()...) 68 baseInterDirc := newBaseInterlockingDirectorate(ctx, schemaReplicant, 0) 69 explainInterDirc := &ExplainInterDirc{ 70 baseInterlockingDirectorate: baseInterDirc, 71 explain: nil, 72 } 73 // mockErrorOperator returns errors 74 mockOpr := mockErrorOperator{baseInterDirc, false, false} 75 explainInterDirc.analyzeInterDirc = &mockOpr 76 tmpCtx := context.Background() 77 _, err := explainInterDirc.generateExplainInfo(tmpCtx) 78 79 expectedStr := "next error, close error" 80 if err != nil && (err.Error() != expectedStr || !mockOpr.closed) { 81 t.Errorf(err.Error()) 82 } 83 // mockErrorOperator panic 84 mockOpr = mockErrorOperator{baseInterDirc, true, false} 85 explainInterDirc.analyzeInterDirc = &mockOpr 86 defer func() { 87 if panicErr := recover(); panicErr == nil || !mockOpr.closed { 88 t.Errorf("panic test failed: without panic or close() is not called") 89 } 90 }() 91 92 _, err = explainInterDirc.generateExplainInfo(tmpCtx) 93 if err != nil { 94 t.Errorf(err.Error()) 95 } 96 }