X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ffoundation%2Fapi%2Frevel%2Fcache%2Fcache_test.go;fp=src%2Ffoundation%2Fapi%2Frevel%2Fcache%2Fcache_test.go;h=bc546170807d88ce534662e6ecbf98f3604ca9a2;hb=1d1ee6961c93781e1187d8c7faa868da6b2f01f4;hp=0000000000000000000000000000000000000000;hpb=56dd5e0f2164b37b40ac1daa188ccc618b4cbd19;p=iec.git diff --git a/src/foundation/api/revel/cache/cache_test.go b/src/foundation/api/revel/cache/cache_test.go new file mode 100644 index 0000000..bc54617 --- /dev/null +++ b/src/foundation/api/revel/cache/cache_test.go @@ -0,0 +1,253 @@ +// Copyright (c) 2012-2016 The Revel Framework Authors, All rights reserved. +// Revel Framework source code and usage is governed by a MIT style +// license that can be found in the LICENSE file. + +package cache + +import ( + "math" + "testing" + "time" +) + +// Tests against a generic Cache interface. +// They should pass for all implementations. +type cacheFactory func(*testing.T, time.Duration) Cache + +// Test typical cache interactions +func typicalGetSet(t *testing.T, newCache cacheFactory) { + var err error + cache := newCache(t, time.Hour) + + value := "foo" + if err = cache.Set("value", value, DefaultExpiryTime); err != nil { + t.Errorf("Error setting a value: %s", err) + } + + value = "" + err = cache.Get("value", &value) + if err != nil { + t.Errorf("Error getting a value: %s", err) + } + if value != "foo" { + t.Errorf("Expected to get foo back, got %s", value) + } +} + +// Test the increment-decrement cases +func incrDecr(t *testing.T, newCache cacheFactory) { + var err error + cache := newCache(t, time.Hour) + + // Normal increment / decrement operation. + if err = cache.Set("int", 10, ForEverNeverExpiry); err != nil { + t.Errorf("Error setting int: %s", err) + } + time.Sleep(time.Second) + newValue, err := cache.Increment("int", 50) + if err != nil { + t.Errorf("Error incrementing int: %s", err) + } + if newValue != 60 { + t.Errorf("Expected 60, was %d", newValue) + } + + if newValue, err = cache.Decrement("int", 50); err != nil { + t.Errorf("Error decrementing: %s", err) + } + if newValue != 10 { + t.Errorf("Expected 10, was %d", newValue) + } + + // Increment wraparound + newValue, err = cache.Increment("int", math.MaxUint64-5) + if err != nil { + t.Errorf("Error wrapping around: %s", err) + } + if newValue != 4 { + t.Errorf("Expected wraparound 4, got %d", newValue) + } + + // Decrement capped at 0 + newValue, err = cache.Decrement("int", 25) + if err != nil { + t.Errorf("Error decrementing below 0: %s", err) + } + if newValue != 0 { + t.Errorf("Expected capped at 0, got %d", newValue) + } +} + +func expiration(t *testing.T, newCache cacheFactory) { + // memcached does not support expiration times less than 1 second. + var err error + cache := newCache(t, time.Second) + // Test Set w/ DefaultExpiryTime + value := 10 + if err = cache.Set("int", value, DefaultExpiryTime); err != nil { + t.Errorf("Set failed: %s", err) + } + time.Sleep(2 * time.Second) + if err = cache.Get("int", &value); err != ErrCacheMiss { + t.Errorf("Expected CacheMiss, but got: %s", err) + } + + // Test Set w/ short time + if err = cache.Set("int", value, time.Second); err != nil { + t.Errorf("Set failed: %s", err) + } + time.Sleep(2 * time.Second) + if err = cache.Get("int", &value); err != ErrCacheMiss { + t.Errorf("Expected CacheMiss, but got: %s", err) + } + + // Test Set w/ longer time. + if err = cache.Set("int", value, time.Hour); err != nil { + t.Errorf("Set failed: %s", err) + } + time.Sleep(2 * time.Second) + if err = cache.Get("int", &value); err != nil { + t.Errorf("Expected to get the value, but got: %s", err) + } + + // Test Set w/ forever. + if err = cache.Set("int", value, ForEverNeverExpiry); err != nil { + t.Errorf("Set failed: %s", err) + } + time.Sleep(2 * time.Second) + if err = cache.Get("int", &value); err != nil { + t.Errorf("Expected to get the value, but got: %s", err) + } +} + +func emptyCache(t *testing.T, newCache cacheFactory) { + var err error + cache := newCache(t, time.Hour) + + err = cache.Get("notexist", 0) + if err == nil { + t.Errorf("Error expected for non-existent key") + } + if err != ErrCacheMiss { + t.Errorf("Expected ErrCacheMiss for non-existent key: %s", err) + } + + err = cache.Delete("notexist") + if err != ErrCacheMiss { + t.Errorf("Expected ErrCacheMiss for non-existent key: %s", err) + } + + _, err = cache.Increment("notexist", 1) + if err != ErrCacheMiss { + t.Errorf("Expected cache miss incrementing non-existent key: %s", err) + } + + _, err = cache.Decrement("notexist", 1) + if err != ErrCacheMiss { + t.Errorf("Expected cache miss decrementing non-existent key: %s", err) + } +} + +func testReplace(t *testing.T, newCache cacheFactory) { + var err error + cache := newCache(t, time.Hour) + + // Replace in an empty cache. + if err = cache.Replace("notexist", 1, ForEverNeverExpiry); err != ErrNotStored { + t.Errorf("Replace in empty cache: expected ErrNotStored, got: %s", err) + } + + // Set a value of 1, and replace it with 2 + if err = cache.Set("int", 1, time.Second); err != nil { + t.Errorf("Unexpected error: %s", err) + } + + if err = cache.Replace("int", 2, time.Second); err != nil { + t.Errorf("Unexpected error: %s", err) + } + var i int + if err = cache.Get("int", &i); err != nil { + t.Errorf("Unexpected error getting a replaced item: %s", err) + } + if i != 2 { + t.Errorf("Expected 2, got %d", i) + } + + // Wait for it to expire and replace with 3 (unsuccessfully). + time.Sleep(2 * time.Second) + if err = cache.Replace("int", 3, time.Second); err != ErrNotStored { + t.Errorf("Expected ErrNotStored, got: %s", err) + } + if err = cache.Get("int", &i); err != ErrCacheMiss { + t.Errorf("Expected cache miss, got: %s", err) + } +} + +func testAdd(t *testing.T, newCache cacheFactory) { + var err error + cache := newCache(t, time.Hour) + // Add to an empty cache. + if err = cache.Add("int", 1, time.Second*3); err != nil { + t.Errorf("Unexpected error adding to empty cache: %s", err) + } + + // Try to add again. (fail) + if err = cache.Add("int", 2, time.Second*3); err != nil { + if err != ErrNotStored { + t.Errorf("Expected ErrNotStored adding dupe to cache: %s", err) + } + } + + // Wait for it to expire, and add again. + time.Sleep(8 * time.Second) + if err = cache.Add("int", 3, time.Second*5); err != nil { + t.Errorf("Unexpected error adding to cache: %s", err) + } + + // Get and verify the value. + var i int + if err = cache.Get("int", &i); err != nil { + t.Errorf("Unexpected error: %s", err) + } + if i != 3 { + t.Errorf("Expected 3, got: %d", i) + } +} + +func testGetMulti(t *testing.T, newCache cacheFactory) { + cache := newCache(t, time.Hour) + + m := map[string]interface{}{ + "str": "foo", + "num": 42, + "foo": struct{ Bar string }{"baz"}, + } + + var keys []string + for key, value := range m { + keys = append(keys, key) + if err := cache.Set(key, value, time.Second*30); err != nil { + t.Errorf("Error setting a value: %s", err) + } + } + + g, err := cache.GetMulti(keys...) + if err != nil { + t.Errorf("Error in get-multi: %s", err) + } + + var str string + if err = g.Get("str", &str); err != nil || str != "foo" { + t.Errorf("Error getting str: %s / %s", err, str) + } + + var num int + if err = g.Get("num", &num); err != nil || num != 42 { + t.Errorf("Error getting num: %s / %v", err, num) + } + + var foo struct{ Bar string } + if err = g.Get("foo", &foo); err != nil || foo.Bar != "baz" { + t.Errorf("Error getting foo: %s / %v", err, foo) + } +}