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  }