func (t *parallelTest) getClient(nodeIdx, clientIdx int) *gosql.DB { for len(t.clients[nodeIdx]) <= clientIdx { // Add a client. pgURL, cleanupFunc := sqlutils.PGUrl(t.T, t.cluster.Server(nodeIdx).ServingAddr(), security.RootUser, "TestParallel") db, err := gosql.Open("postgres", pgURL.String()) if err != nil { t.Fatal(err) } sqlutils.MakeSQLRunner(t, db).Exec("SET DATABASE = test") t.cluster.Stopper().AddCloser( stop.CloserFn(func() { _ = db.Close() cleanupFunc() })) t.clients[nodeIdx] = append(t.clients[nodeIdx], db) } return t.clients[nodeIdx][clientIdx] }
func TestManualReplication(t *testing.T) { defer leaktest.AfterTest(t)() tc := StartTestCluster(t, 3, base.TestClusterArgs{ ReplicationMode: base.ReplicationManual, ServerArgs: base.TestServerArgs{ UseDatabase: "t", }, }) defer tc.Stopper().Stop() s0 := sqlutils.MakeSQLRunner(t, tc.Conns[0]) s1 := sqlutils.MakeSQLRunner(t, tc.Conns[1]) s2 := sqlutils.MakeSQLRunner(t, tc.Conns[2]) s0.Exec(`CREATE DATABASE t`) s0.Exec(`CREATE TABLE test (k INT PRIMARY KEY, v INT)`) s0.Exec(`INSERT INTO test VALUES (5, 1), (4, 2), (1, 2)`) if r := s1.Query(`SELECT * FROM test WHERE k = 5`); !r.Next() { t.Fatal("no rows") } s2.ExecRowsAffected(3, `DELETE FROM test`) // Split the table to a new range. kvDB := tc.Servers[0].DB() tableDesc := sqlbase.GetTableDescriptor(kvDB, "t", "test") tableStartKey := keys.MakeRowSentinelKey(keys.MakeTablePrefix(uint32(tableDesc.ID))) leftRangeDesc, tableRangeDesc, err := tc.SplitRange(tableStartKey) if err != nil { t.Fatal(err) } log.Infof(context.Background(), "After split got ranges: %+v and %+v.", leftRangeDesc, tableRangeDesc) if len(tableRangeDesc.Replicas) == 0 { t.Fatalf( "expected replica on node 1, got no replicas: %+v", tableRangeDesc.Replicas) } if tableRangeDesc.Replicas[0].NodeID != 1 { t.Fatalf( "expected replica on node 1, got replicas: %+v", tableRangeDesc.Replicas) } // Replicate the table's range to all the nodes. tableRangeDesc, err = tc.AddReplicas( tableRangeDesc.StartKey.AsRawKey(), tc.Target(1), tc.Target(2), ) if err != nil { t.Fatal(err) } if len(tableRangeDesc.Replicas) != 3 { t.Fatalf("expected 3 replicas, got %+v", tableRangeDesc.Replicas) } for i := 0; i < 3; i++ { if _, ok := tableRangeDesc.GetReplicaDescriptor( tc.Servers[i].GetFirstStoreID()); !ok { t.Fatalf("expected replica on store %d, got %+v", tc.Servers[i].GetFirstStoreID(), tableRangeDesc.Replicas) } } // Transfer the lease to node 1. leaseHolder, err := tc.FindRangeLeaseHolder( tableRangeDesc, &ReplicationTarget{ NodeID: tc.Servers[0].GetNode().Descriptor.NodeID, StoreID: tc.Servers[0].GetFirstStoreID(), }) if err != nil { t.Fatal(err) } if leaseHolder.StoreID != tc.Servers[0].GetFirstStoreID() { t.Fatalf("expected initial lease on server idx 0, but is on node: %+v", leaseHolder) } err = tc.TransferRangeLease(tableRangeDesc, tc.Target(1)) if err != nil { t.Fatal(err) } // Check that the lease holder has changed. We'll use a bogus hint, which // shouldn't matter (other than ensuring that it's not this call that moves // the range holder, but that a holder already existed). leaseHolder, err = tc.FindRangeLeaseHolder( tableRangeDesc, &ReplicationTarget{ NodeID: tc.Servers[0].GetNode().Descriptor.NodeID, StoreID: tc.Servers[0].GetFirstStoreID(), }) if err != nil { t.Fatal(err) } if leaseHolder.StoreID != tc.Servers[1].GetFirstStoreID() { t.Fatalf("expected lease on server idx 1 (node: %d store: %d), but is on node: %+v", tc.Servers[1].GetNode().Descriptor.NodeID, tc.Servers[1].GetFirstStoreID(), leaseHolder) } }
func (t *parallelTest) setup(spec *parTestSpec) { if spec.ClusterSize == 0 { spec.ClusterSize = 1 } if testing.Verbose() || log.V(1) { log.Infof(t.ctx, "Cluster Size: %d", spec.ClusterSize) } args := base.TestClusterArgs{ ServerArgs: base.TestServerArgs{ MaxOffset: logicMaxOffset, Knobs: base.TestingKnobs{ SQLExecutor: &sql.ExecutorTestingKnobs{ WaitForGossipUpdate: true, CheckStmtStringChange: true, }, }, }, } t.cluster = serverutils.StartTestCluster(t, spec.ClusterSize, args) t.clients = make([][]*gosql.DB, spec.ClusterSize) for i := range t.clients { t.clients[i] = append(t.clients[i], t.cluster.ServerConn(i)) } r0 := sqlutils.MakeSQLRunner(t, t.clients[0][0]) if spec.RangeSplitSize != 0 { if testing.Verbose() || log.V(1) { log.Infof(t.ctx, "Setting range split size: %d", spec.RangeSplitSize) } zoneCfg := config.DefaultZoneConfig() zoneCfg.RangeMaxBytes = int64(spec.RangeSplitSize) zoneCfg.RangeMinBytes = zoneCfg.RangeMaxBytes / 2 buf, err := protoutil.Marshal(&zoneCfg) if err != nil { t.Fatal(err) } objID := keys.RootNamespaceID r0.Exec(`UPDATE system.zones SET config = $2 WHERE id = $1`, objID, buf) } if testing.Verbose() || log.V(1) { log.Infof(t.ctx, "Creating database") } r0.Exec("CREATE DATABASE test") for i := range t.clients { sqlutils.MakeSQLRunner(t, t.clients[i][0]).Exec("SET DATABASE = test") } if spec.ClusterSize >= 3 { if testing.Verbose() || log.V(1) { log.Infof(t.ctx, "Waiting for full replication") } if err := t.cluster.WaitForFullReplication(); err != nil { t.Fatal(err) } } if testing.Verbose() || log.V(1) { log.Infof(t.ctx, "Test setup done") } }
func TestServer(t *testing.T) { defer leaktest.AfterTest(t)() s, sqlDB, kvDB := serverutils.StartServer(t, base.TestServerArgs{}) defer s.Stopper().Stop() conn, err := s.RPCContext().GRPCDial(s.ServingAddr()) if err != nil { t.Fatal(err) } r := sqlutils.MakeSQLRunner(t, sqlDB) r.Exec(`CREATE DATABASE test`) r.Exec(`CREATE TABLE test.t (a INT PRIMARY KEY, b INT)`) r.Exec(`INSERT INTO test.t VALUES (1, 10), (2, 20), (3, 30)`) td := sqlbase.GetTableDescriptor(kvDB, "test", "t") ts := TableReaderSpec{ Table: *td, IndexIdx: 0, Reverse: false, Spans: nil, Filter: Expression{Expr: "$0 != 2"}, // a != 2 OutputColumns: []uint32{0, 1}, // a } txn := client.NewTxn(context.Background(), *kvDB) req := &SetupFlowRequest{Txn: txn.Proto} req.Flow = FlowSpec{ Processors: []ProcessorSpec{{ Core: ProcessorCoreUnion{TableReader: &ts}, Output: []OutputRouterSpec{{ Type: OutputRouterSpec_MIRROR, Streams: []StreamEndpointSpec{{Mailbox: &MailboxSpec{SimpleResponse: true}}}, }}, }}, } distSQLClient := NewDistSQLClient(conn) stream, err := distSQLClient.RunSimpleFlow(context.Background(), req) if err != nil { t.Fatal(err) } var decoder StreamDecoder var rows sqlbase.EncDatumRows for { msg, err := stream.Recv() if err != nil { if err == io.EOF { break } t.Fatal(err) } err = decoder.AddMessage(msg) if err != nil { t.Fatal(err) } rows = testGetDecodedRows(t, &decoder, rows) } if done, trailerErr := decoder.IsDone(); !done { t.Fatal("stream not done") } else if trailerErr != nil { t.Fatal("error in the stream trailer:", trailerErr) } str := rows.String() expected := "[[1 10] [3 30]]" if str != expected { t.Errorf("invalid results: %s, expected %s'", str, expected) } }