switched from gspec -> expect

This commit is contained in:
Karl Seguin 2014-10-25 07:46:18 +07:00
parent a81a0f665c
commit 967200d7bc
5 changed files with 77 additions and 64 deletions

View file

@ -1,46 +1,51 @@
package ccache
import (
"github.com/karlseguin/gspec"
. "github.com/karlseguin/expect"
"testing"
"time"
)
func TestGetMissFromBucket(t *testing.T) {
bucket := testBucket()
gspec.New(t).Expect(bucket.get("invalid")).ToBeNil()
type BucketTests struct {
}
func TestGetHitFromBucket(t *testing.T) {
func Tests_Bucket(t *testing.T) {
Expectify(new(BucketTests), t)
}
func (b *BucketTests) GetMissFromBucket() {
bucket := testBucket()
Expect(bucket.get("invalid")).To.Equal(nil)
}
func (b *BucketTests) GetHitFromBucket() {
bucket := testBucket()
item := bucket.get("power")
assertValue(t, item, "9000")
assertValue(item, "9000")
}
func TestDeleteItemFromBucket(t *testing.T) {
func (b *BucketTests) DeleteItemFromBucket() {
bucket := testBucket()
bucket.delete("power")
gspec.New(t).Expect(bucket.get("power")).ToBeNil()
Expect(bucket.get("power")).To.Equal(nil)
}
func TestSetsANewBucketItem(t *testing.T) {
spec := gspec.New(t)
func (b *BucketTests) SetsANewBucketItem() {
bucket := testBucket()
item, new := bucket.set("spice", TestValue("flow"), time.Minute)
assertValue(t, item, "flow")
assertValue(item, "flow")
item = bucket.get("spice")
assertValue(t, item, "flow")
spec.Expect(new).ToEqual(true)
assertValue(item, "flow")
Expect(new).To.Equal(true)
}
func TestSetsAnExistingItem(t *testing.T) {
spec := gspec.New(t)
func (b *BucketTests) SetsAnExistingItem() {
bucket := testBucket()
item, new := bucket.set("power", TestValue("9002"), time.Minute)
assertValue(t, item, "9002")
assertValue(item, "9002")
item = bucket.get("power")
assertValue(t, item, "9002")
spec.Expect(new).ToEqual(false)
assertValue(item, "9002")
Expect(new).To.Equal(false)
}
func testBucket() *Bucket {
@ -52,9 +57,9 @@ func testBucket() *Bucket {
return b
}
func assertValue(t *testing.T, item *Item, expected string) {
func assertValue(item *Item, expected string) {
value := item.value.(TestValue)
gspec.New(t).Expect(value).ToEqual(TestValue(expected))
Expect(value).To.Equal(TestValue(expected))
}
type TestValue string

View file

@ -26,7 +26,7 @@ func New(config *Configuration) *Cache {
deletables: make(chan *Item, config.deleteBuffer),
promotables: make(chan *Item, config.promoteBuffer),
}
for i := 0; i < config.buckets; i++ {
for i := 0; i < int(config.buckets); i++ {
c.buckets[i] = &Bucket{
lookup: make(map[string]*Item),
}
@ -109,8 +109,7 @@ func (c *Cache) deleteItem(bucket *Bucket, item *Item) {
func (c *Cache) bucket(key string) *Bucket {
h := fnv.New32a()
h.Write([]byte(key))
index := h.Sum32() % c.bucketCount
return c.buckets[index]
return c.buckets[h.Sum32()%c.bucketCount]
}
func (c *Cache) conditionalPromote(item *Item) {
@ -128,7 +127,7 @@ func (c *Cache) worker() {
for {
select {
case item := <-c.promotables:
if c.doPromote(item) && c.list.Len() > c.maxItems {
if c.doPromote(item) && uint64(c.list.Len()) > c.maxItems {
c.gc()
}
case item := <-c.deletables:

View file

@ -1,25 +1,31 @@
package ccache
import (
"github.com/karlseguin/gspec"
. "github.com/karlseguin/expect"
"strconv"
"testing"
"time"
)
func TestCacheGCsTheOldestItems(t *testing.T) {
spec := gspec.New(t)
type CacheTests struct{}
func Test_Cache(t *testing.T) {
Expectify(new(CacheTests), t)
}
func (c *CacheTests) GCsTheOldestItems() {
cache := New(Configure().ItemsToPrune(10))
for i := 0; i < 500; i++ {
cache.Set(strconv.Itoa(i), i, time.Minute)
}
//let the items get promoted (and added to our list)
time.Sleep(time.Millisecond * 10)
cache.gc()
spec.Expect(cache.Get("9")).ToBeNil()
spec.Expect(cache.Get("10").(int)).ToEqual(10)
Expect(cache.Get("9")).To.Equal(nil)
Expect(cache.Get("10").(int)).To.Equal(10)
}
func TestCachePromotedItemsDontGetPruned(t *testing.T) {
spec := gspec.New(t)
func (c *CacheTests) PromotedItemsDontGetPruned() {
cache := New(Configure().ItemsToPrune(10).GetsPerPromote(1))
for i := 0; i < 500; i++ {
cache.Set(strconv.Itoa(i), i, time.Minute)
@ -28,13 +34,12 @@ func TestCachePromotedItemsDontGetPruned(t *testing.T) {
cache.Get("9")
time.Sleep(time.Millisecond * 10)
cache.gc()
spec.Expect(cache.Get("9").(int)).ToEqual(9)
spec.Expect(cache.Get("10")).ToBeNil()
spec.Expect(cache.Get("11").(int)).ToEqual(11)
Expect(cache.Get("9").(int)).To.Equal(9)
Expect(cache.Get("10")).To.Equal(nil)
Expect(cache.Get("11").(int)).To.Equal(11)
}
func TestCacheTrackerDoesNotCleanupHeldInstance(t *testing.T) {
spec := gspec.New(t)
func (c *CacheTests) TrackerDoesNotCleanupHeldInstance() {
cache := New(Configure().ItemsToPrune(10).Track())
for i := 0; i < 10; i++ {
cache.Set(strconv.Itoa(i), i, time.Minute)
@ -42,21 +47,20 @@ func TestCacheTrackerDoesNotCleanupHeldInstance(t *testing.T) {
item := cache.TrackingGet("0")
time.Sleep(time.Millisecond * 10)
cache.gc()
spec.Expect(cache.Get("0").(int)).ToEqual(0)
spec.Expect(cache.Get("1")).ToBeNil()
Expect(cache.Get("0").(int)).To.Equal(0)
Expect(cache.Get("1")).To.Equal(nil)
item.Release()
cache.gc()
spec.Expect(cache.Get("0")).ToBeNil()
Expect(cache.Get("0")).To.Equal(nil)
}
func TestCacheRemovesOldestItemWhenFull(t *testing.T) {
spec := gspec.New(t)
func (c *CacheTests) RemovesOldestItemWhenFull() {
cache := New(Configure().MaxItems(5).ItemsToPrune(1))
for i := 0; i < 7; i++ {
cache.Set(strconv.Itoa(i), i, time.Minute)
}
time.Sleep(time.Millisecond * 10)
spec.Expect(cache.Get("0")).ToBeNil()
spec.Expect(cache.Get("1")).ToBeNil()
spec.Expect(cache.Get("2").(int)).ToEqual(2)
Expect(cache.Get("0")).To.Equal(nil)
Expect(cache.Get("1")).To.Equal(nil)
Expect(cache.Get("2").(int)).To.Equal(2)
}

View file

@ -1,7 +1,7 @@
package ccache
type Configuration struct {
maxItems int
maxItems uint64
buckets int
itemsToPrune int
deleteBuffer int
@ -22,9 +22,9 @@ func Configure() *Configuration {
}
}
// The size, in bytes, of the data to cache
// The max number of items to store in the cache
// [5000]
func (c *Configuration) MaxItems(max int) *Configuration {
func (c *Configuration) MaxItems(max uint64) *Configuration {
c.maxItems = max
return c
}
@ -32,39 +32,39 @@ func (c *Configuration) MaxItems(max int) *Configuration {
// Keys are hashed into % bucket count to provide greater concurrency (every set
// requires a write lock on the bucket)
// [64]
func (c *Configuration) Buckets(count int) *Configuration {
c.buckets = count
func (c *Configuration) Buckets(count uint32) *Configuration {
c.buckets = int(count)
return c
}
// The number of items to prune when memory is low
// [500]
func (c *Configuration) ItemsToPrune(count int) *Configuration {
c.itemsToPrune = count
func (c *Configuration) ItemsToPrune(count uint32) *Configuration {
c.itemsToPrune = int(count)
return c
}
// The size of the queue for items which should be promoted. If the queue fills
// up, promotions are skipped
// [1024]
func (c *Configuration) PromoteBuffer(size int) *Configuration {
c.promoteBuffer = size
func (c *Configuration) PromoteBuffer(size uint32) *Configuration {
c.promoteBuffer = int(size)
return c
}
// The size of the queue for items which should be deleted. If the queue fills
// up, calls to Delete() will block
func (c *Configuration) DeleteBuffer(size int) *Configuration {
c.deleteBuffer = size
func (c *Configuration) DeleteBuffer(size uint32) *Configuration {
c.deleteBuffer = int(size)
return c
}
// Give a large cache with a high read / write ratio, it's usually unecessary
// to promote an item on every Get. GetsPerPromote specifies the number of Gets
// a key must have before being promoted
// [10]
func (c *Configuration) GetsPerPromote(count int) *Configuration {
c.getsPerPromote = int32(count)
// [3]
func (c *Configuration) GetsPerPromote(count int32) *Configuration {
c.getsPerPromote = count
return c
}

View file

@ -1,13 +1,18 @@
package ccache
import (
"github.com/karlseguin/gspec"
. "github.com/karlseguin/expect"
"testing"
)
func TestItemPromotability(t *testing.T) {
spec := gspec.New(t)
item := &Item{promotions: 4}
spec.Expect(item.shouldPromote(5)).ToEqual(true)
spec.Expect(item.shouldPromote(5)).ToEqual(false)
type ItemTests struct{}
func Test_Item(t *testing.T) {
Expectify(new(ItemTests), t)
}
func (i *ItemTests) Promotability() {
item := &Item{promotions: 4}
Expect(item.shouldPromote(5)).To.Equal(true)
Expect(item.shouldPromote(5)).To.Equal(false)
}