OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // +build appengine |
| 6 |
| 7 package memlock |
| 8 |
| 9 import ( |
| 10 "testing" |
| 11 "time" |
| 12 |
| 13 "appengine/memcache" |
| 14 |
| 15 "infra/gae/libs/context/memory" |
| 16 |
| 17 . "github.com/smartystreets/goconvey/convey" |
| 18 ) |
| 19 |
| 20 func init() { |
| 21 delay = time.Millisecond |
| 22 memcacheLockTime = time.Millisecond * 4 |
| 23 } |
| 24 |
| 25 func TestSimple(t *testing.T) { |
| 26 |
| 27 Convey("basic locking", t, func() { |
| 28 c := memory.NewBestContext() |
| 29 mc := c.Memcache |
| 30 mcImpl := mc.(*memory.MemcacheImpl) |
| 31 |
| 32 l, err := New(mc, "testkey", "") |
| 33 So(err, ShouldBeNil) |
| 34 |
| 35 Convey("fails to acquire when memcache is down", func() { |
| 36 mcImpl.SetBrokenFeatures("Add") |
| 37 gotIt := l.TryWithLock(func(check func() bool) { |
| 38 // should never reach here |
| 39 So(false, ShouldBeTrue) |
| 40 }) |
| 41 So(gotIt, ShouldBeFalse) |
| 42 }) |
| 43 |
| 44 Convey("can acquire when empty", func() { |
| 45 gotIt := l.TryWithLock(func(check func() bool) { |
| 46 So(check(), ShouldBeTrue) |
| 47 |
| 48 Convey("waiting for a while keeps refreshing the
lock", func() { |
| 49 time.Sleep(memcacheLockTime * 8) |
| 50 So(check(), ShouldBeTrue) |
| 51 }) |
| 52 |
| 53 Convey("but sometimes we might lose it", func()
{ |
| 54 Convey("because it was evicted", func()
{ |
| 55 mc.Delete("memlock:testkey") |
| 56 time.Sleep(memcacheLockTime) |
| 57 So(check(), ShouldBeFalse) |
| 58 }) |
| 59 |
| 60 Convey("because it got evicted (but we r
ace)", func() { |
| 61 mc.Set(&memcache.Item{ |
| 62 Key: "memlock:testkey"
, |
| 63 Value: []byte(""), |
| 64 }) |
| 65 }) |
| 66 |
| 67 Convey("or because it was stolen", func(
) { |
| 68 mc.Set(&memcache.Item{ |
| 69 Key: "memlock:testkey"
, |
| 70 Value: []byte("wat"), |
| 71 }) |
| 72 time.Sleep(memcacheLockTime) |
| 73 So(check(), ShouldBeFalse) |
| 74 }) |
| 75 |
| 76 Convey("or because of service issues", f
unc() { |
| 77 mcImpl.SetBrokenFeatures("Compar
eAndSwap") |
| 78 time.Sleep(memcacheLockTime) |
| 79 So(check(), ShouldBeFalse) |
| 80 }) |
| 81 }) |
| 82 }) |
| 83 So(gotIt, ShouldBeTrue) |
| 84 |
| 85 Convey("but reentry is a no-no", func() { |
| 86 gotIt := l.TryWithLock(func(check func() bool) { |
| 87 So(check(), ShouldBeTrue) |
| 88 So(func() { |
| 89 l.TryWithLock(func(func() bool)
{}) |
| 90 }, ShouldPanic) |
| 91 }) |
| 92 So(gotIt, ShouldBeTrue) |
| 93 }) |
| 94 }) |
| 95 |
| 96 Convey("an empty context id is random", func() { |
| 97 l2, err := New(mc, "testkey", "") |
| 98 So(err, ShouldBeNil) |
| 99 So(l2.clientID, ShouldNotResemble, l.clientID) |
| 100 }) |
| 101 }) |
| 102 } |
OLD | NEW |