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

     1  // Copyright 2016 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 flowinfra
    12  
    13  import (
    14  	"context"
    15  	"fmt"
    16  	"io"
    17  	"testing"
    18  
    19  	"github.com/cockroachdb/cockroach/pkg/base"
    20  	"github.com/cockroachdb/cockroach/pkg/gossip"
    21  	"github.com/cockroachdb/cockroach/pkg/keys"
    22  	"github.com/cockroachdb/cockroach/pkg/kv"
    23  	"github.com/cockroachdb/cockroach/pkg/rpc"
    24  	"github.com/cockroachdb/cockroach/pkg/sql/execinfra"
    25  	"github.com/cockroachdb/cockroach/pkg/sql/execinfrapb"
    26  	"github.com/cockroachdb/cockroach/pkg/sql/sqlbase"
    27  	"github.com/cockroachdb/cockroach/pkg/testutils"
    28  	"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
    29  	"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
    30  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    31  )
    32  
    33  func TestServer(t *testing.T) {
    34  	defer leaktest.AfterTest(t)()
    35  
    36  	ctx := context.Background()
    37  	s, sqlDB, kvDB := serverutils.StartServer(t, base.TestServerArgs{})
    38  	defer s.Stopper().Stop(ctx)
    39  	conn, err := s.RPCContext().GRPCDialNode(s.ServingRPCAddr(), s.NodeID(),
    40  		rpc.DefaultClass).Connect(ctx)
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  
    45  	r := sqlutils.MakeSQLRunner(sqlDB)
    46  
    47  	r.Exec(t, `CREATE DATABASE test`)
    48  	r.Exec(t, `CREATE TABLE test.t (a INT PRIMARY KEY, b INT)`)
    49  	r.Exec(t, `INSERT INTO test.t VALUES (1, 10), (2, 20), (3, 30)`)
    50  
    51  	td := sqlbase.GetTableDescriptor(kvDB, keys.SystemSQLCodec, "test", "t")
    52  
    53  	ts := execinfrapb.TableReaderSpec{
    54  		Table:    *td,
    55  		IndexIdx: 0,
    56  		Reverse:  false,
    57  		Spans:    []execinfrapb.TableReaderSpan{{Span: td.PrimaryIndexSpan(keys.SystemSQLCodec)}},
    58  	}
    59  	post := execinfrapb.PostProcessSpec{
    60  		Filter:        execinfrapb.Expression{Expr: "@1 != 2"}, // a != 2
    61  		Projection:    true,
    62  		OutputColumns: []uint32{0, 1}, // a
    63  	}
    64  
    65  	txn := kv.NewTxn(ctx, kvDB, s.NodeID())
    66  	leafInputState := txn.GetLeafTxnInputState(ctx)
    67  
    68  	req := &execinfrapb.SetupFlowRequest{
    69  		Version:           execinfra.Version,
    70  		LeafTxnInputState: &leafInputState,
    71  	}
    72  	req.Flow = execinfrapb.FlowSpec{
    73  		Processors: []execinfrapb.ProcessorSpec{{
    74  			Core: execinfrapb.ProcessorCoreUnion{TableReader: &ts},
    75  			Post: post,
    76  			Output: []execinfrapb.OutputRouterSpec{{
    77  				Type:    execinfrapb.OutputRouterSpec_PASS_THROUGH,
    78  				Streams: []execinfrapb.StreamEndpointSpec{{Type: execinfrapb.StreamEndpointSpec_SYNC_RESPONSE}},
    79  			}},
    80  		}},
    81  	}
    82  
    83  	distSQLClient := execinfrapb.NewDistSQLClient(conn)
    84  	stream, err := distSQLClient.RunSyncFlow(ctx)
    85  	if err != nil {
    86  		t.Fatal(err)
    87  	}
    88  	if err := stream.Send(&execinfrapb.ConsumerSignal{SetupFlowRequest: req}); err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	var decoder StreamDecoder
    93  	var rows sqlbase.EncDatumRows
    94  	var metas []execinfrapb.ProducerMetadata
    95  	for {
    96  		msg, err := stream.Recv()
    97  		if err != nil {
    98  			if err == io.EOF {
    99  				break
   100  			}
   101  			t.Fatal(err)
   102  		}
   103  		err = decoder.AddMessage(context.Background(), msg)
   104  		if err != nil {
   105  			t.Fatal(err)
   106  		}
   107  		rows, metas = testGetDecodedRows(t, &decoder, rows, metas)
   108  	}
   109  	metas = ignoreLeafTxnState(metas)
   110  	metas = ignoreMetricsMeta(metas)
   111  	if len(metas) != 0 {
   112  		t.Errorf("unexpected metadata: %v", metas)
   113  	}
   114  	str := rows.String(sqlbase.TwoIntCols)
   115  	expected := "[[1 10] [3 30]]"
   116  	if str != expected {
   117  		t.Errorf("invalid results: %s, expected %s'", str, expected)
   118  	}
   119  
   120  	// Verify version handling.
   121  	t.Run("version", func(t *testing.T) {
   122  		testCases := []struct {
   123  			version     execinfrapb.DistSQLVersion
   124  			expectedErr string
   125  		}{
   126  			{
   127  				version:     execinfra.Version + 1,
   128  				expectedErr: "version mismatch",
   129  			},
   130  			{
   131  				version:     execinfra.MinAcceptedVersion - 1,
   132  				expectedErr: "version mismatch",
   133  			},
   134  			{
   135  				version:     execinfra.MinAcceptedVersion,
   136  				expectedErr: "",
   137  			},
   138  		}
   139  		for _, tc := range testCases {
   140  			t.Run(fmt.Sprintf("%d", tc.version), func(t *testing.T) {
   141  				distSQLClient := execinfrapb.NewDistSQLClient(conn)
   142  				stream, err := distSQLClient.RunSyncFlow(context.Background())
   143  				if err != nil {
   144  					t.Fatal(err)
   145  				}
   146  				req.Version = tc.version
   147  				if err := stream.Send(&execinfrapb.ConsumerSignal{SetupFlowRequest: req}); err != nil {
   148  					t.Fatal(err)
   149  				}
   150  				_, err = stream.Recv()
   151  				if !testutils.IsError(err, tc.expectedErr) {
   152  					t.Errorf("expected error '%s', got %v", tc.expectedErr, err)
   153  				}
   154  				// In the expectedErr == nil case, we leave a flow hanging; we're not
   155  				// consuming it. It will get canceled by the draining process.
   156  			})
   157  		}
   158  	})
   159  }
   160  
   161  // Test that a node gossips its DistSQL version information.
   162  func TestDistSQLServerGossipsVersion(t *testing.T) {
   163  	defer leaktest.AfterTest(t)()
   164  
   165  	s, _, _ := serverutils.StartServer(t, base.TestServerArgs{})
   166  	defer s.Stopper().Stop(context.Background())
   167  
   168  	var v execinfrapb.DistSQLVersionGossipInfo
   169  	if err := s.GossipI().(*gossip.Gossip).GetInfoProto(
   170  		gossip.MakeDistSQLNodeVersionKey(s.NodeID()), &v,
   171  	); err != nil {
   172  		t.Fatal(err)
   173  	}
   174  
   175  	if v.Version != execinfra.Version || v.MinAcceptedVersion != execinfra.MinAcceptedVersion {
   176  		t.Fatalf("node is gossipping the wrong version. Expected: [%d-%d], got [%d-%d",
   177  			execinfra.Version, execinfra.MinAcceptedVersion, v.Version, v.MinAcceptedVersion)
   178  	}
   179  }