Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Unified Diff: impl/memory/datastore_test.go

Issue 1335083002: Add emulation of transaction retries to memory impl of RunInTransaction. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: add Testable() to non-Raw interfaces Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « impl/memory/datastore_query_execution_test.go ('k') | impl/memory/taskqueue_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: impl/memory/datastore_test.go
diff --git a/impl/memory/datastore_test.go b/impl/memory/datastore_test.go
index 4cfffbd47b97c04341501b6d7980fe02cb86fb2f..73a3dd50fbc9b59e36f0e0bb3ff5645a25e9adb9 100644
--- a/impl/memory/datastore_test.go
+++ b/impl/memory/datastore_test.go
@@ -301,7 +301,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) {
So(f.Val, ShouldEqual, 10) // still gets 10
return nil
- }, nil)
+ }, &dsS.TransactionOptions{Attempts: 1})
So(err.Error(), ShouldContainSubstring, "concurrent")
f := &Foo{Id: 1}
@@ -333,7 +333,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) {
Convey("Concurrent transactions only accept one set of changes", func() {
// Note: I think this implementation is actually /slightly/ wrong.
- // Accorting to my read of the docs for appengine, when you open a
+ // According to my read of the docs for appengine, when you open a
// transaction it actually (essentially) holds a reference to the
// entire datastore. Our implementation takes a snapshot of the
// entity group as soon as something observes/affects it.
@@ -417,9 +417,63 @@ func TestDatastoreSingleReadWriter(t *testing.T) {
So(f.Val, ShouldEqual, 10)
})
})
+
+ Convey("Transaction retries", func() {
+ tst := ds.Testable()
+ Reset(func() { tst.SetTransactionRetryCount(0) })
+
+ Convey("SetTransactionRetryCount set to zere", func() {
+ tst.SetTransactionRetryCount(0)
+ calls := 0
+ So(ds.RunInTransaction(func(c context.Context) error {
+ calls++
+ return nil
+ }, nil), ShouldBeNil)
+ So(calls, ShouldEqual, 1)
+ })
+
+ Convey("default TransactionOptions is 3 attempts", func() {
+ tst.SetTransactionRetryCount(100) // more than 3
+ calls := 0
+ So(ds.RunInTransaction(func(c context.Context) error {
+ calls++
+ return nil
+ }, nil), ShouldEqual, dsS.ErrConcurrentTransaction)
+ So(calls, ShouldEqual, 3)
+ })
+
+ Convey("non-default TransactionOptions ", func() {
+ tst.SetTransactionRetryCount(100) // more than 20
+ calls := 0
+ So(ds.RunInTransaction(func(c context.Context) error {
+ calls++
+ return nil
+ }, &dsS.TransactionOptions{Attempts: 20}), ShouldEqual, dsS.ErrConcurrentTransaction)
+ So(calls, ShouldEqual, 20)
+ })
+
+ Convey("SetTransactionRetryCount is respected", func() {
+ tst.SetTransactionRetryCount(1) // less than 3
+ calls := 0
+ So(ds.RunInTransaction(func(c context.Context) error {
+ calls++
+ return nil
+ }, nil), ShouldBeNil)
+ So(calls, ShouldEqual, 2)
+ })
+
+ Convey("fatal errors are not retried", func() {
+ tst.SetTransactionRetryCount(1)
+ calls := 0
+ So(ds.RunInTransaction(func(c context.Context) error {
+ calls++
+ return fmt.Errorf("omg")
+ }, nil).Error(), ShouldEqual, "omg")
+ So(calls, ShouldEqual, 1)
+ })
+ })
})
})
-
})
}
@@ -446,7 +500,7 @@ func TestCompoundIndexes(t *testing.T) {
c := Use(context.Background())
ds := dsS.Get(c)
- t := ds.Raw().Testable().(*dsImpl)
+ t := ds.Testable().(*dsImpl)
head := t.data.head
So(ds.Put(&Model{1, []string{"hello", "world"}, []int64{10, 11}}), ShouldBeNil)
« no previous file with comments | « impl/memory/datastore_query_execution_test.go ('k') | impl/memory/taskqueue_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698