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  }