github.com/Axway/agent-sdk@v1.1.101/pkg/cache/cache_test.go (about)

     1  package cache
     2  
     3  import (
     4  	"encoding/json"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestGlobalCache(t *testing.T) {
    13  	// global cache should have been initialized on package import
    14  	assert.NotNil(t, globalCache, "Expected the Global Cache to have been initialized")
    15  
    16  	// GetCache returns the global cache
    17  	assert.Equal(t, globalCache, GetCache(), "The GetCache method did not return the global cache")
    18  
    19  	// Create a new cache, set it to the as the global cache, validate it was set
    20  	newCache := New()
    21  	newCache.Set("temp", "test data") // set an item to differ the newCache
    22  	assert.NotEqual(t, newCache, GetCache(), "The newly created cache was set as the global, when it should not have been")
    23  	assert.NotEqual(t, newCache, globalCache, "The newly created cache was set as the global, when it should not have been")
    24  	SetCache(nil)
    25  	assert.NotNil(t, globalCache, "The cache was set to nil, when it should not have been")
    26  	SetCache(newCache)
    27  	assert.Equal(t, newCache, GetCache(), "The newly created cache was not set as the global, when it should not have been")
    28  	assert.Equal(t, newCache, globalCache, "The newly created cache was not set as the global, when it should not have been")
    29  }
    30  
    31  func TestSetItemsCache(t *testing.T) {
    32  	// Create new cache
    33  	cache := New()
    34  
    35  	// Set an item, validate that it is in the cache
    36  	key := "key"
    37  	val := "check this"
    38  	err := cache.Set(key, val)
    39  	assert.Nil(t, err, "There was an unexpected error setting a cache item")
    40  	cacheCfg := cache.(*itemCache)
    41  	item, found := cacheCfg.Items[key]
    42  	assert.True(t, found, "The cache item that was just set was not found")
    43  	assert.Equal(t, val, item.GetObject().(string), "The value of the cached item was not what was expected")
    44  	assert.NotNil(t, item.GetUpdateTime(), "The update time was nil")
    45  	assert.NotNil(t, item.GetHash(), "The hash was nil")
    46  	assert.Len(t, item.SecondaryKeys, 0, "The length of the secondary keys on item was more than 0")
    47  	assert.Len(t, cacheCfg.SecKeys, 0, "The length of the global secondary keys was more than 0")
    48  	err = cache.Set("error", map[string]interface{}{"foo": make(chan int)})
    49  	assert.NotNil(t, err, "There was not an error when sending in a value that can't be marshaled")
    50  
    51  	// Set the secondary key, validate that it is in the cache secKeys map and on the cache item
    52  	secKey := "secTemp"
    53  	secKey2 := "secTemp2"
    54  	err = cache.SetSecondaryKey(key, secKey)
    55  	assert.Nil(t, err, "There was an unexpected error setting a secondary key")
    56  	assert.Len(t, item.SecondaryKeys, 1, "The length of the secondary keys on item was not 1")
    57  	assert.Len(t, cacheCfg.SecKeys, 1, "The length of the global secondary keys was not 1")
    58  	err = cache.SetSecondaryKey("bad", secKey2)
    59  	assert.NotNil(t, err, "There was not an error when setting a secondary key with a bad primary key")
    60  	assert.Len(t, item.SecondaryKeys, 1, "The length of the secondary keys changed and was not 1")
    61  	assert.Len(t, cacheCfg.SecKeys, 1, "The length of the global secondary keys changed and was not 1")
    62  	err = cache.SetSecondaryKey(key, key)
    63  	assert.NotNil(t, err, "There was not an error when setting a secondary key with the same value as a primary key")
    64  
    65  	// Set an item with a secondary key, validate that it is in the cache
    66  	cache = New() // Use new cache
    67  	newKey := "newTemp"
    68  	newSecKey := "newSecTemp"
    69  	newVal := "new check this"
    70  	cache.SetWithSecondaryKey(newKey, newSecKey, map[string]interface{}{"foo": make(chan int)})
    71  	assert.NotNil(t, err, "There was not an error when sending in a value that can't be marshaled")
    72  	cache.SetWithSecondaryKey(newKey, newSecKey, newVal)
    73  	cacheCfg = cache.(*itemCache)
    74  	item, found = cacheCfg.Items[newKey]
    75  	assert.True(t, found, "The cache item that was just set was not found")
    76  	assert.Equal(t, newVal, item.GetObject().(string), "The value of the cached item was not what was expected")
    77  	assert.NotNil(t, item.GetUpdateTime(), "The update time was nil")
    78  	assert.NotNil(t, item.GetHash(), "The hash was nil")
    79  	assert.Len(t, item.SecondaryKeys, 1, "The length of the secondary keys on item was not 1")
    80  	assert.Len(t, cacheCfg.SecKeys, 1, "The length of the global secondary keys was not 1")
    81  
    82  	// Set the foreign key, validate that the correct item is set with foreign key and verify errors when incorrect application
    83  	forKey := "forkey"
    84  	err = cache.SetForeignKey(newKey, forKey)
    85  	assert.Nil(t, err, "There was an unexpected error setting a foreign key")
    86  	err = cache.SetForeignKey("bad", forKey)
    87  	assert.NotNil(t, err, "There was not an error when setting a foreign key with a bad primary key")
    88  	err = cache.SetForeignKey(newKey, forKey)
    89  	assert.NotNil(t, err, "There was not an error when setting a foreign key with the same foreign key as before")
    90  
    91  	// Set an item with a foreign key, validate that it is in the cache
    92  	cache = New() // Use new cache
    93  	newKeyFor := "newTempFor"
    94  	newForKey := "newForKey"
    95  	newValFor := "new foreign key added check this"
    96  	cache.SetWithForeignKey(newKeyFor, newForKey, map[string]interface{}{"foo": make(chan int)})
    97  	assert.NotNil(t, err, "There was not an error when sending in a value that can't be marshaled")
    98  	cache.SetWithForeignKey(newKey, newSecKey, newValFor)
    99  	cacheCfg = cache.(*itemCache)
   100  	item, found = cacheCfg.Items[newKey]
   101  	assert.True(t, found, "The cache item that was just set was not found")
   102  	assert.Equal(t, newValFor, item.GetObject().(string), "The value of the cached item was not what was expected")
   103  	assert.NotNil(t, item.GetUpdateTime(), "The update time was nil")
   104  	assert.NotNil(t, item.GetHash(), "The hash was nil")
   105  
   106  }
   107  
   108  func TestGetItemsCache(t *testing.T) {
   109  	// Create new cache
   110  	cache := New()
   111  
   112  	// Add some cache items
   113  	key1 := "key1"
   114  	val1 := "key1 val1"
   115  	cache.Set(key1, val1)
   116  	key2 := "key2"
   117  	key2sec := "key2sec"
   118  	val2 := "key2 val2"
   119  	cache.SetWithSecondaryKey(key2, key2sec, val2)
   120  	key3 := "key3"
   121  	key3for := "key3for"
   122  	val3 := "key3 val3"
   123  	cache.SetWithForeignKey(key3, key3for, val3)
   124  
   125  	// Get
   126  	badKey := "bad"
   127  	bad, err := cache.Get(badKey)
   128  	assert.NotNil(t, err, "An error was expected from Get with a bad key")
   129  	assert.Nil(t, bad, "A value was returned on a bad key")
   130  	iVal, err := cache.Get(key1)
   131  	assert.Nil(t, err, "There was an unexpected error getting key1")
   132  	assert.Equal(t, val1, iVal.(string), "The stored value in cache was wrong")
   133  
   134  	// GetItem
   135  	bad, err = cache.GetItem(badKey)
   136  	assert.NotNil(t, err, "An error was expected from GetItem with a bad key")
   137  	assert.Nil(t, bad, "The Item returned was not nil")
   138  	item, err := cache.GetItem(key1)
   139  	assert.Nil(t, err, "There was an unexpected error getting key1")
   140  	assert.Equal(t, val1, item.GetObject().(string), "The stored value in cache was wrong")
   141  
   142  	// GetBySecondaryKey
   143  	badSecondaryKey := "badSecondaryKey"
   144  	bad, err = cache.GetBySecondaryKey(badSecondaryKey)
   145  	assert.NotNil(t, err, "An error was expected from GetItem with a bad key")
   146  	assert.Nil(t, bad, "The value returned by GetBySecondaryKey was not an nil")
   147  	// add bad secondary key ref in map, should not happen in use
   148  	badSecKeyToPrim := "secKeyNoPrim"
   149  	cache.(*itemCache).SecKeys[badSecKeyToPrim] = badKey
   150  	bad, err = cache.GetBySecondaryKey(badSecKeyToPrim)
   151  	assert.NotNil(t, err, "An error was expected from GetBySecondaryKey with a bad key")
   152  	assert.Nil(t, bad, "The value returned by GetBySecondaryKey was not an nil")
   153  	iVal, err = cache.GetBySecondaryKey(key2sec)
   154  	assert.Nil(t, err, "There was an unexpected error getting key2 with GetBySecondaryKey")
   155  	assert.Equal(t, val2, iVal.(string), "The stored value in cache was wrong")
   156  
   157  	// GetBySecondaryKey
   158  	bad, err = cache.GetItemBySecondaryKey(badSecondaryKey)
   159  	assert.NotNil(t, err, "An error was expected from GetItemBySecondaryKey with a bad key")
   160  	assert.Nil(t, bad, "The Item returned was not nil")
   161  	bad, err = cache.GetItemBySecondaryKey(badSecKeyToPrim)
   162  	assert.NotNil(t, err, "An error was expected from GetItemBySecondaryKey with a bad key")
   163  	assert.Nil(t, bad, "The Item returned by GetItemBySecondaryKey was not an nil")
   164  	item, err = cache.GetItemBySecondaryKey(key2sec)
   165  	assert.Nil(t, err, "There was an unexpected error getting key2 with GetItemBySecondaryKey")
   166  	assert.Equal(t, val2, item.GetObject().(string), "The stored value in cache was wrong")
   167  
   168  	// GetByForeignKey
   169  	badForeignKey := "badForeignKey"
   170  	badItems, _ := cache.GetItemsByForeignKey(badForeignKey)
   171  	assert.Nil(t, badItems, "No items were expected from GetItemsByForeignKey with a bad key")
   172  	items, err := cache.GetItemsByForeignKey(key3for)
   173  	assert.Nil(t, err, "There was an unexpected error getting items with GetItemsByForeignKey")
   174  	assert.Len(t, items, 1, "The length of the secondary keys on item was not 1")
   175  	assert.Equal(t, val3, items[0].GetObject().(string), "The stored value in cache was wrong")
   176  
   177  	// GetForeignKeys
   178  	keys := cache.GetForeignKeys()
   179  	assert.Len(t, keys, 1, "The number of foreign keys in cache was not 1")
   180  }
   181  
   182  func TestHasItemChangedCache(t *testing.T) {
   183  	// Create new cache
   184  	cache := New()
   185  
   186  	// Add some cache items
   187  	key1 := "key1"
   188  	val1 := "key1 val1"
   189  	cache.Set(key1, val1)
   190  	key2 := "key2"
   191  	key2sec := "key2sec"
   192  	val2 := "key2 val2"
   193  	cache.SetWithSecondaryKey(key2, key2sec, val2)
   194  
   195  	// HasItemChanged
   196  	badKey := "bad"
   197  	newVal1 := "key1 val1 2"
   198  	changed, err := cache.HasItemChanged(badKey, newVal1)
   199  	assert.NotNil(t, err, "An error was expected from HasItemChanged with a bad key")
   200  	assert.True(t, changed, "Expected true since the item will not have been found in HasItemChanged")
   201  	changed, err = cache.HasItemChanged(key1, map[string]interface{}{"foo": make(chan int)})
   202  	assert.NotNil(t, err, "An error was expected from HasItemChanged with a value that can't be marshaled to json")
   203  	assert.False(t, changed, "Expected false since HasItemChanged returned an error")
   204  	changed, err = cache.HasItemChanged(key1, val1)
   205  	assert.Nil(t, err, "There was an unexpected error when checking if the value of cached item, key1, has changed")
   206  	assert.False(t, changed, "HasItemChanged did not return false as expected")
   207  	changed, err = cache.HasItemChanged(key1, newVal1)
   208  	assert.Nil(t, err, "There was an unexpected error when checking if the value of cached item, key1, has changed")
   209  	assert.True(t, changed, "HasItemChanged did not return true as expected")
   210  
   211  	// HasItemBySecondaryKeyChanged
   212  	changed, err = cache.HasItemBySecondaryKeyChanged(badKey, newVal1)
   213  	assert.NotNil(t, err, "An error was expected from HasItemBySecondaryKeyChanged with a bad key")
   214  	assert.False(t, changed, "Expected false since HasItemBySecondaryKeyChanged returned an error")
   215  	changed, err = cache.HasItemBySecondaryKeyChanged(key2sec, map[string]interface{}{"foo": make(chan int)})
   216  	assert.NotNil(t, err, "An error was expected from HasItemBySecondaryKeyChanged with a value that can't be marshaled to json")
   217  	assert.False(t, changed, "Expected false since HasItemBySecondaryKeyChanged returned an error")
   218  	changed, err = cache.HasItemBySecondaryKeyChanged(key2sec, val2)
   219  	assert.Nil(t, err, "There was an unexpected error when checking if the value of cached item, key2sec, has changed")
   220  	assert.False(t, changed, "HasItemBySecondaryKeyChanged did not return false as expected")
   221  	changed, err = cache.HasItemBySecondaryKeyChanged(key2sec, newVal1)
   222  	assert.Nil(t, err, "There was an unexpected error when checking if the value of cached item, key2sec, has changed")
   223  	assert.True(t, changed, "HasItemBySecondaryKeyChanged did not return true as expected")
   224  }
   225  
   226  func TestDeleteItemCache(t *testing.T) {
   227  	// Create new cache
   228  	cache := New()
   229  
   230  	// Add some cache items
   231  	key1 := "key1"
   232  	val1 := "key1 val1"
   233  	cache.Set(key1, val1)
   234  	key2 := "key2"
   235  	key2sec := "key2sec"
   236  	val2 := "key2 val2"
   237  	cache.SetWithSecondaryKey(key2, key2sec, val2)
   238  	key3 := "key3"
   239  	key3sec1 := "key3sec1"
   240  	key3sec2 := "key3sec2"
   241  	val3 := "key3 val3"
   242  	cache.SetWithSecondaryKey(key3, key3sec1, val3)
   243  	cache.SetSecondaryKey(key3, key3sec2)
   244  	key4 := "key4"
   245  	key4sec1 := "key4sec1"
   246  	key4sec2 := "key4sec2"
   247  	key4sec3 := "key4sec3"
   248  	val4 := "key4 val4"
   249  	cache.SetWithSecondaryKey(key4, key4sec1, val4)
   250  	cache.SetSecondaryKey(key4, key4sec2)
   251  	cache.SetSecondaryKey(key4, key4sec3)
   252  	key4For1 := "key4For1"
   253  	cache.SetForeignKey(key4, key4For1)
   254  	key5 := "key5"
   255  	val5 := "key5 val5"
   256  	key5For1 := "key5For1"
   257  	cache.SetWithForeignKey(key5, key5For1, val5)
   258  
   259  	// Delete
   260  	badKey := "bad"
   261  	err := cache.Delete(badKey)
   262  	assert.Len(t, cache.(*itemCache).Items, 5, "Expected 5 items in the cache")
   263  	assert.Len(t, cache.(*itemCache).SecKeys, 6, "Expected 6 items in secKeys")
   264  	assert.NotNil(t, err, "An error was expected from Delete with a bad key")
   265  	assert.Len(t, cache.(*itemCache).Items, 5, "Expected 5 items to still be in the cache")
   266  	assert.Len(t, cache.(*itemCache).SecKeys, 6, "Expected 6 items to still be in secKeys")
   267  	iVal2, err := cache.Get(key2)
   268  	assert.Nil(t, err, "Expected no error, item has not been deleted")
   269  	assert.Equal(t, val2, iVal2.(string), "Expected the correct value from val2")
   270  	iVal2Sec, err := cache.GetBySecondaryKey(key2sec)
   271  	assert.Nil(t, err, "Expected no error, item has not been deleted")
   272  	assert.Equal(t, val2, iVal2Sec.(string), "Expected the correct value from val2 secondary key")
   273  	err = cache.Delete(key2)
   274  	assert.Nil(t, err, "An error was not expected from Delete with key2")
   275  	assert.Len(t, cache.(*itemCache).Items, 4, "Expected 4 items to be in the cache")
   276  	assert.Len(t, cache.(*itemCache).SecKeys, 5, "Expected 5 items to still be in secKeys")
   277  
   278  	// DeleteBySecondaryKey
   279  	badSecKey := "badSecKey"
   280  	assert.Len(t, cache.(*itemCache).Items, 4, "Expected 4 items in the cache")
   281  	assert.Len(t, cache.(*itemCache).SecKeys, 5, "Expected 5 items in secKeys")
   282  	err = cache.DeleteBySecondaryKey(badSecKey)
   283  	assert.NotNil(t, err, "An error was expected from DeleteBySecondaryKey with a bad key")
   284  	assert.Len(t, cache.(*itemCache).Items, 4, "Expected 4 items to still be in the cache")
   285  	assert.Len(t, cache.(*itemCache).SecKeys, 5, "Expected 5 items to still be in secKeys")
   286  	err = cache.DeleteBySecondaryKey(key3sec2)
   287  	assert.Nil(t, err, "An error was not expected from DeleteBySecondaryKey with key3sec2")
   288  	assert.Len(t, cache.(*itemCache).Items, 3, "Expected 3 items to be in the cache")
   289  	assert.Len(t, cache.(*itemCache).SecKeys, 3, "Expected 3 items to still be in secKeys")
   290  
   291  	// DeleteSecondaryKey
   292  	assert.Len(t, cache.(*itemCache).Items, 3, "Expected 3 items in the cache")
   293  	assert.Len(t, cache.(*itemCache).SecKeys, 3, "Expected 3 items in secKeys")
   294  	err = cache.DeleteSecondaryKey(badSecKey)
   295  	assert.NotNil(t, err, "An error was expected from DeleteSecondaryKey with a bad key")
   296  	assert.Len(t, cache.(*itemCache).Items, 3, "Expected 3 items to still be in the cache")
   297  	assert.Len(t, cache.(*itemCache).SecKeys, 3, "Expected 3 items to still be in secKeys")
   298  	err = cache.DeleteSecondaryKey(key4sec2)
   299  	assert.Nil(t, err, "An error was not expected from DeleteSecondaryKey with key4sec2")
   300  	assert.Len(t, cache.(*itemCache).Items, 3, "Expected 3 items to be in the cache")
   301  	assert.Len(t, cache.(*itemCache).SecKeys, 2, "Expected 2 items to still be in secKeys")
   302  
   303  	// DeleteItemsByForeignKey
   304  	err = cache.DeleteItemsByForeignKey(badKey)
   305  	assert.NotNil(t, err, "An error was expected from DeleteForeignKey with badKey")
   306  	assert.Len(t, cache.(*itemCache).Items, 3, "Expected 3 items to be in the cache")
   307  	err = cache.DeleteItemsByForeignKey(key5For1)
   308  	assert.Nil(t, err, "No error was expected from DeleteForeignKey with key5For1")
   309  	assert.Len(t, cache.(*itemCache).Items, 2, "Expected 2 items to be in the cache")
   310  
   311  	// DeleteForeignKey
   312  	err = cache.DeleteForeignKey(key4)
   313  	assert.Nil(t, err, "An error was not expected from DeleteForeignKey with key4")
   314  	assert.Len(t, cache.(*itemCache).Items, 2, "Expected 2 items to be in the cache")
   315  
   316  	// Flush
   317  	assert.Len(t, cache.(*itemCache).Items, 2, "Expected 2 items in the cache")
   318  	assert.Len(t, cache.(*itemCache).SecKeys, 2, "Expected 2 items in secKeys")
   319  	cache.Flush()
   320  	assert.Len(t, cache.(*itemCache).Items, 0, "Expected cache to be empty")
   321  	assert.Len(t, cache.(*itemCache).SecKeys, 0, "Expected secKeys to be empty")
   322  }
   323  
   324  func TestSaveAndLoad(t *testing.T) {
   325  	// Create new cache
   326  	cache := New()
   327  
   328  	// Add some cache items
   329  	key1 := "key1"
   330  	val1 := "key1 val1"
   331  	cache.Set(key1, val1)
   332  	key2 := "key2"
   333  	key2sec := "key2sec"
   334  	val2 := "key2 val2"
   335  	cache.SetWithSecondaryKey(key2, key2sec, val2)
   336  	key3 := "key3"
   337  	key3sec1 := "key3sec1"
   338  	key3sec2 := "key3sec2"
   339  	val3 := "key3 val3"
   340  	cache.SetWithSecondaryKey(key3, key3sec1, val3)
   341  	cache.SetSecondaryKey(key3, key3sec2)
   342  	key4 := "key4"
   343  	key4sec1 := "key4sec1"
   344  	key4sec2 := "key4sec2"
   345  	key4sec3 := "key4sec3"
   346  	val4 := "key4 val4"
   347  	cache.SetWithSecondaryKey(key4, key4sec1, val4)
   348  	cache.SetSecondaryKey(key4, key4sec2)
   349  	cache.SetSecondaryKey(key4, key4sec3)
   350  	key5 := "key5"
   351  	val5 := "key5 val5"
   352  	key5For1 := "key5For1"
   353  	cache.SetWithForeignKey(key5, key5For1, val5)
   354  	cacheFile := "cache_save_file.json"
   355  
   356  	// Remove file if it exists
   357  	_, err := os.Stat(cacheFile)
   358  	if os.IsExist(err) {
   359  		os.Remove(cacheFile)
   360  	}
   361  
   362  	// Save
   363  	err = cache.Save(cacheFile)
   364  	assert.Nil(t, err, "An unexpected error was returned by the Save cache method")
   365  
   366  	// Load
   367  	cache2 := Load(cacheFile) // Create a new cache object to load
   368  	assert.Nil(t, err, "An unexpected error was returned by the Load cache method")
   369  	assert.Equal(t, cache.(*itemCache).Items[key1].Object, cache2.(*itemCache).Items[key1].Object, "The loaded key1 value was not the same")
   370  	assert.Equal(t, cache.(*itemCache).Items[key2].Object, cache2.(*itemCache).Items[key2].Object, "The loaded key2 value was not the same")
   371  	assert.Equal(t, cache.(*itemCache).Items[key3].Object, cache2.(*itemCache).Items[key3].Object, "The loaded key3 value was not the same")
   372  	assert.Equal(t, cache.(*itemCache).Items[key4].Object, cache2.(*itemCache).Items[key4].Object, "The loaded key4 value was not the same")
   373  	assert.Equal(t, cache.(*itemCache).Items[key5].Object, cache2.(*itemCache).Items[key5].Object, "The loaded key5 value was not the same")
   374  	assert.Equal(t, cache.(*itemCache).SecKeys, cache2.(*itemCache).SecKeys, "The secondary keys were not loaded properly")
   375  	assert.Equal(t, cache.(*itemCache).Items[key1].SecondaryKeys, cache2.(*itemCache).Items[key1].SecondaryKeys, "The secondary keys for 'key1' were not loaded properly")
   376  	assert.Equal(t, cache.(*itemCache).Items[key2].SecondaryKeys, cache2.(*itemCache).Items[key2].SecondaryKeys, "The secondary keys for 'key2' were not loaded properly")
   377  	assert.Equal(t, cache.(*itemCache).Items[key3].SecondaryKeys, cache2.(*itemCache).Items[key3].SecondaryKeys, "The secondary keys for 'key3' were not loaded properly")
   378  	assert.Equal(t, cache.(*itemCache).Items[key4].SecondaryKeys, cache2.(*itemCache).Items[key4].SecondaryKeys, "The secondary keys for 'key4' were not loaded properly")
   379  	assert.Equal(t, cache.(*itemCache).Items[key5].ForeignKey, cache2.(*itemCache).Items[key5].ForeignKey, "The foreign keys for 'key5' were not loaded properly")
   380  
   381  	// Change original cache, make sure loaded has not changed
   382  	cache.Set(key1, "key1 val2")
   383  	assert.NotEqual(t, cache.(*itemCache).Items[key1].Object, cache2.(*itemCache).Items[key1].Object, "Updating the oringal cache seemed to have changed the loaded cache")
   384  
   385  	// LoadFromBuffer
   386  	cacheBuffer, _ := json.Marshal(cache)
   387  	cache3 := LoadFromBuffer(cacheBuffer) // Create a new cache object to load
   388  	assert.Equal(t, cache.(*itemCache).Items[key1].Object, cache3.(*itemCache).Items[key1].Object, "The loaded key1 value was not the same")
   389  	assert.Equal(t, cache.(*itemCache).Items[key2].Object, cache3.(*itemCache).Items[key2].Object, "The loaded key2 value was not the same")
   390  	assert.Equal(t, cache.(*itemCache).Items[key3].Object, cache3.(*itemCache).Items[key3].Object, "The loaded key3 value was not the same")
   391  	assert.Equal(t, cache.(*itemCache).Items[key4].Object, cache3.(*itemCache).Items[key4].Object, "The loaded key4 value was not the same")
   392  	assert.Equal(t, cache.(*itemCache).Items[key5].Object, cache3.(*itemCache).Items[key5].Object, "The loaded key5 value was not the same")
   393  	assert.Equal(t, cache.(*itemCache).SecKeys, cache3.(*itemCache).SecKeys, "The secondary keys were not loaded properly")
   394  	assert.Equal(t, cache.(*itemCache).Items[key1].SecondaryKeys, cache3.(*itemCache).Items[key1].SecondaryKeys, "The secondary keys for 'key1' were not loaded properly")
   395  	assert.Equal(t, cache.(*itemCache).Items[key2].SecondaryKeys, cache3.(*itemCache).Items[key2].SecondaryKeys, "The secondary keys for 'key2' were not loaded properly")
   396  	assert.Equal(t, cache.(*itemCache).Items[key3].SecondaryKeys, cache3.(*itemCache).Items[key3].SecondaryKeys, "The secondary keys for 'key3' were not loaded properly")
   397  	assert.Equal(t, cache.(*itemCache).Items[key4].SecondaryKeys, cache2.(*itemCache).Items[key4].SecondaryKeys, "The secondary keys for 'key4' were not loaded properly")
   398  	assert.Equal(t, cache.(*itemCache).Items[key5].ForeignKey, cache3.(*itemCache).Items[key5].ForeignKey, "The foreign keys for 'key5' were not loaded properly")
   399  
   400  }
   401  
   402  type st struct {
   403  	val string
   404  }
   405  
   406  func TestItem(t *testing.T) {
   407  	// Create new cache
   408  	cache := New()
   409  	s := &st{
   410  		val: "test",
   411  	}
   412  	cache.Set("key", s)
   413  	ss, _ := cache.Get("key")
   414  	sts := ss.(*st)
   415  
   416  	assert.Equal(t, s.val, "test")
   417  	assert.Equal(t, sts.val, "test")
   418  
   419  	sts.val = "test1"
   420  	assert.Equal(t, s.val, "test")
   421  	assert.Equal(t, sts.val, "test1")
   422  
   423  	cache.Set("key", sts)
   424  	ss, _ = cache.Get("key")
   425  	sts = ss.(*st)
   426  
   427  	assert.Equal(t, s.val, "test")
   428  	assert.Equal(t, sts.val, "test1")
   429  
   430  }
   431  
   432  func TestAsyncCalls(t *testing.T) {
   433  	// This test is to detect data race conditions, no asserts will take place
   434  	// create new cache for testing
   435  	cache := New()
   436  
   437  	load := func() {
   438  		cache.SetWithSecondaryKey("key1", "skey1", struct{}{})
   439  		cache.SetWithSecondaryKey("key2", "skey2", struct{}{})
   440  		cache.SetWithSecondaryKey("key3", "skey3", struct{}{})
   441  		cache.SetWithSecondaryKey("key4", "skey4", struct{}{})
   442  		cache.SetWithSecondaryKey("key5", "skey5", struct{}{})
   443  		cache.SetWithSecondaryKey("key6", "skey6", struct{}{})
   444  		cache.SetWithSecondaryKey("key7", "skey7", struct{}{})
   445  		cache.SetWithSecondaryKey("key8", "skey8", struct{}{})
   446  		cache.SetWithSecondaryKey("key9", "skey9", struct{}{})
   447  		cache.SetWithSecondaryKey("keya", "skeya", struct{}{})
   448  		cache.SetWithSecondaryKey("keyb", "skeyb", struct{}{})
   449  		cache.SetWithSecondaryKey("keyc", "skeyc", struct{}{})
   450  		cache.SetForeignKey("key1", "fkey1")
   451  		cache.SetForeignKey("key2", "fkey1")
   452  		cache.SetForeignKey("key3", "fkey1")
   453  		cache.SetForeignKey("key4", "fkey2")
   454  		cache.SetForeignKey("key5", "fkey2")
   455  		cache.SetForeignKey("key6", "fkey2")
   456  		cache.SetForeignKey("key7", "fkey3")
   457  		cache.SetForeignKey("key8", "fkey3")
   458  		cache.SetForeignKey("key9", "fkey3")
   459  		cache.SetForeignKey("keya", "fkey4")
   460  		cache.SetForeignKey("key8", "fkey4")
   461  		cache.SetForeignKey("keyc", "fkey4")
   462  	}
   463  	load()
   464  
   465  	// add several things to cache at once
   466  	go cache.Set("key1", struct{}{})
   467  	go cache.Set("key2", struct{}{})
   468  	go cache.Set("key3", struct{}{})
   469  	go cache.Set("key4", struct{}{})
   470  	go cache.Set("key5", struct{}{})
   471  
   472  	// attempt to update same key at once
   473  	go cache.Set("key1", struct{}{})
   474  	go cache.Set("key1", struct{}{})
   475  	go cache.Set("key1", struct{}{})
   476  	go cache.SetSecondaryKey("key2", "skey2")
   477  	go cache.SetSecondaryKey("key2", "skey2")
   478  	go cache.SetSecondaryKey("key2", "skey2")
   479  	go cache.SetForeignKey("key2", "fkey1")
   480  	go cache.SetForeignKey("key2", "fkey1")
   481  	go cache.SetForeignKey("key2", "fkey1")
   482  	go cache.SetWithSecondaryKey("key1", "skey1", struct{}{})
   483  	go cache.SetWithSecondaryKey("key2", "skey2", struct{}{})
   484  	go cache.SetWithSecondaryKey("key3", "skey3", struct{}{})
   485  	go cache.SetWithForeignKey("key1", "fkey1", struct{}{})
   486  	go cache.SetWithForeignKey("key2", "fkey1", struct{}{})
   487  	go cache.SetWithForeignKey("key3", "fkey1", struct{}{})
   488  
   489  	// attempt to get the same key at once
   490  	go cache.Get("key1")
   491  	go cache.GetItem("key1")
   492  	go cache.GetBySecondaryKey("skey1")
   493  	go cache.GetItemBySecondaryKey("skey1")
   494  	go cache.Get("key1")
   495  	go cache.GetItem("key1")
   496  	go cache.GetBySecondaryKey("skey1")
   497  	go cache.GetItemBySecondaryKey("skey1")
   498  	go cache.GetItemsByForeignKey("fkey1")
   499  	go cache.GetItemsByForeignKey("fkey1")
   500  	go cache.GetKeys()
   501  	go cache.GetForeignKeys()
   502  
   503  	// has item changed calls
   504  	go cache.HasItemChanged("key1", struct{}{})
   505  	go cache.HasItemChanged("key2", struct{}{})
   506  	go cache.HasItemChanged("key3", struct{}{})
   507  	go cache.HasItemBySecondaryKeyChanged("skey1", struct{}{})
   508  	go cache.HasItemBySecondaryKeyChanged("skey2", struct{}{})
   509  	go cache.HasItemBySecondaryKeyChanged("skey3", struct{}{})
   510  
   511  	// delete calls
   512  	go cache.Delete("key1")
   513  	go cache.Delete("key2")
   514  	go cache.Delete("key1")
   515  	go cache.Delete("key2")
   516  	go cache.DeleteBySecondaryKey("skey3")
   517  	go cache.DeleteBySecondaryKey("skey4")
   518  	go cache.DeleteBySecondaryKey("skey3")
   519  	go cache.DeleteBySecondaryKey("skey4")
   520  	go cache.DeleteSecondaryKey("skey5")
   521  	go cache.DeleteSecondaryKey("skey6")
   522  	go cache.DeleteSecondaryKey("skey5")
   523  	go cache.DeleteSecondaryKey("skey6")
   524  	go cache.DeleteForeignKey("fkey2")
   525  	go cache.DeleteForeignKey("fkey2")
   526  	go cache.DeleteItemsByForeignKey("fkey3")
   527  	go cache.DeleteItemsByForeignKey("fkey4")
   528  	go cache.DeleteItemsByForeignKey("fkey3")
   529  	go cache.DeleteItemsByForeignKey("fkey4")
   530  	go cache.DeleteItemsByForeignKey("fkey1")
   531  	go cache.DeleteItemsByForeignKey("fkey2")
   532  
   533  	// flush the cache
   534  	go cache.Flush()
   535  
   536  	// wait for all items to be deleted
   537  	time.Sleep(time.Second)
   538  	cache.Flush() // flush the cache before the next test
   539  
   540  	// save while all other actions
   541  	load()
   542  
   543  	go cache.Set("key1", struct{}{})
   544  	go cache.SetSecondaryKey("key2", "skey2")
   545  	go cache.SetForeignKey("key1", "fkey1")
   546  	go cache.SetWithSecondaryKey("key3", "skey3", struct{}{})
   547  	go cache.SetWithForeignKey("key4", "fkey2", struct{}{})
   548  	go cache.HasItemChanged("key3", struct{}{})
   549  	go cache.HasItemBySecondaryKeyChanged("skey1", struct{}{})
   550  	go cache.Get("key1")
   551  	go cache.GetItem("key1")
   552  	go cache.GetBySecondaryKey("skey1")
   553  	go cache.GetItemBySecondaryKey("skey1")
   554  	go cache.GetItemsByForeignKey("fkey1")
   555  	go cache.GetKeys()
   556  	go cache.GetForeignKeys()
   557  	go cache.Delete("key2")
   558  	go cache.DeleteBySecondaryKey("skey4")
   559  	go cache.DeleteSecondaryKey("skey5")
   560  	go cache.DeleteItemsByForeignKey("fkey3")
   561  	go cache.DeleteForeignKey("fkey2")
   562  	go cache.Save("./")
   563  
   564  	// wait for all calls to finish
   565  	time.Sleep(time.Second)
   566  }