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

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

Issue 1355783002: Refactor keys and queries in datastore service and implementation. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: appease errcheck Created 5 years, 3 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/datastore_query_test.go ('k') | impl/memory/gkvlite_utils.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 "testing" 9 "testing"
10 "time" 10 "time"
11 11
12 dsS "github.com/luci/gae/service/datastore" 12 dsS "github.com/luci/gae/service/datastore"
13 "github.com/luci/gae/service/datastore/dskey"
14 "github.com/luci/gae/service/datastore/serialize" 13 "github.com/luci/gae/service/datastore/serialize"
15 infoS "github.com/luci/gae/service/info" 14 infoS "github.com/luci/gae/service/info"
16 . "github.com/smartystreets/goconvey/convey" 15 . "github.com/smartystreets/goconvey/convey"
17 "golang.org/x/net/context" 16 "golang.org/x/net/context"
18 ) 17 )
19 18
20 func TestDatastoreKinder(t *testing.T) {
21 t.Parallel()
22
23 Convey("Datastore keys", t, func() {
24 c := Use(context.Background())
25 ds := dsS.Get(c)
26 So(ds, ShouldNotBeNil)
27
28 Convey("implements DSNewKeyer", func() {
29 Convey("NewKey", func() {
30 key := ds.NewKey("nerd", "stringID", 0, nil)
31 So(key, ShouldNotBeNil)
32 So(key.Kind(), ShouldEqual, "nerd")
33 So(key.StringID(), ShouldEqual, "stringID")
34 So(key.IntID(), ShouldEqual, 0)
35 So(key.Parent(), ShouldBeNil)
36 So(key.AppID(), ShouldEqual, "dev~app")
37 So(key.Namespace(), ShouldEqual, "")
38 So(key.String(), ShouldEqual, "/nerd,stringID")
39 So(key.Incomplete(), ShouldBeFalse)
40 So(key.Valid(false, "dev~app", ""), ShouldBeTrue )
41 })
42 })
43
44 })
45 }
46
47 type MetaGroup struct { 19 type MetaGroup struct {
48 » _id int64 `gae:"$id,1"` 20 » _id int64 `gae:"$id,1"`
49 » _kind string `gae:"$kind,__entity_group__"` 21 » _kind string `gae:"$kind,__entity_group__"`
50 » Parent dsS.Key `gae:"$parent"` 22 » Parent *dsS.Key `gae:"$parent"`
51 23
52 Version int64 `gae:"__version__"` 24 Version int64 `gae:"__version__"`
53 } 25 }
54 26
55 func testGetMeta(c context.Context, k dsS.Key) int64 { 27 func testGetMeta(c context.Context, k *dsS.Key) int64 {
56 ds := dsS.Get(c) 28 ds := dsS.Get(c)
57 » mg := &MetaGroup{Parent: dskey.Root(k)} 29 » mg := &MetaGroup{Parent: k.Root()}
58 if err := ds.Get(mg); err != nil { 30 if err := ds.Get(mg); err != nil {
59 panic(err) 31 panic(err)
60 } 32 }
61 return mg.Version 33 return mg.Version
62 } 34 }
63 35
64 var pls = dsS.GetPLS 36 var pls = dsS.GetPLS
65 37
66 type Foo struct { 38 type Foo struct {
67 » Id int64 `gae:"$id"` 39 » ID int64 `gae:"$id"`
68 » Parent dsS.Key `gae:"$parent"` 40 » Parent *dsS.Key `gae:"$parent"`
69 41
70 Val int 42 Val int
71 } 43 }
72 44
73 func TestDatastoreSingleReadWriter(t *testing.T) { 45 func TestDatastoreSingleReadWriter(t *testing.T) {
74 t.Parallel() 46 t.Parallel()
75 47
76 Convey("Datastore single reads and writes", t, func() { 48 Convey("Datastore single reads and writes", t, func() {
77 c := Use(context.Background()) 49 c := Use(context.Background())
78 ds := dsS.Get(c) 50 ds := dsS.Get(c)
79 So(ds, ShouldNotBeNil) 51 So(ds, ShouldNotBeNil)
80 52
81 Convey("getting objects that DNE is an error", func() { 53 Convey("getting objects that DNE is an error", func() {
82 » » » So(ds.Get(&Foo{Id: 1}), ShouldEqual, dsS.ErrNoSuchEntity ) 54 » » » So(ds.Get(&Foo{ID: 1}), ShouldEqual, dsS.ErrNoSuchEntity )
83 }) 55 })
84 56
85 Convey("bad namespaces fail", func() { 57 Convey("bad namespaces fail", func() {
86 _, err := infoS.Get(c).Namespace("$$blzyall") 58 _, err := infoS.Get(c).Namespace("$$blzyall")
87 So(err.Error(), ShouldContainSubstring, "namespace \"$$b lzyall\" does not match") 59 So(err.Error(), ShouldContainSubstring, "namespace \"$$b lzyall\" does not match")
88 }) 60 })
89 61
90 Convey("Can Put stuff", func() { 62 Convey("Can Put stuff", func() {
91 // with an incomplete key! 63 // with an incomplete key!
92 f := &Foo{Val: 10} 64 f := &Foo{Val: 10}
93 So(ds.Put(f), ShouldBeNil) 65 So(ds.Put(f), ShouldBeNil)
94 k := ds.KeyForObj(f) 66 k := ds.KeyForObj(f)
95 » » » So(k.String(), ShouldEqual, "/Foo,1") 67 » » » So(k.String(), ShouldEqual, "dev~app::/Foo,1")
96 68
97 Convey("and Get it back", func() { 69 Convey("and Get it back", func() {
98 » » » » newFoo := &Foo{Id: 1} 70 » » » » newFoo := &Foo{ID: 1}
99 So(ds.Get(newFoo), ShouldBeNil) 71 So(ds.Get(newFoo), ShouldBeNil)
100 So(newFoo, ShouldResemble, f) 72 So(newFoo, ShouldResemble, f)
101 73
102 Convey("but it's hidden from a different namespa ce", func() { 74 Convey("but it's hidden from a different namespa ce", func() {
103 c, err := infoS.Get(c).Namespace("whomba t") 75 c, err := infoS.Get(c).Namespace("whomba t")
104 So(err, ShouldBeNil) 76 So(err, ShouldBeNil)
105 ds = dsS.Get(c) 77 ds = dsS.Get(c)
106 So(ds.Get(f), ShouldEqual, dsS.ErrNoSuch Entity) 78 So(ds.Get(f), ShouldEqual, dsS.ErrNoSuch Entity)
107 }) 79 })
108 80
(...skipping 14 matching lines...) Expand all
123 So(testGetMeta(c, k), ShouldEqual, 1) 95 So(testGetMeta(c, k), ShouldEqual, 1)
124 96
125 foos := make([]Foo, 10) 97 foos := make([]Foo, 10)
126 for i := range foos { 98 for i := range foos {
127 foos[i].Val = 10 99 foos[i].Val = 10
128 foos[i].Parent = k 100 foos[i].Parent = k
129 } 101 }
130 So(ds.PutMulti(foos), ShouldBeNil) 102 So(ds.PutMulti(foos), ShouldBeNil)
131 So(testGetMeta(c, k), ShouldEqual, 11) 103 So(testGetMeta(c, k), ShouldEqual, 11)
132 104
133 » » » » keys := make([]dsS.Key, len(foos)) 105 » » » » keys := make([]*dsS.Key, len(foos))
134 for i, f := range foos { 106 for i, f := range foos {
135 keys[i] = ds.KeyForObj(&f) 107 keys[i] = ds.KeyForObj(&f)
136 } 108 }
137 109
138 Convey("ensure that group versions persist acros s deletes", func() { 110 Convey("ensure that group versions persist acros s deletes", func() {
139 So(ds.DeleteMulti(append(keys, k)), Shou ldBeNil) 111 So(ds.DeleteMulti(append(keys, k)), Shou ldBeNil)
140 112
141 // TODO(riannucci): replace with a Count query instead of this cast 113 // TODO(riannucci): replace with a Count query instead of this cast
142 /* 114 /*
143 ents := ds.(*dsImpl).data.head.G etCollection("ents:") 115 ents := ds.(*dsImpl).data.head.G etCollection("ents:")
144 num, _ := ents.GetTotals() 116 num, _ := ents.GetTotals()
145 // /__entity_root_ids__,Foo 117 // /__entity_root_ids__,Foo
146 // /Foo,1/__entity_group__,1 118 // /Foo,1/__entity_group__,1
147 // /Foo,1/__entity_group_ids__,1 119 // /Foo,1/__entity_group_ids__,1
148 So(num, ShouldEqual, 3) 120 So(num, ShouldEqual, 3)
149 */ 121 */
150 122
151 So(testGetMeta(c, k), ShouldEqual, 22) 123 So(testGetMeta(c, k), ShouldEqual, 22)
152 124
153 » » » » » So(ds.Put(&Foo{Id: 1}), ShouldBeNil) 125 » » » » » So(ds.Put(&Foo{ID: 1}), ShouldBeNil)
154 So(testGetMeta(c, k), ShouldEqual, 23) 126 So(testGetMeta(c, k), ShouldEqual, 23)
155 }) 127 })
156 128
157 Convey("can Get", func() { 129 Convey("can Get", func() {
158 vals := make([]dsS.PropertyMap, len(keys )) 130 vals := make([]dsS.PropertyMap, len(keys ))
159 for i := range vals { 131 for i := range vals {
160 vals[i] = dsS.PropertyMap{} 132 vals[i] = dsS.PropertyMap{}
161 » » » » » » vals[i].SetMeta("key", keys[i]) 133 » » » » » » So(vals[i].SetMeta("key", keys[i ]), ShouldBeNil)
162 } 134 }
163 So(ds.GetMulti(vals), ShouldBeNil) 135 So(ds.GetMulti(vals), ShouldBeNil)
164 136
165 for i, val := range vals { 137 for i, val := range vals {
166 So(val, ShouldResemble, dsS.Prop ertyMap{ 138 So(val, ShouldResemble, dsS.Prop ertyMap{
167 "Val": {dsS.MkProperty( 10)}, 139 "Val": {dsS.MkProperty( 10)},
168 "$key": {dsS.MkPropertyN I(keys[i])}, 140 "$key": {dsS.MkPropertyN I(keys[i])},
169 }) 141 })
170 } 142 }
171 }) 143 })
172 144
173 }) 145 })
174 }) 146 })
175 147
176 Convey("implements DSTransactioner", func() { 148 Convey("implements DSTransactioner", func() {
177 Convey("Put", func() { 149 Convey("Put", func() {
178 f := &Foo{Val: 10} 150 f := &Foo{Val: 10}
179 So(ds.Put(f), ShouldBeNil) 151 So(ds.Put(f), ShouldBeNil)
180 k := ds.KeyForObj(f) 152 k := ds.KeyForObj(f)
181 » » » » So(k.String(), ShouldEqual, "/Foo,1") 153 » » » » So(k.String(), ShouldEqual, "dev~app::/Foo,1")
182 154
183 Convey("can Put new entity groups", func() { 155 Convey("can Put new entity groups", func() {
184 err := ds.RunInTransaction(func(c contex t.Context) error { 156 err := ds.RunInTransaction(func(c contex t.Context) error {
185 ds := dsS.Get(c) 157 ds := dsS.Get(c)
186 158
187 f := &Foo{Val: 100} 159 f := &Foo{Val: 100}
188 So(ds.Put(f), ShouldBeNil) 160 So(ds.Put(f), ShouldBeNil)
189 » » » » » » So(f.Id, ShouldEqual, 2) 161 » » » » » » So(f.ID, ShouldEqual, 2)
190 162
191 » » » » » » f.Id = 0 163 » » » » » » f.ID = 0
192 f.Val = 200 164 f.Val = 200
193 So(ds.Put(f), ShouldBeNil) 165 So(ds.Put(f), ShouldBeNil)
194 » » » » » » So(f.Id, ShouldEqual, 3) 166 » » » » » » So(f.ID, ShouldEqual, 3)
195 167
196 return nil 168 return nil
197 }, &dsS.TransactionOptions{XG: true}) 169 }, &dsS.TransactionOptions{XG: true})
198 So(err, ShouldBeNil) 170 So(err, ShouldBeNil)
199 171
200 » » » » » f := &Foo{Id: 2} 172 » » » » » f := &Foo{ID: 2}
201 So(ds.Get(f), ShouldBeNil) 173 So(ds.Get(f), ShouldBeNil)
202 So(f.Val, ShouldEqual, 100) 174 So(f.Val, ShouldEqual, 100)
203 175
204 » » » » » f.Id = 3 176 » » » » » f.ID = 3
205 So(ds.Get(f), ShouldBeNil) 177 So(ds.Get(f), ShouldBeNil)
206 So(f.Val, ShouldEqual, 200) 178 So(f.Val, ShouldEqual, 200)
207 }) 179 })
208 180
209 Convey("can Put new entities in a current group" , func() { 181 Convey("can Put new entities in a current group" , func() {
210 err := ds.RunInTransaction(func(c contex t.Context) error { 182 err := ds.RunInTransaction(func(c contex t.Context) error {
211 ds := dsS.Get(c) 183 ds := dsS.Get(c)
212 184
213 f := &Foo{Val: 100, Parent: k} 185 f := &Foo{Val: 100, Parent: k}
214 So(ds.Put(f), ShouldBeNil) 186 So(ds.Put(f), ShouldBeNil)
215 » » » » » » So(ds.KeyForObj(f).String(), Sho uldEqual, "/Foo,1/Foo,1") 187 » » » » » » So(ds.KeyForObj(f).String(), Sho uldEqual, "dev~app::/Foo,1/Foo,1")
216 188
217 » » » » » » f.Id = 0 189 » » » » » » f.ID = 0
218 f.Val = 200 190 f.Val = 200
219 So(ds.Put(f), ShouldBeNil) 191 So(ds.Put(f), ShouldBeNil)
220 » » » » » » So(ds.KeyForObj(f).String(), Sho uldEqual, "/Foo,1/Foo,2") 192 » » » » » » So(ds.KeyForObj(f).String(), Sho uldEqual, "dev~app::/Foo,1/Foo,2")
221 193
222 return nil 194 return nil
223 }, nil) 195 }, nil)
224 So(err, ShouldBeNil) 196 So(err, ShouldBeNil)
225 197
226 » » » » » f := &Foo{Id: 1, Parent: k} 198 » » » » » f := &Foo{ID: 1, Parent: k}
227 So(ds.Get(f), ShouldBeNil) 199 So(ds.Get(f), ShouldBeNil)
228 So(f.Val, ShouldEqual, 100) 200 So(f.Val, ShouldEqual, 100)
229 201
230 » » » » » f.Id = 2 202 » » » » » f.ID = 2
231 So(ds.Get(f), ShouldBeNil) 203 So(ds.Get(f), ShouldBeNil)
232 So(f.Val, ShouldEqual, 200) 204 So(f.Val, ShouldEqual, 200)
233 }) 205 })
234 206
235 Convey("Deletes work too", func() { 207 Convey("Deletes work too", func() {
236 err := ds.RunInTransaction(func(c contex t.Context) error { 208 err := ds.RunInTransaction(func(c contex t.Context) error {
237 return dsS.Get(c).Delete(k) 209 return dsS.Get(c).Delete(k)
238 }, nil) 210 }, nil)
239 So(err, ShouldBeNil) 211 So(err, ShouldBeNil)
240 » » » » » So(ds.Get(&Foo{Id: 1}), ShouldEqual, dsS .ErrNoSuchEntity) 212 » » » » » So(ds.Get(&Foo{ID: 1}), ShouldEqual, dsS .ErrNoSuchEntity)
241 }) 213 })
242 214
243 Convey("A Get counts against your group count", func() { 215 Convey("A Get counts against your group count", func() {
244 err := ds.RunInTransaction(func(c contex t.Context) error { 216 err := ds.RunInTransaction(func(c contex t.Context) error {
245 ds := dsS.Get(c) 217 ds := dsS.Get(c)
246 218
247 pm := dsS.PropertyMap{} 219 pm := dsS.PropertyMap{}
248 » » » » » » pm.SetMeta("key", ds.NewKey("Foo ", "", 20, nil)) 220 » » » » » » So(pm.SetMeta("key", ds.NewKey(" Foo", "", 20, nil)), ShouldBeNil)
249 So(ds.Get(pm), ShouldEqual, dsS. ErrNoSuchEntity) 221 So(ds.Get(pm), ShouldEqual, dsS. ErrNoSuchEntity)
250 222
251 » » » » » » pm.SetMeta("key", k) 223 » » » » » » So(pm.SetMeta("key", k), ShouldB eNil)
252 So(ds.Get(pm).Error(), ShouldCon tainSubstring, "cross-group") 224 So(ds.Get(pm).Error(), ShouldCon tainSubstring, "cross-group")
253 return nil 225 return nil
254 }, nil) 226 }, nil)
255 So(err, ShouldBeNil) 227 So(err, ShouldBeNil)
256 }) 228 })
257 229
258 Convey("Get takes a snapshot", func() { 230 Convey("Get takes a snapshot", func() {
259 err := ds.RunInTransaction(func(c contex t.Context) error { 231 err := ds.RunInTransaction(func(c contex t.Context) error {
260 txnDS := dsS.Get(c) 232 txnDS := dsS.Get(c)
261 233
262 So(txnDS.Get(f), ShouldBeNil) 234 So(txnDS.Get(f), ShouldBeNil)
263 So(f.Val, ShouldEqual, 10) 235 So(f.Val, ShouldEqual, 10)
264 236
265 // Don't ever do this in a real program unless you want to guarantee 237 // Don't ever do this in a real program unless you want to guarantee
266 // a failed transaction :) 238 // a failed transaction :)
267 f.Val = 11 239 f.Val = 11
268 So(ds.Put(f), ShouldBeNil) 240 So(ds.Put(f), ShouldBeNil)
269 241
270 So(txnDS.Get(f), ShouldBeNil) 242 So(txnDS.Get(f), ShouldBeNil)
271 So(f.Val, ShouldEqual, 10) 243 So(f.Val, ShouldEqual, 10)
272 244
273 return nil 245 return nil
274 }, nil) 246 }, nil)
275 So(err, ShouldBeNil) 247 So(err, ShouldBeNil)
276 248
277 » » » » » f := &Foo{Id: 1} 249 » » » » » f := &Foo{ID: 1}
278 So(ds.Get(f), ShouldBeNil) 250 So(ds.Get(f), ShouldBeNil)
279 So(f.Val, ShouldEqual, 11) 251 So(f.Val, ShouldEqual, 11)
280 }) 252 })
281 253
282 Convey("and snapshots are consistent even after Puts", func() { 254 Convey("and snapshots are consistent even after Puts", func() {
283 err := ds.RunInTransaction(func(c contex t.Context) error { 255 err := ds.RunInTransaction(func(c contex t.Context) error {
284 txnDS := dsS.Get(c) 256 txnDS := dsS.Get(c)
285 257
286 » » » » » » f := &Foo{Id: 1} 258 » » » » » » f := &Foo{ID: 1}
287 So(txnDS.Get(f), ShouldBeNil) 259 So(txnDS.Get(f), ShouldBeNil)
288 So(f.Val, ShouldEqual, 10) 260 So(f.Val, ShouldEqual, 10)
289 261
290 // Don't ever do this in a real program unless you want to guarantee 262 // Don't ever do this in a real program unless you want to guarantee
291 // a failed transaction :) 263 // a failed transaction :)
292 f.Val = 11 264 f.Val = 11
293 So(ds.Put(f), ShouldBeNil) 265 So(ds.Put(f), ShouldBeNil)
294 266
295 So(txnDS.Get(f), ShouldBeNil) 267 So(txnDS.Get(f), ShouldBeNil)
296 So(f.Val, ShouldEqual, 10) 268 So(f.Val, ShouldEqual, 10)
297 269
298 f.Val = 20 270 f.Val = 20
299 So(txnDS.Put(f), ShouldBeNil) 271 So(txnDS.Put(f), ShouldBeNil)
300 272
301 So(txnDS.Get(f), ShouldBeNil) 273 So(txnDS.Get(f), ShouldBeNil)
302 So(f.Val, ShouldEqual, 10) // st ill gets 10 274 So(f.Val, ShouldEqual, 10) // st ill gets 10
303 275
304 return nil 276 return nil
305 }, &dsS.TransactionOptions{Attempts: 1}) 277 }, &dsS.TransactionOptions{Attempts: 1})
306 So(err.Error(), ShouldContainSubstring, "concurrent") 278 So(err.Error(), ShouldContainSubstring, "concurrent")
307 279
308 » » » » » f := &Foo{Id: 1} 280 » » » » » f := &Foo{ID: 1}
309 So(ds.Get(f), ShouldBeNil) 281 So(ds.Get(f), ShouldBeNil)
310 So(f.Val, ShouldEqual, 11) 282 So(f.Val, ShouldEqual, 11)
311 }) 283 })
312 284
313 Convey("Reusing a transaction context is bad new s", func() { 285 Convey("Reusing a transaction context is bad new s", func() {
314 txnDS := dsS.Interface(nil) 286 txnDS := dsS.Interface(nil)
315 err := ds.RunInTransaction(func(c contex t.Context) error { 287 err := ds.RunInTransaction(func(c contex t.Context) error {
316 txnDS = dsS.Get(c) 288 txnDS = dsS.Get(c)
317 So(txnDS.Get(f), ShouldBeNil) 289 So(txnDS.Get(f), ShouldBeNil)
318 return nil 290 return nil
(...skipping 15 matching lines...) Expand all
334 306
335 Convey("Concurrent transactions only accept one set of changes", func() { 307 Convey("Concurrent transactions only accept one set of changes", func() {
336 // Note: I think this implementation is actually /slightly/ wrong. 308 // Note: I think this implementation is actually /slightly/ wrong.
337 // According to my read of the docs for appengine, when you open a 309 // According to my read of the docs for appengine, when you open a
338 // transaction it actually (essentially) holds a reference to the 310 // transaction it actually (essentially) holds a reference to the
339 // entire datastore. Our implementation takes a snapshot of the 311 // entire datastore. Our implementation takes a snapshot of the
340 // entity group as soon as something obs erves/affects it. 312 // entity group as soon as something obs erves/affects it.
341 // 313 //
342 // That said... I'm not sure if there's really a semantic difference. 314 // That said... I'm not sure if there's really a semantic difference.
343 err := ds.RunInTransaction(func(c contex t.Context) error { 315 err := ds.RunInTransaction(func(c contex t.Context) error {
344 » » » » » » So(dsS.Get(c).Put(&Foo{Id: 1, Va l: 21}), ShouldBeNil) 316 » » » » » » So(dsS.Get(c).Put(&Foo{ID: 1, Va l: 21}), ShouldBeNil)
345 317
346 err := ds.RunInTransaction(func( c context.Context) error { 318 err := ds.RunInTransaction(func( c context.Context) error {
347 » » » » » » » So(dsS.Get(c).Put(&Foo{I d: 1, Val: 27}), ShouldBeNil) 319 » » » » » » » So(dsS.Get(c).Put(&Foo{I D: 1, Val: 27}), ShouldBeNil)
348 return nil 320 return nil
349 }, nil) 321 }, nil)
350 So(err, ShouldBeNil) 322 So(err, ShouldBeNil)
351 323
352 return nil 324 return nil
353 }, nil) 325 }, nil)
354 So(err.Error(), ShouldContainSubstring, "concurrent") 326 So(err.Error(), ShouldContainSubstring, "concurrent")
355 327
356 » » » » » f := &Foo{Id: 1} 328 » » » » » f := &Foo{ID: 1}
357 So(ds.Get(f), ShouldBeNil) 329 So(ds.Get(f), ShouldBeNil)
358 So(f.Val, ShouldEqual, 27) 330 So(f.Val, ShouldEqual, 27)
359 }) 331 })
360 332
361 Convey("XG", func() { 333 Convey("XG", func() {
362 Convey("Modifying two groups with XG=fal se is invalid", func() { 334 Convey("Modifying two groups with XG=fal se is invalid", func() {
363 err := ds.RunInTransaction(func( c context.Context) error { 335 err := ds.RunInTransaction(func( c context.Context) error {
364 ds := dsS.Get(c) 336 ds := dsS.Get(c)
365 » » » » » » » f := &Foo{Id: 1, Val: 20 0} 337 » » » » » » » f := &Foo{ID: 1, Val: 20 0}
366 So(ds.Put(f), ShouldBeNi l) 338 So(ds.Put(f), ShouldBeNi l)
367 339
368 » » » » » » » f.Id = 2 340 » » » » » » » f.ID = 2
369 err := ds.Put(f) 341 err := ds.Put(f)
370 So(err.Error(), ShouldCo ntainSubstring, "cross-group") 342 So(err.Error(), ShouldCo ntainSubstring, "cross-group")
371 return err 343 return err
372 }, nil) 344 }, nil)
373 So(err.Error(), ShouldContainSub string, "cross-group") 345 So(err.Error(), ShouldContainSub string, "cross-group")
374 }) 346 })
375 347
376 Convey("Modifying >25 groups with XG=tru e is invald", func() { 348 Convey("Modifying >25 groups with XG=tru e is invald", func() {
377 err := ds.RunInTransaction(func( c context.Context) error { 349 err := ds.RunInTransaction(func( c context.Context) error {
378 ds := dsS.Get(c) 350 ds := dsS.Get(c)
379 foos := make([]Foo, 25) 351 foos := make([]Foo, 25)
380 for i := int64(1); i < 2 6; i++ { 352 for i := int64(1); i < 2 6; i++ {
381 » » » » » » » » foos[i-1].Id = i 353 » » » » » » » » foos[i-1].ID = i
382 foos[i-1].Val = 200 354 foos[i-1].Val = 200
383 } 355 }
384 So(ds.PutMulti(foos), Sh ouldBeNil) 356 So(ds.PutMulti(foos), Sh ouldBeNil)
385 » » » » » » » err := ds.Put(&Foo{Id: 2 6}) 357 » » » » » » » err := ds.Put(&Foo{ID: 2 6})
386 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups") 358 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups")
387 return err 359 return err
388 }, &dsS.TransactionOptions{XG: t rue}) 360 }, &dsS.TransactionOptions{XG: t rue})
389 So(err.Error(), ShouldContainSub string, "too many entity groups") 361 So(err.Error(), ShouldContainSub string, "too many entity groups")
390 }) 362 })
391 }) 363 })
392 364
393 Convey("Errors and panics", func() { 365 Convey("Errors and panics", func() {
394 Convey("returning an error aborts", func () { 366 Convey("returning an error aborts", func () {
395 err := ds.RunInTransaction(func( c context.Context) error { 367 err := ds.RunInTransaction(func( c context.Context) error {
396 ds := dsS.Get(c) 368 ds := dsS.Get(c)
397 » » » » » » » So(ds.Put(&Foo{Id: 1, Va l: 200}), ShouldBeNil) 369 » » » » » » » So(ds.Put(&Foo{ID: 1, Va l: 200}), ShouldBeNil)
398 return fmt.Errorf("thing y") 370 return fmt.Errorf("thing y")
399 }, nil) 371 }, nil)
400 So(err.Error(), ShouldEqual, "th ingy") 372 So(err.Error(), ShouldEqual, "th ingy")
401 373
402 » » » » » » f := &Foo{Id: 1} 374 » » » » » » f := &Foo{ID: 1}
403 So(ds.Get(f), ShouldBeNil) 375 So(ds.Get(f), ShouldBeNil)
404 So(f.Val, ShouldEqual, 10) 376 So(f.Val, ShouldEqual, 10)
405 }) 377 })
406 378
407 Convey("panicing aborts", func() { 379 Convey("panicing aborts", func() {
408 So(func() { 380 So(func() {
409 » » » » » » » ds.RunInTransaction(func (c context.Context) error { 381 » » » » » » » So(ds.RunInTransaction(f unc(c context.Context) error {
410 ds := dsS.Get(c) 382 ds := dsS.Get(c)
411 So(ds.Put(&Foo{V al: 200}), ShouldBeNil) 383 So(ds.Put(&Foo{V al: 200}), ShouldBeNil)
412 panic("wheeeeee" ) 384 panic("wheeeeee" )
413 » » » » » » » }, nil) 385 » » » » » » » }, nil), ShouldBeNil)
414 }, ShouldPanic) 386 }, ShouldPanic)
415 387
416 » » » » » » f := &Foo{Id: 1} 388 » » » » » » f := &Foo{ID: 1}
417 So(ds.Get(f), ShouldBeNil) 389 So(ds.Get(f), ShouldBeNil)
418 So(f.Val, ShouldEqual, 10) 390 So(f.Val, ShouldEqual, 10)
419 }) 391 })
420 }) 392 })
421 393
422 Convey("Transaction retries", func() { 394 Convey("Transaction retries", func() {
423 tst := ds.Testable() 395 tst := ds.Testable()
424 Reset(func() { tst.SetTransactionRetryCo unt(0) }) 396 Reset(func() { tst.SetTransactionRetryCo unt(0) })
425 397
426 Convey("SetTransactionRetryCount set to zere", func() { 398 Convey("SetTransactionRetryCount set to zere", func() {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 ds := dsS.Get(Use(context.Background())) 517 ds := dsS.Get(Use(context.Background()))
546 m := Model{ID: 1} 518 m := Model{ID: 1}
547 So(ds.Put(&m), ShouldBeNil) 519 So(ds.Put(&m), ShouldBeNil)
548 520
549 // Reset to something non zero to ensure zero is fetched. 521 // Reset to something non zero to ensure zero is fetched.
550 m.Time = time.Now().UTC() 522 m.Time = time.Now().UTC()
551 So(ds.Get(&m), ShouldBeNil) 523 So(ds.Get(&m), ShouldBeNil)
552 So(m.Time.IsZero(), ShouldBeTrue) 524 So(m.Time.IsZero(), ShouldBeTrue)
553 }) 525 })
554 } 526 }
OLDNEW
« no previous file with comments | « impl/memory/datastore_query_test.go ('k') | impl/memory/gkvlite_utils.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698