github.com/vicanso/pike@v1.0.1-0.20210630235453-9099e041f6ec/cache/http_cache_test.go (about) 1 package cache 2 3 import ( 4 "sync" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestCacheStatusString(t *testing.T) { 12 assert := assert.New(t) 13 14 assert.Equal("fetching", StatusFetching.String()) 15 assert.Equal("hitForPass", StatusHitForPass.String()) 16 assert.Equal("hit", StatusHit.String()) 17 assert.Equal("passed", StatusPassed.String()) 18 assert.Equal("unknown", StatusUnknown.String()) 19 } 20 21 func TestHTTPCacheBytes(t *testing.T) { 22 assert := assert.New(t) 23 hc := httpCache{ 24 status: StatusFetching, 25 response: &HTTPResponse{ 26 CompressSrv: "compress", 27 }, 28 createdAt: 1, 29 expiredAt: 2, 30 } 31 data, err := hc.Bytes() 32 assert.Nil(err) 33 34 newHC := NewHTTPCache() 35 err = newHC.FromBytes(data) 36 assert.Nil(err) 37 assert.Equal(hc.status, newHC.status) 38 assert.Equal(hc.response.CompressSrv, newHC.response.CompressSrv) 39 assert.Equal(hc.createdAt, newHC.createdAt) 40 assert.Equal(hc.expiredAt, newHC.expiredAt) 41 } 42 43 func TestHTTPCacheGet(t *testing.T) { 44 assert := assert.New(t) 45 cacheResp, err := NewHTTPResponse(200, nil, "", []byte("Hello world!")) 46 // 避免压缩,方便后面对数据检测 47 cacheResp.CompressMinLength = 1024 48 assert.Nil(err) 49 expiredHC := NewHTTPCache() 50 expiredHC.expiredAt = 1 51 expiredHC.status = StatusHitForPass 52 53 tests := []struct { 54 status Status 55 hc *httpCache 56 resp *HTTPResponse 57 }{ 58 { 59 status: StatusHit, 60 hc: expiredHC, 61 resp: cacheResp, 62 }, 63 { 64 status: StatusHitForPass, 65 hc: NewHTTPCache(), 66 }, 67 } 68 type testResult struct { 69 status Status 70 resp *HTTPResponse 71 } 72 for _, tt := range tests { 73 mu := sync.Mutex{} 74 wg := sync.WaitGroup{} 75 results := make([]*testResult, 0) 76 max := 10 77 for i := 0; i < max; i++ { 78 wg.Add(1) 79 go func() { 80 status, resp := tt.hc.Get() 81 mu.Lock() 82 defer mu.Unlock() 83 results = append(results, &testResult{ 84 status: status, 85 resp: resp, 86 }) 87 wg.Done() 88 }() 89 } 90 // 简单等待10ms,让所有for中的goroutine都已执行 91 time.Sleep(10 * time.Millisecond) 92 switch tt.status { 93 case StatusHit: 94 tt.hc.Cacheable(tt.resp, 300) 95 case StatusHitForPass: 96 tt.hc.HitForPass(-1) 97 } 98 99 wg.Wait() 100 count := 0 101 for _, result := range results { 102 // 如果不相等的,只能是fetching 103 if result.status != tt.status { 104 assert.Equal(StatusFetching, result.status) 105 } else { 106 assert.Equal(tt.status, result.status) 107 count++ 108 // fetching的数据由fetching取,不使用缓存返回 109 assert.Equal(tt.resp, result.resp) 110 } 111 } 112 // 其它状态的都相同 113 assert.Equal(max-1, count) 114 115 // 在后续已设置缓存状态之后,再次获取直接返回 116 status, resp := tt.hc.Get() 117 assert.Equal(tt.status, status) 118 assert.Equal(tt.resp, resp) 119 } 120 } 121 122 func TestHTTPCacheAge(t *testing.T) { 123 assert := assert.New(t) 124 hc := httpCache{ 125 createdAt: nowUnix() - 1, 126 mu: &sync.RWMutex{}, 127 } 128 assert.GreaterOrEqual(hc.Age(), 1) 129 } 130 131 func TestHTTPCacheGetStatus(t *testing.T) { 132 assert := assert.New(t) 133 hc := httpCache{ 134 status: StatusFetching, 135 mu: &sync.RWMutex{}, 136 } 137 assert.Equal(StatusFetching, hc.GetStatus()) 138 } 139 140 func TestHTTPCacheIsExpired(t *testing.T) { 141 assert := assert.New(t) 142 hc := httpCache{ 143 expiredAt: 0, 144 mu: &sync.RWMutex{}, 145 } 146 assert.False(hc.IsExpired()) 147 hc.expiredAt = 1 148 assert.True(hc.IsExpired()) 149 hc.expiredAt = nowUnix() + 10 150 assert.False(hc.IsExpired()) 151 }