-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeylock_test.go
More file actions
140 lines (107 loc) · 2.54 KB
/
keylock_test.go
File metadata and controls
140 lines (107 loc) · 2.54 KB
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
132
133
134
135
136
137
138
139
140
package keylock_test
import (
"sync"
"testing"
"time"
"github.com/pourtorabehsan/keylock"
)
func TestLock(t *testing.T) {
kl := keylock.New()
key := "test-key"
unlock := kl.Lock(key)
var wg sync.WaitGroup
wg.Add(1)
started := make(chan struct{})
go func() {
defer wg.Done()
started <- struct{}{}
unlock2 := kl.Lock(key)
unlock2()
}()
<-started
unlock()
wg.Wait()
}
func TestLockAndUnlock(t *testing.T) {
kl := keylock.New()
key := "test-key"
unlock := kl.Lock(key)
acquired := false
started := make(chan struct{})
go func() {
started <- struct{}{}
unlock2 := kl.Lock(key)
defer unlock2()
acquired = true
}()
<-started
time.Sleep(100 * time.Millisecond) // Give the goroutine time to lock
if acquired {
t.Errorf("Expected lock to be held, but it was released")
}
unlock()
time.Sleep(100 * time.Millisecond) // Give the goroutine time to lock
if !acquired {
t.Errorf("Expected lock to be released, but it was held")
}
}
func TestImmediateLock(t *testing.T) {
kl := keylock.New()
key := "test-key"
unlock, err := kl.LockWithTimeout(key, keylock.Immediate)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
if unlock == nil {
t.Errorf("Expected unlock function, got nil")
}
defer unlock()
// the lock is already held, so this should fail
_, err = kl.LockWithTimeout(key, keylock.Immediate)
if err != keylock.ErrTimeout {
t.Errorf("Expected timeout error, got %v", err)
}
}
func TestLockWithTimeout(t *testing.T) {
kl := keylock.New()
key := "test-key"
unlock, err := kl.LockWithTimeout(key, 100*time.Millisecond)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
// the lock is already held, so this should fail
_, err = kl.LockWithTimeout(key, 100*time.Millisecond)
if err != keylock.ErrTimeout {
t.Errorf("Expected timeout error, got %v", err)
}
go func() {
time.Sleep(200 * time.Millisecond)
unlock()
}()
// The lock should be released after 200 milliseconds
// in the goroutine above, so this should succeed.
unlock2, err := kl.LockWithTimeout(key, 1*time.Second)
if err != nil {
t.Errorf("Expected no error, got %v", err)
}
unlock2()
}
func TestLocksAreIndependent(t *testing.T) {
kl := keylock.New()
key1 := "test-key1"
key2 := "test-key2"
unlock1 := kl.Lock(key1)
var wg sync.WaitGroup
wg.Add(1)
started := make(chan struct{})
go func() {
defer wg.Done()
started <- struct{}{}
unlock2 := kl.Lock(key2)
unlock2()
}()
<-started
// The goroutine should be able to lock key and unlock even though key1 is locked
wg.Wait()
unlock1()
}