github.com/qiniu/go-sdk/v7@v7.27.0/internal/cache/cache_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package cache 5 6 import ( 7 "errors" 8 "os" 9 "reflect" 10 "testing" 11 "time" 12 ) 13 14 type integerCacheValue struct { 15 Value int `json:"value"` 16 RefreshAfter time.Time `json:"refresh_after"` 17 ExpiredAt time.Time `json:"expired_at"` 18 } 19 20 func (v integerCacheValue) ShouldRefresh() bool { 21 return time.Now().After(v.RefreshAfter) 22 } 23 24 func (v integerCacheValue) IsValid() bool { 25 return time.Now().Before(v.ExpiredAt) 26 } 27 28 func (left integerCacheValue) IsEqual(rightV CacheValue) bool { 29 right, ok := rightV.(integerCacheValue) 30 if !ok { 31 return false 32 } 33 return left.Value == right.Value 34 } 35 36 func TestCache(t *testing.T) { 37 cache := NewCache(200 * time.Millisecond) 38 if value, result := cache.Get("key_1", func() (CacheValue, error) { 39 return integerCacheValue{ 40 Value: 1, 41 RefreshAfter: time.Now().Add(50 * time.Millisecond), 42 ExpiredAt: time.Now().Add(100 * time.Millisecond), 43 }, nil 44 }); result != GetResultFromFallback { 45 t.Fatalf("unexpected result: %v", result) 46 } else if v := value.(integerCacheValue).Value; v != 1 { 47 t.Fatalf("unexpected cache value: %v", v) 48 } 49 50 if value, result := cache.Get("key_1", func() (CacheValue, error) { 51 t.Fatal("should not call this fallback") 52 return nil, nil 53 }); result != GetResultFromCache { 54 t.Fatalf("unexpected result: %v", result) 55 } else if v := value.(integerCacheValue).Value; v != 1 { 56 t.Fatalf("unexpected cache value: %v", v) 57 } 58 59 time.Sleep(50 * time.Millisecond) 60 if value, result := cache.Get("key_1", func() (CacheValue, error) { 61 return integerCacheValue{ 62 Value: 2, 63 RefreshAfter: time.Now().Add(50 * time.Millisecond), 64 ExpiredAt: time.Now().Add(100 * time.Millisecond), 65 }, nil 66 }); result != GetResultFromCacheAndRefreshAsync { 67 t.Fatalf("unexpected result: %v", result) 68 } else if v := value.(integerCacheValue).Value; v != 1 { 69 t.Fatalf("unexpected cache value: %v", v) 70 } 71 72 time.Sleep(250 * time.Millisecond) 73 if value, result := cache.Get("key_1", func() (CacheValue, error) { 74 return nil, errors.New("test error") 75 }); result != GetResultFromInvalidCache { 76 t.Fatalf("unexpected result: %v", result) 77 } else if v := value.(integerCacheValue).Value; v != 2 { 78 t.Fatalf("unexpected cache value: %v", v) 79 } 80 time.Sleep(150 * time.Millisecond) 81 cache.flush() 82 if _, result := cache.Get("key_1", func() (CacheValue, error) { 83 return nil, errors.New("test error") 84 }); result != NoResultGot { 85 t.Fatalf("unexpected result: %v", result) 86 } 87 88 if value, result := cache.Get("key_2", func() (CacheValue, error) { 89 return integerCacheValue{Value: 3, ExpiredAt: time.Now().Add(-100 * time.Millisecond)}, nil 90 }); result != GetResultFromFallback { 91 t.Fatalf("unexpected result: %v", result) 92 } else if v := value.(integerCacheValue).Value; v != 3 { 93 t.Fatalf("unexpected cache value: %v", v) 94 } 95 96 if value, result := cache.Get("key_3", func() (CacheValue, error) { 97 return integerCacheValue{Value: 4, ExpiredAt: time.Now().Add(100 * time.Millisecond)}, nil 98 }); result != GetResultFromFallback { 99 t.Fatal("unexpected ok") 100 } else if v := value.(integerCacheValue).Value; v != 4 { 101 t.Fatalf("unexpected cache value: %v", v) 102 } 103 } 104 105 func TestCachePersist(t *testing.T) { 106 cacheFile, err := os.CreateTemp("", "") 107 if err != nil { 108 t.Fatal(err) 109 } 110 defer cacheFile.Close() 111 defer os.Remove(cacheFile.Name()) 112 113 valueType := reflect.TypeOf(integerCacheValue{}) 114 cache, err := NewPersistentCache( 115 valueType, 116 cacheFile.Name(), 117 100*time.Millisecond, 118 100*time.Millisecond, 119 func(err error) { 120 t.Fatalf("no error are expected: %s", err) 121 }) 122 if err != nil { 123 t.Fatal(err) 124 } 125 if value, result := cache.Get("key_1", func() (CacheValue, error) { 126 return integerCacheValue{ 127 Value: 1, 128 RefreshAfter: time.Now().Add(100 * time.Millisecond), 129 ExpiredAt: time.Now().Add(200 * time.Millisecond), 130 }, nil 131 }); result != GetResultFromFallback { 132 t.Fatal("unexpected ok") 133 } else if v := value.(integerCacheValue).Value; v != 1 { 134 t.Fatalf("unexpected cache value: %v", v) 135 } 136 137 time.Sleep(100 * time.Millisecond) 138 cache.flush() 139 140 cacheMap, err := loadCacheMapFrom(valueType, cacheFile) 141 if err != nil { 142 t.Fatal(err) 143 } 144 if value, ok := cacheMap["key_1"]; !ok { 145 t.Fatalf("key_1 should be existed") 146 } else if v := value.Value.(integerCacheValue).Value; v != 1 { 147 t.Fatalf("unexpected cache value: %v", v) 148 } 149 150 time.Sleep(100 * time.Millisecond) 151 cache.flush() 152 153 cacheMap, err = loadCacheMapFrom(valueType, cacheFile) 154 if err != nil { 155 t.Fatal(err) 156 } 157 if len(cacheMap) != 0 { 158 t.Fatalf("key_1 should be deleted") 159 } 160 }