-
Notifications
You must be signed in to change notification settings - Fork 1
/
random_test.go
142 lines (124 loc) · 3.71 KB
/
random_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
141
142
package sc
import (
"context"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// TestCache_GetRandom ensures that the cache returns correct values.
func TestCache_GetRandom(t *testing.T) {
t.Parallel()
for _, c := range allCaches(10) {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
replaceFn := func(ctx context.Context, key string) (string, error) {
time.Sleep(1 * time.Millisecond)
return "result-" + key, nil
}
cache, err := New[string, string](replaceFn, 50*time.Millisecond, 50*time.Millisecond, c.cacheOpts...)
assert.NoError(t, err)
keys := newKeys(newZipfian(1.001, 50, 100), 1000)
for _, key := range keys {
val, err := cache.Get(context.Background(), key)
assert.NoError(t, err)
assert.Equal(t, "result-"+key, val)
}
})
}
}
// TestCache_GetRandom_GracefulReplacement is similar to TestCache_GetRandom, but uses graceful cache replacement.
func TestCache_GetRandom_GracefulReplacement(t *testing.T) {
t.Parallel()
for _, c := range allCaches(10) {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
replaceFn := func(ctx context.Context, key string) (string, error) {
time.Sleep(1 * time.Millisecond)
return "result-" + key, nil
}
cache, err := New[string, string](replaceFn, 10*time.Millisecond, 20*time.Millisecond, c.cacheOpts...)
assert.NoError(t, err)
keys := newKeys(newZipfian(1.001, 50, 100), 1000)
for _, key := range keys {
val, err := cache.Get(context.Background(), key)
assert.NoError(t, err)
assert.Equal(t, "result-"+key, val)
}
})
}
}
// TestCache_GetRandom_Parallel is similar to TestCache_GetRandom, but in parallel.
func TestCache_GetRandom_Parallel(t *testing.T) {
t.Parallel()
const (
concurrency = 25
cacheSize = 100
s = 1.01
v = 10
)
for _, c := range allCaches(cacheSize) {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
replaceFn := func(ctx context.Context, key string) (string, error) {
time.Sleep(1 * time.Millisecond) // sleep for some time to simulate concurrent access
return "result-" + key, nil
}
cache, err := New[string, string](replaceFn, 10*time.Millisecond, 10*time.Millisecond, c.cacheOpts...)
assert.NoError(t, err)
var wg sync.WaitGroup
for i := 0; i < concurrency; i++ {
wg.Add(1)
go func() {
defer wg.Done()
keys := newKeys(newZipfian(s, v, cacheSize*2), cacheSize*10)
for _, key := range keys {
val, err := cache.Get(context.Background(), key)
assert.NoError(t, err)
assert.Equal(t, "result-"+key, val)
}
}()
}
wg.Wait()
})
}
}
// TestCache_GetRandom_Parallel_GracefulReplacement is similar to TestCache_GetRandom_Parallel, but uses graceful cache replacement.
func TestCache_GetRandom_Parallel_GracefulReplacement(t *testing.T) {
t.Parallel()
const (
concurrency = 25
cacheSize = 100
s = 1.01
v = 10
)
for _, c := range allCaches(cacheSize) {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
replaceFn := func(ctx context.Context, key string) (string, error) {
time.Sleep(1 * time.Millisecond) // sleep for some time to simulate concurrent access
return "result-" + key, nil
}
cache, err := New[string, string](replaceFn, 10*time.Millisecond, 20*time.Millisecond, c.cacheOpts...)
assert.NoError(t, err)
var wg sync.WaitGroup
for i := 0; i < concurrency; i++ {
wg.Add(1)
go func() {
defer wg.Done()
keys := newKeys(newZipfian(s, v, cacheSize*2), cacheSize*10)
for _, key := range keys {
val, err := cache.Get(context.Background(), key)
assert.NoError(t, err)
assert.Equal(t, "result-"+key, val)
}
}()
}
wg.Wait()
})
}
}