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

Side by Side 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: behave identically to prod retry logic 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package memory 5 package memory
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "testing" 9 "testing"
10 10
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 So(txnDS.Get(f), ShouldBeNil) 294 So(txnDS.Get(f), ShouldBeNil)
295 So(f.Val, ShouldEqual, 10) 295 So(f.Val, ShouldEqual, 10)
296 296
297 f.Val = 20 297 f.Val = 20
298 So(txnDS.Put(f), ShouldBeNil) 298 So(txnDS.Put(f), ShouldBeNil)
299 299
300 So(txnDS.Get(f), ShouldBeNil) 300 So(txnDS.Get(f), ShouldBeNil)
301 So(f.Val, ShouldEqual, 10) // st ill gets 10 301 So(f.Val, ShouldEqual, 10) // st ill gets 10
302 302
303 return nil 303 return nil
304 » » » » » }, nil) 304 » » » » » }, &dsS.TransactionOptions{Attempts: 1})
305 So(err.Error(), ShouldContainSubstring, "concurrent") 305 So(err.Error(), ShouldContainSubstring, "concurrent")
306 306
307 f := &Foo{Id: 1} 307 f := &Foo{Id: 1}
308 So(ds.Get(f), ShouldBeNil) 308 So(ds.Get(f), ShouldBeNil)
309 So(f.Val, ShouldEqual, 11) 309 So(f.Val, ShouldEqual, 11)
310 }) 310 })
311 311
312 Convey("Reusing a transaction context is bad new s", func() { 312 Convey("Reusing a transaction context is bad new s", func() {
313 txnDS := dsS.Interface(nil) 313 txnDS := dsS.Interface(nil)
314 err := ds.RunInTransaction(func(c contex t.Context) error { 314 err := ds.RunInTransaction(func(c contex t.Context) error {
(...skipping 11 matching lines...) Expand all
326 panic("noooo") 326 panic("noooo")
327 }, nil) 327 }, nil)
328 So(err.Error(), ShouldContainSub string, "nested transactions") 328 So(err.Error(), ShouldContainSub string, "nested transactions")
329 return nil 329 return nil
330 }, nil) 330 }, nil)
331 So(err, ShouldBeNil) 331 So(err, ShouldBeNil)
332 }) 332 })
333 333
334 Convey("Concurrent transactions only accept one set of changes", func() { 334 Convey("Concurrent transactions only accept one set of changes", func() {
335 // Note: I think this implementation is actually /slightly/ wrong. 335 // Note: I think this implementation is actually /slightly/ wrong.
336 » » » » » // Accorting to my read of the docs for appengine, when you open a 336 » » » » » // According to my read of the docs for appengine, when you open a
337 // transaction it actually (essentially) holds a reference to the 337 // transaction it actually (essentially) holds a reference to the
338 // entire datastore. Our implementation takes a snapshot of the 338 // entire datastore. Our implementation takes a snapshot of the
339 // entity group as soon as something obs erves/affects it. 339 // entity group as soon as something obs erves/affects it.
340 // 340 //
341 // That said... I'm not sure if there's really a semantic difference. 341 // That said... I'm not sure if there's really a semantic difference.
342 err := ds.RunInTransaction(func(c contex t.Context) error { 342 err := ds.RunInTransaction(func(c contex t.Context) error {
343 So(dsS.Get(c).Put(&Foo{Id: 1, Va l: 21}), ShouldBeNil) 343 So(dsS.Get(c).Put(&Foo{Id: 1, Va l: 21}), ShouldBeNil)
344 344
345 err := ds.RunInTransaction(func( c context.Context) error { 345 err := ds.RunInTransaction(func( c context.Context) error {
346 So(dsS.Get(c).Put(&Foo{I d: 1, Val: 27}), ShouldBeNil) 346 So(dsS.Get(c).Put(&Foo{I d: 1, Val: 27}), ShouldBeNil)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 So(ds.Put(&Foo{V al: 200}), ShouldBeNil) 410 So(ds.Put(&Foo{V al: 200}), ShouldBeNil)
411 panic("wheeeeee" ) 411 panic("wheeeeee" )
412 }, nil) 412 }, nil)
413 }, ShouldPanic) 413 }, ShouldPanic)
414 414
415 f := &Foo{Id: 1} 415 f := &Foo{Id: 1}
416 So(ds.Get(f), ShouldBeNil) 416 So(ds.Get(f), ShouldBeNil)
417 So(f.Val, ShouldEqual, 10) 417 So(f.Val, ShouldEqual, 10)
418 }) 418 })
419 }) 419 })
420
421 Convey("Transaction retries", func() {
422 tst := ds.Raw().Testable()
423 Reset(func() { tst.SetTransactionRetryCo unt(0) })
424
425 Convey("SetTransactionRetryCount set to zere", func() {
426 tst.SetTransactionRetryCount(0)
427 calls := 0
428 So(ds.RunInTransaction(func(c co ntext.Context) error {
429 calls++
430 return nil
431 }, nil), ShouldBeNil)
432 So(calls, ShouldEqual, 1)
433 })
434
435 Convey("default TransactionOptions is 3 attempts", func() {
436 tst.SetTransactionRetryCount(100 ) // more than 3
437 calls := 0
438 So(ds.RunInTransaction(func(c co ntext.Context) error {
439 calls++
440 return nil
441 }, nil), ShouldEqual, dsS.ErrCon currentTransaction)
442 So(calls, ShouldEqual, 3)
443 })
444
445 Convey("non-default TransactionOptions " , func() {
446 tst.SetTransactionRetryCount(100 ) // more than 20
447 calls := 0
448 So(ds.RunInTransaction(func(c co ntext.Context) error {
449 calls++
450 return nil
451 }, &dsS.TransactionOptions{Attem pts: 20}), ShouldEqual, dsS.ErrConcurrentTransaction)
452 So(calls, ShouldEqual, 20)
453 })
454
455 Convey("SetTransactionRetryCount is resp ected", func() {
456 tst.SetTransactionRetryCount(1) // less than 3
457 calls := 0
458 So(ds.RunInTransaction(func(c co ntext.Context) error {
459 calls++
460 return nil
461 }, nil), ShouldBeNil)
462 So(calls, ShouldEqual, 2)
463 })
464
465 Convey("fatal errors are not retried", f unc() {
466 tst.SetTransactionRetryCount(1)
467 calls := 0
468 So(ds.RunInTransaction(func(c co ntext.Context) error {
469 calls++
470 return fmt.Errorf("omg")
471 }, nil).Error(), ShouldEqual, "o mg")
472 So(calls, ShouldEqual, 1)
473 })
474 })
420 }) 475 })
421 }) 476 })
422
423 }) 477 })
424 } 478 }
425 479
426 func TestCompoundIndexes(t *testing.T) { 480 func TestCompoundIndexes(t *testing.T) {
427 t.Parallel() 481 t.Parallel()
428 482
429 idxKey := func(def dsS.IndexDefinition) string { 483 idxKey := func(def dsS.IndexDefinition) string {
430 So(def, ShouldNotBeNil) 484 So(def, ShouldNotBeNil)
431 return "idx::" + string(serialize.ToBytes(*def.PrepForIdxTable() )) 485 return "idx::" + string(serialize.ToBytes(*def.PrepForIdxTable() ))
432 } 486 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 523
470 idx.SortBy = append(idx.SortBy, dsS.IndexColumn{Property: "Field 1"}) 524 idx.SortBy = append(idx.SortBy, dsS.IndexColumn{Property: "Field 1"})
471 So(head.GetCollection(idxKey(idx)), ShouldBeNil) 525 So(head.GetCollection(idxKey(idx)), ShouldBeNil)
472 526
473 t.AddIndexes(&idx) 527 t.AddIndexes(&idx)
474 coll = head.GetCollection(idxKey(idx)) 528 coll = head.GetCollection(idxKey(idx))
475 So(coll, ShouldNotBeNil) 529 So(coll, ShouldNotBeNil)
476 So(numItms(coll), ShouldEqual, 4) 530 So(numItms(coll), ShouldEqual, 4)
477 }) 531 })
478 } 532 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698