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

Side by Side Diff: impl/memory/raw_datastore_test.go

Issue 1253263002: Make rawdatastore API safer for writing filters. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: fix comments Created 5 years, 4 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 unified diff | Download patch
« no previous file with comments | « impl/memory/raw_datastore_query.go ('k') | impl/prod/datastore_key.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package memory 5 package memory
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "math" 9 "math"
10 "testing" 10 "testing"
(...skipping 16 matching lines...) Expand all
27 key := rds.NewKey("nerd", "stringID", 0, nil) 27 key := rds.NewKey("nerd", "stringID", 0, nil)
28 So(key, ShouldNotBeNil) 28 So(key, ShouldNotBeNil)
29 So(key.Kind(), ShouldEqual, "nerd") 29 So(key.Kind(), ShouldEqual, "nerd")
30 So(key.StringID(), ShouldEqual, "stringID") 30 So(key.StringID(), ShouldEqual, "stringID")
31 So(key.IntID(), ShouldEqual, 0) 31 So(key.IntID(), ShouldEqual, 0)
32 So(key.Parent(), ShouldBeNil) 32 So(key.Parent(), ShouldBeNil)
33 So(key.AppID(), ShouldEqual, "dev~app") 33 So(key.AppID(), ShouldEqual, "dev~app")
34 So(key.Namespace(), ShouldEqual, "") 34 So(key.Namespace(), ShouldEqual, "")
35 So(key.String(), ShouldEqual, "/nerd,stringID") 35 So(key.String(), ShouldEqual, "/nerd,stringID")
36 So(rdsS.KeyIncomplete(key), ShouldBeFalse) 36 So(rdsS.KeyIncomplete(key), ShouldBeFalse)
37 » » » » So(rdsS.KeyValid(key, "", false), ShouldBeTrue) 37 » » » » So(rdsS.KeyValid(key, false, "dev~app", ""), Sho uldBeTrue)
38 }) 38 })
39 }) 39 })
40 40
41 }) 41 })
42 } 42 }
43 43
44 func testGetMeta(c context.Context, k rdsS.Key) int64 { 44 func testGetMeta(c context.Context, k rdsS.Key) int64 {
45 rds := rdsS.Get(c) 45 rds := rdsS.Get(c)
46 » k = rds.NewKey("__entity_group__", "", 1, rdsS.KeyRoot(k)) 46 » retval := int64(0)
47 » pmap := rdsS.PropertyMap{} 47 » err := rds.GetMulti([]rdsS.Key{rds.NewKey("__entity_group__", "", 1, rds S.KeyRoot(k))}, func(val rdsS.PropertyMap, err error) {
48 » rds.Get(k, pmap) 48 » » if err != nil {
49 » return pmap["__version__"][0].Value().(int64) 49 » » » panic(err)
50 » » }
51 » » retval = val["__version__"][0].Value().(int64)
52 » })
53 » if err != nil {
54 » » panic(err)
55 » }
56 » return retval
50 } 57 }
51 58
52 var pls = rdsS.GetPLS 59 var pls = rdsS.GetPLS
53 60
54 func TestDatastoreSingleReadWriter(t *testing.T) { 61 func TestDatastoreSingleReadWriter(t *testing.T) {
55 t.Parallel() 62 t.Parallel()
56 63
64 getOnePM := func(rds rdsS.Interface, key rdsS.Key) (pmap rdsS.PropertyMa p, err error) {
65 blankErr := rds.GetMulti([]rdsS.Key{key}, func(itmPmap rdsS.Prop ertyMap, itmErr error) {
66 pmap = itmPmap
67 err = itmErr
68 })
69 So(blankErr, ShouldBeNil)
70 return
71 }
72
73 delOneErr := func(rds rdsS.Interface, key rdsS.Key) (err error) {
74 blankErr := rds.DeleteMulti([]rdsS.Key{key}, func(itmErr error) {
75 err = itmErr
76 })
77 So(blankErr, ShouldBeNil)
78 return
79 }
80
81 delOne := func(rds rdsS.Interface, key rdsS.Key) {
82 So(delOneErr(rds, key), ShouldBeNil)
83 }
84
85 getOne := func(rds rdsS.Interface, key rdsS.Key, dst interface{}) {
86 pm, err := getOnePM(rds, key)
87 So(err, ShouldBeNil)
88 So(pls(dst).Load(pm), ShouldBeNil)
89 }
90
91 putOneErr := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (re tKey rdsS.Key, err error) {
92 blankErr := rds.PutMulti([]rdsS.Key{key}, []rdsS.PropertyLoadSav er{pls(val)}, func(itmKey rdsS.Key, itmErr error) {
93 err = itmErr
94 retKey = itmKey
95 })
96 So(blankErr, ShouldBeNil)
97 return
98 }
99
100 putOne := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKe y rdsS.Key) {
101 key, err := putOneErr(rds, key, val)
102 So(err, ShouldBeNil)
103 return key
104 }
105
57 Convey("Datastore single reads and writes", t, func() { 106 Convey("Datastore single reads and writes", t, func() {
58 c := Use(context.Background()) 107 c := Use(context.Background())
59 rds := rdsS.Get(c) 108 rds := rdsS.Get(c)
60 So(rds, ShouldNotBeNil) 109 So(rds, ShouldNotBeNil)
61 110
62 Convey("implements DSSingleReadWriter", func() { 111 Convey("implements DSSingleReadWriter", func() {
63 type Foo struct { 112 type Foo struct {
64 Val int 113 Val int
65 } 114 }
66 115
67 Convey("invalid keys break", func() {
68 k := rds.NewKey("Foo", "", 0, nil)
69 So(rds.Get(k, nil), ShouldEqual, rdsS.ErrInvalid Key)
70
71 _, err := rds.Put(rds.NewKey("Foo", "", 0, k), p ls(&Foo{}))
72 So(err, ShouldEqual, rdsS.ErrInvalidKey)
73 })
74
75 Convey("getting objects that DNE is an error", func() { 116 Convey("getting objects that DNE is an error", func() {
76 » » » » k := rds.NewKey("Foo", "", 1, nil) 117 » » » » _, err := getOnePM(rds, rds.NewKey("Foo", "", 1, nil))
77 » » » » So(rds.Get(k, nil), ShouldEqual, rdsS.ErrNoSuchE ntity) 118 » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntity)
78 }) 119 })
79 120
80 Convey("Can Put stuff", func() { 121 Convey("Can Put stuff", func() {
81 // with an incomplete key! 122 // with an incomplete key!
82 k := rds.NewKey("Foo", "", 0, nil) 123 k := rds.NewKey("Foo", "", 0, nil)
83 f := &Foo{Val: 10} 124 f := &Foo{Val: 10}
84 » » » » k, err := rds.Put(k, pls(f)) 125 » » » » k = putOne(rds, k, f)
85 » » » » So(err, ShouldBeNil)
86 So(k.String(), ShouldEqual, "/Foo,1") 126 So(k.String(), ShouldEqual, "/Foo,1")
87 127
88 Convey("and Get it back", func() { 128 Convey("and Get it back", func() {
89 newFoo := &Foo{} 129 newFoo := &Foo{}
90 » » » » » err := rds.Get(k, pls(newFoo)) 130 » » » » » getOne(rds, k, newFoo)
91 » » » » » So(err, ShouldBeNil)
92 So(newFoo, ShouldResemble, f) 131 So(newFoo, ShouldResemble, f)
93 132
94 Convey("and we can Delete it", func() { 133 Convey("and we can Delete it", func() {
95 » » » » » » err := rds.Delete(k) 134 » » » » » » delOne(rds, k)
96 » » » » » » So(err, ShouldBeNil) 135 » » » » » » _, err := getOnePM(rds, k)
97
98 » » » » » » err = rds.Get(k, pls(newFoo))
99 So(err, ShouldEqual, rdsS.ErrNoS uchEntity) 136 So(err, ShouldEqual, rdsS.ErrNoS uchEntity)
100 }) 137 })
101 }) 138 })
102 Convey("Deleteing with a bogus key is bad", func () { 139 Convey("Deleteing with a bogus key is bad", func () {
103 » » » » » err := rds.Delete(rds.NewKey("Foo", "wat ", 100, nil)) 140 » » » » » So(delOneErr(rds, rds.NewKey("Foo", "wat ", 100, nil)), ShouldEqual, rdsS.ErrInvalidKey)
104 » » » » » So(err, ShouldEqual, rdsS.ErrInvalidKey)
105 }) 141 })
106 Convey("Deleteing a DNE entity is fine", func() { 142 Convey("Deleteing a DNE entity is fine", func() {
107 » » » » » err := rds.Delete(rds.NewKey("Foo", "wat ", 0, nil)) 143 » » » » » delOne(rds, rds.NewKey("Foo", "wat", 0, nil))
108 » » » » » So(err, ShouldBeNil)
109 }) 144 })
110 145
111 Convey("with multiple puts", func() { 146 Convey("with multiple puts", func() {
112 So(testGetMeta(c, k), ShouldEqual, 1) 147 So(testGetMeta(c, k), ShouldEqual, 1)
113 148
114 keys := []rdsS.Key{} 149 keys := []rdsS.Key{}
115 » » » » » plss := []rdsS.PropertyLoadSaver{} 150 » » » » » vals := []rdsS.PropertyLoadSaver{}
116 151
117 pkey := k 152 pkey := k
118 for i := 0; i < 10; i++ { 153 for i := 0; i < 10; i++ {
119 keys = append(keys, rds.NewKey(" Foo", "", 0, pkey)) 154 keys = append(keys, rds.NewKey(" Foo", "", 0, pkey))
120 » » » » » » plss = append(plss, pls(&Foo{Val : 10})) 155 » » » » » » vals = append(vals, pls(&Foo{Val : 10}))
121 } 156 }
122 » » » » » keys, err := rds.PutMulti(keys, plss) 157 » » » » » i := 0
158 » » » » » err := rds.PutMulti(keys, vals, func(k r dsS.Key, err error) {
159 » » » » » » So(err, ShouldBeNil)
160 » » » » » » keys[i] = k
161 » » » » » » i++
162 » » » » » })
123 So(err, ShouldBeNil) 163 So(err, ShouldBeNil)
124 So(testGetMeta(c, k), ShouldEqual, 11) 164 So(testGetMeta(c, k), ShouldEqual, 11)
125 165
126 Convey("ensure that group versions persi st across deletes", func() { 166 Convey("ensure that group versions persi st across deletes", func() {
127 » » » » » » So(rds.Delete(k), ShouldBeNil) 167 » » » » » » keys = append(keys, pkey)
128 » » » » » » for i := int64(1); i < 11; i++ { 168 » » » » » » err := rds.DeleteMulti(keys, fun c(err error) {
129 » » » » » » » So(rds.Delete(rds.NewKey ("Foo", "", i, k)), ShouldBeNil) 169 » » » » » » » So(err, ShouldBeNil)
130 » » » » » » } 170 » » » » » » })
171 » » » » » » So(err, ShouldBeNil)
172
131 // TODO(riannucci): replace with a Count query instead of this cast 173 // TODO(riannucci): replace with a Count query instead of this cast
132 » » » » » » ents := rds.(*dsImpl).data.store .GetCollection("ents:") 174 » » » » » » /*
133 » » » » » » num, _ := ents.GetTotals() 175 » » » » » » » ents := rds.(*dsImpl).da ta.store.GetCollection("ents:")
134 » » » » » » // /__entity_root_ids__,Foo 176 » » » » » » » num, _ := ents.GetTotals ()
135 » » » » » » // /Foo,1/__entity_group__,1 177 » » » » » » » // /__entity_root_ids__, Foo
136 » » » » » » // /Foo,1/__entity_group_ids__,1 178 » » » » » » » // /Foo,1/__entity_group __,1
137 » » » » » » So(num, ShouldEqual, 3) 179 » » » » » » » // /Foo,1/__entity_group _ids__,1
180 » » » » » » » So(num, ShouldEqual, 3)
181 » » » » » » */
138 182
139 » » » » » » So(curVersion(ents, groupMetaKey (k)), ShouldEqual, 22) 183 » » » » » » So(testGetMeta(c, k), ShouldEqua l, 22)
140 184
141 » » » » » » k, err := rds.Put(k, pls(f)) 185 » » » » » » putOne(rds, k, f)
142 » » » » » » So(err, ShouldBeNil)
143 So(testGetMeta(c, k), ShouldEqua l, 23) 186 So(testGetMeta(c, k), ShouldEqua l, 23)
144 }) 187 })
145 188
146 » » » » » Convey("can GetMulti", func() { 189 » » » » » Convey("can Get", func() {
147 » » » » » » plss := make([]rdsS.PropertyLoad Saver, len(keys)) 190 » » » » » » vals := []rdsS.PropertyMap{}
148 » » » » » » for i := range plss { 191 » » » » » » err := rds.GetMulti(keys, func(p m rdsS.PropertyMap, err error) {
149 » » » » » » » plss[i] = rdsS.PropertyM ap{} 192 » » » » » » » So(err, ShouldBeNil)
150 » » » » » » } 193 » » » » » » » vals = append(vals, pm)
151 » » » » » » err := rds.GetMulti(keys, plss) 194 » » » » » » })
152 So(err, ShouldBeNil) 195 So(err, ShouldBeNil)
153 » » » » » » for _, pls := range plss { 196
154 » » » » » » » So(pls.(rdsS.PropertyMap ), ShouldResemble, rdsS.PropertyMap{ 197 » » » » » » for _, val := range vals {
155 » » » » » » » » "Val": {rdsS.MkP roperty(10)}, 198 » » » » » » » So(val, ShouldResemble, rdsS.PropertyMap{"Val": {rdsS.MkProperty(10)}})
156 » » » » » » » })
157 } 199 }
158 }) 200 })
159 }) 201 })
160 }) 202 })
161 }) 203 })
162 204
163 Convey("implements DSTransactioner", func() { 205 Convey("implements DSTransactioner", func() {
164 type Foo struct { 206 type Foo struct {
165 Val int 207 Val int
166 } 208 }
167 Convey("Put", func() { 209 Convey("Put", func() {
168 k := rds.NewKey("Foo", "", 0, nil)
169 f := &Foo{Val: 10} 210 f := &Foo{Val: 10}
170 » » » » k, err := rds.Put(k, pls(f)) 211 » » » » origKey := rds.NewKey("Foo", "", 0, nil)
171 » » » » So(err, ShouldBeNil) 212 » » » » k := putOne(rds, origKey, f)
172 So(k.String(), ShouldEqual, "/Foo,1") 213 So(k.String(), ShouldEqual, "/Foo,1")
173 214
174 Convey("can Put new entity groups", func() { 215 Convey("can Put new entity groups", func() {
175 err := rds.RunInTransaction(func(c conte xt.Context) error { 216 err := rds.RunInTransaction(func(c conte xt.Context) error {
176 rds := rdsS.Get(c) 217 rds := rdsS.Get(c)
177 So(rds, ShouldNotBeNil)
178 218
179 f1 := &Foo{Val: 100} 219 f1 := &Foo{Val: 100}
180 » » » » » » k, err := rds.Put(rds.NewKey("Fo o", "", 0, nil), pls(f1)) 220 » » » » » » k := putOne(rds, origKey, f1)
181 » » » » » » So(err, ShouldBeNil)
182 So(k.String(), ShouldEqual, "/Fo o,2") 221 So(k.String(), ShouldEqual, "/Fo o,2")
183 222
184 f2 := &Foo{Val: 200} 223 f2 := &Foo{Val: 200}
185 » » » » » » k, err = rds.Put(rds.NewKey("Foo ", "", 0, nil), pls(f2)) 224 » » » » » » k = putOne(rds, origKey, f2)
186 » » » » » » So(err, ShouldBeNil)
187 So(k.String(), ShouldEqual, "/Fo o,3") 225 So(k.String(), ShouldEqual, "/Fo o,3")
188 226
189 return nil 227 return nil
190 }, &rdsS.TransactionOptions{XG: true}) 228 }, &rdsS.TransactionOptions{XG: true})
191 So(err, ShouldBeNil) 229 So(err, ShouldBeNil)
192 230
193 f := &Foo{} 231 f := &Foo{}
194 » » » » » So(rds.Get(rds.NewKey("Foo", "", 2, nil) , pls(f)), ShouldBeNil) 232 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, nil ), f)
195 So(f.Val, ShouldEqual, 100) 233 So(f.Val, ShouldEqual, 100)
196 234
197 » » » » » f = &Foo{} 235 » » » » » getOne(rds, rds.NewKey("Foo", "", 3, nil ), f)
198 » » » » » So(rds.Get(rds.NewKey("Foo", "", 3, nil) , pls(f)), ShouldBeNil)
199 So(f.Val, ShouldEqual, 200) 236 So(f.Val, ShouldEqual, 200)
200 }) 237 })
201 238
202 Convey("can Put new entities in a current group" , func() { 239 Convey("can Put new entities in a current group" , func() {
240 par := k
203 err := rds.RunInTransaction(func(c conte xt.Context) error { 241 err := rds.RunInTransaction(func(c conte xt.Context) error {
204 rds := rdsS.Get(c) 242 rds := rdsS.Get(c)
205 So(rds, ShouldNotBeNil) 243 So(rds, ShouldNotBeNil)
206 244
207 par := k
208
209 f1 := &Foo{Val: 100} 245 f1 := &Foo{Val: 100}
210 » » » » » » k, err := rds.Put(rds.NewKey("Fo o", "", 0, par), pls(f1)) 246 » » » » » » k := putOne(rds, rds.NewKey("Foo ", "", 0, par), f1)
211 » » » » » » So(err, ShouldBeNil)
212 So(k.String(), ShouldEqual, "/Fo o,1/Foo,1") 247 So(k.String(), ShouldEqual, "/Fo o,1/Foo,1")
213 248
214 f2 := &Foo{Val: 200} 249 f2 := &Foo{Val: 200}
215 » » » » » » k, err = rds.Put(rds.NewKey("Foo ", "", 0, par), pls(f2)) 250 » » » » » » k = putOne(rds, rds.NewKey("Foo" , "", 0, par), f2)
216 » » » » » » So(err, ShouldBeNil)
217 So(k.String(), ShouldEqual, "/Fo o,1/Foo,2") 251 So(k.String(), ShouldEqual, "/Fo o,1/Foo,2")
218 252
219 return nil 253 return nil
220 }, nil) 254 }, nil)
221 So(err, ShouldBeNil) 255 So(err, ShouldBeNil)
222 256
223 » » » » » f1 := &Foo{} 257 » » » » » f := &Foo{}
224 » » » » » So(rds.Get(rds.NewKey("Foo", "", 1, k), pls(f1)), ShouldBeNil) 258 » » » » » getOne(rds, rds.NewKey("Foo", "", 1, k), f)
225 » » » » » So(f1.Val, ShouldEqual, 100) 259 » » » » » So(f.Val, ShouldEqual, 100)
226 260
227 » » » » » f2 := &Foo{} 261 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, k), f)
228 » » » » » So(rds.Get(rds.NewKey("Foo", "", 2, k), pls(f2)), ShouldBeNil) 262 » » » » » So(f.Val, ShouldEqual, 200)
229 » » » » » So(f2.Val, ShouldEqual, 200)
230 }) 263 })
231 264
232 Convey("Deletes work too", func() { 265 Convey("Deletes work too", func() {
233 err := rds.RunInTransaction(func(c conte xt.Context) error { 266 err := rds.RunInTransaction(func(c conte xt.Context) error {
234 rds := rdsS.Get(c) 267 rds := rdsS.Get(c)
235 So(rds, ShouldNotBeNil) 268 So(rds, ShouldNotBeNil)
236 » » » » » » So(rds.Delete(k), ShouldBeNil) 269 » » » » » » delOne(rds, k)
237 return nil 270 return nil
238 }, nil) 271 }, nil)
239 So(err, ShouldBeNil) 272 So(err, ShouldBeNil)
240 » » » » » So(rds.Get(k, nil), ShouldEqual, rdsS.Er rNoSuchEntity) 273 » » » » » _, err = getOnePM(rds, k)
274 » » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntit y)
241 }) 275 })
242 276
243 Convey("A Get counts against your group count", func() { 277 Convey("A Get counts against your group count", func() {
244 err := rds.RunInTransaction(func(c conte xt.Context) error { 278 err := rds.RunInTransaction(func(c conte xt.Context) error {
245 rds := rdsS.Get(c) 279 rds := rdsS.Get(c)
246 » » » » » » So(rds.Get(rds.NewKey("Foo", "", 20, nil), nil), ShouldEqual, rdsS.ErrNoSuchEntity) 280
247 » » » » » » So(rds.Get(k, nil).Error(), Shou ldContainSubstring, "cross-group") 281 » » » » » » _, err := getOnePM(rds, rds.NewK ey("Foo", "", 20, nil))
282 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS uchEntity)
283
284 » » » » » » err = rds.GetMulti([]rdsS.Key{k} , func(_ rdsS.PropertyMap, err error) {
285 » » » » » » » So(err, ShouldBeNil)
286 » » » » » » })
287 » » » » » » So(err.Error(), ShouldContainSub string, "cross-group")
248 return nil 288 return nil
249 }, nil) 289 }, nil)
250 So(err, ShouldBeNil) 290 So(err, ShouldBeNil)
251 }) 291 })
252 292
253 Convey("Get takes a snapshot", func() { 293 Convey("Get takes a snapshot", func() {
254 err := rds.RunInTransaction(func(c conte xt.Context) error { 294 err := rds.RunInTransaction(func(c conte xt.Context) error {
255 txnDS := rdsS.Get(c) 295 txnDS := rdsS.Get(c)
256 So(txnDS, ShouldNotBeNil) 296 So(txnDS, ShouldNotBeNil)
257 297
258 » » » » » » So(txnDS.Get(k, pls(f)), ShouldB eNil) 298 » » » » » » getOne(txnDS, k, f)
259 So(f.Val, ShouldEqual, 10) 299 So(f.Val, ShouldEqual, 10)
260 300
261 // Don't ever do this in a real program unless you want to guarantee 301 // Don't ever do this in a real program unless you want to guarantee
262 // a failed transaction :) 302 // a failed transaction :)
263 f.Val = 11 303 f.Val = 11
264 » » » » » » _, err := rds.Put(k, pls(f)) 304 » » » » » » putOne(rds, k, f)
265 » » » » » » So(err, ShouldBeNil)
266 305
267 » » » » » » So(txnDS.Get(k, pls(f)), ShouldB eNil) 306 » » » » » » getOne(txnDS, k, f)
268 So(f.Val, ShouldEqual, 10) 307 So(f.Val, ShouldEqual, 10)
269 308
270 return nil 309 return nil
271 }, nil) 310 }, nil)
272 So(err, ShouldBeNil) 311 So(err, ShouldBeNil)
273 312
274 f := &Foo{} 313 f := &Foo{}
275 » » » » » So(rds.Get(k, pls(f)), ShouldBeNil) 314 » » » » » getOne(rds, k, f)
276 So(f.Val, ShouldEqual, 11) 315 So(f.Val, ShouldEqual, 11)
277 }) 316 })
278 317
279 Convey("and snapshots are consistent even after Puts", func() { 318 Convey("and snapshots are consistent even after Puts", func() {
280 err := rds.RunInTransaction(func(c conte xt.Context) error { 319 err := rds.RunInTransaction(func(c conte xt.Context) error {
281 txnDS := rdsS.Get(c) 320 txnDS := rdsS.Get(c)
282 So(txnDS, ShouldNotBeNil) 321 So(txnDS, ShouldNotBeNil)
283 322
284 f := &Foo{} 323 f := &Foo{}
285 » » » » » » So(txnDS.Get(k, pls(f)), ShouldB eNil) 324 » » » » » » getOne(txnDS, k, f)
286 So(f.Val, ShouldEqual, 10) 325 So(f.Val, ShouldEqual, 10)
287 326
288 // Don't ever do this in a real program unless you want to guarantee 327 // Don't ever do this in a real program unless you want to guarantee
289 // a failed transaction :) 328 // a failed transaction :)
290 f.Val = 11 329 f.Val = 11
330 putOne(rds, k, f)
291 331
292 » » » » » » _, err := rds.Put(k, pls(f)) 332 » » » » » » getOne(txnDS, k, f)
293 » » » » » » So(err, ShouldBeNil)
294
295 » » » » » » So(txnDS.Get(k, pls(f)), ShouldB eNil)
296 So(f.Val, ShouldEqual, 10) 333 So(f.Val, ShouldEqual, 10)
297 334
298 f.Val = 20 335 f.Val = 20
299 » » » » » » _, err = txnDS.Put(k, pls(f)) 336 » » » » » » putOne(txnDS, k, f)
300 » » » » » » So(err, ShouldBeNil)
301 337
302 » » » » » » So(txnDS.Get(k, pls(f)), ShouldB eNil) 338 » » » » » » getOne(txnDS, k, f)
303 So(f.Val, ShouldEqual, 10) // st ill gets 10 339 So(f.Val, ShouldEqual, 10) // st ill gets 10
304 340
305 return nil 341 return nil
306 }, nil) 342 }, nil)
307 So(err.Error(), ShouldContainSubstring, "concurrent") 343 So(err.Error(), ShouldContainSubstring, "concurrent")
308 344
309 f := &Foo{} 345 f := &Foo{}
310 » » » » » So(rds.Get(k, pls(f)), ShouldBeNil) 346 » » » » » getOne(rds, k, f)
311 So(f.Val, ShouldEqual, 11) 347 So(f.Val, ShouldEqual, 11)
312 }) 348 })
313 349
314 Convey("Reusing a transaction context is bad new s", func() { 350 Convey("Reusing a transaction context is bad new s", func() {
315 k := rds.NewKey("Foo", "", 1, nil) 351 k := rds.NewKey("Foo", "", 1, nil)
316 txnDS := rdsS.Interface(nil) 352 txnDS := rdsS.Interface(nil)
317 err := rds.RunInTransaction(func(c conte xt.Context) error { 353 err := rds.RunInTransaction(func(c conte xt.Context) error {
318 txnDS = rdsS.Get(c) 354 txnDS = rdsS.Get(c)
319 » » » » » » So(txnDS.Get(k, rdsS.PropertyMap {}), ShouldBeNil) 355 » » » » » » getOnePM(txnDS, k)
320 return nil 356 return nil
321 }, nil) 357 }, nil)
322 So(err, ShouldBeNil) 358 So(err, ShouldBeNil)
323 » » » » » So(txnDS.Get(k, rdsS.PropertyMap{}).Erro r(), ShouldContainSubstring, "expired") 359 » » » » » err = txnDS.GetMulti([]rdsS.Key{k}, func (_ rdsS.PropertyMap, err error) {
360 » » » » » » So(err, ShouldBeNil)
361 » » » » » })
362 » » » » » So(err.Error(), ShouldContainSubstring, "expired")
324 }) 363 })
325 364
326 Convey("Nested transactions are rejected", func( ) { 365 Convey("Nested transactions are rejected", func( ) {
327 err := rds.RunInTransaction(func(c conte xt.Context) error { 366 err := rds.RunInTransaction(func(c conte xt.Context) error {
328 err := rdsS.Get(c).RunInTransact ion(func(c context.Context) error { 367 err := rdsS.Get(c).RunInTransact ion(func(c context.Context) error {
329 panic("noooo") 368 panic("noooo")
330 }, nil) 369 }, nil)
331 So(err.Error(), ShouldContainSub string, "nested transactions") 370 So(err.Error(), ShouldContainSub string, "nested transactions")
332 return nil 371 return nil
333 }, nil) 372 }, nil)
334 So(err, ShouldBeNil) 373 So(err, ShouldBeNil)
335 }) 374 })
336 375
337 Convey("Concurrent transactions only accept one set of changes", func() { 376 Convey("Concurrent transactions only accept one set of changes", func() {
338 // Note: I think this implementation is actually /slightly/ wrong. 377 // Note: I think this implementation is actually /slightly/ wrong.
339 // Accorting to my read of the docs for appengine, when you open a 378 // Accorting to my read of the docs for appengine, when you open a
340 // transaction it actually (essentially) holds a reference to the 379 // transaction it actually (essentially) holds a reference to the
341 // entire datastore. Our implementation takes a snapshot of the 380 // entire datastore. Our implementation takes a snapshot of the
342 // entity group as soon as something obs erves/affects it. 381 // entity group as soon as something obs erves/affects it.
343 // 382 //
344 // That said... I'm not sure if there's really a semantic difference. 383 // That said... I'm not sure if there's really a semantic difference.
345 err := rds.RunInTransaction(func(c conte xt.Context) error { 384 err := rds.RunInTransaction(func(c conte xt.Context) error {
346 txnDS := rdsS.Get(c) 385 txnDS := rdsS.Get(c)
347 f := &Foo{Val: 21} 386 f := &Foo{Val: 21}
348 » » » » » » _, err = txnDS.Put(k, pls(f)) 387 » » » » » » putOne(txnDS, k, f)
349 » » » » » » So(err, ShouldBeNil)
350 388
351 err := rds.RunInTransaction(func (c context.Context) error { 389 err := rds.RunInTransaction(func (c context.Context) error {
352 txnDS := rdsS.Get(c) 390 txnDS := rdsS.Get(c)
353 f := &Foo{Val: 27} 391 f := &Foo{Val: 27}
354 » » » » » » » _, err := txnDS.Put(k, p ls(f)) 392 » » » » » » » putOne(txnDS, k, f)
355 » » » » » » » So(err, ShouldBeNil)
356 return nil 393 return nil
357 }, nil) 394 }, nil)
358 So(err, ShouldBeNil) 395 So(err, ShouldBeNil)
359 396
360 return nil 397 return nil
361 }, nil) 398 }, nil)
362 So(err.Error(), ShouldContainSubstring, "concurrent") 399 So(err.Error(), ShouldContainSubstring, "concurrent")
363 400
364 f := &Foo{} 401 f := &Foo{}
365 » » » » » So(rds.Get(k, pls(f)), ShouldBeNil) 402 » » » » » getOne(rds, k, f)
366 So(f.Val, ShouldEqual, 27) 403 So(f.Val, ShouldEqual, 27)
367 }) 404 })
368 405
369 Convey("XG", func() { 406 Convey("XG", func() {
370 Convey("Modifying two groups with XG=fal se is invalid", func() { 407 Convey("Modifying two groups with XG=fal se is invalid", func() {
371 err := rds.RunInTransaction(func (c context.Context) error { 408 err := rds.RunInTransaction(func (c context.Context) error {
372 rds := rdsS.Get(c) 409 rds := rdsS.Get(c)
373 f := &Foo{Val: 200} 410 f := &Foo{Val: 200}
374 » » » » » » » _, err := rds.Put(k, pls (f)) 411 » » » » » » » putOne(rds, k, f)
375 » » » » » » » So(err, ShouldBeNil)
376 412
377 » » » » » » » _, err = rds.Put(rds.New Key("Foo", "", 2, nil), pls(f)) 413 » » » » » » » _, err := putOneErr(rds, rds.NewKey("Foo", "", 2, nil), f)
378 So(err.Error(), ShouldCo ntainSubstring, "cross-group") 414 So(err.Error(), ShouldCo ntainSubstring, "cross-group")
379 return err 415 return err
380 }, nil) 416 }, nil)
381 So(err.Error(), ShouldContainSub string, "cross-group") 417 So(err.Error(), ShouldContainSub string, "cross-group")
382 }) 418 })
383 419
384 Convey("Modifying >25 groups with XG=tru e is invald", func() { 420 Convey("Modifying >25 groups with XG=tru e is invald", func() {
385 err := rds.RunInTransaction(func (c context.Context) error { 421 err := rds.RunInTransaction(func (c context.Context) error {
386 rds := rdsS.Get(c) 422 rds := rdsS.Get(c)
387 for i := int64(1); i < 2 6; i++ { 423 for i := int64(1); i < 2 6; i++ {
388 k := rds.NewKey( "Foo", "", i, nil) 424 k := rds.NewKey( "Foo", "", i, nil)
389 f := &Foo{Val: 2 00} 425 f := &Foo{Val: 2 00}
390 » » » » » » » » _, err := rds.Pu t(k, pls(f)) 426 » » » » » » » » putOne(rds, k, f )
391 » » » » » » » » So(err, ShouldBe Nil)
392 } 427 }
393 f := &Foo{Val: 200} 428 f := &Foo{Val: 200}
394 » » » » » » » _, err := rds.Put(rds.Ne wKey("Foo", "", 27, nil), pls(f)) 429 » » » » » » » _, err := putOneErr(rds, rds.NewKey("Foo", "", 27, nil), f)
395 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups") 430 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups")
396 return err 431 return err
397 }, &rdsS.TransactionOptions{XG: true}) 432 }, &rdsS.TransactionOptions{XG: true})
398 So(err.Error(), ShouldContainSub string, "too many entity groups") 433 So(err.Error(), ShouldContainSub string, "too many entity groups")
399 }) 434 })
400 }) 435 })
401 436
402 Convey("Errors and panics", func() { 437 Convey("Errors and panics", func() {
403 Convey("returning an error aborts", func () { 438 Convey("returning an error aborts", func () {
404 err := rds.RunInTransaction(func (c context.Context) error { 439 err := rds.RunInTransaction(func (c context.Context) error {
405 rds := rdsS.Get(c) 440 rds := rdsS.Get(c)
406 f := &Foo{Val: 200} 441 f := &Foo{Val: 200}
407 » » » » » » » _, err := rds.Put(k, pls (f)) 442 » » » » » » » putOne(rds, k, f)
408 » » » » » » » So(err, ShouldBeNil)
409 443
410 return fmt.Errorf("thing y") 444 return fmt.Errorf("thing y")
411 }, nil) 445 }, nil)
412 So(err.Error(), ShouldEqual, "th ingy") 446 So(err.Error(), ShouldEqual, "th ingy")
413 447
414 f := &Foo{} 448 f := &Foo{}
415 » » » » » » So(rds.Get(k, pls(f)), ShouldBeN il) 449 » » » » » » getOne(rds, k, f)
416 So(f.Val, ShouldEqual, 10) 450 So(f.Val, ShouldEqual, 10)
417 }) 451 })
418 452
419 Convey("panicing aborts", func() { 453 Convey("panicing aborts", func() {
420 So(func() { 454 So(func() {
421 rds.RunInTransaction(fun c(c context.Context) error { 455 rds.RunInTransaction(fun c(c context.Context) error {
422 rds := rdsS.Get( c) 456 rds := rdsS.Get( c)
423 f := &Foo{Val: 2 00} 457 f := &Foo{Val: 2 00}
424 » » » » » » » » _, err := rds.Pu t(k, pls(f)) 458 » » » » » » » » putOne(rds, k, f )
425 » » » » » » » » So(err, ShouldBe Nil)
426 panic("wheeeeee" ) 459 panic("wheeeeee" )
427 }, nil) 460 }, nil)
428 }, ShouldPanic) 461 }, ShouldPanic)
429 462
430 f := &Foo{} 463 f := &Foo{}
431 » » » » » » So(rds.Get(k, pls(f)), ShouldBeN il) 464 » » » » » » getOne(rds, k, f)
432 So(f.Val, ShouldEqual, 10) 465 So(f.Val, ShouldEqual, 10)
433 }) 466 })
434 }) 467 })
435 }) 468 })
436 }) 469 })
437 470
438 }) 471 })
439 } 472 }
440 473
441 const MaxUint = ^uint(0) 474 const MaxUint = ^uint(0)
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 }) 620 })
588 Convey("kindless with decending-__key__ orders", func() { 621 Convey("kindless with decending-__key__ orders", func() {
589 q := rds.NewQuery("").Order("-__key__") 622 q := rds.NewQuery("").Order("-__key__")
590 qi := q.(*queryImpl).checkCorrectness("", false) 623 qi := q.(*queryImpl).checkCorrectness("", false)
591 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders") 624 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders")
592 }) 625 })
593 }) 626 })
594 627
595 }) 628 })
596 } 629 }
OLDNEW
« no previous file with comments | « impl/memory/raw_datastore_query.go ('k') | impl/prod/datastore_key.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698