mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 21:19:28 -06:00
790e1feb93
* streamline initialization of test databases, support on-disk sqlite test db * clean up test databases * introduce testsuite helper * use testsuite everywhere we use a test db * update documentation * improve error handling * disable entity integration test until we can figure out locking error
141 lines
4.0 KiB
Go
141 lines
4.0 KiB
Go
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)
|
|
})
|
|
}
|