apollo-backend/internal/distributedlock/distributed_lock_test.go
2023-04-01 12:07:48 -04:00

84 lines
1.7 KiB
Go

package distributedlock_test
import (
"context"
"fmt"
"math/rand"
"os"
"testing"
"time"
"github.com/christianselig/apollo-backend/internal/distributedlock"
"github.com/go-redis/redis/v8"
"github.com/stretchr/testify/assert"
)
func NewRedisClient(t *testing.T, ctx context.Context) (*redis.Client, func()) {
t.Helper()
opt, err := redis.ParseURL(os.Getenv("REDIS_URL"))
if err != nil {
panic(err)
}
client := redis.NewClient(opt)
if err := client.Ping(ctx).Err(); err != nil {
panic(err)
}
return client, func() {
_ = client.Close()
}
}
func TestDistributedLock_AcquireLock(t *testing.T) {
t.Parallel()
ctx := context.Background()
key := fmt.Sprintf("key:%d-%d", time.Now().UnixNano(), rand.Int63())
client, closer := NewRedisClient(t, ctx)
defer closer()
d, err := distributedlock.New(client, 10*time.Second)
assert.NoError(t, err)
lock, err := d.AcquireLock(ctx, key)
assert.NoError(t, err)
_, err = d.AcquireLock(ctx, key)
assert.Equal(t, distributedlock.ErrLockAlreadyAcquired, err)
err = lock.Release(ctx)
assert.NoError(t, err)
_, err = d.AcquireLock(ctx, key)
assert.NoError(t, err)
}
func TestDistributedLock_WaitAcquireLock(t *testing.T) {
t.Parallel()
ctx := context.Background()
key := fmt.Sprintf("key:%d-%d", time.Now().UnixNano(), rand.Int63())
client, closer := NewRedisClient(t, ctx)
defer closer()
d, err := distributedlock.New(client, 10*time.Second)
assert.NoError(t, err)
lock, err := d.AcquireLock(ctx, key)
assert.NoError(t, err)
go func(l *distributedlock.Lock) {
select {
case <-time.After(100 * time.Millisecond):
_ = l.Release(ctx)
}
}(lock)
lock, err = d.WaitAcquireLock(ctx, key, 5*time.Second)
assert.NoError(t, err)
assert.NotNil(t, lock)
}