diff --git a/server/go.mod b/server/go.mod index fbec53771af7..0de479234862 100644 --- a/server/go.mod +++ b/server/go.mod @@ -11,6 +11,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/golang/protobuf v1.5.3 github.com/google/btree v1.1.2 + github.com/google/go-cmp v0.6.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 diff --git a/server/storage/backend/batch_tx_test.go b/server/storage/backend/batch_tx_test.go index 6fd2bbae6310..7b64ac56aa8b 100644 --- a/server/storage/backend/batch_tx_test.go +++ b/server/storage/backend/batch_tx_test.go @@ -19,6 +19,8 @@ import ( "testing" "time" + "github.com/google/go-cmp/cmp" + bolt "go.etcd.io/bbolt" "go.etcd.io/etcd/server/v3/storage/backend" betesting "go.etcd.io/etcd/server/v3/storage/backend/testing" @@ -205,3 +207,38 @@ func TestBatchTxBatchLimitCommit(t *testing.T) { return nil }) } + +func TestBatchReadMatch(t *testing.T) { + b, _ := betesting.NewTmpBackend(t, time.Hour, 10000) + defer betesting.Close(t, b) + + tx := b.BatchTx() + + tx.Lock() + tx.UnsafeCreateBucket(schema.Test) + tx.UnsafePut(schema.Test, []byte("foo"), []byte("bar")) + tx.Unlock() + tx.Commit() + + checkKeyValueMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo")) + + tx.Lock() + tx.UnsafeDelete(schema.Test, []byte("foo")) + tx.Unlock() + + checkKeyValueMatch(t, b.BatchTx(), b.ReadTx(), []byte("foo")) +} + +func checkKeyValueMatch(t *testing.T, tx backend.BatchTx, rtx backend.ReadTx, key []byte) { + tx.Lock() + ks1, _ := tx.UnsafeRange(schema.Test, key, nil, 0) + tx.Unlock() + + rtx.RLock() + ks2, _ := rtx.UnsafeRange(schema.Test, key, nil, 0) + rtx.RUnlock() + + if diff := cmp.Diff(ks1, ks2); diff != "" { + t.Errorf("response on read and batch transaction doesn't match, diff: %s", diff) + } +}