forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserverlock_test.go
140 lines (111 loc) · 4.02 KB
/
serverlock_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
132
133
134
135
136
137
138
139
140
package serverlock
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/tests/testsuite"
)
func TestMain(m *testing.M) {
testsuite.Run(m)
}
func createTestableServerLock(t *testing.T) *ServerLockService {
t.Helper()
store := db.InitTestDB(t)
return &ServerLockService{
SQLStore: store,
tracer: tracing.InitializeTracerForTest(),
log: log.New("test-logger"),
}
}
func TestServerLock(t *testing.T) {
sl := createTestableServerLock(t)
operationUID := "test-operation"
first, err := sl.getOrCreate(context.Background(), operationUID)
require.NoError(t, err)
t.Run("trying to create three new row locks", func(t *testing.T) {
expectedLastExecution := first.LastExecution
var latest *serverLock
for i := 0; i < 3; i++ {
latest, err = sl.getOrCreate(context.Background(), operationUID)
require.NoError(t, err)
assert.Equal(t, operationUID, first.OperationUID)
assert.Equal(t, int64(1), first.Id)
}
assert.Equal(t,
expectedLastExecution,
latest.LastExecution,
"latest execution should not have changed")
})
t.Run("create lock on first row", func(t *testing.T) {
gotLock, err := sl.acquireLock(context.Background(), first)
require.NoError(t, err)
assert.True(t, gotLock)
gotLock, err = sl.acquireLock(context.Background(), first)
require.NoError(t, err)
assert.False(t, gotLock)
})
}
func TestLockAndRelease(t *testing.T) {
operationUID := "test-operation-release"
t.Run("create lock and then release it", func(t *testing.T) {
sl := createTestableServerLock(t)
duration := time.Hour * 5
err := sl.acquireForRelease(context.Background(), operationUID, duration)
require.NoError(t, err)
err = sl.releaseLock(context.Background(), operationUID)
require.NoError(t, err)
// and now we can acquire it again
err2 := sl.acquireForRelease(context.Background(), operationUID, duration)
require.NoError(t, err2)
err = sl.releaseLock(context.Background(), operationUID)
require.NoError(t, err)
})
t.Run("try to acquire a lock which is already locked, get error", func(t *testing.T) {
sl := createTestableServerLock(t)
duration := time.Hour * 5
err := sl.acquireForRelease(context.Background(), operationUID, duration)
require.NoError(t, err)
err2 := sl.acquireForRelease(context.Background(), operationUID, duration)
require.Error(t, err2, "We should expect an error when trying to get the second lock")
require.Equal(t, "there is already a lock for this actionName: "+operationUID, err2.Error())
err3 := sl.releaseLock(context.Background(), operationUID)
require.NoError(t, err3)
})
t.Run("lock already exists but is timeouted", func(t *testing.T) {
sl := createTestableServerLock(t)
pastLastExec := time.Now().Add(-time.Hour).Unix()
lock := serverLock{
OperationUID: operationUID,
LastExecution: pastLastExec,
}
// inserting a row with lock in the past
err := sl.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *db.Session) error {
affectedRows, err := sess.Insert(&lock)
require.NoError(t, err)
require.Equal(t, int64(1), affectedRows)
require.Equal(t, int64(1), lock.Id)
return nil
})
require.NoError(t, err)
duration := time.Minute * 5
err = sl.acquireForRelease(context.Background(), operationUID, duration)
require.NoError(t, err)
//validate that the lock LastExecution was updated (at least different from the original)
err = sl.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *db.Session) error {
lockRows := []*serverLock{}
err := sess.Where("operation_uid = ?", operationUID).Find(&lockRows)
require.NoError(t, err)
require.Equal(t, 1, len(lockRows))
require.NotEqual(t, pastLastExec, lockRows[0].LastExecution)
return nil
})
require.NoError(t, err)
err3 := sl.releaseLock(context.Background(), operationUID)
require.NoError(t, err3)
})
}