// TestTxnCoordSenderBeginTransactionMinPriority verifies that when starting // a new transaction, a non-zero priority is treated as a minimum value. func TestTxnCoordSenderBeginTransactionMinPriority(t *testing.T) { defer leaktest.AfterTest(t) s := createTestDB(t) defer s.Stop() defer teardownHeartbeats(s.Sender) reply := &proto.PutResponse{} s.Sender.Send(context.Background(), proto.Call{ Args: &proto.PutRequest{ RequestHeader: proto.RequestHeader{ Key: proto.Key("key"), User: security.RootUser, UserPriority: gogoproto.Int32(-10), // negative user priority is translated into positive priority Txn: &proto.Transaction{ Name: "test txn", Isolation: proto.SNAPSHOT, Priority: 11, }, }, }, Reply: reply, }) if reply.Error != nil { t.Fatal(reply.GoError()) } if reply.Txn.Priority != 11 { t.Errorf("expected txn priority 11; got %d", reply.Txn.Priority) } }
func TestKeyAddress(t *testing.T) { defer leaktest.AfterTest(t)() testCases := []struct { key roachpb.Key }{ {MakeNameMetadataKey(0, "BAR")}, {MakeNameMetadataKey(1, "BAR")}, {MakeNameMetadataKey(1, "foo")}, {MakeNameMetadataKey(2, "foo")}, {MakeDescMetadataKey(123)}, {MakeDescMetadataKey(124)}, } var lastKey roachpb.Key for i, test := range testCases { resultAddr, err := keys.Addr(test.key) if err != nil { t.Fatal(err) } result := resultAddr.AsRawKey() if result.Compare(lastKey) <= 0 { t.Errorf("%d: key address %q is <= %q", i, result, lastKey) } lastKey = result } }
// Test that we can resolve the qnames in an expression that has already been // resolved. func TestRetryResolveQNames(t *testing.T) { defer leaktest.AfterTest(t)() expr, err := parser.ParseExprTraditional(`COUNT(a)`) if err != nil { t.Fatal(err) } for i := 0; i < 2; i++ { desc := testTableDesc() s := testInitDummySelectNode(desc) if err := desc.AllocateIDs(); err != nil { t.Fatal(err) } _, err := s.resolveQNames(expr) if err != nil { t.Fatal(err) } if len(s.qvals) != 1 { t.Fatalf("%d: expected 1 qvalue, but found %d", i, len(s.qvals)) } if _, ok := s.qvals[columnRef{&s.source.info, 0}]; !ok { t.Fatalf("%d: unable to find qvalue for column 0 (a)", i) } } }
// TestInfoStoreMostDistant verifies selection of most distant node & // associated hops. func TestInfoStoreMostDistant(t *testing.T) { defer leaktest.AfterTest(t)() nodes := []roachpb.NodeID{ roachpb.NodeID(1), roachpb.NodeID(2), roachpb.NodeID(3), } stopper := stop.NewStopper() defer stopper.Stop() is := newInfoStore(context.TODO(), 1, emptyAddr, stopper) // Add info from each address, with hop count equal to index+1. for i := 0; i < len(nodes); i++ { inf := is.newInfo(nil, time.Second) inf.Hops = uint32(i + 1) inf.NodeID = nodes[i] if err := is.addInfo(fmt.Sprintf("b.%d", i), inf); err != nil { t.Fatal(err) } nodeID, hops := is.mostDistant() if nodeID != inf.NodeID { t.Errorf("%d: expected node %d; got %d", i, inf.NodeID, nodeID) } if hops != inf.Hops { t.Errorf("%d: expected node %d; got %d", i, inf.Hops, hops) } } }
// TestRangeLookupOptionOnReverseScan verifies that a lookup triggered by a // ReverseScan request has the useReverseScan specified. func TestRangeLookupOptionOnReverseScan(t *testing.T) { defer leaktest.AfterTest(t) g, s := makeTestGossip(t) defer s() var testFn rpcSendFn = func(_ rpc.Options, method string, addrs []net.Addr, getArgs func(addr net.Addr) proto.Message, _ func() proto.Message, _ *rpc.Context) ([]proto.Message, error) { return []proto.Message{getArgs(nil).(*roachpb.BatchRequest).CreateReply()}, nil } ctx := &DistSenderContext{ RPCSend: testFn, RangeDescriptorDB: mockRangeDescriptorDB(func(k roachpb.RKey, considerIntents, useReverseScan bool) ([]roachpb.RangeDescriptor, *roachpb.Error) { if len(k) > 0 && !useReverseScan { t.Fatalf("expected UseReverseScan to be set") } return []roachpb.RangeDescriptor{testRangeDescriptor}, nil }), } ds := NewDistSender(ctx, g) rScan := &roachpb.ReverseScanRequest{ Span: roachpb.Span{Key: roachpb.Key("a"), EndKey: roachpb.Key("b")}, } if _, err := client.SendWrapped(ds, nil, rScan); err != nil { t.Fatal(err) } }
// TestRejectFutureCommand verifies that lease holders reject commands that // would cause a large time jump. func TestRejectFutureCommand(t *testing.T) { defer leaktest.AfterTest(t)() const maxOffset = 100 * time.Millisecond manual := hlc.NewManualClock(0) clock := hlc.NewClock(manual.UnixNano) clock.SetMaxOffset(maxOffset) mtc := multiTestContext{ clock: clock, } mtc.Start(t, 1) defer mtc.Stop() // First do a write. The first write will advance the clock by MaxOffset // because of the read cache's low water mark. getArgs := putArgs([]byte("b"), []byte("b")) if _, err := client.SendWrapped(rg1(mtc.stores[0]), nil, &getArgs); err != nil { t.Fatal(err) } if now := clock.Now(); now.WallTime != int64(maxOffset) { t.Fatalf("expected clock to advance to 100ms; got %s", now) } // The logical clock has advanced past the physical clock; increment // the "physical" clock to catch up. manual.Increment(int64(maxOffset)) startTime := manual.UnixNano() // Commands with a future timestamp that is within the MaxOffset // bound will be accepted and will cause the clock to advance. for i := int64(0); i < 3; i++ { incArgs := incrementArgs([]byte("a"), 5) ts := hlc.ZeroTimestamp.Add(startTime+((i+1)*30)*int64(time.Millisecond), 0) if _, err := client.SendWrappedWith(rg1(mtc.stores[0]), nil, roachpb.Header{Timestamp: ts}, &incArgs); err != nil { t.Fatal(err) } } if now := clock.Now(); now.WallTime != int64(190*time.Millisecond) { t.Fatalf("expected clock to advance to 190ms; got %s", now) } // Once the accumulated offset reaches MaxOffset, commands will be rejected. incArgs := incrementArgs([]byte("a"), 11) ts := hlc.ZeroTimestamp.Add(int64((time.Duration(startTime)+maxOffset+1)*time.Millisecond), 0) if _, err := client.SendWrappedWith(rg1(mtc.stores[0]), nil, roachpb.Header{Timestamp: ts}, &incArgs); err == nil { t.Fatalf("expected clock offset error but got nil") } // The clock remained at 190ms and the final command was not executed. if now := clock.Now(); now.WallTime != int64(190*time.Millisecond) { t.Errorf("expected clock to advance to 190ms; got %s", now) } val, _, err := engine.MVCCGet(context.Background(), mtc.engines[0], roachpb.Key("a"), clock.Now(), true, nil) if err != nil { t.Fatal(err) } if v := mustGetInt(val); v != 15 { t.Errorf("expected 15, got %v", v) } }
// TestStoreRangeUpReplicate verifies that the replication queue will notice // under-replicated ranges and replicate them. func TestStoreRangeUpReplicate(t *testing.T) { defer leaktest.AfterTest(t) mtc := startMultiTestContext(t, 3) defer mtc.Stop() // Initialize the gossip network. var wg sync.WaitGroup wg.Add(len(mtc.stores)) key := gossip.MakePrefixPattern(gossip.KeyStorePrefix) mtc.stores[0].Gossip().RegisterCallback(key, func(_ string, _ roachpb.Value) { wg.Done() }) for _, s := range mtc.stores { s.GossipStore() } wg.Wait() // Once we know our peers, trigger a scan. mtc.stores[0].ForceReplicationScanAndProcess() // The range should become available on every node. if err := util.IsTrueWithin(func() bool { for _, s := range mtc.stores { r := s.LookupReplica(roachpb.RKey("a"), roachpb.RKey("b")) if r == nil { return false } } return true }, replicationTimeout); err != nil { t.Fatal(err) } }
// TestBuildEndpointListRemoveStagnantClocks tests the side effect of removing // older offsets when we build an endpoint list. func TestBuildEndpointListRemoveStagnantClocks(t *testing.T) { defer leaktest.AfterTest(t)() offsets := map[string]RemoteOffset{ "0": {Offset: 0, Uncertainty: 10, MeasuredAt: 11}, "stagnant0": {Offset: 1, Uncertainty: 10, MeasuredAt: 0}, "1": {Offset: 2, Uncertainty: 10, MeasuredAt: 20}, "stagnant1": {Offset: 3, Uncertainty: 10, MeasuredAt: 9}, } manual := hlc.NewManualClock(0) clock := hlc.NewClock(manual.UnixNano) clock.SetMaxOffset(5 * time.Nanosecond) remoteClocks := newRemoteClockMonitor(clock) // The stagnant offsets older than this will be removed. remoteClocks.monitorInterval = 10 * time.Nanosecond remoteClocks.mu.offsets = offsets remoteClocks.mu.lastMonitoredAt = time.Unix(0, 10) // offsets measured before this will be removed. remoteClocks.buildEndpointList() _, ok0 := offsets["stagnant0"] _, ok1 := offsets["stagnant1"] if ok0 || ok1 { t.Errorf("expected stagant offsets removed, instead offsets: %v", offsets) } }
// TestFindOffsetWithLargeError tests a case where offset errors are // bigger than the max offset (e.g., a case where heartbeat messages // to the node are having high latency). func TestFindOffsetWithLargeError(t *testing.T) { defer leaktest.AfterTest(t)() maxOffset := 100 * time.Nanosecond manual := hlc.NewManualClock(0) clock := hlc.NewClock(manual.UnixNano) clock.SetMaxOffset(maxOffset) offsets := map[string]RemoteOffset{} // Offsets are bigger than maxOffset, but Errors are also bigger than Offset. offsets["0"] = RemoteOffset{Offset: 110, Uncertainty: 300} offsets["1"] = RemoteOffset{Offset: 120, Uncertainty: 300} offsets["2"] = RemoteOffset{Offset: 130, Uncertainty: 300} remoteClocks := newRemoteClockMonitor(clock) remoteClocks.mu.offsets = offsets interval, err := remoteClocks.findOffsetInterval() if err != nil { t.Fatal(err) } expectedInterval := clusterOffsetInterval{lowerbound: -270, upperbound: 510} if interval != expectedInterval { t.Errorf("expected interval %v, instead %v", expectedInterval, interval) } // The interval is still considered healthy. assertIntervalHealth(true, interval, maxOffset, t) }
func TestExactPrefix(t *testing.T) { defer leaktest.AfterTest(t) testData := []struct { expr string columns []string expected int }{ {`a = 1`, []string{"a"}, 1}, {`a != 1`, []string{"a"}, 0}, {`a IN (1)`, []string{"a"}, 1}, {`a = 1 AND b = 1`, []string{"a", "b"}, 2}, {`(a, b) IN ((1, 2))`, []string{"a", "b"}, 2}, {`(a, b) IN ((1, 2))`, []string{"a"}, 1}, {`(a, b) IN ((1, 2))`, []string{"b"}, 1}, {`(a, b) IN ((1, 2)) AND c = true`, []string{"a", "b", "c"}, 3}, {`a = 1 AND (b, c) IN ((2, true))`, []string{"a", "b", "c"}, 3}, } for _, d := range testData { desc, index := makeTestIndex(t, d.columns) constraints := makeConstraints(t, d.expr, desc, index) prefix := exactPrefix(constraints) if d.expected != prefix { t.Errorf("%s: expected %d, but found %d", d.expr, d.expected, prefix) } } }
func TestColumnTypeSQLString(t *testing.T) { defer leaktest.AfterTest(t) testData := []struct { colType sql.ColumnType expectedSQL string }{ {sql.ColumnType{Kind: sql.ColumnType_INT}, "INT"}, {sql.ColumnType{Kind: sql.ColumnType_INT, Width: 2}, "INT(2)"}, {sql.ColumnType{Kind: sql.ColumnType_FLOAT}, "FLOAT"}, {sql.ColumnType{Kind: sql.ColumnType_FLOAT, Precision: 3}, "FLOAT(3)"}, {sql.ColumnType{Kind: sql.ColumnType_DECIMAL}, "DECIMAL"}, {sql.ColumnType{Kind: sql.ColumnType_DECIMAL, Precision: 6}, "DECIMAL(6)"}, {sql.ColumnType{Kind: sql.ColumnType_DECIMAL, Precision: 7, Width: 8}, "DECIMAL(7,8)"}, {sql.ColumnType{Kind: sql.ColumnType_DATE}, "DATE"}, {sql.ColumnType{Kind: sql.ColumnType_TIMESTAMP}, "TIMESTAMP"}, {sql.ColumnType{Kind: sql.ColumnType_INTERVAL}, "INTERVAL"}, {sql.ColumnType{Kind: sql.ColumnType_STRING}, "STRING"}, {sql.ColumnType{Kind: sql.ColumnType_STRING, Width: 10}, "STRING(10)"}, {sql.ColumnType{Kind: sql.ColumnType_BYTES}, "BYTES"}, } for i, d := range testData { sql := d.colType.SQLString() if d.expectedSQL != sql { t.Errorf("%d: expected %s, but got %s", i, d.expectedSQL, sql) } } }
// TestTxnCoordSenderGC verifies that the coordinator cleans up extant // transactions after the lastUpdateNanos exceeds the timeout. func TestTxnCoordSenderGC(t *testing.T) { defer leaktest.AfterTest(t) s := createTestDB(t) defer s.Stop() // Set heartbeat interval to 1ms for testing. s.Sender.heartbeatInterval = 1 * time.Millisecond txn := newTxn(s.Clock, proto.Key("a")) call := proto.Call{ Args: createPutRequest(proto.Key("a"), []byte("value"), txn), Reply: &proto.PutResponse{}, } if err := sendCall(s.Sender, call); err != nil { t.Fatal(err) } // Now, advance clock past the default client timeout. // Locking the TxnCoordSender to prevent a data race. s.Sender.Lock() s.Manual.Set(defaultClientTimeout.Nanoseconds() + 1) s.Sender.Unlock() if err := util.IsTrueWithin(func() bool { // Locking the TxnCoordSender to prevent a data race. s.Sender.Lock() _, ok := s.Sender.txns[string(txn.ID)] s.Sender.Unlock() return !ok }, 50*time.Millisecond); err != nil { t.Error("expected garbage collection") } }
// TestTxnCoordSenderEndTxn verifies that ending a transaction // sends resolve write intent requests and removes the transaction // from the txns map. func TestTxnCoordSenderEndTxn(t *testing.T) { defer leaktest.AfterTest(t) s := createTestDB(t) defer s.Stop() txn := newTxn(s.Clock, proto.Key("a")) pReply := &proto.PutResponse{} key := proto.Key("a") call := proto.Call{ Args: createPutRequest(key, []byte("value"), txn), Reply: pReply, } if err := sendCall(s.Sender, call); err != nil { t.Fatal(err) } if pReply.GoError() != nil { t.Fatal(pReply.GoError()) } etReply := &proto.EndTransactionResponse{} s.Sender.Send(context.Background(), proto.Call{ Args: &proto.EndTransactionRequest{ RequestHeader: proto.RequestHeader{ Key: txn.Key, Timestamp: txn.Timestamp, Txn: txn, }, Commit: true, }, Reply: etReply, }) if etReply.Error != nil { t.Fatal(etReply.GoError()) } verifyCleanup(key, s.Sender, s.Eng, t) }
// TestTxnCoordSenderMultipleTxns verifies correct operation with // multiple outstanding transactions. func TestTxnCoordSenderMultipleTxns(t *testing.T) { defer leaktest.AfterTest(t) s := createTestDB(t) defer s.Stop() defer teardownHeartbeats(s.Sender) txn1 := newTxn(s.Clock, proto.Key("a")) txn2 := newTxn(s.Clock, proto.Key("b")) call := proto.Call{ Args: createPutRequest(proto.Key("a"), []byte("value"), txn1), Reply: &proto.PutResponse{}} if err := sendCall(s.Sender, call); err != nil { t.Fatal(err) } call = proto.Call{ Args: createPutRequest(proto.Key("b"), []byte("value"), txn2), Reply: &proto.PutResponse{}} if err := sendCall(s.Sender, call); err != nil { t.Fatal(err) } if len(s.Sender.txns) != 2 { t.Errorf("expected length of transactions map to be 2; got %d", len(s.Sender.txns)) } }
func TestBatchDefer(t *testing.T) { defer leaktest.AfterTest(t) stopper := stop.NewStopper() defer stopper.Stop() e := NewInMem(roachpb.Attributes{}, 1<<20, stopper) b := e.NewBatch() defer b.Close() list := []string{} b.Defer(func() { list = append(list, "one") }) b.Defer(func() { list = append(list, "two") }) if err := b.Commit(); err != nil { t.Fatal(err) } // Order was reversed when the defers were run. if !reflect.DeepEqual(list, []string{"two", "one"}) { t.Errorf("expected [two, one]; got %v", list) } }
// TestIsHealthyOffsetInterval tests if we correctly determine if // a clusterOffsetInterval is healthy or not i.e. if it indicates that the // local clock has too great an offset or not. func TestIsHealthyOffsetInterval(t *testing.T) { defer leaktest.AfterTest(t)() maxOffset := 10 * time.Nanosecond interval := clusterOffsetInterval{ lowerbound: 0, upperbound: 0, } assertIntervalHealth(true, interval, maxOffset, t) interval = clusterOffsetInterval{ lowerbound: -11, upperbound: 11, } assertIntervalHealth(true, interval, maxOffset, t) interval = clusterOffsetInterval{ lowerbound: -20, upperbound: -11, } assertIntervalHealth(false, interval, maxOffset, t) interval = clusterOffsetInterval{ lowerbound: 11, upperbound: 20, } assertIntervalHealth(false, interval, maxOffset, t) interval = clusterOffsetInterval{ lowerbound: math.MaxInt64, upperbound: math.MaxInt64, } assertIntervalHealth(false, interval, maxOffset, t) }
// TestHeartbeatResponseFanout check 2 raft groups on the same node distribution, // but each group has different Term, heartbeat response from each group should // not disturb other group's Term or Leadership func TestHeartbeatResponseFanout(t *testing.T) { defer leaktest.AfterTest(t) stopper := stop.NewStopper() defer stopper.Stop() cluster := newTestCluster(nil, 3, stopper, t) groupID1 := roachpb.RangeID(1) cluster.createGroup(groupID1, 0, 3 /* replicas */) groupID2 := roachpb.RangeID(2) cluster.createGroup(groupID2, 0, 3 /* replicas */) leaderIndex := 0 cluster.elect(leaderIndex, groupID1) // GroupID2 will have 3 round of election, so it will have different // term with groupID1, but both leader on the same node. for i := 2; i >= 0; i-- { leaderIndex = i cluster.elect(leaderIndex, groupID2) } // Send a coalesced heartbeat. // Heartbeat response from groupID2 will have a big term than which from groupID1. cluster.nodes[0].coalescedHeartbeat() // Start submit a command to see if groupID1's leader changed? cluster.nodes[0].SubmitCommand(groupID1, makeCommandID(), []byte("command")) select { case _ = <-cluster.events[0].CommandCommitted: log.Infof("SubmitCommand succeed after Heartbeat Response fanout") case <-time.After(500 * time.Millisecond): t.Fatalf("No leader after Heartbeat Response fanout") } }
// TestEndpointListSort tests the sort interface for endpointLists. func TestEndpointListSort(t *testing.T) { defer leaktest.AfterTest(t)() list := endpointList{ endpoint{offset: 5, endType: +1}, endpoint{offset: 3, endType: -1}, endpoint{offset: 3, endType: +1}, endpoint{offset: 1, endType: -1}, endpoint{offset: 4, endType: +1}, } sortedList := endpointList{ endpoint{offset: 1, endType: -1}, endpoint{offset: 3, endType: -1}, endpoint{offset: 3, endType: +1}, endpoint{offset: 4, endType: +1}, endpoint{offset: 5, endType: +1}, } sort.Sort(list) for i := range sortedList { if list[i] != sortedList[i] { t.Errorf("expected index %d of sorted list to be %v, instead %v", i, sortedList[i], list[i]) } } if len(list) != len(sortedList) { t.Errorf("exptected endpoint list to be size %d, instead %d", len(sortedList), len(list)) } }
// TestLeaderRemoveSelf verifies that a leader can remove itself // without panicking and future access to the range returns a // RangeNotFoundError (not RaftGroupDeletedError, and even before // the ReplicaGCQueue has run). func TestLeaderRemoveSelf(t *testing.T) { defer leaktest.AfterTest(t) mtc := startMultiTestContext(t, 2) defer mtc.Stop() // Disable the replica GC queue. This verifies that the replica is // considered removed even before the gc queue has run, and also // helps avoid a deadlock at shutdown. mtc.stores[0].DisableReplicaGCQueue(true) raftID := roachpb.RangeID(1) mtc.replicateRange(raftID, 1) // Remove the replica from first store. mtc.unreplicateRange(raftID, 0) getArgs := getArgs([]byte("a")) // Force the read command request a new lease. clock := mtc.clocks[0] header := roachpb.Header{} header.Timestamp = clock.Update(clock.Now().Add(int64(storage.DefaultLeaderLeaseDuration), 0)) // Expect get a RangeNotFoundError. _, pErr := client.SendWrappedWith(rg1(mtc.stores[0]), nil, header, &getArgs) if _, ok := pErr.GoError().(*roachpb.RangeNotFoundError); !ok { t.Fatalf("expect get RangeNotFoundError, actual get %v ", pErr) } }
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) } }
// Verify that adding two infos with different hops but same keys // always chooses the minimum hops. func TestAddInfoSameKeyDifferentHops(t *testing.T) { defer leaktest.AfterTest(t)() stopper := stop.NewStopper() defer stopper.Stop() is := newInfoStore(context.TODO(), 1, emptyAddr, stopper) info1 := is.newInfo(nil, time.Second) info1.Hops = 1 info2 := is.newInfo(nil, time.Second) info2.Value.Timestamp.WallTime = info1.Value.Timestamp.WallTime info2.Hops = 2 if err := is.addInfo("a", info1); err != nil { t.Errorf("failed insert: %s", err) } if err := is.addInfo("a", info2); err == nil { t.Errorf("shouldn't have inserted info 2: %s", err) } i := is.getInfo("a") if i.Hops != info1.Hops || !proto.Equal(i, info1) { t.Error("failed to properly combine hops and value", i) } // Try yet another info, with lower hops yet (0). info3 := is.newInfo(nil, time.Second) if err := is.addInfo("a", info3); err != nil { t.Error(err) } i = is.getInfo("a") if i.Hops != info3.Hops || !proto.Equal(i, info3) { t.Error("failed to properly combine hops and value", i) } }
func TestStopper(t *testing.T) { defer leaktest.AfterTest(t) s := stop.NewStopper() running := make(chan struct{}) waiting := make(chan struct{}) cleanup := make(chan struct{}) s.RunWorker(func() { <-running }) go func() { <-s.ShouldStop() select { case <-waiting: t.Fatal("expected stopper to have blocked") case <-time.After(1 * time.Millisecond): // Expected. } close(running) select { case <-waiting: // Success. case <-time.After(100 * time.Millisecond): t.Fatal("stopper should have finished waiting") } close(cleanup) }() s.Stop() close(waiting) <-cleanup }
// TestRegisterCallback verifies that a callback is invoked when // registered if there are items which match its regexp in the // infostore. func TestRegisterCallback(t *testing.T) { defer leaktest.AfterTest(t)() stopper := stop.NewStopper() defer stopper.Stop() is := newInfoStore(context.TODO(), 1, emptyAddr, stopper) wg := &sync.WaitGroup{} cb := callbackRecord{wg: wg} i1 := is.newInfo(nil, time.Second) i2 := is.newInfo(nil, time.Second) if err := is.addInfo("key1", i1); err != nil { t.Fatal(err) } if err := is.addInfo("key2", i2); err != nil { t.Fatal(err) } wg.Add(2) is.registerCallback("key.*", cb.Add) wg.Wait() actKeys := cb.Keys() sort.Strings(actKeys) if expKeys := []string{"key1", "key2"}; !reflect.DeepEqual(actKeys, expKeys) { t.Errorf("expected %v, got %v", expKeys, cb.Keys()) } }
func TestStopperIsStopped(t *testing.T) { defer leaktest.AfterTest(t) s := stop.NewStopper() bc := newBlockingCloser() s.AddCloser(bc) go s.Stop() select { case <-s.ShouldStop(): case <-time.After(100 * time.Millisecond): t.Fatal("stopper should have finished waiting") } select { case <-s.IsStopped(): t.Fatal("expected blocked closer to prevent stop") case <-time.After(1 * time.Millisecond): // Expected. } bc.Unblock() select { case <-s.IsStopped(): // Expected case <-time.After(100 * time.Millisecond): t.Fatal("stopper should have finished stopping") } }
// TestIDAllocatorNegativeValue creates an ID allocator against an // increment key which is preset to a negative value. We verify that // the id allocator makes a double-alloc to make up the difference // and push the id allocation into positive integers. func TestIDAllocatorNegativeValue(t *testing.T) { defer leaktest.AfterTest(t) store, _, stopper := createTestStore(t) defer stopper.Stop() // Increment our key to a negative value. newValue, err := engine.MVCCIncrement(store.Engine(), nil, keys.RaftIDGenerator, store.ctx.Clock.Now(), nil, -1024) if err != nil { t.Fatal(err) } if newValue != -1024 { t.Errorf("expected new value to be -1024; got %d", newValue) } idAlloc, err := newIDAllocator(keys.RaftIDGenerator, store.ctx.DB, 2, 10, stopper) if err != nil { t.Errorf("failed to create IDAllocator: %v", err) } value, err := idAlloc.Allocate() if err != nil { t.Fatal(err) } if value != 2 { t.Errorf("expected id allocation to have value 2; got %d", value) } }
// TestBatchScanMaxWithDeleted verifies that if a deletion // in the updates map shadows an entry from the engine, the // max on a scan is still reached. func TestBatchScanMaxWithDeleted(t *testing.T) { defer leaktest.AfterTest(t) stopper := stop.NewStopper() defer stopper.Stop() e := NewInMem(roachpb.Attributes{}, 1<<20, stopper) b := e.NewBatch() defer b.Close() // Write two values. if err := e.Put(MVCCKey("a"), []byte("value1")); err != nil { t.Fatal(err) } if err := e.Put(MVCCKey("b"), []byte("value2")); err != nil { t.Fatal(err) } // Now, delete "a" in batch. if err := b.Clear(MVCCKey("a")); err != nil { t.Fatal(err) } // A scan with max=1 should scan "b". kvs, err := Scan(b, MVCCKey(roachpb.RKeyMin), MVCCKey(roachpb.RKeyMax), 1) if err != nil { t.Fatal(err) } if len(kvs) != 1 || !bytes.Equal(kvs[0].Key, []byte("b")) { t.Errorf("expected scan of \"b\"; got %v", kvs) } }
// TestMetricsRecording verifies that Node statistics are periodically recorded // as time series data. func TestMetricsRecording(t *testing.T) { defer leaktest.AfterTest(t) tsrv := &TestServer{} tsrv.Ctx = NewTestContext() tsrv.Ctx.MetricsFrequency = 5 * time.Millisecond if err := tsrv.Start(); err != nil { t.Fatal(err) } defer tsrv.Stop() checkTimeSeriesKey := func(now int64, keyName string) error { key := ts.MakeDataKey(keyName, "", ts.Resolution10s, now) data := &proto.InternalTimeSeriesData{} return tsrv.db.GetProto(key, data) } // Verify that metrics for the current timestamp are recorded. This should // be true very quickly. util.SucceedsWithin(t, time.Second, func() error { now := tsrv.Clock().PhysicalNow() if err := checkTimeSeriesKey(now, "cr.store.livebytes.1"); err != nil { return err } if err := checkTimeSeriesKey(now, "cr.node.sys.allocbytes.1"); err != nil { return err } return nil }) }
// TestBatchConcurrency verifies operation of batch when the // underlying engine has concurrent modifications to overlapping // keys. This should never happen with the way Cockroach uses // batches, but worth verifying. func TestBatchConcurrency(t *testing.T) { defer leaktest.AfterTest(t) stopper := stop.NewStopper() defer stopper.Stop() e := NewInMem(roachpb.Attributes{}, 1<<20, stopper) b := e.NewBatch() defer b.Close() // Write a merge to the batch. if err := b.Merge(MVCCKey("a"), appender("bar")); err != nil { t.Fatal(err) } val, err := b.Get(MVCCKey("a")) if err != nil { t.Fatal(err) } if !compareMergedValues(t, val, appender("bar")) { t.Error("mismatch of \"a\"") } // Write an engine value. if err := e.Put(MVCCKey("a"), appender("foo")); err != nil { t.Fatal(err) } // Now, read again and verify that the merge happens on top of the mod. val, err = b.Get(MVCCKey("a")) if err != nil { t.Fatal(err) } if !bytes.Equal(val, appender("foobar")) { t.Error("mismatch of \"a\"") } }
func TestReplicaSetSortByCommonAttributePrefix(t *testing.T) { defer leaktest.AfterTest(t) replicaAttrs := [][]string{ {"us-west-1a", "gpu"}, {"us-east-1a", "pdu1", "gpu"}, {"us-east-1a", "pdu1", "fio"}, {"breaker", "us-east-1a", "pdu1", "fio"}, {""}, {"us-west-1a", "pdu1", "fio"}, {"us-west-1a", "pdu1", "fio", "aux"}, } attrs := [][]string{ {"us-carl"}, {"us-west-1a", "pdu1", "fio"}, {"us-west-1a"}, {"", "pdu1", "fio"}, } for i, attr := range attrs { rs := ReplicaSlice{} for _, c := range replicaAttrs { rs = append(rs, ReplicaInfo{ NodeDesc: &roachpb.NodeDescriptor{ Attrs: roachpb.Attributes{Attrs: c}, }, }) } prefixLen := rs.SortByCommonAttributePrefix(attr) if !verifyOrdering(attr, rs, prefixLen) { t.Errorf("%d: attributes not ordered by %s or prefix length %d incorrect:\n%v", i, attr, prefixLen, rs) } } }
func TestInsecure(t *testing.T) { defer leaktest.AfterTest(t) // Start test server in insecure mode. s := &server.TestServer{} s.Ctx = server.NewTestContext() s.Ctx.Insecure = true if err := s.Start(); err != nil { t.Fatalf("Could not start server: %v", err) } t.Logf("Test server listening on %s: %s", s.Ctx.RequestScheme(), s.ServingAddr()) defer s.Stop() // We can't attempt a connection through HTTPS since the client just retries forever. // DB connection using plain HTTP. db, err := sql.Open("cockroach", "http://root@"+s.ServingAddr()) if err != nil { t.Fatal(err) } defer func() { _ = db.Close() }() if _, err := db.Exec(`SELECT 1`); err != nil { t.Fatal(err) } }