github.com/thanos-io/thanos@v0.32.5/pkg/cache/inmemory_test.go (about) 1 // Copyright (c) The Thanos Authors. 2 // Licensed under the Apache License 2.0. 3 4 package cache 5 6 import ( 7 "context" 8 9 "github.com/go-kit/log" 10 11 "testing" 12 "time" 13 14 prom_testutil "github.com/prometheus/client_golang/prometheus/testutil" 15 16 "github.com/efficientgo/core/testutil" 17 ) 18 19 func TestInmemoryCache(t *testing.T) { 20 t.Parallel() 21 22 // Init some data to conveniently define test cases later on. 23 key1 := "key1" 24 key2 := "key2" 25 key3 := "key3" 26 value1 := []byte{1} 27 value2 := []byte{2} 28 value3 := []byte{3} 29 30 tests := map[string]struct { 31 setup map[string][]byte 32 ttl time.Duration 33 testTTL bool 34 mockedErr error 35 fetchKeys []string 36 expectedHits map[string][]byte 37 }{ 38 "should return no hits on empty cache": { 39 setup: nil, 40 ttl: time.Duration(time.Hour), 41 fetchKeys: []string{key1, key2}, 42 expectedHits: map[string][]byte{}, 43 }, 44 "should return no misses on 100% hit ratio": { 45 setup: map[string][]byte{ 46 key1: value1, 47 key2: value2, 48 key3: value3, 49 }, 50 ttl: time.Duration(time.Hour), 51 fetchKeys: []string{key1}, 52 expectedHits: map[string][]byte{ 53 key1: value1, 54 }, 55 }, 56 "should return a miss due to TTL": { 57 setup: map[string][]byte{ 58 key1: value1, 59 key2: value2, 60 key3: value3, 61 }, 62 // setting ttl for the values as 250 ms 63 ttl: time.Duration(250 * time.Millisecond), 64 testTTL: true, 65 fetchKeys: []string{key1}, 66 expectedHits: map[string][]byte{}, 67 }, 68 "should return hits and misses on partial hits": { 69 setup: map[string][]byte{ 70 key1: value1, 71 key2: value2, 72 }, 73 ttl: time.Duration(time.Hour), 74 fetchKeys: []string{key1, key3}, 75 expectedHits: map[string][]byte{key1: value1}, 76 }, 77 } 78 for testName, testData := range tests { 79 t.Run(testName, func(t *testing.T) { 80 conf := []byte(` 81 max_size: 1MB 82 max_item_size: 2KB 83 `) 84 c, _ := NewInMemoryCache("test", log.NewNopLogger(), nil, conf) 85 86 // Store the postings expected before running the test. 87 ctx := context.Background() 88 c.Store(testData.setup, testData.ttl) 89 90 // Add delay to test expiry functionality. 91 if testData.testTTL { 92 // The delay will be based on the TTL itself. 93 time.Sleep(testData.ttl) 94 } 95 96 // Fetch postings from cached and assert on it. 97 hits := c.Fetch(ctx, testData.fetchKeys) 98 testutil.Equals(t, testData.expectedHits, hits) 99 100 // Assert on metrics. 101 testutil.Equals(t, float64(len(testData.fetchKeys)), prom_testutil.ToFloat64(c.requests)) 102 testutil.Equals(t, float64(len(testData.expectedHits)), prom_testutil.ToFloat64(c.hits)) 103 }) 104 } 105 } 106 107 func TestNewInMemoryCache(t *testing.T) { 108 // Should return error when the max size of the cache is smaller than the max size of 109 conf := []byte(` 110 max_size: 2KB 111 max_item_size: 1MB 112 `) 113 cache, err := NewInMemoryCache("test", log.NewNopLogger(), nil, conf) 114 testutil.NotOk(t, err) 115 testutil.Equals(t, (*InMemoryCache)(nil), cache) 116 }