apollo-backend/internal/distributedlock/distributed_lock_test.go

85 lines
1.7 KiB
Go
Raw Permalink Normal View History

2023-04-01 15:57:28 +00:00
package distributedlock_test
import (
"context"
"fmt"
2023-04-01 16:07:48 +00:00
"math/rand"
2023-04-01 15:57:28 +00:00
"os"
"testing"
"time"
2023-04-01 16:07:48 +00:00
"github.com/christianselig/apollo-backend/internal/distributedlock"
"github.com/go-redis/redis/v8"
"github.com/stretchr/testify/assert"
2023-04-01 15:57:28 +00:00
)
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) {
2023-04-01 16:07:48 +00:00
t.Parallel()
2023-04-01 15:57:28 +00:00
ctx := context.Background()
2023-04-01 16:07:48 +00:00
key := fmt.Sprintf("key:%d-%d", time.Now().UnixNano(), rand.Int63())
2023-04-01 15:57:28 +00:00
client, closer := NewRedisClient(t, ctx)
defer closer()
2023-04-01 16:07:48 +00:00
d, err := distributedlock.New(client, 10*time.Second)
assert.NoError(t, err)
2023-04-01 15:57:28 +00:00
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) {
2023-04-01 16:07:48 +00:00
t.Parallel()
2023-04-01 15:57:28 +00:00
ctx := context.Background()
2023-04-01 16:07:48 +00:00
key := fmt.Sprintf("key:%d-%d", time.Now().UnixNano(), rand.Int63())
2023-04-01 15:57:28 +00:00
client, closer := NewRedisClient(t, ctx)
defer closer()
2023-04-01 16:07:48 +00:00
d, err := distributedlock.New(client, 10*time.Second)
assert.NoError(t, err)
2023-04-01 15:57:28 +00:00
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)
}