Skip to content
File

Blob: kv/memory/lease_test.go

go123 lines
1package memory
2 
3import (
4 "context"
5 "crypto/rand"
6 "testing"
7 "time"
8 
9 "go.miragespace.co/specter/spec/chord"
10 
11 "github.com/stretchr/testify/assert"
12)
13 
14func TestAcquireMutualExclusion(t *testing.T) {
15 as := assert.New(t)
16 
17 kv := WithHashFn(chord.Hash)
18 
19 key := make([]byte, 8)
20 rand.Read(key)
21 
22 token, err := kv.Acquire(context.Background(), key, time.Second)
23 as.NoError(err)
24 
25 _, err = kv.Acquire(context.Background(), key, time.Second)
26 as.ErrorIs(err, chord.ErrKVLeaseConflict)
27 
28 as.NoError(kv.Release(context.Background(), key, token))
29}
30 
31func TestAcquireExpired(t *testing.T) {
32 as := assert.New(t)
33 
34 kv := WithHashFn(chord.Hash)
35 
36 key := make([]byte, 8)
37 rand.Read(key)
38 
39 v, _ := kv.fetchVal(key)
40 // expired 2 seconds ago
41 v.lease.Store(uint64(time.Now().Add(time.Duration(-2) * time.Second).UnixNano()))
42 
43 token, err := kv.Acquire(context.Background(), key, time.Second)
44 as.NoError(err)
45 
46 as.NoError(kv.Release(context.Background(), key, token))
47}
48 
49func TestRenewValid(t *testing.T) {
50 as := assert.New(t)
51 
52 kv := WithHashFn(chord.Hash)
53 
54 key := make([]byte, 8)
55 rand.Read(key)
56 
57 token, err := kv.Acquire(context.Background(), key, time.Second)
58 as.NoError(err)
59 
60 time.Sleep(time.Millisecond * 100)
61 
62 n, err := kv.Renew(context.Background(), key, time.Second*2, token)
63 as.NoError(err)
64 as.NotEqual(token, n)
65 
66 // no releasing with the wrong token
67 as.ErrorIs(kv.Release(context.Background(), key, token), chord.ErrKVLeaseExpired)
68 as.NoError(kv.Release(context.Background(), key, n))
69}
70 
71func TestRenewExpired(t *testing.T) {
72 as := assert.New(t)
73 
74 kv := WithHashFn(chord.Hash)
75 
76 key := make([]byte, 8)
77 rand.Read(key)
78 
79 ttl := time.Second
80 
81 tk1, err := kv.Acquire(context.Background(), key, ttl)
82 as.NoError(err)
83 
84 time.Sleep(ttl * 2)
85 
86 tk2, err := kv.Acquire(context.Background(), key, ttl)
87 as.NoError(err)
88 
89 _, err = kv.Renew(context.Background(), key, ttl, tk1)
90 as.ErrorIs(err, chord.ErrKVLeaseExpired)
91 
92 tk2, err = kv.Renew(context.Background(), key, ttl, tk2)
93 as.NoError(err)
94 
95 // no releasing with the wrong token
96 as.ErrorIs(kv.Release(context.Background(), key, tk1), chord.ErrKVLeaseExpired)
97 as.NoError(kv.Release(context.Background(), key, tk2))
98}
99 
100func TestTTLGuard(t *testing.T) {
101 as := assert.New(t)
102 
103 kv := WithHashFn(chord.Hash)
104 
105 key := make([]byte, 8)
106 rand.Read(key)
107 
108 ttl := time.Millisecond * 500
109 
110 _, err := kv.Acquire(context.Background(), key, ttl)
111 as.ErrorIs(err, chord.ErrKVLeaseInvalidTTL)
112 
113 ttl = time.Second
114 tk, err := kv.Acquire(context.Background(), key, ttl)
115 as.NoError(err)
116 
117 ttl = time.Millisecond * 500
118 _, err = kv.Renew(context.Background(), key, ttl, tk)
119 as.ErrorIs(err, chord.ErrKVLeaseInvalidTTL)
120 
121 as.NoError(kv.Release(context.Background(), key, tk))
122}