func newKVNative(b *testing.B) kvInterface { enableTracing := tracing.Disable() s := server.StartTestServer(b) // TestServer.DB() returns the TxnCoordSender wrapped client. But that isn't // a fair comparison with SQL as we want these client requests to be sent // over the network. sender, err := client.NewSender( rpc.NewContext(&base.Context{ User: security.NodeUser, SSLCA: filepath.Join(security.EmbeddedCertsDir, security.EmbeddedCACert), SSLCert: filepath.Join(security.EmbeddedCertsDir, "node.crt"), SSLCertKey: filepath.Join(security.EmbeddedCertsDir, "node.key"), }, nil, s.Stopper()), s.ServingAddr()) if err != nil { b.Fatal(err) } return &kvNative{ db: client.NewDB(sender), doneFn: func() { s.Stop() enableTracing() }, } }
func TestPGWireDBName(t *testing.T) { defer leaktest.AfterTest(t)() s := server.StartTestServer(t) defer s.Stop() pgURL, cleanupFn := sqlutils.PGUrl(t, s.ServingAddr(), security.RootUser, "TestPGWireDBName") pgURL.Path = "foo" defer cleanupFn() { db, err := gosql.Open("postgres", pgURL.String()) if err != nil { t.Fatal(err) } defer db.Close() if _, err := db.Exec(`CREATE DATABASE foo`); err != nil { t.Fatal(err) } if _, err := db.Exec(`CREATE TABLE bar (i INT PRIMARY KEY)`); err != nil { t.Fatal(err) } } db, err := gosql.Open("postgres", pgURL.String()) if err != nil { t.Fatal(err) } defer db.Close() if _, err := db.Exec(`INSERT INTO bar VALUES ($1)`, 1); err != nil { t.Fatal(err) } }
// TestRangeLookupWithOpenTransaction verifies that range lookups are // done in such a way (e.g. using inconsistent reads) that they // proceed in the event that a write intent is extant at the meta // index record being read. func TestRangeLookupWithOpenTransaction(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := createTestClient(t, s.Stopper(), s.ServingAddr()) // Create an intent on the meta1 record by writing directly to the // engine. key := testutils.MakeKey(keys.Meta1Prefix, roachpb.KeyMax) now := s.Clock().Now() txn := roachpb.NewTransaction("txn", roachpb.Key("foobar"), 0, roachpb.SERIALIZABLE, now, 0) if err := engine.MVCCPutProto(s.Ctx.Engines[0], nil, key, now, txn, &roachpb.RangeDescriptor{}); err != nil { t.Fatal(err) } // Now, with an intent pending, attempt (asynchronously) to read // from an arbitrary key. This will cause the distributed sender to // do a range lookup, which will encounter the intent. We're // verifying here that the range lookup doesn't fail with a write // intent error. If it did, it would go into a deadloop attempting // to push the transaction, which in turn requires another range // lookup, etc, ad nauseam. if _, err := db.Get("a"); err != nil { t.Fatal(err) } }
// TestKVDBInternalMethods verifies no internal methods are available // HTTP DB interface. func TestKVDBInternalMethods(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() testCases := []struct { args proto.Request reply proto.Response }{ {&proto.InternalRangeLookupRequest{}, &proto.InternalRangeLookupResponse{}}, {&proto.InternalGCRequest{}, &proto.InternalGCResponse{}}, {&proto.InternalHeartbeatTxnRequest{}, &proto.InternalHeartbeatTxnResponse{}}, {&proto.InternalPushTxnRequest{}, &proto.InternalPushTxnResponse{}}, {&proto.InternalResolveIntentRequest{}, &proto.InternalResolveIntentResponse{}}, {&proto.InternalResolveIntentRangeRequest{}, &proto.InternalResolveIntentRangeResponse{}}, {&proto.InternalMergeRequest{}, &proto.InternalMergeResponse{}}, {&proto.InternalTruncateLogRequest{}, &proto.InternalTruncateLogResponse{}}, } // Verify non-public methods experience bad request errors. db := createTestClient(t, s.ServingAddr()) for i, test := range testCases { test.args.Header().Key = proto.Key("a") if proto.IsRange(test.args) { test.args.Header().EndKey = test.args.Header().Key.Next() } b := &client.Batch{} b.InternalAddCall(proto.Call{Args: test.args, Reply: test.reply}) err := db.Run(b) if err == nil { t.Errorf("%d: unexpected success calling %s", i, test.args.Method()) } else if !strings.Contains(err.Error(), "404 Not Found") { t.Errorf("%d: expected 404; got %s", i, err) } } }
func TestBadRequest(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) db := createTestClient(t, s.Stopper(), s.ServingAddr()) defer s.Stop() // Write key "a". if pErr := db.Put("a", "value"); pErr != nil { t.Fatal(pErr) } if _, pErr := db.Scan("a", "a", 0); !testutils.IsPError(pErr, "truncation resulted in empty batch") { t.Fatalf("unexpected error on scan with startkey == endkey: %v", pErr) } if _, pErr := db.ReverseScan("a", "a", 0); !testutils.IsPError(pErr, "truncation resulted in empty batch") { t.Fatalf("unexpected pError on reverse scan with startkey == endkey: %v", pErr) } if pErr := db.DelRange("x", "a"); !testutils.IsPError(pErr, "truncation resulted in empty batch") { t.Fatalf("unexpected error on deletion on [x, a): %v", pErr) } if pErr := db.DelRange("", "z"); !testutils.IsPError(pErr, "must be greater than LocalMax") { t.Fatalf("unexpected error on deletion on [KeyMin, z): %v", pErr) } }
// TestSingleRangeReverseScan verifies that ReverseScan gets the right results // on a single range. func TestSingleRangeReverseScan(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := initReverseScanTestEnv(s, t) // Case 1: Request.EndKey is in the middle of the range. if rows, pErr := db.ReverseScan("b", "d", 0); pErr != nil { t.Fatalf("unexpected pError on ReverseScan: %s", pErr) } else if l := len(rows); l != 2 { t.Errorf("expected 2 rows; got %d", l) } // Case 2: Request.EndKey is equal to the EndKey of the range. if rows, pErr := db.ReverseScan("e", "g", 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != 2 { t.Errorf("expected 2 rows; got %d", l) } // Case 3: Test roachpb.TableDataMin. Expected to return "g" and "h". wanted := 2 if rows, pErr := db.ReverseScan("g", keys.TableDataMin, 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != wanted { t.Errorf("expected %d rows; got %d", wanted, l) } // Case 4: Test keys.SystemMax // This span covers the system DB keys. Note sql.GetInitialSystemValues // returns one key before keys.SystemMax, but our scan is including one key // (\xffa) created for the test. if rows, pErr := db.ReverseScan(keys.SystemMax, "b", 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != 1 { t.Errorf("expected 1 row; got %d", l) } }
// TestClientGetAndPutProto verifies gets and puts of protobufs using the // client's convenience methods. func TestClientGetAndPutProto(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := createTestClient(t, s.Stopper(), s.ServingAddr()) zoneConfig := &config.ZoneConfig{ ReplicaAttrs: []roachpb.Attributes{ {Attrs: []string{"dc1", "mem"}}, {Attrs: []string{"dc2", "mem"}}, }, RangeMinBytes: 1 << 10, // 1k RangeMaxBytes: 1 << 18, // 256k } key := roachpb.Key(testUser + "/zone-config") if pErr := db.Put(key, zoneConfig); pErr != nil { t.Fatalf("unable to put proto: %s", pErr) } readZoneConfig := &config.ZoneConfig{} if pErr := db.GetProto(key, readZoneConfig); pErr != nil { t.Fatalf("unable to get proto: %v", pErr) } if !proto.Equal(zoneConfig, readZoneConfig) { t.Errorf("expected %+v, but found %+v", zoneConfig, readZoneConfig) } }
func TestMultiRangeBatchBoundedScans(t *testing.T) { defer leaktest.AfterTest(t)() s := server.StartTestServer(t) defer s.Stop() db := setupMultipleRanges(t, s, "a", "b", "c", "d", "e", "f") for _, key := range []string{"a", "aa", "aaa", "b", "bb", "cc", "d", "dd", "ff"} { if err := db.Put(key, "value"); err != nil { t.Fatal(err) } } b := db.NewBatch() b.Scan("aaa", "dd", 3) b.Scan("a", "z", 2) b.Scan("cc", "ff", 3) if err := db.Run(b); err != nil { t.Fatal(err) } checkScanResults(t, b.Results, [][]string{ {"aaa", "b", "bb"}, {"a", "aa"}, {"cc", "d", "dd"}, }) }
func TestPGWireMetrics(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() // Setup pgwire client. pgUrl, cleanupFn := sqlutils.PGUrl(t, s, security.RootUser, "TestPGWireMetrics") defer cleanupFn() const minbytes = 20 // Make sure we're starting at 0. if _, _, err := checkPGWireMetrics(s, 0, 0, 0, 0); err != nil { t.Fatal(err) } // A single query should give us some I/O. if err := trivialQuery(pgUrl); err != nil { t.Fatal(err) } bytesIn, bytesOut, err := checkPGWireMetrics(s, minbytes, minbytes, 300, 300) if err != nil { t.Fatal(err) } if err := trivialQuery(pgUrl); err != nil { t.Fatal(err) } // A second query should give us more I/O. _, _, err = checkPGWireMetrics(s, bytesIn+minbytes, bytesOut+minbytes, 300, 300) if err != nil { t.Fatal(err) } }
// TestKVDBEndTransactionWithTriggers verifies that triggers are // disallowed on call to EndTransaction. func TestKVDBEndTransactionWithTriggers(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := createTestClient(t, s.ServingAddr()) err := db.Txn(func(txn *client.Txn) error { // Make an EndTransaction request which would fail if not // stripped. In this case, we set the start key to "bar" for a // split of the default range; start key must be "" in this case. b := &client.Batch{} b.Put("foo", "only here to make this a rw transaction") b.InternalAddCall(proto.Call{ Args: &proto.EndTransactionRequest{ RequestHeader: proto.RequestHeader{Key: proto.Key("foo")}, Commit: true, InternalCommitTrigger: &proto.InternalCommitTrigger{ SplitTrigger: &proto.SplitTrigger{ UpdatedDesc: proto.RangeDescriptor{StartKey: proto.Key("bar")}, }, }, }, Reply: &proto.EndTransactionResponse{}, }) return txn.Run(b) }) if err == nil { t.Errorf("expected 400 bad request error on commit") } }
// TestHTTPAuthentication tests authentication for the KV http endpoint. func TestHTTPAuthentication(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() // createTestClient creates a "root" client. db := createTestClient(t, s.ServingAddr()) // We call Run() on the client which lets us build our own request, // specifying the user. arg := &proto.PutRequest{} arg.Header().Key = proto.Key("a") arg.Header().User = security.RootUser reply := &proto.PutResponse{} b := &client.Batch{} b.InternalAddCall(proto.Call{Args: arg, Reply: reply}) err := db.Run(b) if err != nil { t.Fatal(err) } // Try again, but this time with arg.User = "******". arg.Header().User = "******" b = &client.Batch{} b.InternalAddCall(proto.Call{Args: arg, Reply: reply}) err = db.Run(b) if err == nil { t.Fatal("Expected error!") } }
// TestAuthentication tests authentication for the KV endpoint. func TestAuthentication(t *testing.T) { defer leaktest.AfterTest(t)() s := server.StartTestServer(t) defer s.Stop() var b1 client.Batch b1.Put("a", "b") // Create a node user client and call Run() on it which lets us build our own // request, specifying the user. db1 := createTestClientForUser(t, s.Stopper(), s.ServingAddr(), security.NodeUser) if err := db1.Run(&b1); err != nil { t.Fatal(err) } var b2 client.Batch b2.Put("c", "d") // Try again, but this time with certs for a non-node user (even the root // user has no KV permissions). db2 := createTestClientForUser(t, s.Stopper(), s.ServingAddr(), security.RootUser) if err := db2.Run(&b2); !testutils.IsError(err, "is not allowed") { t.Fatal(err) } }
// TestNoSequenceCachePutOnRangeMismatchError verifies that the // sequence cache is not updated with RangeKeyMismatchError. This is a // higher-level version of TestSequenceCacheShouldCache. func TestNoSequenceCachePutOnRangeMismatchError(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := setupMultipleRanges(t, s, "b", "c") // The requests in the transaction below will be chunked and // sent to replicas in the following way: // 1) A batch request containing a BeginTransaction and a // put on "a" are sent to a replica owning range ["a","b"). // 2) A next batch request containing a put on "b" and a put // on "c" are sent to a replica owning range ["b","c"). // (The range cache has a stale range descriptor.) // 3) The put request on "c" causes a RangeKeyMismatchError. // 4) The dist sender re-sends a request to the same replica. // This time the request contains only the put on "b" to the // same replica. // 5) The command succeeds since the sequence cache has not yet been updated. epoch := 0 if pErr := db.Txn(func(txn *client.Txn) *roachpb.Error { epoch++ b := txn.NewBatch() b.Put("a", "val") b.Put("b", "val") b.Put("c", "val") return txn.CommitInBatch(b) }); pErr != nil { t.Errorf("unexpected error on transactional Puts: %s", pErr) } if epoch != 1 { t.Errorf("unexpected epoch; the txn must not be retried, but got %d retries", epoch) } }
// TestReverseScanWithSplitAndMerge verifies that ReverseScan gets the right results // across multiple ranges while range splits and merges happen. func TestReverseScanWithSplitAndMerge(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := initReverseScanTestEnv(s, t) // Case 1: An encounter with a range split. // Split the range ["b", "e") at "c". if pErr := db.AdminSplit("c"); pErr != nil { t.Fatal(pErr) } // The ReverseScan will run into a stale descriptor. if rows, pErr := db.ReverseScan("a", "d", 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != 3 { t.Errorf("expected 3 rows; got %d", l) } // Case 2: encounter with range merge . // Merge the range ["e", "g") and ["g", "\xff\xff") . if pErr := db.AdminMerge("e"); pErr != nil { t.Fatal(pErr) } if rows, pErr := db.ReverseScan("d", "g", 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != 3 { t.Errorf("expected 3 rows; got %d", l) } }
func TestSend(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() sender, err := newHTTPSender(s.ServingAddr(), testutils.NewRootTestBaseContext(), defaultRetryOptions) if err != nil { log.Fatalf("Couldn't create HTTPSender for server:(%s)", s.ServingAddr()) } testCases := []struct { req string reply string }{ {"ping", "ping"}, {"default", "default"}, } for _, test := range testCases { request := &sqlwire.Request{Sql: test.req} call := sqlwire.Call{Args: request, Reply: &sqlwire.Response{}} sender.Send(context.TODO(), call) reply := *call.Reply.Results[0].Rows[0].Values[0].StringVal if reply != test.reply { log.Fatalf("Server sent back reply: %s", reply) } } }
func TestDropAndCreateTable(t *testing.T) { defer leaktest.AfterTest(t)() t.Skip(`TODO(andrei, dt): Fails with 'table "foo" does not exist'`) s := server.StartTestServer(t) defer s.Stop() pgURL, cleanupFn := sqlutils.PGUrl(t, s.ServingAddr(), security.RootUser, "TestDropAndCreateTable") pgURL.Path = "test" defer cleanupFn() db, err := gosql.Open("postgres", pgURL.String()) if err != nil { t.Fatal(err) } defer db.Close() if _, err := db.Exec(`CREATE DATABASE test`); err != nil { t.Fatal(err) } for i := 0; i < 20; i++ { if _, err := db.Exec(`DROP TABLE IF EXISTS foo`); err != nil { t.Fatal(err) } //NB: a `time.Sleep(time.Second)` here makes this pass. if _, err := db.Exec(`CREATE TABLE foo (k INT PRIMARY KEY)`); err != nil { t.Fatal(err) } if _, err := db.Exec(`INSERT INTO foo VALUES (1), (2), (3)`); err != nil { t.Fatal(err) } } }
// TestClientEmptyValues verifies that empty values are preserved // for both empty []byte and integer=0. This used to fail when we // allowed the protobufs to be gob-encoded using the default go rpc // gob codec because gob treats pointer values and non-pointer values // as equivalent and elides zero-valued defaults on decode. func TestClientEmptyValues(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := createTestClient(t, s.Stopper(), s.ServingAddr()) if pErr := db.Put(testUser+"/a", []byte{}); pErr != nil { t.Error(pErr) } if gr, pErr := db.Get(testUser + "/a"); pErr != nil { t.Error(pErr) } else if bytes := gr.ValueBytes(); bytes == nil || len(bytes) != 0 { t.Errorf("expected non-nil empty byte slice; got %q", bytes) } if _, pErr := db.Inc(testUser+"/b", 0); pErr != nil { t.Error(pErr) } if gr, pErr := db.Get(testUser + "/b"); pErr != nil { t.Error(pErr) } else if gr.Value == nil { t.Errorf("expected non-nil integer") } else if gr.ValueInt() != 0 { t.Errorf("expected 0-valued integer, but got %d", gr.ValueInt()) } }
func TestDropAndCreateTable(t *testing.T) { defer leaktest.AfterTest(t)() s := server.StartTestServer(t) defer s.Stop() pgURL, cleanupFn := sqlutils.PGUrl(t, s.ServingAddr(), security.RootUser, "TestDropAndCreateTable") pgURL.Path = "test" defer cleanupFn() db, err := gosql.Open("postgres", pgURL.String()) if err != nil { t.Fatal(err) } defer db.Close() if _, err := db.Exec(`CREATE DATABASE test`); err != nil { t.Fatal(err) } for i := 0; i < 20; i++ { if _, err := db.Exec(`DROP TABLE IF EXISTS foo`); err != nil { t.Fatal(err) } if _, err := db.Exec(`CREATE TABLE foo (k INT PRIMARY KEY)`); err != nil { t.Fatal(err) } if _, err := db.Exec(`INSERT INTO foo VALUES (1), (2), (3)`); err != nil { t.Fatal(err) } } }
// TestAuthentication tests authentication for the KV endpoint. func TestAuthentication(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() arg := &proto.PutRequest{} arg.Header().Key = proto.Key("a") reply := &proto.PutResponse{} b := &client.Batch{} b.InternalAddCall(proto.Call{Args: arg, Reply: reply}) // Create a "node" client and call Run() on it which lets us build // our own request, specifying the user. db1 := createTestClientForUser(t, s.Stopper(), s.ServingAddr(), security.NodeUser) if err := db1.Run(b); err != nil { t.Fatal(err) } // Try again, but this time with certs for a non-node user (even the root // user has no KV permissions). db2 := createTestClientForUser(t, s.Stopper(), s.ServingAddr(), security.RootUser) if err := db2.Run(b); err == nil { t.Fatal("Expected error!") } }
// TestClientRunTransaction verifies some simple transaction isolation // semantics. func TestClientRunTransaction(t *testing.T) { defer leaktest.AfterTest(t)() s := server.StartTestServer(t) defer s.Stop() dbCtx := client.DefaultDBContext() dbCtx.TxnRetryOptions.InitialBackoff = 1 * time.Millisecond db := createTestClientForUser(t, s.Stopper(), s.ServingAddr(), security.NodeUser, dbCtx) for _, commit := range []bool{true, false} { value := []byte("value") key := []byte(fmt.Sprintf("%s/key-%t", testUser, commit)) // Use snapshot isolation so non-transactional read can always push. err := db.Txn(func(txn *client.Txn) error { if err := txn.SetIsolation(roachpb.SNAPSHOT); err != nil { return err } // Put transactional value. if err := txn.Put(key, value); err != nil { return err } // Attempt to read outside of txn. if gr, err := db.Get(key); err != nil { return err } else if gr.Value != nil { return util.Errorf("expected nil value; got %+v", gr.Value) } // Read within the transaction. if gr, err := txn.Get(key); err != nil { return err } else if gr.Value == nil || !bytes.Equal(gr.ValueBytes(), value) { return util.Errorf("expected value %q; got %q", value, gr.ValueBytes()) } if !commit { return util.Errorf("purposefully failing transaction") } return nil }) if commit != (err == nil) { t.Errorf("expected success? %t; got %s", commit, err) } else if !commit && !testutils.IsError(err, "purposefully failing transaction") { t.Errorf("unexpected failure with !commit: %s", err) } // Verify the value is now visible on commit == true, and not visible otherwise. gr, err := db.Get(key) if commit { if err != nil || gr.Value == nil || !bytes.Equal(gr.ValueBytes(), value) { t.Errorf("expected success reading value: %+v, %s", gr.Value, err) } } else { if err != nil || gr.Value != nil { t.Errorf("expected success and nil value: %+v, %s", gr.Value, err) } } } }
func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open("https://root@" + s.ServingAddr() + "?certs=test_certs") if err != nil { log.Fatal(err) } return s, db }
func setup(t *testing.T) (*server.TestServer, *sql.DB) { s := server.StartTestServer(nil) db, err := sql.Open("cockroach", "https://root@"+s.ServingAddr()+"?certs=test_certs") if err != nil { t.Fatal(err) } return s, db }
// TestClientRunTransaction verifies some simple transaction isolation // semantics. func TestClientRunTransaction(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() defer setTxnRetryBackoff(1 * time.Millisecond)() db := createTestClient(s.ServingAddr()) for _, commit := range []bool{true, false} { value := []byte("value") key := []byte(fmt.Sprintf("key-%t", commit)) // Use snapshot isolation so non-transactional read can always push. err := db.Txn(func(txn *client.Txn) error { txn.SetSnapshotIsolation() // Put transactional value. if err := txn.Put(key, value); err != nil { return err } // Attempt to read outside of txn. if gr, err := db.Get(key); err != nil { return err } else if gr.Value != nil { return util.Errorf("expected nil value; got %+v", gr.Value) } // Read within the transaction. if gr, err := txn.Get(key); err != nil { return err } else if gr.Value == nil || !bytes.Equal(gr.ValueBytes(), value) { return util.Errorf("expected value %q; got %q", value, gr.ValueBytes()) } if !commit { return errors.New("purposefully failing transaction") } return nil }) if commit != (err == nil) { t.Errorf("expected success? %t; got %s", commit, err) } else if !commit && err.Error() != "purposefully failing transaction" { t.Errorf("unexpected failure with !commit: %s", err) } // Verify the value is now visible on commit == true, and not visible otherwise. gr, err := db.Get(key) if commit { if err != nil || gr.Value == nil || !bytes.Equal(gr.ValueBytes(), value) { t.Errorf("expected success reading value: %+v, %s", gr.Value, err) } } else { if err != nil || gr.Value != nil { t.Errorf("expected success and nil value: %+v, %s", gr.Value, err) } } } }
// maybeStartLocalServer will start a temporary local server if no database URL has been // provided. func maybeStartLocalServer() *server.TestServer { if *dbURL != "" { return nil } // Start a local test server. security.SetReadFileFn(securitytest.Asset) serv := server.StartTestServer(nil) *dbURL = "https://root@" + serv.ServingAddr() + "?certs=test_certs" return serv }
func setup() (*server.TestServer, *client.DB) { s := server.StartTestServer(nil) db, err := client.Open(s.Stopper(), fmt.Sprintf("rpcs://%s@%s?certs=test_certs", security.NodeUser, s.ServingAddr())) if err != nil { log.Fatal(err) } return s, db }
// setupMultipleRanges creates a test server and splits the // key range at the given key. Returns the test server and client. // The caller is responsible for stopping the server and // closing the client. func setupMultipleRanges(t *testing.T, splitAt string) (*server.TestServer, *client.DB) { s := server.StartTestServer(t) db := createTestClient(t, s.ServingAddr()) // Split the keyspace at the given key. if err := db.AdminSplit(splitAt); err != nil { t.Fatal(err) } return s, db }
// TestClientBatch runs a batch of increment calls and then verifies the // results. func TestClientBatch(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := createTestClient(s.ServingAddr()) keys := []proto.Key{} b := &client.Batch{} for i := 0; i < 10; i++ { key := proto.Key(fmt.Sprintf("key %02d", i)) keys = append(keys, key) b.Inc(key, int64(i)) } if err := db.Run(b); err != nil { t.Error(err) } for i, result := range b.Results { if v := result.Rows[0].ValueInt(); v != int64(i) { t.Errorf("%d: expected %d; got %d", i, i, v) } } // Now try 2 scans. b = &client.Batch{} b.Scan("key 00", "key 05", 0) b.Scan("key 05", "key 10", 0) if err := db.Run(b); err != nil { t.Error(err) } scan1 := b.Results[0].Rows scan2 := b.Results[1].Rows if len(scan1) != 5 || len(scan2) != 5 { t.Errorf("expected scan results to include 5 and 5 rows; got %d and %d", len(scan1), len(scan2)) } for i := 0; i < 5; i++ { if key := proto.Key(scan1[i].Key); !key.Equal(keys[i]) { t.Errorf("expected scan1 key %d to be %q; got %q", i, keys[i], key) } if val := scan1[i].ValueInt(); val != int64(i) { t.Errorf("expected scan1 result %d to be %d; got %d", i, i, val) } if key := proto.Key(scan2[i].Key); !key.Equal(keys[i+5]) { t.Errorf("expected scan2 key %d to be %q; got %q", i, keys[i+5], key) } if val := scan2[i].ValueInt(); val != int64(i+5) { t.Errorf("expected scan2 result %d to be %d; got %d", i, i+5, val) } } }
func newKVNative(b *testing.B) kvInterface { enableTracing := tracing.Disable() s := server.StartTestServer(b) return &kvNative{ db: s.DB(), doneFn: func() { s.Stop() enableTracing() }, } }
// TestMultiRangeScanReverseScanDeleteResolve verifies that Scan, ReverseScan, // DeleteRange and ResolveIntentRange work across ranges. func TestMultiRangeScanReverseScanDeleteResolve(t *testing.T) { defer leaktest.AfterTest(t) s := server.StartTestServer(t) defer s.Stop() db := setupMultipleRanges(t, s, "b") // Write keys before, at, and after the split key. for _, key := range []string{"a", "b", "c"} { if pErr := db.Put(key, "value"); pErr != nil { t.Fatal(pErr) } } // Scan to retrieve the keys just written. if rows, pErr := db.Scan("a", "q", 0); pErr != nil { t.Fatalf("unexpected pError on Scan: %s", pErr) } else if l := len(rows); l != 3 { t.Errorf("expected 3 rows; got %d", l) } // Scan in reverse order to retrieve the keys just written. if rows, pErr := db.ReverseScan("a", "q", 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != 3 { t.Errorf("expected 3 rows; got %d", l) } // Delete the keys within a transaction. Implicitly, the intents are // resolved via ResolveIntentRange upon completion. if pErr := db.Txn(func(txn *client.Txn) *roachpb.Error { b := txn.NewBatch() b.DelRange("a", "d") return txn.CommitInBatch(b) }); pErr != nil { t.Fatalf("unexpected error on transactional DeleteRange: %s", pErr) } // Scan consistently to make sure the intents are gone. if rows, pErr := db.Scan("a", "q", 0); pErr != nil { t.Fatalf("unexpected error on Scan: %s", pErr) } else if l := len(rows); l != 0 { t.Errorf("expected 0 rows; got %d", l) } // ReverseScan consistently to make sure the intents are gone. if rows, pErr := db.ReverseScan("a", "q", 0); pErr != nil { t.Fatalf("unexpected error on ReverseScan: %s", pErr) } else if l := len(rows); l != 0 { t.Errorf("expected 0 rows; got %d", l) } }
// TestKVDBInternalMethods verifies no internal methods are available // HTTP DB interface. func TestKVDBInternalMethods(t *testing.T) { defer leaktest.AfterTest(t) t.Skip("test broken & disabled; obsolete after after #2271") s := server.StartTestServer(t) defer s.Stop() testCases := []proto.Request{ &proto.HeartbeatTxnRequest{}, &proto.GCRequest{}, &proto.PushTxnRequest{}, &proto.RangeLookupRequest{}, &proto.ResolveIntentRequest{}, &proto.ResolveIntentRangeRequest{}, &proto.MergeRequest{}, &proto.TruncateLogRequest{}, &proto.LeaderLeaseRequest{}, &proto.EndTransactionRequest{ InternalCommitTrigger: &proto.InternalCommitTrigger{}, }, } // Verify internal methods experience bad request errors. db := createTestClient(t, s.Stopper(), s.ServingAddr()) for i, args := range testCases { args.Header().Key = proto.Key("a") if proto.IsRange(args) { args.Header().EndKey = args.Header().Key.Next() } b := &client.Batch{} b.InternalAddCall(proto.Call{Args: args, Reply: args.CreateReply()}) err := db.Run(b).GoError() if err == nil { t.Errorf("%d: unexpected success calling %s", i, args.Method()) } else if !testutils.IsError(err, "(couldn't find method|contains commit trigger)") { t.Errorf("%d: expected missing method %s; got %s", i, args.Method(), err) } // Verify same but within a Batch request. ba := &proto.BatchRequest{} ba.Add(args) b = &client.Batch{} b.InternalAddCall(proto.Call{Args: ba, Reply: &proto.BatchResponse{}}) if err := db.Run(b).GoError(); err == nil { t.Errorf("%d: unexpected success calling %s", i, args.Method()) } else if !testutils.IsError(err, "(contains an internal request|contains commit trigger)") { t.Errorf("%d: expected disallowed method error %s; got %s", i, args.Method(), err) } } }