github.com/songzhibin97/gkit@v1.2.13/cache/local_cache/cache_test.go (about)

     1  package local_cache
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"runtime"
     7  	"strconv"
     8  	"sync"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  type TestStruct struct {
    14  	Num      int
    15  	Children []*TestStruct
    16  }
    17  
    18  func TestCache(t *testing.T) {
    19  	tc := NewCache()
    20  
    21  	a, found := tc.Get("a")
    22  	if found || a != nil {
    23  		t.Error("a exist:", a)
    24  	}
    25  
    26  	b, found := tc.Get("b")
    27  	if found || b != nil {
    28  		t.Error("b exist:", b)
    29  	}
    30  
    31  	c, found := tc.Get("c")
    32  	if found || c != nil {
    33  		t.Error("c exist::", c)
    34  	}
    35  
    36  	tc.Set("a", 1, DefaultExpire)
    37  	tc.Set("b", "b", DefaultExpire)
    38  	tc.Set("c", 3.5, DefaultExpire)
    39  
    40  	v, found := tc.Get("a")
    41  	if !found {
    42  		t.Error("a not exist")
    43  	}
    44  	if v == nil {
    45  		t.Error("a == nil")
    46  	} else if vv := v.(int); vv+2 != 3 {
    47  		t.Error("vv != 3", vv)
    48  	}
    49  
    50  	v, found = tc.Get("b")
    51  	if !found {
    52  		t.Error("b not exist")
    53  	}
    54  	if v == nil {
    55  		t.Error("b == nil")
    56  	} else if vv := v.(string); vv+"B" != "bB" {
    57  		t.Error("bb != bB:", vv)
    58  	}
    59  
    60  	v, found = tc.Get("c")
    61  	if !found {
    62  		t.Error("c not exist")
    63  	}
    64  	if v == nil {
    65  		t.Error("x for c is nil")
    66  	} else if vv := v.(float64); vv+1.2 != 4.7 {
    67  		t.Error("vv != 4,7:", vv)
    68  	}
    69  }
    70  
    71  func TestCacheTimes(t *testing.T) {
    72  	var found bool
    73  	tc := NewCache(SetDefaultExpire(50*time.Millisecond), SetInternal(time.Millisecond))
    74  	tc.Set("a", 1, DefaultExpire)
    75  	tc.Set("b", 2, NoExpire)
    76  	tc.Set("c", 3, 20*time.Millisecond)
    77  	tc.Set("d", 4, 70*time.Millisecond)
    78  
    79  	<-time.After(25 * time.Millisecond)
    80  	_, found = tc.Get("c")
    81  	if found {
    82  		t.Error("Found c when it should have been automatically deleted")
    83  	}
    84  
    85  	<-time.After(30 * time.Millisecond)
    86  	_, found = tc.Get("a")
    87  	if found {
    88  		t.Error("Found a when it should have been automatically deleted")
    89  	}
    90  
    91  	_, found = tc.Get("b")
    92  	if !found {
    93  		t.Error("Did not find b even though it was set to never expire")
    94  	}
    95  
    96  	_, found = tc.Get("d")
    97  	if !found {
    98  		t.Error("Did not find d even though it was set to expire later than the default")
    99  	}
   100  
   101  	<-time.After(20 * time.Millisecond)
   102  	_, found = tc.Get("d")
   103  	if found {
   104  		t.Error("Found d when it should have been automatically deleted (later than the default)")
   105  	}
   106  }
   107  
   108  func TestNewFrom(t *testing.T) {
   109  	m := map[string]Iterator{
   110  		"a": {Val: 1, Expire: 0},
   111  		"b": {Val: 2, Expire: 0},
   112  	}
   113  	tc := NewCache(SetInternal(0), SetMember(m))
   114  	a, found := tc.Get("a")
   115  	if !found {
   116  		t.Fatal("Did not find a")
   117  	}
   118  	if a.(int) != 1 {
   119  		t.Fatal("a is not 1")
   120  	}
   121  	b, found := tc.Get("b")
   122  	if !found {
   123  		t.Fatal("Did not find b")
   124  	}
   125  	if b.(int) != 2 {
   126  		t.Fatal("b is not 2")
   127  	}
   128  }
   129  
   130  func TestStorePointerToStruct(t *testing.T) {
   131  	tc := NewCache()
   132  	tc.Set("foo", &TestStruct{Num: 1}, DefaultExpire)
   133  	x, found := tc.Get("foo")
   134  	if !found {
   135  		t.Fatal("*TestStruct was not found for foo")
   136  	}
   137  	foo := x.(*TestStruct)
   138  	foo.Num++
   139  
   140  	y, found := tc.Get("foo")
   141  	if !found {
   142  		t.Fatal("*TestStruct was not found for foo (second time)")
   143  	}
   144  	bar := y.(*TestStruct)
   145  	if bar.Num != 2 {
   146  		t.Fatal("TestStruct.Num is not 2")
   147  	}
   148  }
   149  
   150  func TestIncrementWithInt(t *testing.T) {
   151  	tc := NewCache()
   152  	tc.Set("tint", 1, DefaultExpire)
   153  	err := tc.Increment("tint", 2)
   154  	if err != nil {
   155  		t.Error("Error incrementing:", err)
   156  	}
   157  	x, found := tc.Get("tint")
   158  	if !found {
   159  		t.Error("tint was not found")
   160  	}
   161  	if x.(int) != 3 {
   162  		t.Error("tint is not 3:", x)
   163  	}
   164  }
   165  
   166  func TestIncrementWithInt8(t *testing.T) {
   167  	tc := NewCache()
   168  	tc.Set("tint8", int8(1), DefaultExpire)
   169  	err := tc.Increment("tint8", 2)
   170  	if err != nil {
   171  		t.Error("Error incrementing:", err)
   172  	}
   173  	x, found := tc.Get("tint8")
   174  	if !found {
   175  		t.Error("tint8 was not found")
   176  	}
   177  	if x.(int8) != 3 {
   178  		t.Error("tint8 is not 3:", x)
   179  	}
   180  }
   181  
   182  func TestIncrementWithInt16(t *testing.T) {
   183  	tc := NewCache()
   184  	tc.Set("tint16", int16(1), DefaultExpire)
   185  	err := tc.Increment("tint16", 2)
   186  	if err != nil {
   187  		t.Error("Error incrementing:", err)
   188  	}
   189  	x, found := tc.Get("tint16")
   190  	if !found {
   191  		t.Error("tint16 was not found")
   192  	}
   193  	if x.(int16) != 3 {
   194  		t.Error("tint16 is not 3:", x)
   195  	}
   196  }
   197  
   198  func TestIncrementWithInt32(t *testing.T) {
   199  	tc := NewCache()
   200  	tc.Set("tint32", int32(1), DefaultExpire)
   201  	err := tc.Increment("tint32", 2)
   202  	if err != nil {
   203  		t.Error("Error incrementing:", err)
   204  	}
   205  	x, found := tc.Get("tint32")
   206  	if !found {
   207  		t.Error("tint32 was not found")
   208  	}
   209  	if x.(int32) != 3 {
   210  		t.Error("tint32 is not 3:", x)
   211  	}
   212  }
   213  
   214  func TestIncrementWithInt64(t *testing.T) {
   215  	tc := NewCache()
   216  	tc.Set("tint64", int64(1), DefaultExpire)
   217  	err := tc.Increment("tint64", 2)
   218  	if err != nil {
   219  		t.Error("Error incrementing:", err)
   220  	}
   221  	x, found := tc.Get("tint64")
   222  	if !found {
   223  		t.Error("tint64 was not found")
   224  	}
   225  	if x.(int64) != 3 {
   226  		t.Error("tint64 is not 3:", x)
   227  	}
   228  }
   229  
   230  func TestIncrementWithUint(t *testing.T) {
   231  	tc := NewCache()
   232  	tc.Set("tUint", uint(1), DefaultExpire)
   233  	err := tc.Increment("tUint", 2)
   234  	if err != nil {
   235  		t.Error("Error incrementing:", err)
   236  	}
   237  	x, found := tc.Get("tUint")
   238  	if !found {
   239  		t.Error("tUint was not found")
   240  	}
   241  	if x.(uint) != 3 {
   242  		t.Error("tUint is not 3:", x)
   243  	}
   244  }
   245  
   246  func TestIncrementWithUintPtr(t *testing.T) {
   247  	tc := NewCache()
   248  	tc.Set("tUintPtr", uintptr(1), DefaultExpire)
   249  	err := tc.Increment("tUintPtr", 2)
   250  	if err != nil {
   251  		t.Error("Error incrementing:", err)
   252  	}
   253  
   254  	x, found := tc.Get("tUintPtr")
   255  	if !found {
   256  		t.Error("tUintPtr was not found")
   257  	}
   258  	if x.(uintptr) != 3 {
   259  		t.Error("tUintPtr is not 3:", x)
   260  	}
   261  }
   262  
   263  func TestIncrementWithUint8(t *testing.T) {
   264  	tc := NewCache()
   265  	tc.Set("tUint8", uint8(1), DefaultExpire)
   266  	err := tc.Increment("tUint8", 2)
   267  	if err != nil {
   268  		t.Error("Error incrementing:", err)
   269  	}
   270  	x, found := tc.Get("tUint8")
   271  	if !found {
   272  		t.Error("tUint8 was not found")
   273  	}
   274  	if x.(uint8) != 3 {
   275  		t.Error("tUint8 is not 3:", x)
   276  	}
   277  }
   278  
   279  func TestIncrementWithUint16(t *testing.T) {
   280  	tc := NewCache()
   281  	tc.Set("tUint16", uint16(1), DefaultExpire)
   282  	err := tc.Increment("tUint16", 2)
   283  	if err != nil {
   284  		t.Error("Error incrementing:", err)
   285  	}
   286  
   287  	x, found := tc.Get("tUint16")
   288  	if !found {
   289  		t.Error("tUint16 was not found")
   290  	}
   291  	if x.(uint16) != 3 {
   292  		t.Error("tUint16 is not 3:", x)
   293  	}
   294  }
   295  
   296  func TestIncrementWithUint32(t *testing.T) {
   297  	tc := NewCache()
   298  	tc.Set("tUint32", uint32(1), DefaultExpire)
   299  	err := tc.Increment("tUint32", 2)
   300  	if err != nil {
   301  		t.Error("Error incrementing:", err)
   302  	}
   303  	x, found := tc.Get("tUint32")
   304  	if !found {
   305  		t.Error("tUint32 was not found")
   306  	}
   307  	if x.(uint32) != 3 {
   308  		t.Error("tUint32 is not 3:", x)
   309  	}
   310  }
   311  
   312  func TestIncrementWithUint64(t *testing.T) {
   313  	tc := NewCache()
   314  	tc.Set("tUint64", uint64(1), DefaultExpire)
   315  	err := tc.Increment("tUint64", 2)
   316  	if err != nil {
   317  		t.Error("Error incrementing:", err)
   318  	}
   319  
   320  	x, found := tc.Get("tUint64")
   321  	if !found {
   322  		t.Error("tUint64 was not found")
   323  	}
   324  	if x.(uint64) != 3 {
   325  		t.Error("tUint64 is not 3:", x)
   326  	}
   327  }
   328  
   329  func TestIncrementWithFloat32(t *testing.T) {
   330  	tc := NewCache()
   331  	tc.Set("float32", float32(1.5), DefaultExpire)
   332  	err := tc.Increment("float32", 2)
   333  	if err != nil {
   334  		t.Error("Error incrementing:", err)
   335  	}
   336  	x, found := tc.Get("float32")
   337  	if !found {
   338  		t.Error("float32 was not found")
   339  	}
   340  	if x.(float32) != 3.5 {
   341  		t.Error("float32 is not 3.5:", x)
   342  	}
   343  }
   344  
   345  func TestIncrementWithFloat64(t *testing.T) {
   346  	tc := NewCache()
   347  	tc.Set("float64", 1.5, DefaultExpire)
   348  	err := tc.Increment("float64", 2)
   349  	if err != nil {
   350  		t.Error("Error incrementing:", err)
   351  	}
   352  	x, found := tc.Get("float64")
   353  	if !found {
   354  		t.Error("float64 was not found")
   355  	}
   356  	if x.(float64) != 3.5 {
   357  		t.Error("float64 is not 3.5:", x)
   358  	}
   359  }
   360  
   361  func TestIncrementFloatWithFloat32(t *testing.T) {
   362  	tc := NewCache()
   363  	tc.Set("float32", float32(1.5), DefaultExpire)
   364  	err := tc.IncrementFloat("float32", 2)
   365  	if err != nil {
   366  		t.Error("Error incrementFloating:", err)
   367  	}
   368  	x, found := tc.Get("float32")
   369  	if !found {
   370  		t.Error("float32 was not found")
   371  	}
   372  	if x.(float32) != 3.5 {
   373  		t.Error("float32 is not 3.5:", x)
   374  	}
   375  }
   376  
   377  func TestIncrementFloatWithFloat64(t *testing.T) {
   378  	tc := NewCache()
   379  	tc.Set("float64", 1.5, DefaultExpire)
   380  	err := tc.IncrementFloat("float64", 2)
   381  	if err != nil {
   382  		t.Error("Error incrementFloating:", err)
   383  	}
   384  	x, found := tc.Get("float64")
   385  	if !found {
   386  		t.Error("float64 was not found")
   387  	}
   388  	if x.(float64) != 3.5 {
   389  		t.Error("float64 is not 3.5:", x)
   390  	}
   391  }
   392  
   393  func TestDecrementWithInt(t *testing.T) {
   394  	tc := NewCache()
   395  	tc.Set("int", 5, DefaultExpire)
   396  	err := tc.Decrement("int", 2)
   397  	if err != nil {
   398  		t.Error("Error decrementing:", err)
   399  	}
   400  	x, found := tc.Get("int")
   401  	if !found {
   402  		t.Error("int was not found")
   403  	}
   404  	if x.(int) != 3 {
   405  		t.Error("int is not 3:", x)
   406  	}
   407  }
   408  
   409  func TestDecrementWithInt8(t *testing.T) {
   410  	tc := NewCache()
   411  	tc.Set("int8", int8(5), DefaultExpire)
   412  	err := tc.Decrement("int8", 2)
   413  	if err != nil {
   414  		t.Error("Error decrementing:", err)
   415  	}
   416  	x, found := tc.Get("int8")
   417  	if !found {
   418  		t.Error("int8 was not found")
   419  	}
   420  	if x.(int8) != 3 {
   421  		t.Error("int8 is not 3:", x)
   422  	}
   423  }
   424  
   425  func TestDecrementWithInt16(t *testing.T) {
   426  	tc := NewCache()
   427  	tc.Set("int16", int16(5), DefaultExpire)
   428  	err := tc.Decrement("int16", 2)
   429  	if err != nil {
   430  		t.Error("Error decrementing:", err)
   431  	}
   432  	x, found := tc.Get("int16")
   433  	if !found {
   434  		t.Error("int16 was not found")
   435  	}
   436  	if x.(int16) != 3 {
   437  		t.Error("int16 is not 3:", x)
   438  	}
   439  }
   440  
   441  func TestDecrementWithInt32(t *testing.T) {
   442  	tc := NewCache()
   443  	tc.Set("int32", int32(5), DefaultExpire)
   444  	err := tc.Decrement("int32", 2)
   445  	if err != nil {
   446  		t.Error("Error decrementing:", err)
   447  	}
   448  	x, found := tc.Get("int32")
   449  	if !found {
   450  		t.Error("int32 was not found")
   451  	}
   452  	if x.(int32) != 3 {
   453  		t.Error("int32 is not 3:", x)
   454  	}
   455  }
   456  
   457  func TestDecrementWithInt64(t *testing.T) {
   458  	tc := NewCache()
   459  	tc.Set("int64", int64(5), DefaultExpire)
   460  	err := tc.Decrement("int64", 2)
   461  	if err != nil {
   462  		t.Error("Error decrementing:", err)
   463  	}
   464  	x, found := tc.Get("int64")
   465  	if !found {
   466  		t.Error("int64 was not found")
   467  	}
   468  	if x.(int64) != 3 {
   469  		t.Error("int64 is not 3:", x)
   470  	}
   471  }
   472  
   473  func TestDecrementWithUint(t *testing.T) {
   474  	tc := NewCache()
   475  	tc.Set("uint", uint(5), DefaultExpire)
   476  	err := tc.Decrement("uint", 2)
   477  	if err != nil {
   478  		t.Error("Error decrementing:", err)
   479  	}
   480  	x, found := tc.Get("uint")
   481  	if !found {
   482  		t.Error("uint was not found")
   483  	}
   484  	if x.(uint) != 3 {
   485  		t.Error("uint is not 3:", x)
   486  	}
   487  }
   488  
   489  func TestDecrementWithUintPtr(t *testing.T) {
   490  	tc := NewCache()
   491  	tc.Set("uintPtr", uintptr(5), DefaultExpire)
   492  	err := tc.Decrement("uintPtr", 2)
   493  	if err != nil {
   494  		t.Error("Error decrementing:", err)
   495  	}
   496  	x, found := tc.Get("uintPtr")
   497  	if !found {
   498  		t.Error("uintPtr was not found")
   499  	}
   500  	if x.(uintptr) != 3 {
   501  		t.Error("uintPtr is not 3:", x)
   502  	}
   503  }
   504  
   505  func TestDecrementWithUint8(t *testing.T) {
   506  	tc := NewCache()
   507  	tc.Set("uint8", uint8(5), DefaultExpire)
   508  	err := tc.Decrement("uint8", 2)
   509  	if err != nil {
   510  		t.Error("Error decrementing:", err)
   511  	}
   512  	x, found := tc.Get("uint8")
   513  	if !found {
   514  		t.Error("uint8 was not found")
   515  	}
   516  	if x.(uint8) != 3 {
   517  		t.Error("uint8 is not 3:", x)
   518  	}
   519  }
   520  
   521  func TestDecrementWithUint16(t *testing.T) {
   522  	tc := NewCache()
   523  	tc.Set("uint16", uint16(5), DefaultExpire)
   524  	err := tc.Decrement("uint16", 2)
   525  	if err != nil {
   526  		t.Error("Error decrementing:", err)
   527  	}
   528  	x, found := tc.Get("uint16")
   529  	if !found {
   530  		t.Error("uint16 was not found")
   531  	}
   532  	if x.(uint16) != 3 {
   533  		t.Error("uint16 is not 3:", x)
   534  	}
   535  }
   536  
   537  func TestDecrementWithUint32(t *testing.T) {
   538  	tc := NewCache()
   539  	tc.Set("uint32", uint32(5), DefaultExpire)
   540  	err := tc.Decrement("uint32", 2)
   541  	if err != nil {
   542  		t.Error("Error decrementing:", err)
   543  	}
   544  	x, found := tc.Get("uint32")
   545  	if !found {
   546  		t.Error("uint32 was not found")
   547  	}
   548  	if x.(uint32) != 3 {
   549  		t.Error("uint32 is not 3:", x)
   550  	}
   551  }
   552  
   553  func TestDecrementWithUint64(t *testing.T) {
   554  	tc := NewCache()
   555  	tc.Set("uint64", uint64(5), DefaultExpire)
   556  	err := tc.Decrement("uint64", 2)
   557  	if err != nil {
   558  		t.Error("Error decrementing:", err)
   559  	}
   560  	x, found := tc.Get("uint64")
   561  	if !found {
   562  		t.Error("uint64 was not found")
   563  	}
   564  	if x.(uint64) != 3 {
   565  		t.Error("uint64 is not 3:", x)
   566  	}
   567  }
   568  
   569  func TestDecrementWithFloat32(t *testing.T) {
   570  	tc := NewCache()
   571  	tc.Set("float32", float32(5.5), DefaultExpire)
   572  	err := tc.Decrement("float32", 2)
   573  	if err != nil {
   574  		t.Error("Error decrementing:", err)
   575  	}
   576  	x, found := tc.Get("float32")
   577  	if !found {
   578  		t.Error("float32 was not found")
   579  	}
   580  	if x.(float32) != 3.5 {
   581  		t.Error("float32 is not 3:", x)
   582  	}
   583  }
   584  
   585  func TestDecrementWithFloat64(t *testing.T) {
   586  	tc := NewCache()
   587  	tc.Set("float64", 5.5, DefaultExpire)
   588  	err := tc.Decrement("float64", 2)
   589  	if err != nil {
   590  		t.Error("Error decrementing:", err)
   591  	}
   592  	x, found := tc.Get("float64")
   593  	if !found {
   594  		t.Error("float64 was not found")
   595  	}
   596  	if x.(float64) != 3.5 {
   597  		t.Error("float64 is not 3:", x)
   598  	}
   599  }
   600  
   601  func TestDecrementFloatWithFloat32(t *testing.T) {
   602  	tc := NewCache()
   603  	tc.Set("float32", float32(5.5), DefaultExpire)
   604  	err := tc.DecrementFloat("float32", 2)
   605  	if err != nil {
   606  		t.Error("Error decrementing:", err)
   607  	}
   608  	x, found := tc.Get("float32")
   609  	if !found {
   610  		t.Error("float32 was not found")
   611  	}
   612  	if x.(float32) != 3.5 {
   613  		t.Error("float32 is not 3:", x)
   614  	}
   615  }
   616  
   617  func TestDecrementFloatWithFloat64(t *testing.T) {
   618  	tc := NewCache()
   619  	tc.Set("float64", 5.5, DefaultExpire)
   620  	err := tc.DecrementFloat("float64", 2)
   621  	if err != nil {
   622  		t.Error("Error decrementing:", err)
   623  	}
   624  	x, found := tc.Get("float64")
   625  	if !found {
   626  		t.Error("float64 was not found")
   627  	}
   628  	if x.(float64) != 3.5 {
   629  		t.Error("float64 is not 3:", x)
   630  	}
   631  }
   632  
   633  func TestIncrementInt(t *testing.T) {
   634  	tc := NewCache()
   635  	tc.Set("tint", 1, DefaultExpire)
   636  	n, err := tc.IncrementInt("tint", 2)
   637  	if err != nil {
   638  		t.Error("Error incrementing:", err)
   639  	}
   640  	if n != 3 {
   641  		t.Error("Returned number is not 3:", n)
   642  	}
   643  	x, found := tc.Get("tint")
   644  	if !found {
   645  		t.Error("tint was not found")
   646  	}
   647  	if x.(int) != 3 {
   648  		t.Error("tint is not 3:", x)
   649  	}
   650  }
   651  
   652  func TestIncrementInt8(t *testing.T) {
   653  	tc := NewCache()
   654  	tc.Set("tint8", int8(1), DefaultExpire)
   655  	n, err := tc.IncrementInt8("tint8", 2)
   656  	if err != nil {
   657  		t.Error("Error incrementing:", err)
   658  	}
   659  	if n != 3 {
   660  		t.Error("Returned number is not 3:", n)
   661  	}
   662  	x, found := tc.Get("tint8")
   663  	if !found {
   664  		t.Error("tint8 was not found")
   665  	}
   666  	if x.(int8) != 3 {
   667  		t.Error("tint8 is not 3:", x)
   668  	}
   669  }
   670  
   671  func TestIncrementInt16(t *testing.T) {
   672  	tc := NewCache()
   673  	tc.Set("tint16", int16(1), DefaultExpire)
   674  	n, err := tc.IncrementInt16("tint16", 2)
   675  	if err != nil {
   676  		t.Error("Error incrementing:", err)
   677  	}
   678  	if n != 3 {
   679  		t.Error("Returned number is not 3:", n)
   680  	}
   681  	x, found := tc.Get("tint16")
   682  	if !found {
   683  		t.Error("tint16 was not found")
   684  	}
   685  	if x.(int16) != 3 {
   686  		t.Error("tint16 is not 3:", x)
   687  	}
   688  }
   689  
   690  func TestIncrementInt32(t *testing.T) {
   691  	tc := NewCache()
   692  	tc.Set("tint32", int32(1), DefaultExpire)
   693  	n, err := tc.IncrementInt32("tint32", 2)
   694  	if err != nil {
   695  		t.Error("Error incrementing:", err)
   696  	}
   697  	if n != 3 {
   698  		t.Error("Returned number is not 3:", n)
   699  	}
   700  	x, found := tc.Get("tint32")
   701  	if !found {
   702  		t.Error("tint32 was not found")
   703  	}
   704  	if x.(int32) != 3 {
   705  		t.Error("tint32 is not 3:", x)
   706  	}
   707  }
   708  
   709  func TestIncrementInt64(t *testing.T) {
   710  	tc := NewCache()
   711  	tc.Set("tint64", int64(1), DefaultExpire)
   712  	n, err := tc.IncrementInt64("tint64", 2)
   713  	if err != nil {
   714  		t.Error("Error incrementing:", err)
   715  	}
   716  	if n != 3 {
   717  		t.Error("Returned number is not 3:", n)
   718  	}
   719  	x, found := tc.Get("tint64")
   720  	if !found {
   721  		t.Error("tint64 was not found")
   722  	}
   723  	if x.(int64) != 3 {
   724  		t.Error("tint64 is not 3:", x)
   725  	}
   726  }
   727  
   728  func TestIncrementUint(t *testing.T) {
   729  	tc := NewCache()
   730  	tc.Set("tUint", uint(1), DefaultExpire)
   731  	n, err := tc.IncrementUint("tUint", 2)
   732  	if err != nil {
   733  		t.Error("Error incrementing:", err)
   734  	}
   735  	if n != 3 {
   736  		t.Error("Returned number is not 3:", n)
   737  	}
   738  	x, found := tc.Get("tUint")
   739  	if !found {
   740  		t.Error("tUint was not found")
   741  	}
   742  	if x.(uint) != 3 {
   743  		t.Error("tUint is not 3:", x)
   744  	}
   745  }
   746  
   747  func TestIncrementUintPtr(t *testing.T) {
   748  	tc := NewCache()
   749  	tc.Set("tUintPtr", uintptr(1), DefaultExpire)
   750  	n, err := tc.IncrementUintPtr("tUintPtr", 2)
   751  	if err != nil {
   752  		t.Error("Error incrementing:", err)
   753  	}
   754  	if n != 3 {
   755  		t.Error("Returned number is not 3:", n)
   756  	}
   757  	x, found := tc.Get("tUintPtr")
   758  	if !found {
   759  		t.Error("tUintPtr was not found")
   760  	}
   761  	if x.(uintptr) != 3 {
   762  		t.Error("tUintPtr is not 3:", x)
   763  	}
   764  }
   765  
   766  func TestIncrementUint8(t *testing.T) {
   767  	tc := NewCache()
   768  	tc.Set("tUint8", uint8(1), DefaultExpire)
   769  	n, err := tc.IncrementUint8("tUint8", 2)
   770  	if err != nil {
   771  		t.Error("Error incrementing:", err)
   772  	}
   773  	if n != 3 {
   774  		t.Error("Returned number is not 3:", n)
   775  	}
   776  	x, found := tc.Get("tUint8")
   777  	if !found {
   778  		t.Error("tUint8 was not found")
   779  	}
   780  	if x.(uint8) != 3 {
   781  		t.Error("tUint8 is not 3:", x)
   782  	}
   783  }
   784  
   785  func TestIncrementUint16(t *testing.T) {
   786  	tc := NewCache()
   787  	tc.Set("tUint16", uint16(1), DefaultExpire)
   788  	n, err := tc.IncrementUint16("tUint16", 2)
   789  	if err != nil {
   790  		t.Error("Error incrementing:", err)
   791  	}
   792  	if n != 3 {
   793  		t.Error("Returned number is not 3:", n)
   794  	}
   795  	x, found := tc.Get("tUint16")
   796  	if !found {
   797  		t.Error("tUint16 was not found")
   798  	}
   799  	if x.(uint16) != 3 {
   800  		t.Error("tUint16 is not 3:", x)
   801  	}
   802  }
   803  
   804  func TestIncrementUint32(t *testing.T) {
   805  	tc := NewCache()
   806  	tc.Set("tUint32", uint32(1), DefaultExpire)
   807  	n, err := tc.IncrementUint32("tUint32", 2)
   808  	if err != nil {
   809  		t.Error("Error incrementing:", err)
   810  	}
   811  	if n != 3 {
   812  		t.Error("Returned number is not 3:", n)
   813  	}
   814  	x, found := tc.Get("tUint32")
   815  	if !found {
   816  		t.Error("tUint32 was not found")
   817  	}
   818  	if x.(uint32) != 3 {
   819  		t.Error("tUint32 is not 3:", x)
   820  	}
   821  }
   822  
   823  func TestIncrementUint64(t *testing.T) {
   824  	tc := NewCache()
   825  	tc.Set("tUint64", uint64(1), DefaultExpire)
   826  	n, err := tc.IncrementUint64("tUint64", 2)
   827  	if err != nil {
   828  		t.Error("Error incrementing:", err)
   829  	}
   830  	if n != 3 {
   831  		t.Error("Returned number is not 3:", n)
   832  	}
   833  	x, found := tc.Get("tUint64")
   834  	if !found {
   835  		t.Error("tUint64 was not found")
   836  	}
   837  	if x.(uint64) != 3 {
   838  		t.Error("tUint64 is not 3:", x)
   839  	}
   840  }
   841  
   842  func TestIncrementFloat32(t *testing.T) {
   843  	tc := NewCache()
   844  	tc.Set("float32", float32(1.5), DefaultExpire)
   845  	n, err := tc.IncrementFloat32("float32", 2)
   846  	if err != nil {
   847  		t.Error("Error incrementing:", err)
   848  	}
   849  	if n != 3.5 {
   850  		t.Error("Returned number is not 3.5:", n)
   851  	}
   852  	x, found := tc.Get("float32")
   853  	if !found {
   854  		t.Error("float32 was not found")
   855  	}
   856  	if x.(float32) != 3.5 {
   857  		t.Error("float32 is not 3.5:", x)
   858  	}
   859  }
   860  
   861  func TestIncrementFloat64(t *testing.T) {
   862  	tc := NewCache()
   863  	tc.Set("float64", 1.5, DefaultExpire)
   864  	n, err := tc.IncrementFloat64("float64", 2)
   865  	if err != nil {
   866  		t.Error("Error incrementing:", err)
   867  	}
   868  	if n != 3.5 {
   869  		t.Error("Returned number is not 3.5:", n)
   870  	}
   871  	x, found := tc.Get("float64")
   872  	if !found {
   873  		t.Error("float64 was not found")
   874  	}
   875  	if x.(float64) != 3.5 {
   876  		t.Error("float64 is not 3.5:", x)
   877  	}
   878  }
   879  
   880  func TestDecrementInt8(t *testing.T) {
   881  	tc := NewCache()
   882  	tc.Set("int8", int8(5), DefaultExpire)
   883  	n, err := tc.DecrementInt8("int8", 2)
   884  	if err != nil {
   885  		t.Error("Error decrementing:", err)
   886  	}
   887  	if n != 3 {
   888  		t.Error("Returned number is not 3:", n)
   889  	}
   890  	x, found := tc.Get("int8")
   891  	if !found {
   892  		t.Error("int8 was not found")
   893  	}
   894  	if x.(int8) != 3 {
   895  		t.Error("int8 is not 3:", x)
   896  	}
   897  }
   898  
   899  func TestDecrementInt16(t *testing.T) {
   900  	tc := NewCache()
   901  	tc.Set("int16", int16(5), DefaultExpire)
   902  	n, err := tc.DecrementInt16("int16", 2)
   903  	if err != nil {
   904  		t.Error("Error decrementing:", err)
   905  	}
   906  	if n != 3 {
   907  		t.Error("Returned number is not 3:", n)
   908  	}
   909  	x, found := tc.Get("int16")
   910  	if !found {
   911  		t.Error("int16 was not found")
   912  	}
   913  	if x.(int16) != 3 {
   914  		t.Error("int16 is not 3:", x)
   915  	}
   916  }
   917  
   918  func TestDecrementInt32(t *testing.T) {
   919  	tc := NewCache()
   920  	tc.Set("int32", int32(5), DefaultExpire)
   921  	n, err := tc.DecrementInt32("int32", 2)
   922  	if err != nil {
   923  		t.Error("Error decrementing:", err)
   924  	}
   925  	if n != 3 {
   926  		t.Error("Returned number is not 3:", n)
   927  	}
   928  	x, found := tc.Get("int32")
   929  	if !found {
   930  		t.Error("int32 was not found")
   931  	}
   932  	if x.(int32) != 3 {
   933  		t.Error("int32 is not 3:", x)
   934  	}
   935  }
   936  
   937  func TestDecrementInt64(t *testing.T) {
   938  	tc := NewCache()
   939  	tc.Set("int64", int64(5), DefaultExpire)
   940  	n, err := tc.DecrementInt64("int64", 2)
   941  	if err != nil {
   942  		t.Error("Error decrementing:", err)
   943  	}
   944  	if n != 3 {
   945  		t.Error("Returned number is not 3:", n)
   946  	}
   947  	x, found := tc.Get("int64")
   948  	if !found {
   949  		t.Error("int64 was not found")
   950  	}
   951  	if x.(int64) != 3 {
   952  		t.Error("int64 is not 3:", x)
   953  	}
   954  }
   955  
   956  func TestDecrementUint(t *testing.T) {
   957  	tc := NewCache()
   958  	tc.Set("uint", uint(5), DefaultExpire)
   959  	n, err := tc.DecrementUint("uint", 2)
   960  	if err != nil {
   961  		t.Error("Error decrementing:", err)
   962  	}
   963  	if n != 3 {
   964  		t.Error("Returned number is not 3:", n)
   965  	}
   966  	x, found := tc.Get("uint")
   967  	if !found {
   968  		t.Error("uint was not found")
   969  	}
   970  	if x.(uint) != 3 {
   971  		t.Error("uint is not 3:", x)
   972  	}
   973  }
   974  
   975  func TestDecrementUintPtr(t *testing.T) {
   976  	tc := NewCache()
   977  	tc.Set("uintPtr", uintptr(5), DefaultExpire)
   978  	n, err := tc.DecrementUintPtr("uintPtr", 2)
   979  	if err != nil {
   980  		t.Error("Error decrementing:", err)
   981  	}
   982  	if n != 3 {
   983  		t.Error("Returned number is not 3:", n)
   984  	}
   985  	x, found := tc.Get("uintPtr")
   986  	if !found {
   987  		t.Error("uintPtr was not found")
   988  	}
   989  	if x.(uintptr) != 3 {
   990  		t.Error("uintPtr is not 3:", x)
   991  	}
   992  }
   993  
   994  func TestDecrementUint8(t *testing.T) {
   995  	tc := NewCache()
   996  	tc.Set("uint8", uint8(5), DefaultExpire)
   997  	n, err := tc.DecrementUint8("uint8", 2)
   998  	if err != nil {
   999  		t.Error("Error decrementing:", err)
  1000  	}
  1001  	if n != 3 {
  1002  		t.Error("Returned number is not 3:", n)
  1003  	}
  1004  	x, found := tc.Get("uint8")
  1005  	if !found {
  1006  		t.Error("uint8 was not found")
  1007  	}
  1008  	if x.(uint8) != 3 {
  1009  		t.Error("uint8 is not 3:", x)
  1010  	}
  1011  }
  1012  
  1013  func TestDecrementUint16(t *testing.T) {
  1014  	tc := NewCache()
  1015  	tc.Set("uint16", uint16(5), DefaultExpire)
  1016  	n, err := tc.DecrementUint16("uint16", 2)
  1017  	if err != nil {
  1018  		t.Error("Error decrementing:", err)
  1019  	}
  1020  	if n != 3 {
  1021  		t.Error("Returned number is not 3:", n)
  1022  	}
  1023  	x, found := tc.Get("uint16")
  1024  	if !found {
  1025  		t.Error("uint16 was not found")
  1026  	}
  1027  	if x.(uint16) != 3 {
  1028  		t.Error("uint16 is not 3:", x)
  1029  	}
  1030  }
  1031  
  1032  func TestDecrementUint32(t *testing.T) {
  1033  	tc := NewCache()
  1034  	tc.Set("uint32", uint32(5), DefaultExpire)
  1035  	n, err := tc.DecrementUint32("uint32", 2)
  1036  	if err != nil {
  1037  		t.Error("Error decrementing:", err)
  1038  	}
  1039  	if n != 3 {
  1040  		t.Error("Returned number is not 3:", n)
  1041  	}
  1042  	x, found := tc.Get("uint32")
  1043  	if !found {
  1044  		t.Error("uint32 was not found")
  1045  	}
  1046  	if x.(uint32) != 3 {
  1047  		t.Error("uint32 is not 3:", x)
  1048  	}
  1049  }
  1050  
  1051  func TestDecrementUint64(t *testing.T) {
  1052  	tc := NewCache()
  1053  	tc.Set("uint64", uint64(5), DefaultExpire)
  1054  	n, err := tc.DecrementUint64("uint64", 2)
  1055  	if err != nil {
  1056  		t.Error("Error decrementing:", err)
  1057  	}
  1058  	if n != 3 {
  1059  		t.Error("Returned number is not 3:", n)
  1060  	}
  1061  	x, found := tc.Get("uint64")
  1062  	if !found {
  1063  		t.Error("uint64 was not found")
  1064  	}
  1065  	if x.(uint64) != 3 {
  1066  		t.Error("uint64 is not 3:", x)
  1067  	}
  1068  }
  1069  
  1070  func TestDecrementFloat32(t *testing.T) {
  1071  	tc := NewCache()
  1072  	tc.Set("float32", float32(5), DefaultExpire)
  1073  	n, err := tc.DecrementFloat32("float32", 2)
  1074  	if err != nil {
  1075  		t.Error("Error decrementing:", err)
  1076  	}
  1077  	if n != 3 {
  1078  		t.Error("Returned number is not 3:", n)
  1079  	}
  1080  	x, found := tc.Get("float32")
  1081  	if !found {
  1082  		t.Error("float32 was not found")
  1083  	}
  1084  	if x.(float32) != 3 {
  1085  		t.Error("float32 is not 3:", x)
  1086  	}
  1087  }
  1088  
  1089  func TestDecrementFloat64(t *testing.T) {
  1090  	tc := NewCache()
  1091  	tc.Set("float64", float64(5), DefaultExpire)
  1092  	n, err := tc.DecrementFloat64("float64", 2)
  1093  	if err != nil {
  1094  		t.Error("Error decrementing:", err)
  1095  	}
  1096  	if n != 3 {
  1097  		t.Error("Returned number is not 3:", n)
  1098  	}
  1099  	x, found := tc.Get("float64")
  1100  	if !found {
  1101  		t.Error("float64 was not found")
  1102  	}
  1103  	if x.(float64) != 3 {
  1104  		t.Error("float64 is not 3:", x)
  1105  	}
  1106  }
  1107  
  1108  func TestAdd(t *testing.T) {
  1109  	tc := NewCache()
  1110  	err := tc.Add("foo", "bar", DefaultExpire)
  1111  	if err != nil {
  1112  		t.Error("Couldn't add foo even though it shouldn't exist")
  1113  	}
  1114  	err = tc.Add("foo", "baz", DefaultExpire)
  1115  	if err == nil {
  1116  		t.Error("Successfully added another foo when it should have returned an error")
  1117  	}
  1118  }
  1119  
  1120  func TestReplace(t *testing.T) {
  1121  	tc := NewCache()
  1122  	err := tc.Replace("foo", "bar", DefaultExpire)
  1123  	if err == nil {
  1124  		t.Error("Replaced foo when it shouldn't exist")
  1125  	}
  1126  	tc.Set("foo", "bar", DefaultExpire)
  1127  	err = tc.Replace("foo", "bar", DefaultExpire)
  1128  	if err != nil {
  1129  		t.Error("Couldn't replace existing key foo")
  1130  	}
  1131  }
  1132  
  1133  func TestDelete(t *testing.T) {
  1134  	tc := NewCache()
  1135  	tc.Set("foo", "bar", DefaultExpire)
  1136  	tc.Delete("foo")
  1137  	x, found := tc.Get("foo")
  1138  	if found {
  1139  		t.Error("foo was found, but it should have been deleted")
  1140  	}
  1141  	if x != nil {
  1142  		t.Error("x is not nil:", x)
  1143  	}
  1144  }
  1145  
  1146  func TestItemCount(t *testing.T) {
  1147  	tc := NewCache()
  1148  	tc.Set("foo", "1", DefaultExpire)
  1149  	tc.Set("bar", "2", DefaultExpire)
  1150  	tc.Set("baz", "3", DefaultExpire)
  1151  	if n := tc.Count(); n != 3 {
  1152  		t.Errorf("Item count is not 3: %d", n)
  1153  	}
  1154  }
  1155  
  1156  func TestFlush(t *testing.T) {
  1157  	tc := NewCache()
  1158  	tc.Set("foo", "bar", DefaultExpire)
  1159  	tc.Set("baz", "yes", DefaultExpire)
  1160  	tc.Flush()
  1161  	x, found := tc.Get("foo")
  1162  	if found {
  1163  		t.Error("foo was found, but it should have been deleted")
  1164  	}
  1165  	if x != nil {
  1166  		t.Error("x is not nil:", x)
  1167  	}
  1168  	x, found = tc.Get("baz")
  1169  	if found {
  1170  		t.Error("baz was found, but it should have been deleted")
  1171  	}
  1172  	if x != nil {
  1173  		t.Error("x is not nil:", x)
  1174  	}
  1175  }
  1176  
  1177  func TestIncrementOverflowInt(t *testing.T) {
  1178  	tc := NewCache()
  1179  	tc.Set("i8", int8(127), DefaultExpire)
  1180  	err := tc.Increment("i8", 1)
  1181  	if err != nil {
  1182  		t.Error("Error incrementing i8:", err)
  1183  	}
  1184  	x, _ := tc.Get("i8")
  1185  	i8 := x.(int8)
  1186  	if i8 != -128 {
  1187  		t.Error("i8 did not overflow as expected; value:", i8)
  1188  	}
  1189  }
  1190  
  1191  func TestIncrementOverflowUint(t *testing.T) {
  1192  	tc := NewCache()
  1193  	tc.Set("ui8", uint8(255), DefaultExpire)
  1194  	err := tc.Increment("ui8", 1)
  1195  	if err != nil {
  1196  		t.Error("Error incrementing int8:", err)
  1197  	}
  1198  	x, _ := tc.Get("ui8")
  1199  	ui8 := x.(uint8)
  1200  	if ui8 != 0 {
  1201  		t.Error("ui8 did not overflow as expected; value:", ui8)
  1202  	}
  1203  }
  1204  
  1205  func TestDecrementUnderflowUint(t *testing.T) {
  1206  	tc := NewCache()
  1207  	tc.Set("ui8", uint8(0), DefaultExpire)
  1208  	err := tc.Decrement("ui8", 1)
  1209  	if err != nil {
  1210  		t.Error("Error decrementing int8:", err)
  1211  	}
  1212  	x, _ := tc.Get("ui8")
  1213  	ui8 := x.(uint8)
  1214  	if ui8 != 255 {
  1215  		t.Error("ui8 did not underflow as expected; value:", ui8)
  1216  	}
  1217  }
  1218  
  1219  func TestOnEvicted(t *testing.T) {
  1220  	tc := NewCache()
  1221  	tc.Set("foo", 3, DefaultExpire)
  1222  	if tc.capture == nil {
  1223  		t.Fatal("tc.onEvicted is nil")
  1224  	}
  1225  	works := false
  1226  	tc.ChangeCapture(func(k string, v interface{}) {
  1227  		if k == "foo" && v.(int) == 3 {
  1228  			works = true
  1229  		}
  1230  		tc.Set("bar", 4, DefaultExpire)
  1231  	})
  1232  	tc.Delete("foo")
  1233  	x, _ := tc.Get("bar")
  1234  	if !works {
  1235  		t.Error("works bool not true")
  1236  	}
  1237  	if x.(int) != 4 {
  1238  		t.Error("bar was not 4")
  1239  	}
  1240  }
  1241  
  1242  func TestCacheSerialization(t *testing.T) {
  1243  	tc := NewCache()
  1244  	testFillAndSerialize(t, &tc)
  1245  
  1246  	// Check if gob.Register behaves properly even after multiple gob.Register
  1247  	// on c.Items (many of which will be the same type)
  1248  	testFillAndSerialize(t, &tc)
  1249  }
  1250  
  1251  func testFillAndSerialize(t *testing.T, tc *Cache) {
  1252  	tc.Set("a", "a", DefaultExpire)
  1253  	tc.Set("b", "b", DefaultExpire)
  1254  	tc.Set("c", "c", DefaultExpire)
  1255  	tc.Set("expired", "foo", 1*time.Millisecond)
  1256  	tc.Set("*struct", &TestStruct{Num: 1}, DefaultExpire)
  1257  	tc.Set("[]struct", []TestStruct{
  1258  		{Num: 2},
  1259  		{Num: 3},
  1260  	}, DefaultExpire)
  1261  	tc.Set("[]*struct", []*TestStruct{
  1262  		{Num: 4},
  1263  		{Num: 5},
  1264  	}, DefaultExpire)
  1265  	tc.Set("structuration", &TestStruct{
  1266  		Num: 42,
  1267  		Children: []*TestStruct{
  1268  			{Num: 6174},
  1269  			{Num: 4716},
  1270  		},
  1271  	}, DefaultExpire)
  1272  
  1273  	fp := &bytes.Buffer{}
  1274  	err := tc.Save(fp)
  1275  	if err != nil {
  1276  		t.Fatal("Couldn't save cache to fp:", err)
  1277  	}
  1278  
  1279  	oc := NewCache()
  1280  	err = oc.Load(fp)
  1281  	if err != nil {
  1282  		t.Fatal("Couldn't load cache from fp:", err)
  1283  	}
  1284  
  1285  	a, found := oc.Get("a")
  1286  	if !found {
  1287  		t.Error("a was not found")
  1288  	}
  1289  	if a.(string) != "a" {
  1290  		t.Error("a is not a")
  1291  	}
  1292  
  1293  	b, found := oc.Get("b")
  1294  	if !found {
  1295  		t.Error("b was not found")
  1296  	}
  1297  	if b.(string) != "b" {
  1298  		t.Error("b is not b")
  1299  	}
  1300  
  1301  	c, found := oc.Get("c")
  1302  	if !found {
  1303  		t.Error("c was not found")
  1304  	}
  1305  	if c.(string) != "c" {
  1306  		t.Error("c is not c")
  1307  	}
  1308  
  1309  	<-time.After(5 * time.Millisecond)
  1310  	_, found = oc.Get("expired")
  1311  	if found {
  1312  		t.Error("expired was found")
  1313  	}
  1314  
  1315  	s1, found := oc.Get("*struct")
  1316  	if !found {
  1317  		t.Error("*struct was not found")
  1318  	}
  1319  	if s1.(*TestStruct).Num != 1 {
  1320  		t.Error("*struct.Num is not 1")
  1321  	}
  1322  
  1323  	s2, found := oc.Get("[]struct")
  1324  	if !found {
  1325  		t.Error("[]struct was not found")
  1326  	}
  1327  	s2r := s2.([]TestStruct)
  1328  	if len(s2r) != 2 {
  1329  		t.Error("Length of s2r is not 2")
  1330  	}
  1331  	if s2r[0].Num != 2 {
  1332  		t.Error("s2r[0].Num is not 2")
  1333  	}
  1334  	if s2r[1].Num != 3 {
  1335  		t.Error("s2r[1].Num is not 3")
  1336  	}
  1337  
  1338  	s3, found := oc.get("[]*struct")
  1339  	if !found {
  1340  		t.Error("[]*struct was not found")
  1341  	}
  1342  	s3r := s3.([]*TestStruct)
  1343  	if len(s3r) != 2 {
  1344  		t.Error("Length of s3r is not 2")
  1345  	}
  1346  	if s3r[0].Num != 4 {
  1347  		t.Error("s3r[0].Num is not 4")
  1348  	}
  1349  	if s3r[1].Num != 5 {
  1350  		t.Error("s3r[1].Num is not 5")
  1351  	}
  1352  
  1353  	s4, found := oc.get("structuration")
  1354  	if !found {
  1355  		t.Error("structuration was not found")
  1356  	}
  1357  	s4r := s4.(*TestStruct)
  1358  	if len(s4r.Children) != 2 {
  1359  		t.Error("Length of s4r.Children is not 2")
  1360  	}
  1361  	if s4r.Children[0].Num != 6174 {
  1362  		t.Error("s4r.Children[0].Num is not 6174")
  1363  	}
  1364  	if s4r.Children[1].Num != 4716 {
  1365  		t.Error("s4r.Children[1].Num is not 4716")
  1366  	}
  1367  }
  1368  
  1369  func TestFileSerialization(t *testing.T) {
  1370  	tc := NewCache()
  1371  	_ = tc.Add("a", "a", DefaultExpire)
  1372  	_ = tc.Add("b", "b", DefaultExpire)
  1373  	f, err := ioutil.TempFile("", "go-cache-cache.dat")
  1374  	if err != nil {
  1375  		t.Fatal("Couldn't create cache file:", err)
  1376  	}
  1377  	path := f.Name()
  1378  	_ = f.Close()
  1379  	_ = tc.SaveFile(path)
  1380  
  1381  	oc := NewCache()
  1382  	_ = oc.Add("a", "aa", 0) // this should not be overwritten
  1383  	err = oc.LoadFile(path)
  1384  	if err != nil {
  1385  		t.Error(err)
  1386  	}
  1387  	a, found := oc.Get("a")
  1388  	if !found {
  1389  		t.Error("a was not found")
  1390  	}
  1391  	aStr := a.(string)
  1392  	if aStr != "aa" {
  1393  		if aStr == "a" {
  1394  			t.Error("a was overwritten")
  1395  		} else {
  1396  			t.Error("a is not aa")
  1397  		}
  1398  	}
  1399  	b, found := oc.Get("b")
  1400  	if !found {
  1401  		t.Error("b was not found")
  1402  	}
  1403  	if b.(string) != "b" {
  1404  		t.Error("b is not b")
  1405  	}
  1406  }
  1407  
  1408  func TestSerializeUnserializable(t *testing.T) {
  1409  	tc := NewCache()
  1410  	ch := make(chan bool, 1)
  1411  	ch <- true
  1412  	tc.Set("chan", ch, DefaultExpire)
  1413  	fp := &bytes.Buffer{}
  1414  	err := tc.Save(fp) // this should fail gracefully
  1415  	if err != nil && err.Error() != "gob NewTypeObject can't handle type: chan bool" {
  1416  		t.Error("Error from Save was not gob NewTypeObject can't handle type chan bool:", err)
  1417  	}
  1418  }
  1419  
  1420  func BenchmarkCacheGetExpiring(b *testing.B) {
  1421  	benchmarkCacheGet(b)
  1422  }
  1423  
  1424  func BenchmarkCacheGetNotExpiring(b *testing.B) {
  1425  	benchmarkCacheGet(b)
  1426  }
  1427  
  1428  func benchmarkCacheGet(b *testing.B) {
  1429  	b.StopTimer()
  1430  	tc := NewCache()
  1431  	tc.Set("foo", "bar", DefaultExpire)
  1432  	b.StartTimer()
  1433  	for i := 0; i < b.N; i++ {
  1434  		tc.Get("foo")
  1435  	}
  1436  }
  1437  
  1438  func BenchmarkRWMutexMapGet(b *testing.B) {
  1439  	b.StopTimer()
  1440  	m := map[string]string{
  1441  		"foo": "bar",
  1442  	}
  1443  	mu := sync.RWMutex{}
  1444  	b.StartTimer()
  1445  	for i := 0; i < b.N; i++ {
  1446  		mu.RLock()
  1447  		_, _ = m["foo"]
  1448  		mu.RUnlock()
  1449  	}
  1450  }
  1451  
  1452  func BenchmarkRWMutexInterfaceMapGetStruct(b *testing.B) {
  1453  	b.StopTimer()
  1454  	s := struct{ name string }{name: "foo"}
  1455  	m := map[interface{}]string{
  1456  		s: "bar",
  1457  	}
  1458  	mu := sync.RWMutex{}
  1459  	b.StartTimer()
  1460  	for i := 0; i < b.N; i++ {
  1461  		mu.RLock()
  1462  		_, _ = m[s]
  1463  		mu.RUnlock()
  1464  	}
  1465  }
  1466  
  1467  func BenchmarkRWMutexInterfaceMapGetString(b *testing.B) {
  1468  	b.StopTimer()
  1469  	m := map[interface{}]string{
  1470  		"foo": "bar",
  1471  	}
  1472  	mu := sync.RWMutex{}
  1473  	b.StartTimer()
  1474  	for i := 0; i < b.N; i++ {
  1475  		mu.RLock()
  1476  		_, _ = m["foo"]
  1477  		mu.RUnlock()
  1478  	}
  1479  }
  1480  
  1481  func BenchmarkCacheGetConcurrentExpiring(b *testing.B) {
  1482  	benchmarkCacheGetConcurrent(b)
  1483  }
  1484  
  1485  func BenchmarkCacheGetConcurrentNotExpiring(b *testing.B) {
  1486  	benchmarkCacheGetConcurrent(b)
  1487  }
  1488  
  1489  func benchmarkCacheGetConcurrent(b *testing.B) {
  1490  	b.StopTimer()
  1491  	tc := NewCache()
  1492  	tc.Set("foo", "bar", DefaultExpire)
  1493  	wg := new(sync.WaitGroup)
  1494  	workers := runtime.NumCPU()
  1495  	each := b.N / workers
  1496  	wg.Add(workers)
  1497  	b.StartTimer()
  1498  	for i := 0; i < workers; i++ {
  1499  		go func() {
  1500  			for j := 0; j < each; j++ {
  1501  				tc.Get("foo")
  1502  			}
  1503  			wg.Done()
  1504  		}()
  1505  	}
  1506  	wg.Wait()
  1507  }
  1508  
  1509  func BenchmarkRWMutexMapGetConcurrent(b *testing.B) {
  1510  	b.StopTimer()
  1511  	m := map[string]string{
  1512  		"foo": "bar",
  1513  	}
  1514  	mu := sync.RWMutex{}
  1515  	wg := new(sync.WaitGroup)
  1516  	workers := runtime.NumCPU()
  1517  	each := b.N / workers
  1518  	wg.Add(workers)
  1519  	b.StartTimer()
  1520  	for i := 0; i < workers; i++ {
  1521  		go func() {
  1522  			for j := 0; j < each; j++ {
  1523  				mu.RLock()
  1524  				_, _ = m["foo"]
  1525  				mu.RUnlock()
  1526  			}
  1527  			wg.Done()
  1528  		}()
  1529  	}
  1530  	wg.Wait()
  1531  }
  1532  
  1533  func BenchmarkCacheGetManyConcurrentExpiring(b *testing.B) {
  1534  	benchmarkCacheGetManyConcurrent(b)
  1535  }
  1536  
  1537  func BenchmarkCacheGetManyConcurrentNotExpiring(b *testing.B) {
  1538  	benchmarkCacheGetManyConcurrent(b)
  1539  }
  1540  
  1541  func benchmarkCacheGetManyConcurrent(b *testing.B) {
  1542  	// This is the same as BenchmarkCacheGetConcurrent, but its result
  1543  	// can be compared against BenchmarkShardedCacheGetManyConcurrent
  1544  	// in sharded_test.go.
  1545  	b.StopTimer()
  1546  	n := 10000
  1547  	tc := NewCache()
  1548  	keys := make([]string, n)
  1549  	for i := 0; i < n; i++ {
  1550  		k := "foo" + strconv.Itoa(i)
  1551  		keys[i] = k
  1552  		tc.Set(k, "bar", DefaultExpire)
  1553  	}
  1554  	each := b.N / n
  1555  	wg := new(sync.WaitGroup)
  1556  	wg.Add(n)
  1557  	for _, v := range keys {
  1558  		go func(k string) {
  1559  			for j := 0; j < each; j++ {
  1560  				tc.Get(k)
  1561  			}
  1562  			wg.Done()
  1563  		}(v)
  1564  	}
  1565  	b.StartTimer()
  1566  	wg.Wait()
  1567  }
  1568  
  1569  func BenchmarkCacheSetExpiring(b *testing.B) {
  1570  	benchmarkCacheSet(b)
  1571  }
  1572  
  1573  func BenchmarkCacheSetNotExpiring(b *testing.B) {
  1574  	benchmarkCacheSet(b)
  1575  }
  1576  
  1577  func benchmarkCacheSet(b *testing.B) {
  1578  	b.StopTimer()
  1579  	tc := NewCache()
  1580  	b.StartTimer()
  1581  	for i := 0; i < b.N; i++ {
  1582  		tc.Set("foo", "bar", DefaultExpire)
  1583  	}
  1584  }
  1585  
  1586  func BenchmarkRWMutexMapSet(b *testing.B) {
  1587  	b.StopTimer()
  1588  	m := map[string]string{}
  1589  	mu := sync.RWMutex{}
  1590  	b.StartTimer()
  1591  	for i := 0; i < b.N; i++ {
  1592  		mu.Lock()
  1593  		m["foo"] = "bar"
  1594  		mu.Unlock()
  1595  	}
  1596  }
  1597  
  1598  func BenchmarkCacheSetDelete(b *testing.B) {
  1599  	b.StopTimer()
  1600  	tc := NewCache(SetCapture(nil))
  1601  	b.StartTimer()
  1602  	for i := 0; i < b.N; i++ {
  1603  		tc.Set("foo", "bar", DefaultExpire)
  1604  		tc.Delete("foo")
  1605  	}
  1606  }
  1607  
  1608  func BenchmarkRWMutexMapSetDelete(b *testing.B) {
  1609  	b.StopTimer()
  1610  	m := map[string]string{}
  1611  	mu := sync.RWMutex{}
  1612  	b.StartTimer()
  1613  	for i := 0; i < b.N; i++ {
  1614  		mu.Lock()
  1615  		m["foo"] = "bar"
  1616  		mu.Unlock()
  1617  		mu.Lock()
  1618  		delete(m, "foo")
  1619  		mu.Unlock()
  1620  	}
  1621  }
  1622  
  1623  func BenchmarkCacheSetDeleteSingleLock(b *testing.B) {
  1624  	b.StopTimer()
  1625  	tc := NewCache()
  1626  	b.StartTimer()
  1627  	for i := 0; i < b.N; i++ {
  1628  		tc.Lock()
  1629  		tc.set("foo", "bar", DefaultExpire)
  1630  		tc.delete("foo")
  1631  		tc.Unlock()
  1632  	}
  1633  }
  1634  
  1635  func BenchmarkRWMutexMapSetDeleteSingleLock(b *testing.B) {
  1636  	b.StopTimer()
  1637  	m := map[string]string{}
  1638  	mu := sync.RWMutex{}
  1639  	b.StartTimer()
  1640  	for i := 0; i < b.N; i++ {
  1641  		mu.Lock()
  1642  		m["foo"] = "bar"
  1643  		delete(m, "foo")
  1644  		mu.Unlock()
  1645  	}
  1646  }
  1647  
  1648  func BenchmarkIncrementInt(b *testing.B) {
  1649  	b.StopTimer()
  1650  	tc := NewCache()
  1651  	tc.Set("foo", 0, DefaultExpire)
  1652  	b.StartTimer()
  1653  	for i := 0; i < b.N; i++ {
  1654  		_, _ = tc.IncrementInt("foo", 1)
  1655  	}
  1656  }
  1657  
  1658  func BenchmarkDeleteExpiredLoop(b *testing.B) {
  1659  	b.StopTimer()
  1660  	tc := NewCache(SetDefaultExpire(5*time.Minute), SetCapture(nil))
  1661  	for i := 0; i < 100000; i++ {
  1662  		tc.set(strconv.Itoa(i), "bar", DefaultExpire)
  1663  	}
  1664  	b.StartTimer()
  1665  	for i := 0; i < b.N; i++ {
  1666  		tc.DeleteExpire()
  1667  	}
  1668  }
  1669  
  1670  func TestGetWithExpiration(t *testing.T) {
  1671  	tc := NewCache()
  1672  
  1673  	a, expiration, found := tc.GetWithExpire("a")
  1674  	if found || a != nil || !expiration.IsZero() {
  1675  		t.Error("Getting A found value that shouldn't exist:", a)
  1676  	}
  1677  
  1678  	b, expiration, found := tc.GetWithExpire("b")
  1679  	if found || b != nil || !expiration.IsZero() {
  1680  		t.Error("Getting B found value that shouldn't exist:", b)
  1681  	}
  1682  
  1683  	c, expiration, found := tc.GetWithExpire("c")
  1684  	if found || c != nil || !expiration.IsZero() {
  1685  		t.Error("Getting C found value that shouldn't exist:", c)
  1686  	}
  1687  
  1688  	tc.Set("a", 1, DefaultExpire)
  1689  	tc.Set("b", "b", DefaultExpire)
  1690  	tc.Set("c", 3.5, DefaultExpire)
  1691  	tc.Set("d", 1, NoExpire)
  1692  	tc.Set("e", 1, 50*time.Millisecond)
  1693  
  1694  	x, expiration, found := tc.GetWithExpire("a")
  1695  	if !found {
  1696  		t.Error("a was not found while getting a2")
  1697  	}
  1698  	if x == nil {
  1699  		t.Error("x for a is nil")
  1700  	} else if a2 := x.(int); a2+2 != 3 {
  1701  		t.Error("a2 (which should be 1) plus 2 does not equal 3; value:", a2)
  1702  	}
  1703  	if !expiration.IsZero() {
  1704  		t.Error("expiration for a is not a zeroed time")
  1705  	}
  1706  
  1707  	x, expiration, found = tc.GetWithExpire("b")
  1708  	if !found {
  1709  		t.Error("b was not found while getting b2")
  1710  	}
  1711  	if x == nil {
  1712  		t.Error("x for b is nil")
  1713  	} else if b2 := x.(string); b2+"B" != "bB" {
  1714  		t.Error("b2 (which should be b) plus B does not equal bB; value:", b2)
  1715  	}
  1716  	if !expiration.IsZero() {
  1717  		t.Error("expiration for b is not a zeroed time")
  1718  	}
  1719  
  1720  	x, expiration, found = tc.GetWithExpire("c")
  1721  	if !found {
  1722  		t.Error("c was not found while getting c2")
  1723  	}
  1724  	if x == nil {
  1725  		t.Error("x for c is nil")
  1726  	} else if c2 := x.(float64); c2+1.2 != 4.7 {
  1727  		t.Error("c2 (which should be 3.5) plus 1.2 does not equal 4.7; value:", c2)
  1728  	}
  1729  	if !expiration.IsZero() {
  1730  		t.Error("expiration for c is not a zeroed time")
  1731  	}
  1732  
  1733  	x, expiration, found = tc.GetWithExpire("d")
  1734  	if !found {
  1735  		t.Error("d was not found while getting d2")
  1736  	}
  1737  	if x == nil {
  1738  		t.Error("x for d is nil")
  1739  	} else if d2 := x.(int); d2+2 != 3 {
  1740  		t.Error("d (which should be 1) plus 2 does not equal 3; value:", d2)
  1741  	}
  1742  	if !expiration.IsZero() {
  1743  		t.Error("expiration for d is not a zeroed time")
  1744  	}
  1745  
  1746  	x, expiration, found = tc.GetWithExpire("e")
  1747  	if !found {
  1748  		t.Error("e was not found while getting e2")
  1749  	}
  1750  	if x == nil {
  1751  		t.Error("x for e is nil")
  1752  	} else if e2 := x.(int); e2+2 != 3 {
  1753  		t.Error("e (which should be 1) plus 2 does not equal 3; value:", e2)
  1754  	}
  1755  	if expiration.UnixNano() != tc.member["e"].Expire {
  1756  		t.Error("expiration for e is not the correct time")
  1757  	}
  1758  	if expiration.UnixNano() < time.Now().UnixNano() {
  1759  		t.Error("expiration for e is in the past")
  1760  	}
  1761  }