Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(856)

Unified Diff: logdog/common/storage/bigtable/testing.go

Issue 2435113002: LogDog: Add Storage-layer data caching. (Closed)
Patch Set: Fix byteLimit bug. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « logdog/common/storage/bigtable/storage_test.go ('k') | logdog/common/storage/caching/cache.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: logdog/common/storage/bigtable/testing.go
diff --git a/logdog/common/storage/bigtable/testing.go b/logdog/common/storage/bigtable/testing.go
new file mode 100644
index 0000000000000000000000000000000000000000..14633b0aaaf886acf7fa9d8ad8dfa05f7adc2393
--- /dev/null
+++ b/logdog/common/storage/bigtable/testing.go
@@ -0,0 +1,187 @@
+// Copyright 2016 The LUCI Authors. All rights reserved.
+// Use of this source code is governed under the Apache License, Version 2.0
+// that can be found in the LICENSE file.
+
+package bigtable
+
+import (
+ "bytes"
+ "fmt"
+ "time"
+
+ "github.com/luci/gkvlite"
+
+ "github.com/luci/luci-go/common/data/recordio"
+ "github.com/luci/luci-go/logdog/common/storage"
+
+ "golang.org/x/net/context"
+)
+
+// btTableTest is an in-memory implementation of btTable interface for testing.
+//
+// This is a simple implementation; not an efficient one.
+type btTableTest struct {
+ s *gkvlite.Store
+ c *gkvlite.Collection
+
+ // err, if true, is the error immediately returned by functions.
+ err error
+
+ // maxLogAge is the currently-configured maximum log age.
+ maxLogAge time.Duration
+}
+
+// Testing is an extension of storage.Storage with additional testing
+// capabilities.
+type Testing interface {
+ storage.Storage
+
+ DataMap() map[string][]byte
+ SetMaxRowSize(int)
+ SetErr(error)
+ MaxLogAge() time.Duration
+}
+
+type btTestingStorage struct {
+ *btStorage
+ mem *btTableTest
+}
+
+func (st *btTestingStorage) Close() {
+ // Override Close to make sure our gkvlite instance is closed.
+ st.mem.close()
+ st.btStorage.Close()
+}
+
+func (st *btTestingStorage) DataMap() map[string][]byte { return st.mem.dataMap() }
+func (st *btTestingStorage) SetMaxRowSize(v int) { st.maxRowSize = v }
+func (st *btTestingStorage) SetErr(err error) { st.mem.err = err }
+func (st *btTestingStorage) MaxLogAge() time.Duration { return st.mem.maxLogAge }
+
+// NewMemoryInstance returns an in-memory BigTable Storage implementation.
+// This can be supplied in the Raw field in Options to simulate a BigTable
+// connection.
+//
+// Close should be called on the resulting value after the user is finished in
+// order to free resources.
+func NewMemoryInstance(c context.Context, opts Options) Testing {
+ mem := &btTableTest{}
+ base := newBTStorage(c, opts, nil, nil, mem)
+ return &btTestingStorage{
+ btStorage: base,
+ mem: mem,
+ }
+}
+
+func (t *btTableTest) close() {
+ if t.s != nil {
+ t.s.Close()
+ t.s = nil
+ }
+}
+
+func (t *btTableTest) collection() *gkvlite.Collection {
+ if t.s == nil {
+ var err error
+ t.s, err = gkvlite.NewStore(nil)
+ if err != nil {
+ panic(err)
+ }
+ t.c = t.s.MakePrivateCollection(bytes.Compare)
+ }
+ return t.c
+}
+
+func (t *btTableTest) putLogData(c context.Context, rk *rowKey, d []byte) error {
+ if t.err != nil {
+ return t.err
+ }
+
+ // Record/count sanity check.
+ records, err := recordio.Split(d)
+ if err != nil {
+ return err
+ }
+ if int64(len(records)) != rk.count {
+ return fmt.Errorf("count mismatch (%d != %d)", len(records), rk.count)
+ }
+
+ enc := []byte(rk.encode())
+ coll := t.collection()
+ if item, _ := coll.Get(enc); item != nil {
+ return storage.ErrExists
+ }
+
+ clone := make([]byte, len(d))
+ copy(clone, d)
+ if err := coll.Set(enc, clone); err != nil {
+ panic(err)
+ }
+ return nil
+}
+
+func (t *btTableTest) getLogData(c context.Context, rk *rowKey, limit int, keysOnly bool, cb btGetCallback) error {
+ if t.err != nil {
+ return t.err
+ }
+
+ enc := []byte(rk.encode())
+ prefix := rk.pathPrefix()
+ var ierr error
+ err := t.collection().VisitItemsAscend(enc, !keysOnly, func(i *gkvlite.Item) bool {
+ var drk *rowKey
+ drk, ierr = decodeRowKey(string(i.Key))
+ if ierr != nil {
+ return false
+ }
+ if drk.pathPrefix() != prefix {
+ return false
+ }
+
+ rowData := i.Val
+ if keysOnly {
+ rowData = nil
+ }
+
+ if ierr = cb(drk, rowData); ierr != nil {
+ if ierr == errStop {
+ ierr = nil
+ }
+ return false
+ }
+
+ if limit > 0 {
+ limit--
+ if limit == 0 {
+ return false
+ }
+ }
+
+ return true
+ })
+ if err != nil {
+ panic(err)
+ }
+ return ierr
+}
+
+func (t *btTableTest) setMaxLogAge(c context.Context, d time.Duration) error {
+ if t.err != nil {
+ return t.err
+ }
+ t.maxLogAge = d
+ return nil
+}
+
+func (t *btTableTest) dataMap() map[string][]byte {
+ result := map[string][]byte{}
+
+ err := t.collection().VisitItemsAscend([]byte(nil), true, func(i *gkvlite.Item) bool {
+ result[string(i.Key)] = i.Val
+ return true
+ })
+ if err != nil {
+ panic(err)
+ }
+ return result
+}
« no previous file with comments | « logdog/common/storage/bigtable/storage_test.go ('k') | logdog/common/storage/caching/cache.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698