-
Notifications
You must be signed in to change notification settings - Fork 0
/
lockfile_test.go
128 lines (114 loc) · 3.06 KB
/
lockfile_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
package githttp
import (
"io/ioutil"
"os"
"sync"
"sync/atomic"
"testing"
"time"
)
func TestUpgradeLock(t *testing.T) {
dir, err := ioutil.TempDir("", "commits_test")
if err != nil {
t.Fatalf("Failed to create directory: %v", err)
}
defer os.RemoveAll(dir)
m := NewLockfileManager()
defer m.Clear()
l := m.NewLockfile(dir)
if err := l.RLock(); err != nil {
t.Fatalf("Failed to lock git repository for reading: %v", err)
}
if err := l.RLock(); err != nil {
t.Fatalf("Failed to re-lock git repository for reading: %v", err)
}
if err := l.Lock(); err != nil {
t.Fatalf("Failed to lock git repository for writing: %v", err)
}
if err := l.Lock(); err != nil {
t.Fatalf("Failed to re-lock git repository for writing: %v", err)
}
if err := l.Unlock(); err != nil {
t.Fatalf("Failed to unlock git repository: %v", err)
}
if ok, err := l.TryRLock(); !ok || err != nil {
t.Fatalf("Failed to trylock git repository for reading: %v", err)
}
if ok, err := l.TryRLock(); !ok || err != nil {
t.Fatalf("Failed to re-tryock git repository for reading: %v", err)
}
if err := l.RLock(); err != nil {
t.Fatalf("Failed to re-lock git repository for reading: %v", err)
}
if ok, err := l.TryLock(); !ok || err != nil {
t.Fatalf("Failed to trylock git repository for writing: %v", err)
}
if ok, err := l.TryLock(); !ok || err != nil {
t.Fatalf("Failed to re-trylock git repository for writing: %v", err)
}
if err := l.Lock(); err != nil {
t.Fatalf("Failed to re-lock git repository for writing: %v", err)
}
if err := l.Unlock(); err != nil {
t.Fatalf("Failed to unlock git repository: %v", err)
}
}
func TestMultipleReadersLock(t *testing.T) {
dir, err := ioutil.TempDir("", "commits_test")
if err != nil {
t.Fatalf("Failed to create directory: %v", err)
}
defer os.RemoveAll(dir)
m := NewLockfileManager()
defer m.Clear()
l := m.NewLockfile(dir)
if err = l.RLock(); err != nil {
t.Fatalf("Failed to lock git repository for reading: %v", err)
}
defer l.Unlock()
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
l := m.NewLockfile(dir)
if err := l.RLock(); err != nil {
t.Errorf("Failed to lock git repository for reading: %v", err)
panic(err)
}
defer l.Unlock()
}()
}
wg.Wait()
}
func TestSingleWriterLock(t *testing.T) {
dir, err := ioutil.TempDir("", "commits_test")
if err != nil {
t.Fatalf("Failed to create directory: %v", err)
}
defer os.RemoveAll(dir)
m := NewLockfileManager()
defer m.Clear()
var writerCount int32
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
l := m.NewLockfile(dir)
if err := l.Lock(); err != nil {
t.Errorf("Failed to lock git repository for reading: %v", err)
panic(err)
}
// Try to make the other goroutines execute.
time.Sleep(time.Millisecond)
if new := atomic.AddInt32(&writerCount, 1); new != 1 {
t.Errorf("More than one concurrent writer!")
panic("More than one concurrent writer!")
}
defer atomic.AddInt32(&writerCount, -1)
defer l.Unlock()
}()
}
wg.Wait()
}