forked from benalexau/ibconnect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdist_lock_test.go
131 lines (104 loc) · 2.67 KB
/
dist_lock_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package core
import (
"testing"
"time"
)
func TestNormalLockCycle(t *testing.T) {
distLock := getLockManager(t)
defer distLock.Close()
lock := int64(2349875)
abandon := make(chan struct{})
reply := distLock.Request(lock, abandon)
expectLock(t, reply)
close(abandon)
expectRelease(t, reply)
}
func TestCompetingLockNotGranted(t *testing.T) {
lock := int64(2349875)
// need 2 lock managers as one connection can acquire the same lock twice
distLock1 := getLockManager(t)
defer distLock1.Close()
distLock2 := getLockManager(t)
defer distLock2.Close()
abandon1 := make(chan struct{})
reply1 := distLock1.Request(lock, abandon1)
expectLock(t, reply1)
abandon2 := make(chan struct{})
reply2 := distLock2.Request(lock, abandon2)
expectNoLock(t, reply2, 100*time.Millisecond)
close(abandon1)
expectRelease(t, reply1)
expectLock(t, reply2)
close(abandon2)
expectRelease(t, reply2)
}
func TestLockManagerClosureCancelsLocks(t *testing.T) {
distLock := getLockManager(t)
defer distLock.Close()
lock := int64(2349875)
abandon := make(chan struct{})
reply := distLock.Request(lock, abandon)
expectLock(t, reply)
distLock.Close()
expectRelease(t, reply)
}
func TestClosedLockManagerGivesClosedReplyForNewRequests(t *testing.T) {
distLock := getLockManager(t)
distLock.Close()
lock := int64(2349875)
abandon := make(chan struct{})
reply := distLock.Request(lock, abandon)
expectClosedReplyChannel(t, reply)
}
func getLockManager(t *testing.T) *DistLock {
config := NewTestConfig(t)
distLock, err := NewDistLock(config.DbUrl)
if err != nil {
t.Fatal(err)
}
return distLock
}
func expectLock(t *testing.T, reply <-chan bool) {
select {
case acquired, ok := <-reply:
if !ok {
t.Fatal("reply channel unexpectedly closed")
}
if !acquired {
t.Fatal("server incorrectly sent false on reply channel")
}
case <-time.After(3000 * time.Millisecond):
t.Fatal("lock manager did not sent reply to lock request")
}
}
func expectNoLock(t *testing.T, reply <-chan bool, waitTime time.Duration) {
select {
case acquired, ok := <-reply:
if !ok {
t.Fatal("reply channel unexpectedly closed")
}
if acquired {
t.Fatal("server incorrectly acquired the lock")
}
case <-time.After(waitTime):
// good, this is what we want
}
}
func expectClosedReplyChannel(t *testing.T, reply <-chan bool) {
select {
case _, ok := <-reply:
if ok {
t.Fatal("reply channel should have been closed")
}
}
}
func expectRelease(t *testing.T, reply <-chan bool) {
select {
case _, ok := <-reply:
if ok {
t.Fatal("reply channel should not have sent data")
}
case <-time.After(3000 * time.Millisecond):
t.Fatal("lock manager did not confirm abandonment of lock")
}
}