-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmutex_test.go
73 lines (61 loc) · 2.19 KB
/
mutex_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
package distlock
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func runLockTestsWithoutLifetime(t *testing.T, provider Provider) {
factory := New(provider, WithNamespace("deadlock"))
m1 := factory.New("build-images")
m2 := factory.New("build-images")
m3 := factory.New("start-containers")
assert.NoError(t, m1.Lock())
assert.ErrorIs(t, m1.Lock(), ErrAlreadyLocked)
assert.ErrorIs(t, m2.Lock(), ErrAlreadyLocked)
assert.NoError(t, m3.Lock())
assert.NoError(t, m1.Unlock())
assert.ErrorIs(t, m2.Unlock(), ErrNotLocked)
assert.NoError(t, m3.Unlock())
}
func runLockTestsWithLifetime(t *testing.T, provider Provider) {
factory := New(provider, WithLockLifetime(1*time.Second))
m := factory.New("johndoe", WithNamespace("questions"))
expectedMutexDisplayName := fmt.Sprintf("Mutex(%s:questions:johndoe)", provider.Name())
gotMutexDisplayName := m.String()
if gotMutexDisplayName != expectedMutexDisplayName {
t.Errorf("Mutex display name incorrect. Expected: %s, got: %s",
expectedMutexDisplayName,
gotMutexDisplayName,
)
}
testLockAndUnlockInTime(t, m)
testUnlockAfterAnExpiredLock(t, m)
testLockContention(t, m)
m1 := factory.New("apple", WithLockLifetime(10*time.Millisecond))
m2 := factory.New("apple", WithLockLifetime(100*time.Millisecond))
testUnlockAfterOwnerChange(t, m1, m2)
}
func testLockAndUnlockInTime(t *testing.T, m Mutex) {
assert.NoError(t, m.Lock())
assert.NoError(t, m.Unlock())
// expectLocked(t, m.Lock())
// expectUnlocked(t, m.Unlock())
}
func testUnlockAfterAnExpiredLock(t *testing.T, m Mutex) {
assert.NoError(t, m.Lock())
time.Sleep(1200 * time.Millisecond) // expired (released by system)
assert.ErrorIs(t, m.Unlock(), ErrNotLocked)
}
func testLockContention(t *testing.T, m Mutex) {
assert.NoError(t, m.Lock())
assert.ErrorIs(t, m.Lock(), ErrAlreadyLocked)
assert.NoError(t, m.Unlock())
}
func testUnlockAfterOwnerChange(t *testing.T, m1, m2 Mutex) {
assert.NoError(t, m1.Lock())
assert.ErrorIs(t, m2.Lock(), ErrAlreadyLocked)
time.Sleep(50 * time.Millisecond) // m1 expired (released by system)
assert.NoError(t, m2.Lock()) // m2 can obtain the lock, since m1 is expired
assert.ErrorIs(t, m1.Unlock(), ErrNotLocked)
}