func (t *parallelTest) setup() { ctx := server.MakeTestContext() ctx.MaxOffset = logicMaxOffset ctx.TestingKnobs.SQLExecutor = &sql.ExecutorTestingKnobs{ WaitForGossipUpdate: true, CheckStmtStringChange: true, } t.srv = setupTestServerWithContext(t.T, &ctx) }
func createTestServerContext() (server.Context, *CommandFilters) { ctx := server.MakeTestContext() var cmdFilters CommandFilters cmdFilters.AppendFilter(checkEndTransactionTrigger, true) ctx.TestingKnobs.Store = &storage.StoreTestingKnobs{ TestingCommandFilter: cmdFilters.runFilters, } return ctx, &cmdFilters }
func Fuzz(data []byte) int { defer func() { if r := recover(); r != nil { if !panicExpected(r) { panic(r) } } }() // Run in insecure mode to avoid dealing with TLS. ctx := server.MakeTestContext() ctx.Insecure = true s := server.StartTestServerWithContext(nil, &ctx) defer s.Stop() conn, err := net.Dial("tcp", s.ServingAddr()) if err != nil { panic(err) } defer conn.Close() // Connect to the PGWire v3 server. This connection message includes information // to match with pgwire.Match and bypass sql/pgwire.parseOptions: // - 4 byte prefix for the buffer's length // - 4 bytes for the version30 value // - 1 byte for a null terminator to skip session args const version30 = 196608 var connectBuf [9]byte binary.BigEndian.PutUint32(connectBuf[:4], uint32(len(connectBuf))) binary.BigEndian.PutUint32(connectBuf[4:8], version30) if err != nil { panic(err) } conn.Write(connectBuf[:]) time.Sleep(1 * time.Millisecond) // Send a pgwire "typed message" (see sql/pgwire.readBuffer.{readTypedMsg, readUntypedMsg}). // The message includes: // - 1 byte for the type // - 4 bytes for the message's length (minus the type prefix) // - the rest of message // // TODO(nvanbenschoten) investigate sending multiple messages. sendBuf := data if len(data) > 1 { newLen := len(data) + 4 sendBuf = make([]byte, newLen) sendBuf[0] = data[0] binary.BigEndian.PutUint32(sendBuf[1:5], uint32(newLen-1)) copy(sendBuf[5:], data[1:]) } conn.Write(sendBuf) time.Sleep(1 * time.Millisecond) return 0 }
func TestLeaseManagerReacquire(testingT *testing.T) { defer leaktest.AfterTest(testingT)() ctx := server.MakeTestContext() var releaseWaiter leaseReleaseWaiter ctx.TestingKnobs = base.TestingKnobs{ SQLLeaseManager: &csql.LeaseManagerTestingKnobs{ LeaseStoreTestingKnobs: csql.LeaseStoreTestingKnobs{ LeaseReleasedEvent: releaseWaiter.LeaseReleasedNotification, }, }, } t := newLeaseTest(testingT, &ctx) defer t.cleanup() const descID = keys.LeaseTableID // Acquire 2 leases from the same node. They should point to the same lease // structure. l1 := t.mustAcquire(1, descID, 0) l2 := t.mustAcquire(1, descID, 0) if l1 != l2 { t.Fatalf("expected same lease, but found %p != %p", l1, l2) } if l1.Refcount() != 2 { t.Fatalf("expected refcount of 2, but found %d", l1.Refcount()) } t.expectLeases(descID, "/1/1") // Set the minimum lease duration such that the next lease acquisition will // require the lease to be reacquired. savedLeaseDuration, savedMinLeaseDuration := csql.LeaseDuration, csql.MinLeaseDuration defer func() { csql.LeaseDuration, csql.MinLeaseDuration = savedLeaseDuration, savedMinLeaseDuration }() csql.MinLeaseDuration = l1.Expiration().Sub(timeutil.Now()) csql.LeaseDuration = 2 * csql.MinLeaseDuration // Another lease acquisition from the same node will result in a new lease. l3 := t.mustAcquire(1, descID, 0) if l1 == l3 { t.Fatalf("expected different leases, but found %p", l1) } if l3.Refcount() != 1 { t.Fatalf("expected refcount of 1, but found %d", l3.Refcount()) } if l3.Expiration().Before(l1.Expiration()) { t.Fatalf("expected new lease expiration (%s) to be after old lease expiration (%s)", l3.Expiration(), l1.Expiration()) } t.expectLeases(descID, "/1/1 /1/1") t.mustRelease(1, l1, nil) t.mustRelease(1, l2, &releaseWaiter) t.mustRelease(1, l3, nil) }
// Test that if there's an error on COMMIT that needs to be reported to the user // the txn will be rolled back. As opposed to an error on a COMMIT in an auto-retry // txn, where we retry the txn (not tested here). func TestErrorOnCommit(t *testing.T) { defer leaktest.AfterTest(t)() ctx := server.MakeTestContext() ctx.TestingKnobs.SQLExecutor = &sql.ExecutorTestingKnobs{FixTxnPriority: true} server, sqlDB, _ := setupWithContext(t, &ctx) defer cleanup(server, sqlDB) if _, err := sqlDB.Exec(` CREATE DATABASE t; CREATE TABLE t.test (k INT PRIMARY KEY, v TEXT); `); err != nil { t.Fatal(err) } tx, err := sqlDB.Begin() if err != nil { t.Fatal(err) } if _, err := tx.Exec("SAVEPOINT cockroach_restart; SET TRANSACTION PRIORITY LOW;"); err != nil { t.Fatal(err) } if _, err = tx.Exec("INSERT INTO t.test (k, v) VALUES (0, 'sentinel');"); err != nil { t.Fatal(err) } abortTxn(t, sqlDB, 0) if err = tx.Commit(); err == nil { t.Fatal("expected commit to fail") } // Check that there's no error reading and we don't see any rows. var rows *gosql.Rows if rows, err = sqlDB.Query("SELECT * FROM t.test"); err != nil { t.Fatal(err) } if rows.Next() { var k int var v string _ = rows.Scan(&k, &v) t.Fatalf("found unexpected row: %d %s", k, v) } rows.Close() }
func Example_insecure() { c := cliTest{cleanupFunc: func() {}} ctx := server.MakeTestContext() ctx.Insecure = true c.TestServer.Ctx = &ctx if err := c.Start(); err != nil { log.Fatalf("Could not start server: %v", err) } defer c.stop() c.Run("debug kv put --insecure a 1 b 2") c.Run("debug kv scan --insecure") // Output: // debug kv put --insecure a 1 b 2 // debug kv scan --insecure // "a" "1" // "b" "2" // 2 result(s) }
func TestDB_Put_insecure(t *testing.T) { defer leaktest.AfterTest(t)() ctx := server.MakeTestContext() ctx.Insecure = true s := server.TestServer{ Ctx: &ctx, } if err := s.Start(); err != nil { log.Fatalf("Could not start server: %v", err) } defer s.Stop() db := s.DB() if err := db.Put("aa", "1"); err != nil { panic(err) } result, err := db.Get("aa") if err != nil { panic(err) } checkResult(t, []byte("1"), result.ValueBytes()) }
func (t *logicTest) setup() { // TODO(pmattis): Add a flag to make it easy to run the tests against a local // MySQL or Postgres instance. ctx := server.MakeTestContext() ctx.MaxOffset = logicMaxOffset ctx.TestingKnobs.SQLExecutor = &sql.ExecutorTestingKnobs{ WaitForGossipUpdate: true, CheckStmtStringChange: true, } t.srv = setupTestServerWithContext(t.T, &ctx) // db may change over the lifetime of this function, with intermediate // values cached in t.clients and finally closed in t.close(). t.cleanupRootUser = t.setUser(security.RootUser) if _, err := t.db.Exec(` CREATE DATABASE test; SET DATABASE = test; `); err != nil { t.Fatal(err) } }
func ExampleDB_Put_insecure() { ctx := server.MakeTestContext() ctx.Insecure = true s := server.TestServer{ Ctx: &ctx, } if err := s.Start(); err != nil { log.Fatalf("Could not start server: %v", err) } defer s.Stop() db := s.DB() if err := db.Put("aa", "1"); err != nil { panic(err) } result, err := db.Get("aa") if err != nil { panic(err) } fmt.Printf("aa=%s\n", result.ValueBytes()) // Output: // aa=1 }
func setup(t *testing.T) (*testServer, *gosql.DB, *client.DB) { ctx := server.MakeTestContext() return setupWithContext(t, &ctx) }
func TestLeaseManagerPublishVersionChanged(testingT *testing.T) { defer leaktest.AfterTest(testingT)() ctx := server.MakeTestContext() t := newLeaseTest(testingT, &ctx) defer t.cleanup() const descID = keys.LeaseTableID // Start two goroutines that are concurrently trying to publish a new version // of the descriptor. The first goroutine progresses to the update function // and then signals the second goroutine to start which is allowed to proceed // through completion. The first goroutine is then signaled and when it // attempts to publish the new version it will encounter an update error and // retry the transaction. Upon retry it will see that the descriptor version // has changed and have to proceed to its outer retry loop and wait for the // number of leases on the previous version to drop to 0. n1 := t.node(1) n2 := t.node(2) n1update := make(chan struct{}) n2start := make(chan struct{}) var wg sync.WaitGroup wg.Add(2) go func(n1update, n2start chan struct{}) { _, err := n1.Publish(descID, func(*sqlbase.TableDescriptor) error { if n2start != nil { // Signal node 2 to start. close(n2start) n2start = nil } // Wait for node 2 signal indicating that node 2 finished publication of // a new version. <-n1update return nil }) if err != nil { panic(err) } wg.Done() }(n1update, n2start) go func(n1update, n2start chan struct{}) { // Wait for node 1 signal indicating that node 1 is in its update() // function. <-n2start _, err := n2.Publish(descID, func(*sqlbase.TableDescriptor) error { return nil }) if err != nil { panic(err) } close(n1update) wg.Done() }(n1update, n2start) wg.Wait() t.mustAcquire(1, descID, 0) t.expectLeases(descID, "/3/1") }
func TestLeaseManager(testingT *testing.T) { defer leaktest.AfterTest(testingT)() ctx := server.MakeTestContext() t := newLeaseTest(testingT, &ctx) defer t.cleanup() const descID = keys.LeaseTableID // We can't acquire a lease on a non-existent table. expected := "descriptor not found" if _, err := t.acquire(1, 10000, 0); !testutils.IsError(err, expected) { t.Fatalf("expected %s, but found %v", expected, err) } l1 := t.mustAcquire(1, descID, 0) t.expectLeases(descID, "/1/1") // Node 2 never acquired a lease on descID, so we should expect an error. if err := t.release(2, l1); err == nil { t.Fatalf("expected error, but found none") } t.mustRelease(1, l1) t.expectLeases(descID, "/1/1") // It is an error to acquire a lease for a specific version that doesn't // exist yet. expected = "version 2 of table .* does not exist" if _, err := t.acquire(1, descID, 2); !testutils.IsError(err, expected) { t.Fatalf("expected %s, but found %v", expected, err) } // Publish a new version and explicitly acquire it. l2 := t.mustAcquire(1, descID, 0) t.mustPublish(1, descID) l3 := t.mustAcquire(1, descID, 2) t.expectLeases(descID, "/1/1 /2/1") // When the last local reference on the new version is released we don't // release the node lease. t.mustRelease(1, l3) t.expectLeases(descID, "/1/1 /2/1") // We can still acquire a local reference on the old version since it hasn't // expired. l4 := t.mustAcquire(1, descID, 1) t.mustRelease(1, l4) t.expectLeases(descID, "/1/1 /2/1") // When the last local reference on the old version is released the node // lease is also released. t.mustRelease(1, l2) t.expectLeases(descID, "/2/1") // It is an error to acquire a lease for an old version once a new version // exists and there are no local references for the old version. expected = "lease.go.*: table .* unable to acquire lease on old version: 1 < 2" if _, err := t.acquire(1, descID, 1); !testutils.IsError(err, expected) { t.Fatalf("expected %s, but found %v", expected, err) } // Acquire 2 node leases on version 2. l5 := t.mustAcquire(1, descID, 2) l6 := t.mustAcquire(2, descID, 2) // Publish version 3. This will succeed immediately. t.mustPublish(3, descID) // Start a goroutine to publish version 4 which will block until the version // 2 leases are released. var wg sync.WaitGroup wg.Add(1) go func() { t.mustPublish(3, descID) wg.Done() }() // Force both nodes ahead to version 3. l7 := t.mustAcquire(1, descID, 3) l8 := t.mustAcquire(2, descID, 3) t.expectLeases(descID, "/2/1 /2/2 /3/1 /3/2") t.mustRelease(1, l5) t.expectLeases(descID, "/2/2 /3/1 /3/2") t.mustRelease(2, l6) t.expectLeases(descID, "/3/1 /3/2") // Wait for version 4 to be published. wg.Wait() l9 := t.mustAcquire(1, descID, 4) t.mustRelease(1, l7) t.mustRelease(2, l8) t.expectLeases(descID, "/3/2 /4/1") t.mustRelease(1, l9) t.expectLeases(descID, "/3/2 /4/1") }
// TestPropagateTxnOnError verifies that DistSender.sendChunk properly // propagates the txn data to a next iteration. Use txn.Writing field to // verify that. func TestPropagateTxnOnError(t *testing.T) { defer leaktest.AfterTest(t)() var storeKnobs storage.StoreTestingKnobs // Set up a filter to so that the first CPut operation will // get a ReadWithinUncertaintyIntervalError. targetKey := roachpb.Key("b") var numGets int32 storeKnobs.TestingCommandFilter = func(fArgs storagebase.FilterArgs) *roachpb.Error { _, ok := fArgs.Req.(*roachpb.ConditionalPutRequest) if ok && fArgs.Req.Header().Key.Equal(targetKey) { if atomic.AddInt32(&numGets, 1) == 1 { z := roachpb.ZeroTimestamp pErr := roachpb.NewReadWithinUncertaintyIntervalError(z, z) return roachpb.NewErrorWithTxn(pErr, fArgs.Hdr.Txn) } } return nil } ctx := server.MakeTestContext() ctx.TestingKnobs.Store = &storeKnobs s := server.StartTestServerWithContext(t, &ctx) defer s.Stop() db := setupMultipleRanges(t, s, "b") // Set the initial value on the target key "b". origVal := "val" if err := db.Put(targetKey, origVal); err != nil { t.Fatal(err) } // The following txn creates a batch request that is split // into two requests: Put and CPut. The CPut operation will // get a ReadWithinUncertaintyIntervalError and the txn will be // retried. epoch := 0 if err := db.Txn(func(txn *client.Txn) error { epoch++ if epoch >= 2 { // Writing must be true since we ran the BeginTransaction command. if !txn.Proto.Writing { t.Errorf("unexpected non-writing txn") } } else { // Writing must be false since we haven't run any write command. if txn.Proto.Writing { t.Errorf("unexpected writing txn") } } b := txn.NewBatch() b.Put("a", "val") b.CPut(targetKey, "new_val", origVal) err := txn.CommitInBatch(b) if epoch == 1 { if retErr, ok := err.(*roachpb.RetryableTxnError); ok { if _, ok := retErr.Cause.(*roachpb.ReadWithinUncertaintyIntervalError); ok { if !retErr.Transaction.Writing { t.Errorf("unexpected non-writing txn on error") } } else { t.Errorf("expected ReadWithinUncertaintyIntervalError, but got: %s", retErr.Cause) } } else { t.Errorf("expected a retryable error, but got: %s", err) } } return err }); err != nil { t.Errorf("unexpected error on transactional Puts: %s", err) } if epoch != 2 { t.Errorf("unexpected epoch; the txn must be retried exactly once, but got %d", epoch) } }
// getFastScanContext returns a test context with fast scan. func getFastScanContext() server.Context { c := server.MakeTestContext() c.ScanInterval = time.Millisecond c.ScanMaxIdleTime = time.Millisecond return c }