// Indirectly this tests that the transaction remembers the NodeID of the node // being read from correctly, at least in this simple case. Not remembering the // node would lead to thousands of transaction restarts and almost certainly a // test timeout. func TestUncertaintyRestarts(t *testing.T) { defer leaktest.AfterTest(t) s := createTestDB(t) defer s.Stop() // Set a large offset so that a busy restart-loop // really shows. Also makes sure that the values // we write in the future below don't actually // wind up in the past. offset := 4000 * time.Millisecond s.Clock.SetMaxOffset(offset) key := roachpb.Key("key") value := roachpb.Value{ Bytes: nil, // Set for each Put } // With the correct restart behaviour, we see only one restart // and the value read is the very first one (as nothing else // has been written) wantedBytes := []byte("value-0") i := -1 tErr := s.DB.Txn(func(txn *client.Txn) error { i++ s.Manual.Increment(1) futureTS := s.Clock.Now() futureTS.WallTime++ value.Bytes = []byte(fmt.Sprintf("value-%d", i)) if err := engine.MVCCPut(s.Eng, nil, key, futureTS, value, nil); err != nil { t.Fatal(err) } gr, err := txn.Get(key) if err != nil { return err } if !gr.Exists() || !bytes.Equal(gr.ValueBytes(), wantedBytes) { t.Fatalf("%d: read wrong value: %v, wanted %q", i, gr.Value, wantedBytes) } return nil }) if i != 1 { t.Errorf("txn restarted %d times, expected only one restart", i) } if tErr != nil { t.Fatal(tErr) } }