github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/importccl/load_test.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Licensed as a CockroachDB Enterprise file under the Cockroach Community 4 // License (the "License"); you may not use this file except in compliance with 5 // the License. You may obtain a copy of the License at 6 // 7 // https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt 8 9 package importccl_test 10 11 import ( 12 "bytes" 13 "context" 14 gosql "database/sql" 15 "fmt" 16 "strings" 17 "testing" 18 19 "github.com/cockroachdb/cockroach/pkg/base" 20 "github.com/cockroachdb/cockroach/pkg/ccl/importccl" 21 "github.com/cockroachdb/cockroach/pkg/keys" 22 "github.com/cockroachdb/cockroach/pkg/kv" 23 "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" 24 "github.com/cockroachdb/cockroach/pkg/sql/tests" 25 "github.com/cockroachdb/cockroach/pkg/testutils" 26 "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" 27 "github.com/cockroachdb/cockroach/pkg/testutils/testcluster" 28 "github.com/cockroachdb/cockroach/pkg/util/hlc" 29 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 30 "github.com/cockroachdb/cockroach/pkg/workload/bank" 31 "github.com/cockroachdb/cockroach/pkg/workload/workloadsql" 32 "github.com/stretchr/testify/assert" 33 "github.com/stretchr/testify/require" 34 ) 35 36 func bankBuf(numAccounts int) *bytes.Buffer { 37 bankData := bank.FromRows(numAccounts).Tables()[0] 38 var buf bytes.Buffer 39 fmt.Fprintf(&buf, "CREATE TABLE %s %s;\n", bankData.Name, bankData.Schema) 40 for rowIdx := 0; rowIdx < bankData.InitialRows.NumBatches; rowIdx++ { 41 for _, row := range bankData.InitialRows.BatchRows(rowIdx) { 42 rowTuple := strings.Join(workloadsql.StringTuple(row), `,`) 43 fmt.Fprintf(&buf, "INSERT INTO %s VALUES (%s);\n", bankData.Name, rowTuple) 44 } 45 } 46 return &buf 47 } 48 49 func TestGetDescriptorFromDB(t *testing.T) { 50 defer leaktest.AfterTest(t)() 51 52 ctx := context.Background() 53 params, _ := tests.CreateTestServerParams() 54 s, sqlDB, kvDB := serverutils.StartServer(t, params) 55 defer s.Stopper().Stop(ctx) 56 57 aliceDesc := &sqlbase.DatabaseDescriptor{Name: "alice"} 58 bobDesc := &sqlbase.DatabaseDescriptor{Name: "bob"} 59 60 err := kvDB.Txn(ctx, func(ctx context.Context, txn *kv.Txn) error { 61 if err := txn.SetSystemConfigTrigger(); err != nil { 62 return err 63 } 64 batch := txn.NewBatch() 65 batch.Put(sqlbase.NewDatabaseKey("bob").Key(keys.SystemSQLCodec), 9999) 66 batch.Put(sqlbase.NewDeprecatedDatabaseKey("alice").Key(keys.SystemSQLCodec), 10000) 67 68 batch.Put(sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, 9999), sqlbase.WrapDescriptor(bobDesc)) 69 batch.Put(sqlbase.MakeDescMetadataKey(keys.SystemSQLCodec, 10000), sqlbase.WrapDescriptor(aliceDesc)) 70 return txn.CommitInBatch(ctx, batch) 71 }) 72 require.NoError(t, err) 73 74 for _, tc := range []struct { 75 dbName string 76 77 expected *sqlbase.DatabaseDescriptor 78 expectedErr error 79 }{ 80 {"bob", bobDesc, nil}, 81 {"alice", aliceDesc, nil}, 82 {"not_found", nil, gosql.ErrNoRows}, 83 } { 84 t.Run(tc.dbName, func(t *testing.T) { 85 ret, err := importccl.TestingGetDescriptorFromDB(ctx, sqlDB, tc.dbName) 86 if tc.expectedErr != nil { 87 assert.Error(t, err) 88 assert.Equal(t, tc.expectedErr, err) 89 } else { 90 assert.NoError(t, err) 91 assert.Equal(t, tc.expected, ret) 92 } 93 }) 94 } 95 } 96 97 func TestImportChunking(t *testing.T) { 98 defer leaktest.AfterTest(t)() 99 100 // Generate at least 2 chunks. 101 const chunkSize = 1024 * 500 102 numAccounts := int(chunkSize / 100 * 2) 103 104 ctx := context.Background() 105 dir, cleanup := testutils.TempDir(t) 106 defer cleanup() 107 108 tc := testcluster.StartTestCluster(t, 1, base.TestClusterArgs{ServerArgs: base.TestServerArgs{ExternalIODir: dir}}) 109 defer tc.Stopper().Stop(ctx) 110 111 if _, err := tc.Conns[0].Exec("CREATE DATABASE data"); err != nil { 112 t.Fatal(err) 113 } 114 115 ts := hlc.Timestamp{WallTime: hlc.UnixNano()} 116 desc, err := importccl.Load(ctx, tc.Conns[0], bankBuf(numAccounts), "data", "nodelocal://0"+dir, ts, chunkSize, dir, dir) 117 if err != nil { 118 t.Fatalf("%+v", err) 119 } 120 if len(desc.Files) < 2 { 121 t.Errorf("expected at least 2 ranges") 122 } 123 } 124 125 func TestImportOutOfOrder(t *testing.T) { 126 defer leaktest.AfterTest(t)() 127 128 ctx := context.Background() 129 dir, cleanup := testutils.TempDir(t) 130 defer cleanup() 131 132 tc := testcluster.StartTestCluster(t, 1, base.TestClusterArgs{ServerArgs: base.TestServerArgs{ExternalIODir: dir}}) 133 defer tc.Stopper().Stop(ctx) 134 135 if _, err := tc.Conns[0].Exec("CREATE DATABASE data"); err != nil { 136 t.Fatal(err) 137 } 138 bankData := bank.FromRows(2).Tables()[0] 139 row1 := workloadsql.StringTuple(bankData.InitialRows.BatchRows(0)[0]) 140 row2 := workloadsql.StringTuple(bankData.InitialRows.BatchRows(1)[0]) 141 142 var buf bytes.Buffer 143 fmt.Fprintf(&buf, "CREATE TABLE %s %s;\n", bankData.Name, bankData.Schema) 144 // Intentionally write the rows out of order. 145 fmt.Fprintf(&buf, "INSERT INTO %s VALUES (%s);\n", bankData.Name, strings.Join(row2, `,`)) 146 fmt.Fprintf(&buf, "INSERT INTO %s VALUES (%s);\n", bankData.Name, strings.Join(row1, `,`)) 147 148 ts := hlc.Timestamp{WallTime: hlc.UnixNano()} 149 _, err := importccl.Load(ctx, tc.Conns[0], &buf, "data", "nodelocal://0/foo", ts, 0, dir, dir) 150 if !testutils.IsError(err, "out of order row") { 151 t.Fatalf("expected out of order row, got: %+v", err) 152 } 153 } 154 155 func BenchmarkLoad(b *testing.B) { 156 if testing.Short() { 157 b.Skip("TODO: fix benchmark") 158 } 159 // NB: This benchmark takes liberties in how b.N is used compared to the go 160 // documentation's description. We're getting useful information out of it, 161 // but this is not a pattern to cargo-cult. 162 ctx := context.Background() 163 dir, cleanup := testutils.TempDir(b) 164 defer cleanup() 165 166 tc := testcluster.StartTestCluster(b, 1, base.TestClusterArgs{ServerArgs: base.TestServerArgs{ExternalIODir: dir}}) 167 defer tc.Stopper().Stop(ctx) 168 if _, err := tc.Conns[0].Exec("CREATE DATABASE data"); err != nil { 169 b.Fatal(err) 170 } 171 172 ts := hlc.Timestamp{WallTime: hlc.UnixNano()} 173 buf := bankBuf(b.N) 174 b.SetBytes(int64(buf.Len() / b.N)) 175 b.ResetTimer() 176 if _, err := importccl.Load(ctx, tc.Conns[0], buf, "data", dir, ts, 0, dir, dir); err != nil { 177 b.Fatalf("%+v", err) 178 } 179 }