...

Source file src/github.com/patrickmn/go-cache/cache_test.go

Documentation: github.com/patrickmn/go-cache

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

View as plain text