github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/distsql/vectorized_panic_propagation_test.go (about)

     1  // Copyright 2019 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package distsql
    12  
    13  import (
    14  	"context"
    15  	"sync"
    16  	"testing"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/col/coldata"
    19  	"github.com/cockroachdb/cockroach/pkg/settings/cluster"
    20  	"github.com/cockroachdb/cockroach/pkg/sql/colexec"
    21  	"github.com/cockroachdb/cockroach/pkg/sql/colexecbase"
    22  	"github.com/cockroachdb/cockroach/pkg/sql/colflow"
    23  	"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/flowinfra"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    26  	"github.com/cockroachdb/cockroach/pkg/testutils/distsqlutils"
    27  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  // TestNonVectorizedPanicDoesntHangServer verifies that propagating a non
    32  // vectorized panic doesn't result in a hang as described in:
    33  // https://github.com/cockroachdb/cockroach/issues/39779
    34  func TestNonVectorizedPanicDoesntHangServer(t *testing.T) {
    35  	defer leaktest.AfterTest(t)()
    36  	ctx := context.Background()
    37  	st := cluster.MakeTestingClusterSettings()
    38  	evalCtx := tree.MakeTestingEvalContext(st)
    39  	defer evalCtx.Stop(ctx)
    40  
    41  	flowCtx := execinfra.FlowCtx{
    42  		EvalCtx: &evalCtx,
    43  		Cfg:     &execinfra.ServerConfig{Settings: cluster.MakeTestingClusterSettings()},
    44  	}
    45  	base := flowinfra.NewFlowBase(
    46  		flowCtx,
    47  		nil, /* flowReg */
    48  		nil, /* syncFlowConsumer */
    49  		nil, /* localProcessors */
    50  	)
    51  	flow := colflow.NewVectorizedFlow(base)
    52  
    53  	mat, err := colexec.NewMaterializer(
    54  		&flowCtx,
    55  		0, /* processorID */
    56  		&colexecbase.CallbackOperator{
    57  			NextCb: func(ctx context.Context) coldata.Batch {
    58  				panic("")
    59  			},
    60  		},
    61  		nil, /* typs */
    62  		&distsqlutils.RowBuffer{},
    63  		nil, /* metadataSourceQueue */
    64  		nil, /* toClose */
    65  		nil, /* outputStatsToTrace */
    66  		nil, /* cancelFlow */
    67  	)
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  
    72  	ctx, err = base.Setup(ctx, nil, flowinfra.FuseAggressively)
    73  	require.NoError(t, err)
    74  
    75  	base.SetProcessors([]execinfra.Processor{mat})
    76  	// This test specifically verifies that a flow doesn't get stuck in Wait for
    77  	// asynchronous components that haven't been signaled to exit. To simulate
    78  	// this we just create a mock startable.
    79  	flow.AddStartable(
    80  		flowinfra.StartableFn(func(ctx context.Context, wg *sync.WaitGroup, _ context.CancelFunc) {
    81  			wg.Add(1)
    82  			go func() {
    83  				// Ensure context is canceled.
    84  				<-ctx.Done()
    85  				wg.Done()
    86  			}()
    87  		}),
    88  	)
    89  
    90  	require.Panics(t, func() { require.NoError(t, flow.Run(ctx, nil)) })
    91  }