vendor: update all dependencies
This commit is contained in:
+1
-1
@@ -867,7 +867,7 @@ func (iac *InstanceAdminClient) Clusters(ctx context.Context, instanceId string)
|
||||
// GetCluster fetches a cluster in an instance
|
||||
func (iac *InstanceAdminClient) GetCluster(ctx context.Context, instanceID, clusterID string) (*ClusterInfo, error) {
|
||||
ctx = mergeOutgoingMetadata(ctx, iac.md)
|
||||
req := &btapb.GetClusterRequest{Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters" + clusterID}
|
||||
req := &btapb.GetClusterRequest{Name: "projects/" + iac.project + "/instances/" + instanceID + "/clusters/" + clusterID}
|
||||
c, err := iac.iClient.GetCluster(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+5
-6
@@ -15,18 +15,17 @@
|
||||
package bigtable
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/internal/testutil"
|
||||
|
||||
"fmt"
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/api/iterator"
|
||||
btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func TestAdminIntegration(t *testing.T) {
|
||||
@@ -102,7 +101,7 @@ func TestAdminIntegration(t *testing.T) {
|
||||
t.Errorf("adminClient.Tables returned %#v, want %#v", got, want)
|
||||
}
|
||||
|
||||
adminClient.WaitForReplication(ctx, "mytable")
|
||||
must(adminClient.WaitForReplication(ctx, "mytable"))
|
||||
|
||||
if err := adminClient.DeleteTable(ctx, "myothertable"); err != nil {
|
||||
t.Fatalf("Deleting table: %v", err)
|
||||
@@ -172,13 +171,13 @@ func TestAdminIntegration(t *testing.T) {
|
||||
}
|
||||
|
||||
var gotRowCount int
|
||||
tbl.ReadRows(ctx, RowRange{}, func(row Row) bool {
|
||||
must(tbl.ReadRows(ctx, RowRange{}, func(row Row) bool {
|
||||
gotRowCount += 1
|
||||
if !strings.HasPrefix(row.Key(), "b") {
|
||||
t.Errorf("Invalid row after dropping range: %v", row)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}))
|
||||
if gotRowCount != 5 {
|
||||
t.Errorf("Invalid row count after dropping range: got %v, want %v", gotRowCount, 5)
|
||||
}
|
||||
|
||||
+3
@@ -192,6 +192,9 @@ func (t *Table) ReadRows(ctx context.Context, arg RowSet, f func(Row) bool, opts
|
||||
tracePrintf(ctx, attrMap, "Retry details in ReadRows")
|
||||
return err
|
||||
}
|
||||
attrMap["time_secs"] = time.Since(startTime).Seconds()
|
||||
attrMap["rowCount"] = len(res.Chunks)
|
||||
tracePrintf(ctx, attrMap, "Details in ReadRows")
|
||||
|
||||
for _, cc := range res.Chunks {
|
||||
row, err := cr.Process(cc)
|
||||
|
||||
+29
-26
@@ -317,7 +317,8 @@ func (s *server) ReadRows(req *btpb.ReadRowsRequest, stream btpb.Bigtable_ReadRo
|
||||
return true
|
||||
}
|
||||
|
||||
if req.Rows != nil {
|
||||
if req.Rows != nil &&
|
||||
len(req.Rows.RowKeys)+len(req.Rows.RowRanges) > 0 {
|
||||
// Add the explicitly given keys
|
||||
for _, key := range req.Rows.RowKeys {
|
||||
k := string(key)
|
||||
@@ -698,8 +699,7 @@ func (s *server) MutateRows(req *btpb.MutateRowsRequest, stream btpb.Bigtable_Mu
|
||||
}
|
||||
r.mu.Unlock()
|
||||
}
|
||||
stream.Send(res)
|
||||
return nil
|
||||
return stream.Send(res)
|
||||
}
|
||||
|
||||
func (s *server) CheckAndMutateRow(ctx context.Context, req *btpb.CheckAndMutateRowRequest) (*btpb.CheckAndMutateRowResponse, error) {
|
||||
@@ -861,12 +861,13 @@ func (s *server) ReadModifyWriteRow(ctx context.Context, req *btpb.ReadModifyWri
|
||||
if !ok {
|
||||
return nil, status.Errorf(codes.NotFound, "table %q not found", req.TableName)
|
||||
}
|
||||
updates := make(map[string]cell) // copy of updated cells; keyed by full column name
|
||||
|
||||
fs := tbl.columnFamilies()
|
||||
|
||||
rowKey := string(req.RowKey)
|
||||
r := tbl.mutableRow(rowKey)
|
||||
resultRow := newRow(rowKey) // copy of updated cells
|
||||
|
||||
// This must be done before the row lock, acquired below, is released.
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
@@ -914,35 +915,37 @@ func (s *server) ReadModifyWriteRow(ctx context.Context, req *btpb.ReadModifyWri
|
||||
binary.BigEndian.PutUint64(val[:], uint64(v))
|
||||
newCell = cell{ts: ts, value: val[:]}
|
||||
}
|
||||
key := strings.Join([]string{fam, col}, ":")
|
||||
updates[key] = newCell
|
||||
|
||||
// Store the new cell
|
||||
f.cells[col] = appendOrReplaceCell(f.cellsByColumn(col), newCell)
|
||||
|
||||
// Store a copy for the result row
|
||||
resultFamily := resultRow.getOrCreateFamily(fam, fs[fam].order)
|
||||
resultFamily.cellsByColumn(col) // create the column
|
||||
resultFamily.cells[col] = []cell{newCell} // overwrite the cells
|
||||
}
|
||||
|
||||
// Build the response using the result row
|
||||
res := &btpb.Row{
|
||||
Key: req.RowKey,
|
||||
Key: req.RowKey,
|
||||
Families: make([]*btpb.Family, len(resultRow.families)),
|
||||
}
|
||||
for col, cell := range updates {
|
||||
i := strings.Index(col, ":")
|
||||
fam, qual := col[:i], col[i+1:]
|
||||
var f *btpb.Family
|
||||
for _, ff := range res.Families {
|
||||
if ff.Name == fam {
|
||||
f = ff
|
||||
break
|
||||
|
||||
for i, family := range resultRow.sortedFamilies() {
|
||||
res.Families[i] = &btpb.Family{
|
||||
Name: family.name,
|
||||
Columns: make([]*btpb.Column, len(family.colNames)),
|
||||
}
|
||||
|
||||
for j, colName := range family.colNames {
|
||||
res.Families[i].Columns[j] = &btpb.Column{
|
||||
Qualifier: []byte(colName),
|
||||
Cells: []*btpb.Cell{{
|
||||
TimestampMicros: family.cells[colName][0].ts,
|
||||
Value: family.cells[colName][0].value,
|
||||
}},
|
||||
}
|
||||
}
|
||||
if f == nil {
|
||||
f = &btpb.Family{Name: fam}
|
||||
res.Families = append(res.Families, f)
|
||||
}
|
||||
f.Columns = append(f.Columns, &btpb.Column{
|
||||
Qualifier: []byte(qual),
|
||||
Cells: []*btpb.Cell{{
|
||||
TimestampMicros: cell.ts,
|
||||
Value: cell.value,
|
||||
}},
|
||||
})
|
||||
}
|
||||
return &btpb.ReadModifyWriteRowResponse{Row: res}, nil
|
||||
}
|
||||
|
||||
+89
-2
@@ -23,6 +23,8 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"golang.org/x/net/context"
|
||||
btapb "google.golang.org/genproto/googleapis/bigtable/admin/v2"
|
||||
btpb "google.golang.org/genproto/googleapis/bigtable/v2"
|
||||
@@ -99,7 +101,9 @@ func TestConcurrentMutationsReadModifyAndGC(t *testing.T) {
|
||||
RowKey: []byte(fmt.Sprint(rand.Intn(100))),
|
||||
Mutations: ms(),
|
||||
}
|
||||
s.MutateRow(ctx, req)
|
||||
if _, err := s.MutateRow(ctx, req); err != nil {
|
||||
panic(err) // can't use t.Fatal in goroutine
|
||||
}
|
||||
}
|
||||
}()
|
||||
wg.Add(1)
|
||||
@@ -548,7 +552,9 @@ func TestReadRowsOrder(t *testing.T) {
|
||||
}
|
||||
}
|
||||
for i := count; i > 0; i-- {
|
||||
s.ReadModifyWriteRow(ctx, rmw(i))
|
||||
if _, err := s.ReadModifyWriteRow(ctx, rmw(i)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
req = &btpb.ReadRowsRequest{
|
||||
TableName: tblInfo.Name,
|
||||
@@ -621,6 +627,87 @@ func TestCheckAndMutateRowWithoutPredicate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServer_ReadModifyWriteRow(t *testing.T) {
|
||||
s := &server{
|
||||
tables: make(map[string]*table),
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
newTbl := btapb.Table{
|
||||
ColumnFamilies: map[string]*btapb.ColumnFamily{
|
||||
"cf": {GcRule: &btapb.GcRule{Rule: &btapb.GcRule_MaxNumVersions{MaxNumVersions: 1}}},
|
||||
},
|
||||
}
|
||||
tbl, err := s.CreateTable(ctx, &btapb.CreateTableRequest{Parent: "cluster", TableId: "t", Table: &newTbl})
|
||||
if err != nil {
|
||||
t.Fatalf("Creating table: %v", err)
|
||||
}
|
||||
|
||||
req := &btpb.ReadModifyWriteRowRequest{
|
||||
TableName: tbl.Name,
|
||||
RowKey: []byte("row-key"),
|
||||
Rules: []*btpb.ReadModifyWriteRule{
|
||||
{
|
||||
FamilyName: "cf",
|
||||
ColumnQualifier: []byte("q1"),
|
||||
Rule: &btpb.ReadModifyWriteRule_AppendValue{
|
||||
AppendValue: []byte("a"),
|
||||
},
|
||||
},
|
||||
// multiple ops for same cell
|
||||
{
|
||||
FamilyName: "cf",
|
||||
ColumnQualifier: []byte("q1"),
|
||||
Rule: &btpb.ReadModifyWriteRule_AppendValue{
|
||||
AppendValue: []byte("b"),
|
||||
},
|
||||
},
|
||||
// different cell whose qualifier should sort before the prior rules
|
||||
{
|
||||
FamilyName: "cf",
|
||||
ColumnQualifier: []byte("q0"),
|
||||
Rule: &btpb.ReadModifyWriteRule_IncrementAmount{
|
||||
IncrementAmount: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
got, err := s.ReadModifyWriteRow(ctx, req)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("ReadModifyWriteRow error: %v", err)
|
||||
}
|
||||
|
||||
want := &btpb.ReadModifyWriteRowResponse{
|
||||
Row: &btpb.Row{
|
||||
Key: []byte("row-key"),
|
||||
Families: []*btpb.Family{{
|
||||
Name: "cf",
|
||||
Columns: []*btpb.Column{
|
||||
{
|
||||
Qualifier: []byte("q0"),
|
||||
Cells: []*btpb.Cell{{
|
||||
Value: []byte{0, 0, 0, 0, 0, 0, 0, 1},
|
||||
}},
|
||||
},
|
||||
{
|
||||
Qualifier: []byte("q1"),
|
||||
Cells: []*btpb.Cell{{
|
||||
Value: []byte("ab"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
diff := cmp.Diff(got, want, cmpopts.IgnoreFields(btpb.Cell{}, "TimestampMicros"))
|
||||
if diff != "" {
|
||||
t.Errorf("unexpected response: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to populate table data
|
||||
func populateTable(ctx context.Context, s *server) (*btapb.Table, error) {
|
||||
newTbl := btapb.Table{
|
||||
|
||||
+43
-12
@@ -332,7 +332,8 @@ var commands = []struct {
|
||||
Name: "lookup",
|
||||
Desc: "Read from a single row",
|
||||
do: doLookup,
|
||||
Usage: "cbt lookup <table> <row> [app-profile=<app profile id>]\n" +
|
||||
Usage: "cbt lookup <table> <row> [cells-per-column=<n>] [app-profile=<app profile id>]\n" +
|
||||
" cells-per-column=<n> Read only this many cells per column\n" +
|
||||
" app-profile=<app profile id> The app profile id to use for the request (replication alpha)\n",
|
||||
Required: cbtconfig.ProjectAndInstanceRequired,
|
||||
},
|
||||
@@ -356,12 +357,13 @@ var commands = []struct {
|
||||
Desc: "Read rows",
|
||||
do: doRead,
|
||||
Usage: "cbt read <table> [start=<row>] [end=<row>] [prefix=<prefix>]" +
|
||||
" [regex=<regex>] [count=<n>] [app-profile=<app profile id>]\n" +
|
||||
" [regex=<regex>] [count=<n>] [cells-per-column=<n>] [app-profile=<app profile id>]\n" +
|
||||
" start=<row> Start reading at this row\n" +
|
||||
" end=<row> Stop reading before this row\n" +
|
||||
" prefix=<prefix> Read rows with this prefix\n" +
|
||||
" regex=<regex> Read rows with keys matching this regex\n" +
|
||||
" count=<n> Read only this many rows\n" +
|
||||
" cells-per-column=<n> Read only this many cells per column\n" +
|
||||
" app-profile=<app profile id> The app profile id to use for the request (replication alpha)\n",
|
||||
Required: cbtconfig.ProjectAndInstanceRequired,
|
||||
},
|
||||
@@ -850,19 +852,34 @@ func doListClusters(ctx context.Context, args ...string) {
|
||||
|
||||
func doLookup(ctx context.Context, args ...string) {
|
||||
if len(args) < 2 {
|
||||
log.Fatalf("usage: cbt lookup <table> <row> [app-profile=<app profile id>]")
|
||||
log.Fatalf("usage: cbt lookup <table> <row> [cells-per-column=<n>] [app-profile=<app profile id>]")
|
||||
}
|
||||
var appProfile string
|
||||
if len(args) > 2 {
|
||||
i := strings.Index(args[2], "=")
|
||||
|
||||
parsed := make(map[string]string)
|
||||
for _, arg := range args[2:] {
|
||||
i := strings.Index(arg, "=")
|
||||
if i < 0 {
|
||||
log.Fatalf("Bad arg %q", args[2])
|
||||
log.Fatalf("Bad arg %q", arg)
|
||||
}
|
||||
appProfile = strings.Split(args[2], "=")[1]
|
||||
key, val := arg[:i], arg[i+1:]
|
||||
switch key {
|
||||
default:
|
||||
log.Fatalf("Unknown arg key %q", key)
|
||||
case "cells-per-column", "app-profile":
|
||||
parsed[key] = val
|
||||
}
|
||||
}
|
||||
var opts []bigtable.ReadOption
|
||||
if cellsPerColumn := parsed["cells-per-column"]; cellsPerColumn != "" {
|
||||
n, err := strconv.Atoi(cellsPerColumn)
|
||||
if err != nil {
|
||||
log.Fatalf("Bad number of cells per column %q: %v", cellsPerColumn, err)
|
||||
}
|
||||
opts = append(opts, bigtable.RowFilter(bigtable.LatestNFilter(n)))
|
||||
}
|
||||
table, row := args[0], args[1]
|
||||
tbl := getClient(bigtable.ClientConfig{AppProfile: appProfile}).Open(table)
|
||||
r, err := tbl.ReadRow(ctx, row)
|
||||
tbl := getClient(bigtable.ClientConfig{AppProfile: parsed["app-profile"]}).Open(table)
|
||||
r, err := tbl.ReadRow(ctx, row, opts...)
|
||||
if err != nil {
|
||||
log.Fatalf("Reading row: %v", err)
|
||||
}
|
||||
@@ -995,7 +1012,7 @@ func doRead(ctx context.Context, args ...string) {
|
||||
case "limit":
|
||||
// Be nicer; we used to support this, but renamed it to "end".
|
||||
log.Fatalf("Unknown arg key %q; did you mean %q?", key, "end")
|
||||
case "start", "end", "prefix", "count", "regex", "app-profile":
|
||||
case "start", "end", "prefix", "count", "cells-per-column", "regex", "app-profile":
|
||||
parsed[key] = val
|
||||
}
|
||||
}
|
||||
@@ -1021,8 +1038,22 @@ func doRead(ctx context.Context, args ...string) {
|
||||
}
|
||||
opts = append(opts, bigtable.LimitRows(n))
|
||||
}
|
||||
|
||||
var filters []bigtable.Filter
|
||||
if cellsPerColumn := parsed["cells-per-column"]; cellsPerColumn != "" {
|
||||
n, err := strconv.Atoi(cellsPerColumn)
|
||||
if err != nil {
|
||||
log.Fatalf("Bad number of cells per column %q: %v", cellsPerColumn, err)
|
||||
}
|
||||
filters = append(filters, bigtable.LatestNFilter(n))
|
||||
}
|
||||
if regex := parsed["regex"]; regex != "" {
|
||||
opts = append(opts, bigtable.RowFilter(bigtable.RowKeyFilter(regex)))
|
||||
filters = append(filters, bigtable.RowKeyFilter(regex))
|
||||
}
|
||||
if len(filters) > 1 {
|
||||
opts = append(opts, bigtable.RowFilter(bigtable.ChainFilters(filters...)))
|
||||
} else if len(filters) == 1 {
|
||||
opts = append(opts, bigtable.RowFilter(filters[0]))
|
||||
}
|
||||
|
||||
// TODO(dsymonds): Support filters.
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ func main() {
|
||||
go func() {
|
||||
s := <-c
|
||||
log.Printf("Caught %v, cleaning scratch table.", s)
|
||||
adminClient.DeleteTable(context.Background(), *scratchTable)
|
||||
_ = adminClient.DeleteTable(context.Background(), *scratchTable)
|
||||
os.Exit(1)
|
||||
}()
|
||||
|
||||
|
||||
+4
-6
@@ -19,6 +19,10 @@ Package bigtable is an API to Google Cloud Bigtable.
|
||||
|
||||
See https://cloud.google.com/bigtable/docs/ for general product documentation.
|
||||
|
||||
See https://godoc.org/cloud.google.com/go for authentication, timeouts,
|
||||
connection pooling and similar aspects of this package.
|
||||
|
||||
|
||||
Setup and Credentials
|
||||
|
||||
Use NewClient or NewAdminClient to create a client that can be used to access
|
||||
@@ -92,12 +96,6 @@ If a read or write operation encounters a transient error it will be retried unt
|
||||
response, an unretryable error or the context deadline is reached. Non-idempotent writes (where
|
||||
the timestamp is set to ServerTime) will not be retried. In the case of ReadRows, retried calls
|
||||
will not re-scan rows that have already been processed.
|
||||
|
||||
Authentication
|
||||
|
||||
See examples of authorization and authentication at
|
||||
https://godoc.org/cloud.google.com/go#pkg-examples.
|
||||
|
||||
*/
|
||||
package bigtable // import "cloud.google.com/go/bigtable"
|
||||
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ func TestRandomizedDelays(t *testing.T) {
|
||||
deadline := time.Now().Add(1 * time.Second)
|
||||
ctx, _ := context.WithDeadline(context.Background(), deadline)
|
||||
var invokeTime time.Time
|
||||
Invoke(ctx, func(childCtx context.Context) error {
|
||||
_ = Invoke(ctx, func(childCtx context.Context) error {
|
||||
// Keep failing, make sure we never slept more than max (plus a fudge factor)
|
||||
if !invokeTime.IsZero() {
|
||||
if got, want := time.Since(invokeTime), max; got > (want + 20*time.Millisecond) {
|
||||
|
||||
+8
-3
@@ -123,10 +123,15 @@ func (agg *Aggregate) String() string {
|
||||
|
||||
// WriteCSV writes a csv file to the given Writer,
|
||||
// with a header row and one row per aggregate.
|
||||
func WriteCSV(aggs []*Aggregate, iow io.Writer) error {
|
||||
func WriteCSV(aggs []*Aggregate, iow io.Writer) (err error) {
|
||||
w := csv.NewWriter(iow)
|
||||
defer w.Flush()
|
||||
err := w.Write([]string{"name", "count", "errors", "min", "median", "max", "p75", "p90", "p95", "p99"})
|
||||
defer func() {
|
||||
w.Flush()
|
||||
if err == nil {
|
||||
err = w.Error()
|
||||
}
|
||||
}()
|
||||
err = w.Write([]string{"name", "count", "errors", "min", "median", "max", "p75", "p90", "p95", "p99"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+20
-13
@@ -60,10 +60,10 @@ func TestSingleCell(t *testing.T) {
|
||||
func TestMultipleCells(t *testing.T) {
|
||||
cr := newChunkReader()
|
||||
|
||||
cr.Process(cc("rs", "fm1", "col1", 0, "val1", 0, false))
|
||||
cr.Process(cc("rs", "fm1", "col1", 1, "val2", 0, false))
|
||||
cr.Process(cc("rs", "fm1", "col2", 0, "val3", 0, false))
|
||||
cr.Process(cc("rs", "fm2", "col1", 0, "val4", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col1", 1, "val2", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col2", 0, "val3", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm2", "col1", 0, "val4", 0, false))
|
||||
row, err := cr.Process(cc("rs", "fm2", "col2", 1, "extralongval5", 0, true))
|
||||
if err != nil {
|
||||
t.Fatalf("Processing chunk: %v", err)
|
||||
@@ -95,8 +95,8 @@ func TestMultipleCells(t *testing.T) {
|
||||
func TestSplitCells(t *testing.T) {
|
||||
cr := newChunkReader()
|
||||
|
||||
cr.Process(cc("rs", "fm1", "col1", 0, "hello ", 11, false))
|
||||
cr.Process(ccData("world", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "hello ", 11, false))
|
||||
mustProcess(t, cr, ccData("world", 0, false))
|
||||
row, err := cr.Process(cc("rs", "fm1", "col2", 0, "val2", 0, true))
|
||||
if err != nil {
|
||||
t.Fatalf("Processing chunk: %v", err)
|
||||
@@ -171,12 +171,11 @@ func TestBlankQualifier(t *testing.T) {
|
||||
|
||||
func TestReset(t *testing.T) {
|
||||
cr := newChunkReader()
|
||||
|
||||
cr.Process(cc("rs", "fm1", "col1", 0, "val1", 0, false))
|
||||
cr.Process(cc("rs", "fm1", "col1", 1, "val2", 0, false))
|
||||
cr.Process(cc("rs", "fm1", "col2", 0, "val3", 0, false))
|
||||
cr.Process(ccReset())
|
||||
row, _ := cr.Process(cc("rs1", "fm1", "col1", 1, "val1", 0, true))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col1", 1, "val2", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col2", 0, "val3", 0, false))
|
||||
mustProcess(t, cr, ccReset())
|
||||
row := mustProcess(t, cr, cc("rs1", "fm1", "col1", 1, "val1", 0, true))
|
||||
want := []ReadItem{ri("rs1", "fm1", "col1", 1, "val1")}
|
||||
if !testutil.Equal(row["fm1"], want) {
|
||||
t.Fatalf("Reset: got: %v\nwant: %v\n", row["fm1"], want)
|
||||
@@ -189,13 +188,21 @@ func TestReset(t *testing.T) {
|
||||
func TestNewFamEmptyQualifier(t *testing.T) {
|
||||
cr := newChunkReader()
|
||||
|
||||
cr.Process(cc("rs", "fm1", "col1", 0, "val1", 0, false))
|
||||
mustProcess(t, cr, cc("rs", "fm1", "col1", 0, "val1", 0, false))
|
||||
_, err := cr.Process(cc(nilStr, "fm2", nilStr, 0, "val2", 0, true))
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error on second chunk with no qualifier set")
|
||||
}
|
||||
}
|
||||
|
||||
func mustProcess(t *testing.T, cr *chunkReader, cc *btspb.ReadRowsResponse_CellChunk) Row {
|
||||
row, err := cr.Process(cc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
||||
// The read rows acceptance test reads a json file specifying a number of tests,
|
||||
// each consisting of one or more cell chunk text protos and one or more resulting
|
||||
// cells or errors.
|
||||
|
||||
+18
-13
@@ -179,28 +179,28 @@ func TestRetryApplyBulk(t *testing.T) {
|
||||
f = func(ss grpc.ServerStream) error {
|
||||
var err error
|
||||
req := new(btpb.MutateRowsRequest)
|
||||
ss.RecvMsg(req)
|
||||
must(ss.RecvMsg(req))
|
||||
switch errCount {
|
||||
case 0:
|
||||
// Retryable request failure
|
||||
err = status.Errorf(codes.Unavailable, "")
|
||||
case 1:
|
||||
// Two mutations fail
|
||||
writeMutateRowsResponse(ss, codes.Unavailable, codes.OK, codes.Aborted)
|
||||
must(writeMutateRowsResponse(ss, codes.Unavailable, codes.OK, codes.Aborted))
|
||||
err = nil
|
||||
case 2:
|
||||
// Two failures were retried. One will succeed.
|
||||
if want, got := 2, len(req.Entries); want != got {
|
||||
t.Errorf("2 bulk retries, got: %d, want %d", got, want)
|
||||
}
|
||||
writeMutateRowsResponse(ss, codes.OK, codes.Aborted)
|
||||
must(writeMutateRowsResponse(ss, codes.OK, codes.Aborted))
|
||||
err = nil
|
||||
case 3:
|
||||
// One failure was retried and will succeed.
|
||||
if want, got := 1, len(req.Entries); want != got {
|
||||
t.Errorf("1 bulk retry, got: %d, want %d", got, want)
|
||||
}
|
||||
writeMutateRowsResponse(ss, codes.OK)
|
||||
must(writeMutateRowsResponse(ss, codes.OK))
|
||||
err = nil
|
||||
}
|
||||
errCount++
|
||||
@@ -218,12 +218,12 @@ func TestRetryApplyBulk(t *testing.T) {
|
||||
f = func(ss grpc.ServerStream) error {
|
||||
var err error
|
||||
req := new(btpb.MutateRowsRequest)
|
||||
ss.RecvMsg(req)
|
||||
must(ss.RecvMsg(req))
|
||||
switch errCount {
|
||||
case 0:
|
||||
// Give non-idempotent mutation a retryable error code.
|
||||
// Nothing should be retried.
|
||||
writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.Aborted)
|
||||
must(writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.Aborted))
|
||||
err = nil
|
||||
case 1:
|
||||
t.Errorf("unretryable errors: got one retry, want no retries")
|
||||
@@ -245,8 +245,7 @@ func TestRetryApplyBulk(t *testing.T) {
|
||||
|
||||
// Test individual errors and a deadline exceeded
|
||||
f = func(ss grpc.ServerStream) error {
|
||||
writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.OK, codes.Aborted)
|
||||
return nil
|
||||
return writeMutateRowsResponse(ss, codes.FailedPrecondition, codes.OK, codes.Aborted)
|
||||
}
|
||||
ctx, _ = context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
errors, err = tbl.ApplyBulk(ctx, []string{"row1", "row2", "row3"}, []*Mutation{m1, m2, m3})
|
||||
@@ -320,7 +319,7 @@ func TestRetryReadRows(t *testing.T) {
|
||||
f = func(ss grpc.ServerStream) error {
|
||||
var err error
|
||||
req := new(btpb.ReadRowsRequest)
|
||||
ss.RecvMsg(req)
|
||||
must(ss.RecvMsg(req))
|
||||
switch errCount {
|
||||
case 0:
|
||||
// Retryable request failure
|
||||
@@ -330,7 +329,7 @@ func TestRetryReadRows(t *testing.T) {
|
||||
if want, got := "a", string(req.Rows.RowRanges[0].GetStartKeyClosed()); want != got {
|
||||
t.Errorf("first retry, no data received yet: got %q, want %q", got, want)
|
||||
}
|
||||
writeReadRowsResponse(ss, "a", "b")
|
||||
must(writeReadRowsResponse(ss, "a", "b"))
|
||||
err = status.Errorf(codes.Unavailable, "")
|
||||
case 2:
|
||||
// Retryable request failure
|
||||
@@ -340,7 +339,7 @@ func TestRetryReadRows(t *testing.T) {
|
||||
err = status.Errorf(codes.Unavailable, "")
|
||||
case 3:
|
||||
// Write two more rows
|
||||
writeReadRowsResponse(ss, "c", "d")
|
||||
must(writeReadRowsResponse(ss, "c", "d"))
|
||||
err = nil
|
||||
}
|
||||
errCount++
|
||||
@@ -348,10 +347,10 @@ func TestRetryReadRows(t *testing.T) {
|
||||
}
|
||||
|
||||
var got []string
|
||||
tbl.ReadRows(ctx, NewRange("a", "z"), func(r Row) bool {
|
||||
must(tbl.ReadRows(ctx, NewRange("a", "z"), func(r Row) bool {
|
||||
got = append(got, r.Key())
|
||||
return true
|
||||
})
|
||||
}))
|
||||
want := []string{"a", "b", "c", "d"}
|
||||
if !testutil.Equal(got, want) {
|
||||
t.Errorf("retry range integration: got %v, want %v", got, want)
|
||||
@@ -370,3 +369,9 @@ func writeReadRowsResponse(ss grpc.ServerStream, rowKeys ...string) error {
|
||||
}
|
||||
return ss.SendMsg(&btpb.ReadRowsResponse{Chunks: chunks})
|
||||
}
|
||||
|
||||
func must(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user