@@ -6,8 +6,10 @@ import (
66	"testing" 
77	"time" 
88
9+ 	"github.com/go-kit/log" 
910	"github.com/prometheus/client_golang/prometheus" 
1011	"github.com/stretchr/testify/require" 
12+ 	"github.com/thanos-io/thanos/pkg/cache" 
1113)
1214
1315func  Test_MultiLevelChunkCacheStore (t  * testing.T ) {
@@ -72,6 +74,43 @@ func Test_MultiLevelChunkCacheStore(t *testing.T) {
7274	}
7375}
7476
77+ func  Test_MultiLevelChunkCacheFetchRace (t  * testing.T ) {
78+ 	cfg  :=  MultiLevelChunkCacheConfig {
79+ 		MaxAsyncConcurrency : 10 ,
80+ 		MaxAsyncBufferSize :  100000 ,
81+ 		MaxBackfillItems :    10000 ,
82+ 		BackFillTTL :         time .Hour  *  24 ,
83+ 	}
84+ 	reg  :=  prometheus .NewRegistry ()
85+ 
86+ 	m1  :=  newMockChunkCache ("m1" , map [string ][]byte {
87+ 		"key1" : []byte ("value1" ),
88+ 		"key2" : []byte ("value2" ),
89+ 	})
90+ 
91+ 	inMemory , err  :=  cache .NewInMemoryCacheWithConfig ("test" , log .NewNopLogger (), reg , cache.InMemoryCacheConfig {MaxSize : 10  *  1024 , MaxItemSize : 1024 })
92+ 	require .NoError (t , err )
93+ 
94+ 	inMemory .Store (map [string ][]byte {
95+ 		"key2" : []byte ("value2" ),
96+ 		"key3" : []byte ("value3" ),
97+ 	}, time .Minute )
98+ 
99+ 	c  :=  newMultiLevelChunkCache ("chunk-cache" , cfg , reg , inMemory , m1 )
100+ 
101+ 	hits  :=  c .Fetch (context .Background (), []string {"key1" , "key2" , "key3" , "key4" })
102+ 
103+ 	require .Equal (t , 3 , len (hits ))
104+ 
105+ 	// We should be able to change the returned values without any race problem 
106+ 	delete (hits , "key1" )
107+ 
108+ 	mlc  :=  c .(* multiLevelChunkCache )
109+ 	//Wait until async operation finishes. 
110+ 	mlc .backfillProcessor .Stop ()
111+ 
112+ }
113+ 
75114func  Test_MultiLevelChunkCacheFetch (t  * testing.T ) {
76115	cfg  :=  MultiLevelChunkCacheConfig {
77116		MaxAsyncConcurrency : 10 ,
@@ -81,12 +120,14 @@ func Test_MultiLevelChunkCacheFetch(t *testing.T) {
81120	}
82121
83122	testCases  :=  map [string ]struct  {
84- 		m1ExistingData       map [string ][]byte 
85- 		m2ExistingData       map [string ][]byte 
86- 		expectedM1Data       map [string ][]byte 
87- 		expectedM2Data       map [string ][]byte 
88- 		expectedFetchedData  map [string ][]byte 
89- 		fetchKeys            []string 
123+ 		m1ExistingData         map [string ][]byte 
124+ 		m2ExistingData         map [string ][]byte 
125+ 		expectedM1Data         map [string ][]byte 
126+ 		expectedM2Data         map [string ][]byte 
127+ 		expectedFetchedData    map [string ][]byte 
128+ 		expectedM1FetchedKeys  []string 
129+ 		expectedM2FetchedKeys  []string 
130+ 		fetchKeys              []string 
90131	}{
91132		"fetched data should be union of m1, m2 and 'key2' and `key3' should be backfilled to m1" : {
92133			m1ExistingData : map [string ][]byte {
@@ -96,6 +137,8 @@ func Test_MultiLevelChunkCacheFetch(t *testing.T) {
96137				"key2" : []byte ("value2" ),
97138				"key3" : []byte ("value3" ),
98139			},
140+ 			expectedM1FetchedKeys : []string {"key1" , "key2" , "key3" },
141+ 			expectedM2FetchedKeys : []string {"key2" , "key3" },
99142			expectedM1Data : map [string ][]byte {
100143				"key1" : []byte ("value1" ),
101144				"key2" : []byte ("value2" ),
@@ -119,6 +162,8 @@ func Test_MultiLevelChunkCacheFetch(t *testing.T) {
119162			m2ExistingData : map [string ][]byte {
120163				"key2" : []byte ("value2" ),
121164			},
165+ 			expectedM1FetchedKeys : []string {"key1" , "key2" , "key3" },
166+ 			expectedM2FetchedKeys : []string {"key2" , "key3" },
122167			expectedM1Data : map [string ][]byte {
123168				"key1" : []byte ("value1" ),
124169				"key2" : []byte ("value2" ),
@@ -157,6 +202,8 @@ type mockChunkCache struct {
157202	mu    sync.Mutex 
158203	name  string 
159204	data  map [string ][]byte 
205+ 
206+ 	fetchedKeys  []string 
160207}
161208
162209func  newMockChunkCache (name  string , data  map [string ][]byte ) * mockChunkCache  {
@@ -180,6 +227,7 @@ func (m *mockChunkCache) Fetch(_ context.Context, keys []string) map[string][]by
180227	h  :=  map [string ][]byte {}
181228
182229	for  _ , k  :=  range  keys  {
230+ 		m .fetchedKeys  =  append (m .fetchedKeys , k )
183231		if  _ , ok  :=  m .data [k ]; ok  {
184232			h [k ] =  m .data [k ]
185233		}
0 commit comments