66 "math"
77 "math/rand"
88 "runtime"
9+ "strings"
910 "sync"
1011 "testing"
1112 "time"
@@ -27,6 +28,119 @@ func TestWriteAndGetOnCache(t *testing.T) {
2728 assertEqual (t , value , cachedValue )
2829}
2930
31+ func TestAppendAndGetOnCache (t * testing.T ) {
32+ t .Parallel ()
33+
34+ // given
35+ cache , _ := NewBigCache (DefaultConfig (5 * time .Second ))
36+ key := "key"
37+ value1 := make ([]byte , 50 )
38+ rand .Read (value1 )
39+ value2 := make ([]byte , 50 )
40+ rand .Read (value2 )
41+ value3 := make ([]byte , 50 )
42+ rand .Read (value3 )
43+
44+ // when
45+ _ , err := cache .Get (key )
46+
47+ // then
48+ assertEqual (t , ErrEntryNotFound , err )
49+
50+ // when
51+ cache .Append (key , value1 )
52+ cachedValue , err := cache .Get (key )
53+
54+ // then
55+ noError (t , err )
56+ assertEqual (t , value1 , cachedValue )
57+
58+ // when
59+ cache .Append (key , value2 )
60+ cachedValue , err = cache .Get (key )
61+
62+ // then
63+ noError (t , err )
64+ expectedValue := value1
65+ expectedValue = append (expectedValue , value2 ... )
66+ assertEqual (t , expectedValue , cachedValue )
67+
68+ // when
69+ cache .Append (key , value3 )
70+ cachedValue , err = cache .Get (key )
71+
72+ // then
73+ noError (t , err )
74+ expectedValue = value1
75+ expectedValue = append (expectedValue , value2 ... )
76+ expectedValue = append (expectedValue , value3 ... )
77+ assertEqual (t , expectedValue , cachedValue )
78+ }
79+
80+ // TestAppendRandomly does simultaneous appends to check for corruption errors.
81+ func TestAppendRandomly (t * testing.T ) {
82+ t .Parallel ()
83+
84+ c := Config {
85+ Shards : 1 ,
86+ LifeWindow : 5 * time .Second ,
87+ CleanWindow : 1 * time .Second ,
88+ MaxEntriesInWindow : 1000 * 10 * 60 ,
89+ MaxEntrySize : 500 ,
90+ StatsEnabled : true ,
91+ Verbose : true ,
92+ Hasher : newDefaultHasher (),
93+ HardMaxCacheSize : 1 ,
94+ Logger : DefaultLogger (),
95+ }
96+ cache , err := NewBigCache (c )
97+ noError (t , err )
98+
99+ nKeys := 5
100+ nAppendsPerKey := 2000
101+ nWorker := 10
102+ var keys []string
103+ for i := 0 ; i < nKeys ; i ++ {
104+ for j := 0 ; j < nAppendsPerKey ; j ++ {
105+ keys = append (keys , fmt .Sprintf ("key%d" , i ))
106+ }
107+ }
108+ rand .Shuffle (len (keys ), func (i , j int ) {
109+ keys [i ], keys [j ] = keys [j ], keys [i ]
110+ })
111+
112+ jobs := make (chan string , len (keys ))
113+ for _ , key := range keys {
114+ jobs <- key
115+ }
116+ close (jobs )
117+
118+ var wg sync.WaitGroup
119+ for i := 0 ; i < nWorker ; i ++ {
120+ wg .Add (1 )
121+ go func () {
122+ for {
123+ key , ok := <- jobs
124+ if ! ok {
125+ break
126+ }
127+ cache .Append (key , []byte (key ))
128+ }
129+ wg .Done ()
130+ }()
131+ }
132+ wg .Wait ()
133+
134+ assertEqual (t , nKeys , cache .Len ())
135+ for i := 0 ; i < nKeys ; i ++ {
136+ key := fmt .Sprintf ("key%d" , i )
137+ expectedValue := []byte (strings .Repeat (key , nAppendsPerKey ))
138+ cachedValue , err := cache .Get (key )
139+ noError (t , err )
140+ assertEqual (t , expectedValue , cachedValue )
141+ }
142+ }
143+
30144func TestConstructCacheWithDefaultHasher (t * testing.T ) {
31145 t .Parallel ()
32146
0 commit comments