Chromium Code Reviews| Index: filter/dscache/dscache_test.go |
| diff --git a/filter/dscache/dscache_test.go b/filter/dscache/dscache_test.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b01b924ecb2fb9e8a2b5651c931a19db140a9c0d |
| --- /dev/null |
| +++ b/filter/dscache/dscache_test.go |
| @@ -0,0 +1,104 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package dscache |
| + |
| +import ( |
| + "fmt" |
| + "math/rand" |
| + "testing" |
| + "time" |
| + |
| + "github.com/luci/gae/impl/memory" |
| + "github.com/luci/gae/service/datastore" |
| + "github.com/luci/gae/service/memcache" |
| + "github.com/luci/luci-go/common/clock" |
| + "github.com/luci/luci-go/common/clock/testclock" |
| + "github.com/luci/luci-go/common/mathrand" |
| + . "github.com/smartystreets/goconvey/convey" |
| + "golang.org/x/net/context" |
| +) |
| + |
| +type object struct { |
| + ID int64 `gae:"$id"` |
| + |
| + Value string |
| +} |
| + |
| +func TestDSCache(t *testing.T) { |
| + t.Parallel() |
| + |
| + zeroTime, err := time.Parse("2006-01-02T15:04:05.999999999Z", "2006-01-02T15:04:05.999999999Z") |
| + if err != nil { |
| + panic(err) |
| + } |
| + |
| + Convey("Test dscache", t, func() { |
| + c := mathrand.Set(context.Background(), rand.New(rand.NewSource(1))) |
| + clk := testclock.New(zeroTime) |
| + c = clock.Set(c, clk) |
| + c = memory.Use(c) |
| + dsUnder := datastore.Get(c) |
| + ds := datastore.Get(FilterRDS(c)) |
| + mc := memcache.Get(c) |
| + |
| + itmFor := func(i int, k datastore.Key) memcache.Item { |
| + return mc.NewItem(fmt.Sprintf(KeyFormat, i, mkKeySuffix(k))) |
| + } |
| + |
| + So(dsUnder, ShouldNotBeNil) |
| + So(ds, ShouldNotBeNil) |
| + So(mc, ShouldNotBeNil) |
| + |
| + Convey("basically works", func() { |
| + o := object{ID: 1, Value: "hi"} |
| + So(ds.Put(&o), ShouldBeNil) |
| + |
| + o = object{ID: 1} |
| + So(dsUnder.Get(&o), ShouldBeNil) |
| + So(o.Value, ShouldEqual, "hi") |
| + |
| + itm := itmFor(0, ds.KeyForObj(&o)) |
| + So(mc.Get(itm), ShouldEqual, memcache.ErrCacheMiss) |
| + |
| + o = object{ID: 1} |
| + So(ds.Get(&o), ShouldBeNil) |
| + So(o.Value, ShouldEqual, "hi") |
| + So(mc.Get(itm), ShouldBeNil) |
| + So(itm.Value(), ShouldResemble, |
| + []byte("\x00\x80\x80W1[\x8fW(\x80\x80\x06i5@")) |
| + |
| + Convey("now we don't need the datastore!", func() { |
| + o := object{ID: 1} |
| + |
| + // delete it, bypassing the cache filter. Don't do this in production |
| + // unless you want a crappy cache. |
| + So(dsUnder.Delete(ds.KeyForObj(&o)), ShouldBeNil) |
| + |
| + itm := itmFor(0, ds.KeyForObj(&o)) |
| + So(mc.Get(itm), ShouldBeNil) |
| + So(itm.Value(), ShouldResemble, |
| + []byte("\x00\x80\x80W1[\x8fW(\x80\x80\x06i5@")) |
|
iannucci
2015/08/04 05:26:17
for reference, the equivalent gob encoding is 57 b
|
| + |
| + So(ds.Get(&o), ShouldBeNil) |
| + So(o.Value, ShouldEqual, "hi") |
| + }) |
| + |
| + Convey("deleting it properly records that", func() { |
| + o := object{ID: 1} |
| + So(ds.Delete(ds.KeyForObj(&o)), ShouldBeNil) |
| + |
| + itm := itmFor(0, ds.KeyForObj(&o)) |
| + So(mc.Get(itm), ShouldEqual, memcache.ErrCacheMiss) |
| + So(ds.Get(&o), ShouldEqual, datastore.ErrNoSuchEntity) |
| + |
| + So(mc.Get(itm), ShouldBeNil) |
| + So(itm.Value(), ShouldResemble, []byte{}) |
| + |
| + // this one hits memcache |
| + So(ds.Get(&o), ShouldEqual, datastore.ErrNoSuchEntity) |
| + }) |
| + }) |
| + }) |
| +} |