Index: impl/memory/raw_datastore_test.go |
diff --git a/impl/memory/raw_datastore_test.go b/impl/memory/raw_datastore_test.go |
index 829b3b0fc4cb20351de79196fc6450e6a825d4f8..b0ca0b4abcedb49eb1a1495a3208ed5382709564 100644 |
--- a/impl/memory/raw_datastore_test.go |
+++ b/impl/memory/raw_datastore_test.go |
@@ -34,7 +34,7 @@ func TestDatastoreKinder(t *testing.T) { |
So(key.Namespace(), ShouldEqual, "") |
So(key.String(), ShouldEqual, "/nerd,stringID") |
So(rdsS.KeyIncomplete(key), ShouldBeFalse) |
- So(rdsS.KeyValid(key, "", false), ShouldBeTrue) |
+ So(rdsS.KeyValid(key, false, "dev~app", ""), ShouldBeTrue) |
}) |
}) |
@@ -43,10 +43,17 @@ func TestDatastoreKinder(t *testing.T) { |
func testGetMeta(c context.Context, k rdsS.Key) int64 { |
rds := rdsS.Get(c) |
- k = rds.NewKey("__entity_group__", "", 1, rdsS.KeyRoot(k)) |
- pmap := rdsS.PropertyMap{} |
- rds.Get(k, pmap) |
- return pmap["__version__"][0].Value().(int64) |
+ retval := int64(0) |
+ err := rds.GetMulti([]rdsS.Key{rds.NewKey("__entity_group__", "", 1, rdsS.KeyRoot(k))}, func(val rdsS.PropertyMap, err error) { |
+ if err != nil { |
+ panic(err) |
+ } |
+ retval = val["__version__"][0].Value().(int64) |
+ }) |
+ if err != nil { |
+ panic(err) |
+ } |
+ return retval |
} |
var pls = rdsS.GetPLS |
@@ -54,6 +61,48 @@ var pls = rdsS.GetPLS |
func TestDatastoreSingleReadWriter(t *testing.T) { |
t.Parallel() |
+ getOnePM := func(rds rdsS.Interface, key rdsS.Key) (pmap rdsS.PropertyMap, err error) { |
+ blankErr := rds.GetMulti([]rdsS.Key{key}, func(itmPmap rdsS.PropertyMap, itmErr error) { |
+ pmap = itmPmap |
+ err = itmErr |
+ }) |
+ So(blankErr, ShouldBeNil) |
+ return |
+ } |
+ |
+ delOneErr := func(rds rdsS.Interface, key rdsS.Key) (err error) { |
+ blankErr := rds.DeleteMulti([]rdsS.Key{key}, func(itmErr error) { |
+ err = itmErr |
+ }) |
+ So(blankErr, ShouldBeNil) |
+ return |
+ } |
+ |
+ delOne := func(rds rdsS.Interface, key rdsS.Key) { |
+ So(delOneErr(rds, key), ShouldBeNil) |
+ } |
+ |
+ getOne := func(rds rdsS.Interface, key rdsS.Key, dst interface{}) { |
+ pm, err := getOnePM(rds, key) |
+ So(err, ShouldBeNil) |
+ So(pls(dst).Load(pm), ShouldBeNil) |
+ } |
+ |
+ putOneErr := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKey rdsS.Key, err error) { |
+ blankErr := rds.PutMulti([]rdsS.Key{key}, []rdsS.PropertyLoadSaver{pls(val)}, func(itmKey rdsS.Key, itmErr error) { |
+ err = itmErr |
+ retKey = itmKey |
+ }) |
+ So(blankErr, ShouldBeNil) |
+ return |
+ } |
+ |
+ putOne := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKey rdsS.Key) { |
+ key, err := putOneErr(rds, key, val) |
+ So(err, ShouldBeNil) |
+ return key |
+ } |
+ |
Convey("Datastore single reads and writes", t, func() { |
c := Use(context.Background()) |
rds := rdsS.Get(c) |
@@ -64,96 +113,89 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
Val int |
} |
- Convey("invalid keys break", func() { |
- k := rds.NewKey("Foo", "", 0, nil) |
- So(rds.Get(k, nil), ShouldEqual, rdsS.ErrInvalidKey) |
- |
- _, err := rds.Put(rds.NewKey("Foo", "", 0, k), pls(&Foo{})) |
- So(err, ShouldEqual, rdsS.ErrInvalidKey) |
- }) |
- |
Convey("getting objects that DNE is an error", func() { |
- k := rds.NewKey("Foo", "", 1, nil) |
- So(rds.Get(k, nil), ShouldEqual, rdsS.ErrNoSuchEntity) |
+ _, err := getOnePM(rds, rds.NewKey("Foo", "", 1, nil)) |
+ So(err, ShouldEqual, rdsS.ErrNoSuchEntity) |
}) |
Convey("Can Put stuff", func() { |
// with an incomplete key! |
k := rds.NewKey("Foo", "", 0, nil) |
f := &Foo{Val: 10} |
- k, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ k = putOne(rds, k, f) |
So(k.String(), ShouldEqual, "/Foo,1") |
Convey("and Get it back", func() { |
newFoo := &Foo{} |
- err := rds.Get(k, pls(newFoo)) |
- So(err, ShouldBeNil) |
+ getOne(rds, k, newFoo) |
So(newFoo, ShouldResemble, f) |
Convey("and we can Delete it", func() { |
- err := rds.Delete(k) |
- So(err, ShouldBeNil) |
- |
- err = rds.Get(k, pls(newFoo)) |
+ delOne(rds, k) |
+ _, err := getOnePM(rds, k) |
So(err, ShouldEqual, rdsS.ErrNoSuchEntity) |
}) |
}) |
Convey("Deleteing with a bogus key is bad", func() { |
- err := rds.Delete(rds.NewKey("Foo", "wat", 100, nil)) |
- So(err, ShouldEqual, rdsS.ErrInvalidKey) |
+ So(delOneErr(rds, rds.NewKey("Foo", "wat", 100, nil)), ShouldEqual, rdsS.ErrInvalidKey) |
}) |
Convey("Deleteing a DNE entity is fine", func() { |
- err := rds.Delete(rds.NewKey("Foo", "wat", 0, nil)) |
- So(err, ShouldBeNil) |
+ delOne(rds, rds.NewKey("Foo", "wat", 0, nil)) |
}) |
Convey("with multiple puts", func() { |
So(testGetMeta(c, k), ShouldEqual, 1) |
keys := []rdsS.Key{} |
- plss := []rdsS.PropertyLoadSaver{} |
+ vals := []rdsS.PropertyLoadSaver{} |
pkey := k |
for i := 0; i < 10; i++ { |
keys = append(keys, rds.NewKey("Foo", "", 0, pkey)) |
- plss = append(plss, pls(&Foo{Val: 10})) |
+ vals = append(vals, pls(&Foo{Val: 10})) |
} |
- keys, err := rds.PutMulti(keys, plss) |
+ i := 0 |
+ err := rds.PutMulti(keys, vals, func(k rdsS.Key, err error) { |
+ So(err, ShouldBeNil) |
+ keys[i] = k |
+ i++ |
+ }) |
So(err, ShouldBeNil) |
So(testGetMeta(c, k), ShouldEqual, 11) |
Convey("ensure that group versions persist across deletes", func() { |
- So(rds.Delete(k), ShouldBeNil) |
- for i := int64(1); i < 11; i++ { |
- So(rds.Delete(rds.NewKey("Foo", "", i, k)), ShouldBeNil) |
- } |
- // TODO(riannucci): replace with a Count query instead of this cast |
- ents := rds.(*dsImpl).data.store.GetCollection("ents:") |
- num, _ := ents.GetTotals() |
- // /__entity_root_ids__,Foo |
- // /Foo,1/__entity_group__,1 |
- // /Foo,1/__entity_group_ids__,1 |
- So(num, ShouldEqual, 3) |
- |
- So(curVersion(ents, groupMetaKey(k)), ShouldEqual, 22) |
- |
- k, err := rds.Put(k, pls(f)) |
+ keys = append(keys, pkey) |
+ err := rds.DeleteMulti(keys, func(err error) { |
+ So(err, ShouldBeNil) |
+ }) |
So(err, ShouldBeNil) |
+ |
+ // TODO(riannucci): replace with a Count query instead of this cast |
+ /* |
+ ents := rds.(*dsImpl).data.store.GetCollection("ents:") |
+ num, _ := ents.GetTotals() |
+ // /__entity_root_ids__,Foo |
+ // /Foo,1/__entity_group__,1 |
+ // /Foo,1/__entity_group_ids__,1 |
+ So(num, ShouldEqual, 3) |
+ */ |
+ |
+ So(testGetMeta(c, k), ShouldEqual, 22) |
+ |
+ putOne(rds, k, f) |
So(testGetMeta(c, k), ShouldEqual, 23) |
}) |
- Convey("can GetMulti", func() { |
- plss := make([]rdsS.PropertyLoadSaver, len(keys)) |
- for i := range plss { |
- plss[i] = rdsS.PropertyMap{} |
- } |
- err := rds.GetMulti(keys, plss) |
+ Convey("can Get", func() { |
+ vals := []rdsS.PropertyMap{} |
+ err := rds.GetMulti(keys, func(pm rdsS.PropertyMap, err error) { |
+ So(err, ShouldBeNil) |
+ vals = append(vals, pm) |
+ }) |
So(err, ShouldBeNil) |
- for _, pls := range plss { |
- So(pls.(rdsS.PropertyMap), ShouldResemble, rdsS.PropertyMap{ |
- "Val": {rdsS.MkProperty(10)}, |
- }) |
+ |
+ for _, val := range vals { |
+ So(val, ShouldResemble, rdsS.PropertyMap{"Val": {rdsS.MkProperty(10)}}) |
} |
}) |
}) |
@@ -165,25 +207,21 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
Val int |
} |
Convey("Put", func() { |
- k := rds.NewKey("Foo", "", 0, nil) |
f := &Foo{Val: 10} |
- k, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ origKey := rds.NewKey("Foo", "", 0, nil) |
+ k := putOne(rds, origKey, f) |
So(k.String(), ShouldEqual, "/Foo,1") |
Convey("can Put new entity groups", func() { |
err := rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
- So(rds, ShouldNotBeNil) |
f1 := &Foo{Val: 100} |
- k, err := rds.Put(rds.NewKey("Foo", "", 0, nil), pls(f1)) |
- So(err, ShouldBeNil) |
+ k := putOne(rds, origKey, f1) |
So(k.String(), ShouldEqual, "/Foo,2") |
f2 := &Foo{Val: 200} |
- k, err = rds.Put(rds.NewKey("Foo", "", 0, nil), pls(f2)) |
- So(err, ShouldBeNil) |
+ k = putOne(rds, origKey, f2) |
So(k.String(), ShouldEqual, "/Foo,3") |
return nil |
@@ -191,60 +229,62 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
So(err, ShouldBeNil) |
f := &Foo{} |
- So(rds.Get(rds.NewKey("Foo", "", 2, nil), pls(f)), ShouldBeNil) |
+ getOne(rds, rds.NewKey("Foo", "", 2, nil), f) |
So(f.Val, ShouldEqual, 100) |
- f = &Foo{} |
- So(rds.Get(rds.NewKey("Foo", "", 3, nil), pls(f)), ShouldBeNil) |
+ getOne(rds, rds.NewKey("Foo", "", 3, nil), f) |
So(f.Val, ShouldEqual, 200) |
}) |
Convey("can Put new entities in a current group", func() { |
+ par := k |
err := rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
So(rds, ShouldNotBeNil) |
- par := k |
- |
f1 := &Foo{Val: 100} |
- k, err := rds.Put(rds.NewKey("Foo", "", 0, par), pls(f1)) |
- So(err, ShouldBeNil) |
+ k := putOne(rds, rds.NewKey("Foo", "", 0, par), f1) |
So(k.String(), ShouldEqual, "/Foo,1/Foo,1") |
f2 := &Foo{Val: 200} |
- k, err = rds.Put(rds.NewKey("Foo", "", 0, par), pls(f2)) |
- So(err, ShouldBeNil) |
+ k = putOne(rds, rds.NewKey("Foo", "", 0, par), f2) |
So(k.String(), ShouldEqual, "/Foo,1/Foo,2") |
return nil |
}, nil) |
So(err, ShouldBeNil) |
- f1 := &Foo{} |
- So(rds.Get(rds.NewKey("Foo", "", 1, k), pls(f1)), ShouldBeNil) |
- So(f1.Val, ShouldEqual, 100) |
+ f := &Foo{} |
+ getOne(rds, rds.NewKey("Foo", "", 1, k), f) |
+ So(f.Val, ShouldEqual, 100) |
- f2 := &Foo{} |
- So(rds.Get(rds.NewKey("Foo", "", 2, k), pls(f2)), ShouldBeNil) |
- So(f2.Val, ShouldEqual, 200) |
+ getOne(rds, rds.NewKey("Foo", "", 2, k), f) |
+ So(f.Val, ShouldEqual, 200) |
}) |
Convey("Deletes work too", func() { |
err := rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
So(rds, ShouldNotBeNil) |
- So(rds.Delete(k), ShouldBeNil) |
+ delOne(rds, k) |
return nil |
}, nil) |
So(err, ShouldBeNil) |
- So(rds.Get(k, nil), ShouldEqual, rdsS.ErrNoSuchEntity) |
+ _, err = getOnePM(rds, k) |
+ So(err, ShouldEqual, rdsS.ErrNoSuchEntity) |
}) |
Convey("A Get counts against your group count", func() { |
err := rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
- So(rds.Get(rds.NewKey("Foo", "", 20, nil), nil), ShouldEqual, rdsS.ErrNoSuchEntity) |
- So(rds.Get(k, nil).Error(), ShouldContainSubstring, "cross-group") |
+ |
+ _, err := getOnePM(rds, rds.NewKey("Foo", "", 20, nil)) |
+ So(err, ShouldEqual, rdsS.ErrNoSuchEntity) |
+ |
+ err = rds.GetMulti([]rdsS.Key{k}, func(_ rdsS.PropertyMap, err error) { |
+ So(err, ShouldBeNil) |
+ }) |
+ So(err.Error(), ShouldContainSubstring, "cross-group") |
return nil |
}, nil) |
So(err, ShouldBeNil) |
@@ -255,16 +295,15 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
txnDS := rdsS.Get(c) |
So(txnDS, ShouldNotBeNil) |
- So(txnDS.Get(k, pls(f)), ShouldBeNil) |
+ getOne(txnDS, k, f) |
So(f.Val, ShouldEqual, 10) |
// Don't ever do this in a real program unless you want to guarantee |
// a failed transaction :) |
f.Val = 11 |
- _, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(rds, k, f) |
- So(txnDS.Get(k, pls(f)), ShouldBeNil) |
+ getOne(txnDS, k, f) |
So(f.Val, ShouldEqual, 10) |
return nil |
@@ -272,7 +311,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
So(err, ShouldBeNil) |
f := &Foo{} |
- So(rds.Get(k, pls(f)), ShouldBeNil) |
+ getOne(rds, k, f) |
So(f.Val, ShouldEqual, 11) |
}) |
@@ -282,24 +321,21 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
So(txnDS, ShouldNotBeNil) |
f := &Foo{} |
- So(txnDS.Get(k, pls(f)), ShouldBeNil) |
+ getOne(txnDS, k, f) |
So(f.Val, ShouldEqual, 10) |
// Don't ever do this in a real program unless you want to guarantee |
// a failed transaction :) |
f.Val = 11 |
+ putOne(rds, k, f) |
- _, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
- |
- So(txnDS.Get(k, pls(f)), ShouldBeNil) |
+ getOne(txnDS, k, f) |
So(f.Val, ShouldEqual, 10) |
f.Val = 20 |
- _, err = txnDS.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(txnDS, k, f) |
- So(txnDS.Get(k, pls(f)), ShouldBeNil) |
+ getOne(txnDS, k, f) |
So(f.Val, ShouldEqual, 10) // still gets 10 |
return nil |
@@ -307,7 +343,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
So(err.Error(), ShouldContainSubstring, "concurrent") |
f := &Foo{} |
- So(rds.Get(k, pls(f)), ShouldBeNil) |
+ getOne(rds, k, f) |
So(f.Val, ShouldEqual, 11) |
}) |
@@ -316,11 +352,14 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
txnDS := rdsS.Interface(nil) |
err := rds.RunInTransaction(func(c context.Context) error { |
txnDS = rdsS.Get(c) |
- So(txnDS.Get(k, rdsS.PropertyMap{}), ShouldBeNil) |
+ getOnePM(txnDS, k) |
return nil |
}, nil) |
So(err, ShouldBeNil) |
- So(txnDS.Get(k, rdsS.PropertyMap{}).Error(), ShouldContainSubstring, "expired") |
+ err = txnDS.GetMulti([]rdsS.Key{k}, func(_ rdsS.PropertyMap, err error) { |
+ So(err, ShouldBeNil) |
+ }) |
+ So(err.Error(), ShouldContainSubstring, "expired") |
}) |
Convey("Nested transactions are rejected", func() { |
@@ -345,14 +384,12 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
err := rds.RunInTransaction(func(c context.Context) error { |
txnDS := rdsS.Get(c) |
f := &Foo{Val: 21} |
- _, err = txnDS.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(txnDS, k, f) |
err := rds.RunInTransaction(func(c context.Context) error { |
txnDS := rdsS.Get(c) |
f := &Foo{Val: 27} |
- _, err := txnDS.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(txnDS, k, f) |
return nil |
}, nil) |
So(err, ShouldBeNil) |
@@ -362,7 +399,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
So(err.Error(), ShouldContainSubstring, "concurrent") |
f := &Foo{} |
- So(rds.Get(k, pls(f)), ShouldBeNil) |
+ getOne(rds, k, f) |
So(f.Val, ShouldEqual, 27) |
}) |
@@ -371,10 +408,9 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
err := rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
f := &Foo{Val: 200} |
- _, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(rds, k, f) |
- _, err = rds.Put(rds.NewKey("Foo", "", 2, nil), pls(f)) |
+ _, err := putOneErr(rds, rds.NewKey("Foo", "", 2, nil), f) |
So(err.Error(), ShouldContainSubstring, "cross-group") |
return err |
}, nil) |
@@ -387,11 +423,10 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
for i := int64(1); i < 26; i++ { |
k := rds.NewKey("Foo", "", i, nil) |
f := &Foo{Val: 200} |
- _, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(rds, k, f) |
} |
f := &Foo{Val: 200} |
- _, err := rds.Put(rds.NewKey("Foo", "", 27, nil), pls(f)) |
+ _, err := putOneErr(rds, rds.NewKey("Foo", "", 27, nil), f) |
So(err.Error(), ShouldContainSubstring, "too many entity groups") |
return err |
}, &rdsS.TransactionOptions{XG: true}) |
@@ -404,15 +439,14 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
err := rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
f := &Foo{Val: 200} |
- _, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(rds, k, f) |
return fmt.Errorf("thingy") |
}, nil) |
So(err.Error(), ShouldEqual, "thingy") |
f := &Foo{} |
- So(rds.Get(k, pls(f)), ShouldBeNil) |
+ getOne(rds, k, f) |
So(f.Val, ShouldEqual, 10) |
}) |
@@ -421,14 +455,13 @@ func TestDatastoreSingleReadWriter(t *testing.T) { |
rds.RunInTransaction(func(c context.Context) error { |
rds := rdsS.Get(c) |
f := &Foo{Val: 200} |
- _, err := rds.Put(k, pls(f)) |
- So(err, ShouldBeNil) |
+ putOne(rds, k, f) |
panic("wheeeeee") |
}, nil) |
}, ShouldPanic) |
f := &Foo{} |
- So(rds.Get(k, pls(f)), ShouldBeNil) |
+ getOne(rds, k, f) |
So(f.Val, ShouldEqual, 10) |
}) |
}) |