Beispiel #1
0
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)
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
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)
}
Beispiel #5
0
// 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()
}
Beispiel #6
0
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)
}
Beispiel #7
0
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())
}
Beispiel #8
0
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)
	}
}
Beispiel #9
0
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
}
Beispiel #10
0
func setup(t *testing.T) (*testServer, *gosql.DB, *client.DB) {
	ctx := server.MakeTestContext()
	return setupWithContext(t, &ctx)
}
Beispiel #11
0
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")
}
Beispiel #12
0
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)
	}
}
Beispiel #14
0
// 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
}