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

Side by Side Diff: go/src/infra/gae/libs/wrapper/memory/datastore_test.go

Issue 1230303003: Revert "Refactor current GAE abstraction library to be free of the SDK*" (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Created 5 years, 5 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
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 » "infra/gae/libs/gae" 9 » "infra/gae/libs/meta"
10 » "infra/gae/libs/gae/helper" 10 » "infra/gae/libs/wrapper"
11 "math" 11 "math"
12 "testing" 12 "testing"
13 13
14 . "github.com/smartystreets/goconvey/convey" 14 . "github.com/smartystreets/goconvey/convey"
15 "golang.org/x/net/context" 15 "golang.org/x/net/context"
16
17 "appengine/datastore"
16 ) 18 )
17 19
18 func TestDatastoreKinder(t *testing.T) { 20 func TestDatastoreKinder(t *testing.T) {
19 t.Parallel() 21 t.Parallel()
20 22
21 » Convey("Datastore keys", t, func() { 23 » Convey("Datastore kinds and keys", t, func() {
22 c := Use(context.Background()) 24 c := Use(context.Background())
23 » » rds := gae.GetRDS(c) 25 » » ds := wrapper.GetDS(c)
24 » » So(rds, ShouldNotBeNil) 26 » » So(ds, ShouldNotBeNil)
27
28 » » Convey("implements DSKinder", func() {
29 » » » type Foo struct{}
30 » » » So(ds.Kind(&Foo{}), ShouldEqual, "Foo")
31
32 » » » Convey("which can be tweaked by DSKindSetter", func() {
33 » » » » ds.SetKindNameResolver(func(interface{}) string { return "spam" })
34 » » » » So(ds.Kind(&Foo{}), ShouldEqual, "spam")
35
36 » » » » Convey("and it retains the function so you can s tack them", func() {
37 » » » » » cur := ds.KindNameResolver()
38 » » » » » ds.SetKindNameResolver(func(o interface{ }) string { return "wat" + cur(o) })
39 » » » » » So(ds.Kind(&Foo{}), ShouldEqual, "watspa m")
40 » » » » })
41 » » » })
42 » » })
25 43
26 Convey("implements DSNewKeyer", func() { 44 Convey("implements DSNewKeyer", func() {
27 Convey("NewKey", func() { 45 Convey("NewKey", func() {
28 » » » » key := rds.NewKey("nerd", "stringID", 0, nil) 46 » » » » key := ds.NewKey("nerd", "stringID", 0, nil)
29 So(key, ShouldNotBeNil) 47 So(key, ShouldNotBeNil)
30 So(key.Kind(), ShouldEqual, "nerd") 48 So(key.Kind(), ShouldEqual, "nerd")
31 So(key.StringID(), ShouldEqual, "stringID") 49 So(key.StringID(), ShouldEqual, "stringID")
32 So(key.IntID(), ShouldEqual, 0) 50 So(key.IntID(), ShouldEqual, 0)
33 So(key.Parent(), ShouldBeNil) 51 So(key.Parent(), ShouldBeNil)
34 » » » » So(key.AppID(), ShouldEqual, "dev~app") 52 » » » » So(key.AppID(), ShouldEqual, "dev~my~app")
35 So(key.Namespace(), ShouldEqual, "") 53 So(key.Namespace(), ShouldEqual, "")
36 So(key.String(), ShouldEqual, "/nerd,stringID") 54 So(key.String(), ShouldEqual, "/nerd,stringID")
37 » » » » So(helper.DSKeyIncomplete(key), ShouldBeFalse) 55 » » » » So(key.Incomplete(), ShouldBeFalse)
38 » » » » So(helper.DSKeyValid(key, "", false), ShouldBeTr ue) 56 » » » » So(keyValid("", key, userKeyOnly), ShouldBeTrue)
57
58 » » » » chkey := ds.NewKey("wat", "", 100, key)
59 » » » » So(chkey, ShouldNotBeNil)
60 » » » » So(chkey.Kind(), ShouldEqual, "wat")
61 » » » » So(chkey.StringID(), ShouldEqual, "")
62 » » » » So(chkey.IntID(), ShouldEqual, 100)
63 » » » » So(chkey.Parent(), ShouldEqual, key)
64 » » » » So(chkey.AppID(), ShouldEqual, "dev~my~app")
65 » » » » So(chkey.Namespace(), ShouldEqual, "")
66 » » » » So(chkey.String(), ShouldEqual, "/nerd,stringID/ wat,100")
67 » » » » So(key.Incomplete(), ShouldBeFalse)
68 » » » » So(keyValid("", chkey, userKeyOnly), ShouldBeTru e)
69
70 » » » » incompl := ds.NewKey("sup", "", 0, key)
71 » » » » So(incompl, ShouldNotBeNil)
72 » » » » So(incompl.Incomplete(), ShouldBeTrue)
73 » » » » So(keyValid("", incompl, userKeyOnly), ShouldBeT rue)
74 » » » » So(incompl.String(), ShouldEqual, "/nerd,stringI D/sup,0")
75
76 » » » » bad := ds.NewKey("nooo", "", 10, incompl)
77 » » » » So(bad, ShouldNotBeNil)
78 » » » » So(bad.Incomplete(), ShouldBeFalse)
79 » » » » So(keyValid("", bad, userKeyOnly), ShouldBeFalse )
80 » » » » So(bad.String(), ShouldEqual, "/nerd,stringID/su p,0/nooo,10")
81
82 » » » » So(rootKey(bad), ShouldEqual, key)
83
84 » » » » Convey("other key validation", func() {
85 » » » » » So(keyValid("", nil, userKeyOnly), Shoul dBeFalse)
86
87 » » » » » key := ds.NewKey("", "", 0, nil)
88 » » » » » So(key, ShouldNotBeNil)
89
90 » » » » » So(keyValid("", key, userKeyOnly), Shoul dBeFalse)
91
92 » » » » » key = ds.NewKey("noop", "power level", 9 000, nil)
93 » » » » » So(key, ShouldNotBeNil)
94
95 » » » » » So(keyValid("", key, userKeyOnly), Shoul dBeFalse)
96 » » » » })
97 » » » })
98
99 » » » Convey("NewKeyObj", func() {
100 » » » » type Foo struct {
101 » » » » » _knd string `goon:"kind,coool" `
102 » » » » » ID int64 `goon:"id"`
103 » » » » » Parent *datastore.Key `goon:"parent"`
104 » » » » }
105 » » » » f := &Foo{ID: 100}
106 » » » » k := ds.NewKeyObj(f)
107 » » » » So(k.String(), ShouldEqual, "/coool,100")
108
109 » » » » f.Parent = k
110 » » » » f._knd = "weevils"
111 » » » » f.ID = 19
112 » » » » k = ds.NewKeyObj(f)
113 » » » » So(k.String(), ShouldEqual, "/coool,100/weevils, 19")
114
115 » » » » Convey("panics when you do a dumb thing", func() {
116 » » » » » type Foo struct {
117 » » » » » » ID []byte `goon:"id"`
118 » » » » » }
119 » » » » » So(func() { ds.NewKeyObj(&Foo{}) }, Shou ldPanic)
120 » » » » })
121 » » » })
122
123 » » » Convey("NewKeyObjError", func() {
124 » » » » type Foo struct {
125 » » » » » ID []byte `goon:"id"`
126 » » » » }
127 » » » » _, err := ds.NewKeyObjError(&Foo{})
128 » » » » So(err.Error(), ShouldContainSubstring, "must be int64 or string")
39 }) 129 })
40 }) 130 })
41 131
42 }) 132 })
43 } 133 }
44 134
45 func testGetMeta(c context.Context, k gae.DSKey) int64 {
46 rds := gae.GetRDS(c)
47 k = rds.NewKey("__entity_group__", "", 1, helper.DSKeyRoot(k))
48 pmap := gae.DSPropertyMap{}
49 rds.Get(k, &pmap)
50 return pmap["__version__"][0].Value().(int64)
51 }
52
53 func TestDatastoreSingleReadWriter(t *testing.T) { 135 func TestDatastoreSingleReadWriter(t *testing.T) {
54 t.Parallel() 136 t.Parallel()
55 137
56 Convey("Datastore single reads and writes", t, func() { 138 Convey("Datastore single reads and writes", t, func() {
57 c := Use(context.Background()) 139 c := Use(context.Background())
58 » » rds := gae.GetRDS(c) 140 » » ds := wrapper.GetDS(c)
59 » » So(rds, ShouldNotBeNil) 141 » » So(ds, ShouldNotBeNil)
60 142
61 Convey("implements DSSingleReadWriter", func() { 143 Convey("implements DSSingleReadWriter", func() {
62 type Foo struct { 144 type Foo struct {
63 » » » » Val int 145 » » » » ID int64 `goon:"id" datastore:"-"`
146 » » » » Parent *datastore.Key `goon:"parent" datastore:" -"`
147 » » » » Val int
64 } 148 }
65 149
66 Convey("invalid keys break", func() { 150 Convey("invalid keys break", func() {
67 » » » » k := rds.NewKey("Foo", "", 0, nil) 151 » » » » k := ds.NewKeyObj(&Foo{})
68 » » » » So(rds.Get(k, nil), ShouldEqual, gae.ErrDSInvali dKey) 152 » » » » f := &Foo{Parent: k}
69 153 » » » » So(ds.Get(f), ShouldEqual, datastore.ErrInvalidK ey)
70 » » » » _, err := rds.Put(rds.NewKey("Foo", "", 0, k), & Foo{}) 154
71 » » » » So(err, ShouldEqual, gae.ErrDSInvalidKey) 155 » » » » _, err := ds.Put(f)
156 » » » » So(err, ShouldEqual, datastore.ErrInvalidKey)
72 }) 157 })
73 158
74 Convey("getting objects that DNE is an error", func() { 159 Convey("getting objects that DNE is an error", func() {
75 » » » » k := rds.NewKey("Foo", "", 1, nil) 160 » » » » So(ds.Get(&Foo{ID: 1}), ShouldEqual, datastore.E rrNoSuchEntity)
76 » » » » So(rds.Get(k, nil), ShouldEqual, gae.ErrDSNoSuch Entity)
77 }) 161 })
78 162
79 Convey("Can Put stuff", func() { 163 Convey("Can Put stuff", func() {
80 // with an incomplete key! 164 // with an incomplete key!
81 k := rds.NewKey("Foo", "", 0, nil)
82 f := &Foo{Val: 10} 165 f := &Foo{Val: 10}
83 » » » » k, err := rds.Put(k, f) 166 » » » » k, err := ds.Put(f)
84 So(err, ShouldBeNil) 167 So(err, ShouldBeNil)
85 So(k.String(), ShouldEqual, "/Foo,1") 168 So(k.String(), ShouldEqual, "/Foo,1")
169 So(ds.NewKeyObj(f), ShouldResemble, k)
86 170
87 Convey("and Get it back", func() { 171 Convey("and Get it back", func() {
88 » » » » » newFoo := &Foo{} 172 » » » » » newFoo := &Foo{ID: 1}
89 » » » » » err := rds.Get(k, newFoo) 173 » » » » » err := ds.Get(newFoo)
90 So(err, ShouldBeNil) 174 So(err, ShouldBeNil)
91 So(newFoo, ShouldResemble, f) 175 So(newFoo, ShouldResemble, f)
92 176
93 Convey("and we can Delete it", func() { 177 Convey("and we can Delete it", func() {
94 » » » » » » err := rds.Delete(k) 178 » » » » » » err := ds.Delete(ds.NewKey("Foo" , "", 1, nil))
95 So(err, ShouldBeNil) 179 So(err, ShouldBeNil)
96 180
97 » » » » » » err = rds.Get(k, newFoo) 181 » » » » » » err = ds.Get(newFoo)
98 » » » » » » So(err, ShouldEqual, gae.ErrDSNo SuchEntity) 182 » » » » » » So(err, ShouldEqual, datastore.E rrNoSuchEntity)
99 }) 183 })
100 }) 184 })
101 Convey("Deleteing with a bogus key is bad", func () { 185 Convey("Deleteing with a bogus key is bad", func () {
102 » » » » » err := rds.Delete(rds.NewKey("Foo", "wat ", 100, nil)) 186 » » » » » err := ds.Delete(ds.NewKey("Foo", "wat", 100, nil))
103 » » » » » So(err, ShouldEqual, gae.ErrDSInvalidKey ) 187 » » » » » So(err, ShouldEqual, datastore.ErrInvali dKey)
104 }) 188 })
105 Convey("Deleteing a DNE entity is fine", func() { 189 Convey("Deleteing a DNE entity is fine", func() {
106 » » » » » err := rds.Delete(rds.NewKey("Foo", "wat ", 0, nil)) 190 » » » » » err := ds.Delete(ds.NewKey("Foo", "wat", 0, nil))
107 So(err, ShouldBeNil) 191 So(err, ShouldBeNil)
108 }) 192 })
109 193
110 Convey("serialization breaks in the normal ways" , func() { 194 Convey("serialization breaks in the normal ways" , func() {
111 type BadFoo struct { 195 type BadFoo struct {
112 » » » » » » Val uint8 196 » » » » » » _kind string `goon:"kind,Foo"`
197 » » » » » » ID int64 `goon:"id" datastor e:"-"`
198 » » » » » » Val uint8
113 } 199 }
114 » » » » » _, err := rds.Put(k, &BadFoo{}) 200 » » » » » _, err := ds.Put(&BadFoo{})
115 » » » » » So(err.Error(), ShouldContainSubstring, "invalid type: uint8") 201 » » » » » So(err.Error(), ShouldContainSubstring,
116 202 » » » » » » "unsupported struct field type: uint8")
117 » » » » » err = rds.Get(k, &BadFoo{}) 203
118 » » » » » So(err.Error(), ShouldContainSubstring, "invalid type: uint8") 204 » » » » » err = ds.Get(&BadFoo{ID: 1})
205 » » » » » So(err.Error(), ShouldContainSubstring,
206 » » » » » » "type mismatch: int versus uint8 ")
119 }) 207 })
120 208
121 Convey("check that metadata works", func() { 209 Convey("check that metadata works", func() {
122 » » » » » So(testGetMeta(c, k), ShouldEqual, 1) 210 » » » » » val, _ := meta.GetEntityGroupVersion(c, k)
123 211 » » » » » So(val, ShouldEqual, 1)
124 » » » » » pkey := k 212
125 for i := 0; i < 10; i++ { 213 for i := 0; i < 10; i++ {
126 » » » » » » k := rds.NewKey("Foo", "", 0, pk ey) 214 » » » » » » _, err = ds.Put(&Foo{Val: 10, Pa rent: k})
127 » » » » » » _, err = rds.Put(k, &Foo{Val: 10 })
128 So(err, ShouldBeNil) 215 So(err, ShouldBeNil)
129 } 216 }
130 » » » » » So(testGetMeta(c, k), ShouldEqual, 11) 217 » » » » » val, _ = meta.GetEntityGroupVersion(c, k )
218 » » » » » So(val, ShouldEqual, 11)
131 219
132 Convey("ensure that group versions persi st across deletes", func() { 220 Convey("ensure that group versions persi st across deletes", func() {
133 » » » » » » So(rds.Delete(k), ShouldBeNil) 221 » » » » » » So(ds.Delete(k), ShouldBeNil)
134 for i := int64(1); i < 11; i++ { 222 for i := int64(1); i < 11; i++ {
135 » » » » » » » So(rds.Delete(rds.NewKey ("Foo", "", i, k)), ShouldBeNil) 223 » » » » » » » So(ds.Delete(ds.NewKey(" Foo", "", i, k)), ShouldBeNil)
136 } 224 }
137 // TODO(riannucci): replace with a Count query instead of this cast 225 // TODO(riannucci): replace with a Count query instead of this cast
138 » » » » » » ents := rds.(*dsImpl).data.store .GetCollection("ents:") 226 » » » » » » ents := ds.(*dsImpl).data.store. GetCollection("ents:")
139 num, _ := ents.GetTotals() 227 num, _ := ents.GetTotals()
140 // /__entity_root_ids__,Foo 228 // /__entity_root_ids__,Foo
141 // /Foo,1/__entity_group__,1 229 // /Foo,1/__entity_group__,1
142 // /Foo,1/__entity_group_ids__,1 230 // /Foo,1/__entity_group_ids__,1
143 So(num, ShouldEqual, 3) 231 So(num, ShouldEqual, 3)
144 232
145 version, err := curVersion(ents, groupMetaKey(k)) 233 version, err := curVersion(ents, groupMetaKey(k))
146 So(err, ShouldBeNil) 234 So(err, ShouldBeNil)
147 So(version, ShouldEqual, 22) 235 So(version, ShouldEqual, 22)
148 236
149 » » » » » » k, err := rds.Put(k, f) 237 » » » » » » k, err := ds.Put(f)
150 So(err, ShouldBeNil) 238 So(err, ShouldBeNil)
151 » » » » » » So(testGetMeta(c, k), ShouldEqua l, 23) 239 » » » » » » val, _ := meta.GetEntityGroupVer sion(c, k)
240 » » » » » » So(val, ShouldEqual, 23)
152 }) 241 })
153 }) 242 })
154 }) 243 })
155 }) 244 })
156 245
157 Convey("implements DSTransactioner", func() { 246 Convey("implements DSTransactioner", func() {
158 type Foo struct { 247 type Foo struct {
159 » » » » Val int 248 » » » » ID int64 `goon:"id" datastore:"-"`
249 » » » » Parent *datastore.Key `goon:"parent" datastore:" -"`
250 » » » » Val int
160 } 251 }
161 Convey("Put", func() { 252 Convey("Put", func() {
162 k := rds.NewKey("Foo", "", 0, nil)
163 f := &Foo{Val: 10} 253 f := &Foo{Val: 10}
164 » » » » k, err := rds.Put(k, f) 254 » » » » k, err := ds.Put(f)
165 So(err, ShouldBeNil) 255 So(err, ShouldBeNil)
166 So(k.String(), ShouldEqual, "/Foo,1") 256 So(k.String(), ShouldEqual, "/Foo,1")
257 So(ds.NewKeyObj(f), ShouldResemble, k)
167 258
168 Convey("can Put new entity groups", func() { 259 Convey("can Put new entity groups", func() {
169 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 260 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
170 » » » » » » rds := gae.GetRDS(c) 261 » » » » » » ds := wrapper.GetDS(c)
171 » » » » » » So(rds, ShouldNotBeNil) 262 » » » » » » So(ds, ShouldNotBeNil)
172 263
173 f1 := &Foo{Val: 100} 264 f1 := &Foo{Val: 100}
174 » » » » » » k, err := rds.Put(rds.NewKey("Fo o", "", 0, nil), f1) 265 » » » » » » k, err := ds.Put(f1)
175 So(err, ShouldBeNil) 266 So(err, ShouldBeNil)
176 So(k.String(), ShouldEqual, "/Fo o,2") 267 So(k.String(), ShouldEqual, "/Fo o,2")
177 268
178 f2 := &Foo{Val: 200} 269 f2 := &Foo{Val: 200}
179 » » » » » » k, err = rds.Put(rds.NewKey("Foo ", "", 0, nil), f2) 270 » » » » » » k, err = ds.Put(f2)
180 So(err, ShouldBeNil) 271 So(err, ShouldBeNil)
181 So(k.String(), ShouldEqual, "/Fo o,3") 272 So(k.String(), ShouldEqual, "/Fo o,3")
182 273
183 return nil 274 return nil
184 » » » » » }, &gae.DSTransactionOptions{XG: true}) 275 » » » » » }, &datastore.TransactionOptions{XG: tru e})
185 So(err, ShouldBeNil) 276 So(err, ShouldBeNil)
186 277
187 » » » » » f := &Foo{} 278 » » » » » f := &Foo{ID: 2}
188 » » » » » So(rds.Get(rds.NewKey("Foo", "", 2, nil) , f), ShouldBeNil) 279 » » » » » So(ds.Get(f), ShouldBeNil)
189 So(f.Val, ShouldEqual, 100) 280 So(f.Val, ShouldEqual, 100)
190 281
191 » » » » » f = &Foo{} 282 » » » » » f = &Foo{ID: 3}
192 » » » » » So(rds.Get(rds.NewKey("Foo", "", 3, nil) , f), ShouldBeNil) 283 » » » » » So(ds.Get(f), ShouldBeNil)
193 So(f.Val, ShouldEqual, 200) 284 So(f.Val, ShouldEqual, 200)
194 }) 285 })
195 286
196 Convey("can Put new entities in a current group" , func() { 287 Convey("can Put new entities in a current group" , func() {
197 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 288 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
198 » » » » » » rds := gae.GetRDS(c) 289 » » » » » » ds := wrapper.GetDS(c)
199 » » » » » » So(rds, ShouldNotBeNil) 290 » » » » » » So(ds, ShouldNotBeNil)
200 291
201 » » » » » » par := k 292 » » » » » » f1 := &Foo{Val: 100, Parent: ds. NewKeyObj(f)}
202 293 » » » » » » k, err := ds.Put(f1)
203 » » » » » » f1 := &Foo{Val: 100}
204 » » » » » » k, err := rds.Put(rds.NewKey("Fo o", "", 0, par), f1)
205 So(err, ShouldBeNil) 294 So(err, ShouldBeNil)
206 So(k.String(), ShouldEqual, "/Fo o,1/Foo,1") 295 So(k.String(), ShouldEqual, "/Fo o,1/Foo,1")
207 296
208 » » » » » » f2 := &Foo{Val: 200} 297 » » » » » » f2 := &Foo{Val: 200, Parent: ds. NewKeyObj(f)}
209 » » » » » » k, err = rds.Put(rds.NewKey("Foo ", "", 0, par), f2) 298 » » » » » » k, err = ds.Put(f2)
210 So(err, ShouldBeNil) 299 So(err, ShouldBeNil)
211 So(k.String(), ShouldEqual, "/Fo o,1/Foo,2") 300 So(k.String(), ShouldEqual, "/Fo o,1/Foo,2")
212 301
213 return nil 302 return nil
214 }, nil) 303 }, nil)
215 So(err, ShouldBeNil) 304 So(err, ShouldBeNil)
216 305
217 » » » » » f1 := &Foo{} 306 » » » » » f1 := &Foo{ID: 1, Parent: ds.NewKeyObj(& Foo{ID: 1})}
218 » » » » » So(rds.Get(rds.NewKey("Foo", "", 1, k), f1), ShouldBeNil) 307 » » » » » So(ds.Get(f1), ShouldBeNil)
219 So(f1.Val, ShouldEqual, 100) 308 So(f1.Val, ShouldEqual, 100)
220 309
221 » » » » » f2 := &Foo{} 310 » » » » » f2 := &Foo{ID: 2, Parent: f1.Parent}
222 » » » » » So(rds.Get(rds.NewKey("Foo", "", 2, k), f2), ShouldBeNil) 311 » » » » » So(ds.Get(f2), ShouldBeNil)
223 So(f2.Val, ShouldEqual, 200) 312 So(f2.Val, ShouldEqual, 200)
224 }) 313 })
225 314
226 Convey("Deletes work too", func() { 315 Convey("Deletes work too", func() {
227 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 316 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
228 » » » » » » rds := gae.GetRDS(c) 317 » » » » » » ds := wrapper.GetDS(c)
229 » » » » » » So(rds, ShouldNotBeNil) 318 » » » » » » So(ds, ShouldNotBeNil)
230 » » » » » » So(rds.Delete(k), ShouldBeNil) 319 » » » » » » So(ds.Delete(ds.NewKeyObj(f)), S houldBeNil)
231 return nil 320 return nil
232 }, nil) 321 }, nil)
233 So(err, ShouldBeNil) 322 So(err, ShouldBeNil)
234 » » » » » So(rds.Get(k, f), ShouldEqual, gae.ErrDS NoSuchEntity) 323 » » » » » So(ds.Get(f), ShouldEqual, datastore.Err NoSuchEntity)
235 }) 324 })
236 325
237 Convey("A Get counts against your group count", func() { 326 Convey("A Get counts against your group count", func() {
238 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 327 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
239 » » » » » » rds := gae.GetRDS(c) 328 » » » » » » ds := wrapper.GetDS(c)
240 » » » » » » f := &Foo{} 329 » » » » » » f := &Foo{ID: 20}
241 » » » » » » So(rds.Get(rds.NewKey("Foo", "", 20, nil), f), ShouldEqual, gae.ErrDSNoSuchEntity) 330 » » » » » » So(ds.Get(f), ShouldEqual, datas tore.ErrNoSuchEntity)
242 331
243 » » » » » » So(rds.Get(k, f).Error(), Should ContainSubstring, "cross-group") 332 » » » » » » f.ID = 1
333 » » » » » » So(ds.Get(f).Error(), ShouldCont ainSubstring, "cross-group")
244 return nil 334 return nil
245 }, nil) 335 }, nil)
246 So(err, ShouldBeNil) 336 So(err, ShouldBeNil)
247 }) 337 })
248 338
249 Convey("Get takes a snapshot", func() { 339 Convey("Get takes a snapshot", func() {
250 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 340 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
251 » » » » » » txnDS := gae.GetRDS(c) 341 » » » » » » txnDS := wrapper.GetDS(c)
252 So(txnDS, ShouldNotBeNil) 342 So(txnDS, ShouldNotBeNil)
253 343
254 » » » » » » So(txnDS.Get(k, f), ShouldBeNil) 344 » » » » » » f := &Foo{ID: 1}
345 » » » » » » So(txnDS.Get(f), ShouldBeNil)
255 So(f.Val, ShouldEqual, 10) 346 So(f.Val, ShouldEqual, 10)
256 347
257 // Don't ever do this in a real program unless you want to guarantee 348 // Don't ever do this in a real program unless you want to guarantee
258 // a failed transaction :) 349 // a failed transaction :)
259 f.Val = 11 350 f.Val = 11
260 » » » » » » _, err := rds.Put(k, f) 351 » » » » » » _, err := ds.Put(f)
261 So(err, ShouldBeNil) 352 So(err, ShouldBeNil)
262 353
263 » » » » » » So(txnDS.Get(k, f), ShouldBeNil) 354 » » » » » » So(txnDS.Get(f), ShouldBeNil)
264 So(f.Val, ShouldEqual, 10) 355 So(f.Val, ShouldEqual, 10)
265 356
266 return nil 357 return nil
267 }, nil) 358 }, nil)
268 So(err, ShouldBeNil) 359 So(err, ShouldBeNil)
269 360
270 » » » » » f := &Foo{} 361 » » » » » f := &Foo{ID: 1}
271 » » » » » So(rds.Get(k, f), ShouldBeNil) 362 » » » » » So(ds.Get(f), ShouldBeNil)
272 So(f.Val, ShouldEqual, 11) 363 So(f.Val, ShouldEqual, 11)
364
273 }) 365 })
274 366
275 Convey("and snapshots are consistent even after Puts", func() { 367 Convey("and snapshots are consistent even after Puts", func() {
276 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 368 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
277 » » » » » » txnDS := gae.GetRDS(c) 369 » » » » » » txnDS := wrapper.GetDS(c)
278 So(txnDS, ShouldNotBeNil) 370 So(txnDS, ShouldNotBeNil)
279 371
280 » » » » » » f := &Foo{} 372 » » » » » » f := &Foo{ID: 1}
281 » » » » » » So(txnDS.Get(k, f), ShouldBeNil) 373 » » » » » » So(txnDS.Get(f), ShouldBeNil)
282 So(f.Val, ShouldEqual, 10) 374 So(f.Val, ShouldEqual, 10)
283 375
284 // Don't ever do this in a real program unless you want to guarantee 376 // Don't ever do this in a real program unless you want to guarantee
285 // a failed transaction :) 377 // a failed transaction :)
286 f.Val = 11 378 f.Val = 11
287 » » » » » » _, err := rds.Put(k, f) 379 » » » » » » _, err := ds.Put(f)
288 So(err, ShouldBeNil) 380 So(err, ShouldBeNil)
289 381
290 » » » » » » So(txnDS.Get(k, f), ShouldBeNil) 382 » » » » » » So(txnDS.Get(f), ShouldBeNil)
291 So(f.Val, ShouldEqual, 10) 383 So(f.Val, ShouldEqual, 10)
292 384
293 f.Val = 20 385 f.Val = 20
294 » » » » » » _, err = txnDS.Put(k, f) 386 » » » » » » _, err = txnDS.Put(f)
295 So(err, ShouldBeNil) 387 So(err, ShouldBeNil)
296 388
297 » » » » » » So(txnDS.Get(k, f), ShouldBeNil) 389 » » » » » » So(txnDS.Get(f), ShouldBeNil)
298 So(f.Val, ShouldEqual, 10) // st ill gets 10 390 So(f.Val, ShouldEqual, 10) // st ill gets 10
299 391
300 return nil 392 return nil
301 }, nil) 393 }, nil)
302 So(err.Error(), ShouldContainSubstring, "concurrent") 394 So(err.Error(), ShouldContainSubstring, "concurrent")
303 395
304 » » » » » f := &Foo{} 396 » » » » » f := &Foo{ID: 1}
305 » » » » » So(rds.Get(k, f), ShouldBeNil) 397 » » » » » So(ds.Get(f), ShouldBeNil)
306 So(f.Val, ShouldEqual, 11) 398 So(f.Val, ShouldEqual, 11)
307 }) 399 })
308 400
309 Convey("Reusing a transaction context is bad new s", func() { 401 Convey("Reusing a transaction context is bad new s", func() {
310 » » » » » k := rds.NewKey("Foo", "", 1, nil) 402 » » » » » txnDS := wrapper.Datastore(nil)
311 » » » » » txnDS := gae.RawDatastore(nil) 403 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
312 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 404 » » » » » » txnDS = wrapper.GetDS(c)
313 » » » » » » txnDS = gae.GetRDS(c) 405 » » » » » » So(txnDS.Get(&Foo{ID: 1}), Shoul dBeNil)
314 » » » » » » So(txnDS.Get(k, &Foo{}), ShouldB eNil)
315 return nil 406 return nil
316 }, nil) 407 }, nil)
317 So(err, ShouldBeNil) 408 So(err, ShouldBeNil)
318 » » » » » So(txnDS.Get(k, &Foo{}).Error(), ShouldC ontainSubstring, "expired") 409 » » » » » So(txnDS.Get(&Foo{ID: 1}).Error(), Shoul dContainSubstring, "expired")
319 }) 410 })
320 411
321 Convey("Nested transactions are rejected", func( ) { 412 Convey("Nested transactions are rejected", func( ) {
322 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 413 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
323 » » » » » » err := gae.GetRDS(c).RunInTransa ction(func(c context.Context) error { 414 » » » » » » err := wrapper.GetDS(c).RunInTra nsaction(func(c context.Context) error {
324 panic("noooo") 415 panic("noooo")
325 }, nil) 416 }, nil)
326 So(err.Error(), ShouldContainSub string, "nested transactions") 417 So(err.Error(), ShouldContainSub string, "nested transactions")
327 return nil 418 return nil
328 }, nil) 419 }, nil)
329 So(err, ShouldBeNil) 420 So(err, ShouldBeNil)
330 }) 421 })
331 422
332 Convey("Concurrent transactions only accept one set of changes", func() { 423 Convey("Concurrent transactions only accept one set of changes", func() {
333 // Note: I think this implementation is actually /slightly/ wrong. 424 // Note: I think this implementation is actually /slightly/ wrong.
334 // Accorting to my read of the docs for appengine, when you open a 425 // Accorting to my read of the docs for appengine, when you open a
335 // transaction it actually (essentially) holds a reference to the 426 // transaction it actually (essentially) holds a reference to the
336 // entire datastore. Our implementation takes a snapshot of the 427 // entire datastore. Our implementation takes a snapshot of the
337 // entity group as soon as something obs erves/affects it. 428 // entity group as soon as something obs erves/affects it.
338 // 429 //
339 // That said... I'm not sure if there's really a semantic difference. 430 // That said... I'm not sure if there's really a semantic difference.
340 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 431 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
341 » » » » » » txnDS := gae.GetRDS(c) 432 » » » » » » txnDS := wrapper.GetDS(c)
342 » » » » » » f := &Foo{Val: 21} 433 » » » » » » f := &Foo{ID: 1, Val: 21}
343 » » » » » » _, err = txnDS.Put(k, f) 434 » » » » » » _, err = txnDS.Put(f)
344 So(err, ShouldBeNil) 435 So(err, ShouldBeNil)
345 436
346 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 437 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
347 » » » » » » » txnDS := gae.GetRDS(c) 438 » » » » » » » txnDS := wrapper.GetDS(c )
348 » » » » » » » f := &Foo{Val: 27} 439 » » » » » » » f := &Foo{ID: 1, Val: 27 }
349 » » » » » » » _, err := txnDS.Put(k, f ) 440 » » » » » » » _, err := txnDS.Put(f)
350 So(err, ShouldBeNil) 441 So(err, ShouldBeNil)
351 return nil 442 return nil
352 }, nil) 443 }, nil)
353 So(err, ShouldBeNil) 444 So(err, ShouldBeNil)
354 445
355 return nil 446 return nil
356 }, nil) 447 }, nil)
357 So(err.Error(), ShouldContainSubstring, "concurrent") 448 So(err.Error(), ShouldContainSubstring, "concurrent")
358 449
359 » » » » » f := &Foo{} 450 » » » » » f := &Foo{ID: 1}
360 » » » » » So(rds.Get(k, f), ShouldBeNil) 451 » » » » » So(ds.Get(f), ShouldBeNil)
361 So(f.Val, ShouldEqual, 27) 452 So(f.Val, ShouldEqual, 27)
362 }) 453 })
363 454
364 Convey("XG", func() { 455 Convey("XG", func() {
365 Convey("Modifying two groups with XG=fal se is invalid", func() { 456 Convey("Modifying two groups with XG=fal se is invalid", func() {
366 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 457 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
367 » » » » » » » rds := gae.GetRDS(c) 458 » » » » » » » ds := wrapper.GetDS(c)
368 » » » » » » » f := &Foo{Val: 200} 459 » » » » » » » f := &Foo{ID: 1, Val: 20 0}
369 » » » » » » » _, err := rds.Put(k, f) 460 » » » » » » » _, err := ds.Put(f)
370 So(err, ShouldBeNil) 461 So(err, ShouldBeNil)
371 462
372 » » » » » » » _, err = rds.Put(rds.New Key("Foo", "", 2, nil), f) 463 » » » » » » » f.ID = 2
464 » » » » » » » _, err = ds.Put(f)
373 So(err.Error(), ShouldCo ntainSubstring, "cross-group") 465 So(err.Error(), ShouldCo ntainSubstring, "cross-group")
374 return err 466 return err
375 }, nil) 467 }, nil)
376 So(err.Error(), ShouldContainSub string, "cross-group") 468 So(err.Error(), ShouldContainSub string, "cross-group")
377 }) 469 })
378 470
379 Convey("Modifying >25 groups with XG=tru e is invald", func() { 471 Convey("Modifying >25 groups with XG=tru e is invald", func() {
380 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 472 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
381 » » » » » » » rds := gae.GetRDS(c) 473 » » » » » » » ds := wrapper.GetDS(c)
382 for i := int64(1); i < 2 6; i++ { 474 for i := int64(1); i < 2 6; i++ {
383 » » » » » » » » k := rds.NewKey( "Foo", "", i, nil) 475 » » » » » » » » f := &Foo{ID: i, Val: 200}
384 » » » » » » » » f := &Foo{Val: 2 00} 476 » » » » » » » » _, err := ds.Put (f)
385 » » » » » » » » _, err := rds.Pu t(k, f)
386 So(err, ShouldBe Nil) 477 So(err, ShouldBe Nil)
387 } 478 }
388 » » » » » » » f := &Foo{Val: 200} 479 » » » » » » » f := &Foo{ID: 27, Val: 2 00}
389 » » » » » » » _, err := rds.Put(rds.Ne wKey("Foo", "", 27, nil), f) 480 » » » » » » » _, err := ds.Put(f)
390 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups") 481 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups")
391 return err 482 return err
392 » » » » » » }, &gae.DSTransactionOptions{XG: true}) 483 » » » » » » }, &datastore.TransactionOptions {XG: true})
393 So(err.Error(), ShouldContainSub string, "too many entity groups") 484 So(err.Error(), ShouldContainSub string, "too many entity groups")
394 }) 485 })
395 }) 486 })
396 487
397 Convey("Errors and panics", func() { 488 Convey("Errors and panics", func() {
398 Convey("returning an error aborts", func () { 489 Convey("returning an error aborts", func () {
399 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 490 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
400 » » » » » » » rds := gae.GetRDS(c) 491 » » » » » » » ds := wrapper.GetDS(c)
401 » » » » » » » f := &Foo{Val: 200} 492 » » » » » » » f := &Foo{ID: 1, Val: 20 0}
402 » » » » » » » _, err := rds.Put(k, f) 493 » » » » » » » _, err := ds.Put(f)
403 So(err, ShouldBeNil) 494 So(err, ShouldBeNil)
404 495
405 return fmt.Errorf("thing y") 496 return fmt.Errorf("thing y")
406 }, nil) 497 }, nil)
407 So(err.Error(), ShouldEqual, "th ingy") 498 So(err.Error(), ShouldEqual, "th ingy")
408 499
409 » » » » » » f := &Foo{} 500 » » » » » » f := &Foo{ID: 1}
410 » » » » » » So(rds.Get(k, f), ShouldBeNil) 501 » » » » » » So(ds.Get(f), ShouldBeNil)
411 So(f.Val, ShouldEqual, 10) 502 So(f.Val, ShouldEqual, 10)
412 }) 503 })
413 504
414 Convey("panicing aborts", func() { 505 Convey("panicing aborts", func() {
415 So(func() { 506 So(func() {
416 » » » » » » » rds.RunInTransaction(fun c(c context.Context) error { 507 » » » » » » » ds.RunInTransaction(func (c context.Context) error {
417 » » » » » » » » rds := gae.GetRD S(c) 508 » » » » » » » » ds := wrapper.Ge tDS(c)
418 » » » » » » » » f := &Foo{Val: 2 00} 509 » » » » » » » » f := &Foo{ID: 1, Val: 200}
419 » » » » » » » » _, err := rds.Pu t(k, f) 510 » » » » » » » » _, err := ds.Put (f)
420 So(err, ShouldBe Nil) 511 So(err, ShouldBe Nil)
421 panic("wheeeeee" ) 512 panic("wheeeeee" )
422 }, nil) 513 }, nil)
423 }, ShouldPanic) 514 }, ShouldPanic)
424 515
425 » » » » » » f := &Foo{} 516 » » » » » » f := &Foo{ID: 1}
426 » » » » » » So(rds.Get(k, f), ShouldBeNil) 517 » » » » » » So(ds.Get(f), ShouldBeNil)
427 So(f.Val, ShouldEqual, 10) 518 So(f.Val, ShouldEqual, 10)
428 }) 519 })
429 }) 520 })
430 }) 521 })
431 }) 522 })
432 523
433 }) 524 })
434 } 525 }
435 526
436 const MaxUint = ^uint(0) 527 const MaxUint = ^uint(0)
437 const MaxInt = int(MaxUint >> 1) 528 const MaxInt = int(MaxUint >> 1)
438 const IntIs32Bits = int64(MaxInt) < math.MaxInt64 529 const IntIs32Bits = int64(MaxInt) < math.MaxInt64
439 530
440 func TestDatastoreQueryer(t *testing.T) { 531 func TestDatastoreQueryer(t *testing.T) {
441 Convey("Datastore Query suport", t, func() { 532 Convey("Datastore Query suport", t, func() {
442 c := Use(context.Background()) 533 c := Use(context.Background())
443 » » rds := gae.GetRDS(c) 534 » » ds := wrapper.GetDS(c)
444 » » So(rds, ShouldNotBeNil) 535 » » So(ds, ShouldNotBeNil)
445 536
446 Convey("can create good queries", func() { 537 Convey("can create good queries", func() {
447 » » » q := rds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) 538 » » » q := ds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39)
448 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab s")) 539 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab s"))
449 So(q, ShouldNotBeNil) 540 So(q, ShouldNotBeNil)
450 So(q.(*queryImpl).err, ShouldBeNil) 541 So(q.(*queryImpl).err, ShouldBeNil)
451 qi := q.(*queryImpl).checkCorrectness("", false) 542 qi := q.(*queryImpl).checkCorrectness("", false)
452 So(qi.err, ShouldBeNil) 543 So(qi.err, ShouldBeNil)
453 }) 544 })
454 545
455 Convey("normalize ensures orders make sense", func() { 546 Convey("normalize ensures orders make sense", func() {
456 » » » q := rds.NewQuery("Cool") 547 » » » q := ds.NewQuery("Cool")
457 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob ").Order("bob") 548 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob ").Order("bob")
458 549
459 Convey("removes dups and equality orders", func() { 550 Convey("removes dups and equality orders", func() {
460 q = q.Order("wat") 551 q = q.Order("wat")
461 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 552 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
462 So(qi.err, ShouldBeNil) 553 So(qi.err, ShouldBeNil)
463 So(qi.order, ShouldResemble, []queryOrder{{"wat" , qASC}}) 554 So(qi.order, ShouldResemble, []queryOrder{{"wat" , qASC}})
464 }) 555 })
465 556
466 Convey("keeps inequality orders", func() { 557 Convey("keeps inequality orders", func() {
467 q = q.Order("wat") 558 q = q.Order("wat")
468 q := q.Filter("bob >", 10).Filter("wat <", 29) 559 q := q.Filter("bob >", 10).Filter("wat <", 29)
469 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 560 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
470 So(qi.order, ShouldResemble, []queryOrder{{"bob" , qASC}, {"wat", qASC}}) 561 So(qi.order, ShouldResemble, []queryOrder{{"bob" , qASC}, {"wat", qASC}})
471 So(qi.err.Error(), ShouldContainSubstring, "Only one inequality") 562 So(qi.err.Error(), ShouldContainSubstring, "Only one inequality")
472 }) 563 })
473 564
474 Convey("if we equality-filter on __key__, order is ditch ed", func() { 565 Convey("if we equality-filter on __key__, order is ditch ed", func() {
475 q = q.Order("wat") 566 q = q.Order("wat")
476 » » » » q := q.Filter("__key__ =", rds.NewKey("Foo", "wa t", 0, nil)) 567 » » » » q := q.Filter("__key__ =", ds.NewKey("Foo", "wat ", 0, nil))
477 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 568 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
478 So(qi.order, ShouldResemble, []queryOrder(nil)) 569 So(qi.order, ShouldResemble, []queryOrder(nil))
479 So(qi.err, ShouldBeNil) 570 So(qi.err, ShouldBeNil)
480 }) 571 })
481 572
482 Convey("if we order by key and something else, key domin ates", func() { 573 Convey("if we order by key and something else, key domin ates", func() {
483 q := q.Order("__key__").Order("wat") 574 q := q.Order("__key__").Order("wat")
484 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 575 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
485 So(qi.order, ShouldResemble, []queryOrder{{"__ke y__", qASC}}) 576 So(qi.order, ShouldResemble, []queryOrder{{"__ke y__", qASC}})
486 So(qi.err, ShouldBeNil) 577 So(qi.err, ShouldBeNil)
487 }) 578 })
488 }) 579 })
489 580
490 Convey("can create bad queries", func() { 581 Convey("can create bad queries", func() {
491 » » » q := rds.NewQuery("Foo") 582 » » » q := ds.NewQuery("Foo")
492 583
493 Convey("bad filter ops", func() { 584 Convey("bad filter ops", func() {
494 q := q.Filter("Bob !", "value") 585 q := q.Filter("Bob !", "value")
495 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid operator \"!\"") 586 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid operator \"!\"")
496 }) 587 })
497 Convey("bad filter", func() { 588 Convey("bad filter", func() {
498 q := q.Filter("Bob", "value") 589 q := q.Filter("Bob", "value")
499 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid filter") 590 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid filter")
500 }) 591 })
501 Convey("bad order", func() { 592 Convey("bad order", func() {
(...skipping 20 matching lines...) Expand all
522 if !IntIs32Bits { 613 if !IntIs32Bits {
523 q := q.Offset(MaxInt) 614 q := q.Offset(MaxInt)
524 So(q.(*queryImpl).err.Error(), ShouldCon tainSubstring, "query offset overflow") 615 So(q.(*queryImpl).err.Error(), ShouldCon tainSubstring, "query offset overflow")
525 } 616 }
526 }) 617 })
527 Convey("Bad cursors", func() { 618 Convey("Bad cursors", func() {
528 q := q.Start(queryCursor("")).End(queryCursor("" )) 619 q := q.Start(queryCursor("")).End(queryCursor("" ))
529 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid cursor") 620 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid cursor")
530 }) 621 })
531 Convey("Bad ancestors", func() { 622 Convey("Bad ancestors", func() {
532 » » » » q := q.Ancestor(rds.NewKey("Goop", "wat", 10, ni l)) 623 » » » » q := q.Ancestor(ds.NewKey("Goop", "wat", 10, nil ))
533 So(q, ShouldNotBeNil) 624 So(q, ShouldNotBeNil)
534 qi := q.(*queryImpl).checkCorrectness("", false) 625 qi := q.(*queryImpl).checkCorrectness("", false)
535 » » » » So(qi.err, ShouldEqual, gae.ErrDSInvalidKey) 626 » » » » So(qi.err, ShouldEqual, datastore.ErrInvalidKey)
536 }) 627 })
537 Convey("nil ancestors", func() { 628 Convey("nil ancestors", func() {
538 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn ess("", false) 629 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn ess("", false)
539 So(qi.err.Error(), ShouldContainSubstring, "nil query ancestor") 630 So(qi.err.Error(), ShouldContainSubstring, "nil query ancestor")
540 }) 631 })
541 Convey("Bad key filters", func() { 632 Convey("Bad key filters", func() {
542 » » » » q := q.Filter("__key__ =", rds.NewKey("Goop", "w at", 10, nil)) 633 » » » » q := q.Filter("__key__ =", ds.NewKey("Goop", "wa t", 10, nil))
543 qi := q.(*queryImpl).checkCorrectness("", false) 634 qi := q.(*queryImpl).checkCorrectness("", false)
544 » » » » So(qi.err, ShouldEqual, gae.ErrDSInvalidKey) 635 » » » » So(qi.err, ShouldEqual, datastore.ErrInvalidKey)
545 }) 636 })
546 Convey("non-ancestor queries in a transaction", func() { 637 Convey("non-ancestor queries in a transaction", func() {
547 qi := q.(*queryImpl).checkCorrectness("", true) 638 qi := q.(*queryImpl).checkCorrectness("", true)
548 So(qi.err.Error(), ShouldContainSubstring, "Only ancestor queries") 639 So(qi.err.Error(), ShouldContainSubstring, "Only ancestor queries")
549 }) 640 })
550 Convey("absurd numbers of filters are prohibited", func( ) { 641 Convey("absurd numbers of filters are prohibited", func( ) {
551 » » » » q := q.Ancestor(rds.NewKey("thing", "wat", 0, ni l)) 642 » » » » q := q.Ancestor(ds.NewKey("thing", "wat", 0, nil ))
552 for i := 0; i < 100; i++ { 643 for i := 0; i < 100; i++ {
553 q = q.Filter("something =", 10) 644 q = q.Filter("something =", 10)
554 } 645 }
555 qi := q.(*queryImpl).checkCorrectness("", false) 646 qi := q.(*queryImpl).checkCorrectness("", false)
556 So(qi.err.Error(), ShouldContainSubstring, "quer y is too large") 647 So(qi.err.Error(), ShouldContainSubstring, "quer y is too large")
557 }) 648 })
558 Convey("filters for __key__ that aren't keys", func() { 649 Convey("filters for __key__ that aren't keys", func() {
559 q := q.Filter("__key__ = ", 10) 650 q := q.Filter("__key__ = ", 10)
560 qi := q.(*queryImpl).checkCorrectness("", false) 651 qi := q.(*queryImpl).checkCorrectness("", false)
561 So(qi.err.Error(), ShouldContainSubstring, "must be a Key") 652 So(qi.err.Error(), ShouldContainSubstring, "must be a Key")
562 }) 653 })
563 Convey("multiple inequalities", func() { 654 Convey("multiple inequalities", func() {
564 q := q.Filter("bob > ", 19).Filter("charlie < ", 20) 655 q := q.Filter("bob > ", 19).Filter("charlie < ", 20)
565 qi := q.(*queryImpl).checkCorrectness("", false) 656 qi := q.(*queryImpl).checkCorrectness("", false)
566 So(qi.err.Error(), ShouldContainSubstring, "one inequality filter") 657 So(qi.err.Error(), ShouldContainSubstring, "one inequality filter")
567 }) 658 })
568 Convey("bad sort orders", func() { 659 Convey("bad sort orders", func() {
569 q := q.Filter("bob > ", 19).Order("-charlie") 660 q := q.Filter("bob > ", 19).Order("-charlie")
570 qi := q.(*queryImpl).checkCorrectness("", false) 661 qi := q.(*queryImpl).checkCorrectness("", false)
571 So(qi.err.Error(), ShouldContainSubstring, "firs t sort property") 662 So(qi.err.Error(), ShouldContainSubstring, "firs t sort property")
572 }) 663 })
573 Convey("kindless with non-__key__ filters", func() { 664 Convey("kindless with non-__key__ filters", func() {
574 » » » » q := rds.NewQuery("").Filter("face <", 25.3) 665 » » » » q := ds.NewQuery("").Filter("face <", 25.3)
575 qi := q.(*queryImpl).checkCorrectness("", false) 666 qi := q.(*queryImpl).checkCorrectness("", false)
576 So(qi.err.Error(), ShouldContainSubstring, "kind is required for non-__key__") 667 So(qi.err.Error(), ShouldContainSubstring, "kind is required for non-__key__")
577 }) 668 })
578 Convey("kindless with non-__key__ orders", func() { 669 Convey("kindless with non-__key__ orders", func() {
579 » » » » q := rds.NewQuery("").Order("face") 670 » » » » q := ds.NewQuery("").Order("face")
580 qi := q.(*queryImpl).checkCorrectness("", false) 671 qi := q.(*queryImpl).checkCorrectness("", false)
581 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders") 672 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders")
582 }) 673 })
583 Convey("kindless with decending-__key__ orders", func() { 674 Convey("kindless with decending-__key__ orders", func() {
584 » » » » q := rds.NewQuery("").Order("-__key__") 675 » » » » q := ds.NewQuery("").Order("-__key__")
585 qi := q.(*queryImpl).checkCorrectness("", false) 676 qi := q.(*queryImpl).checkCorrectness("", false)
586 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders") 677 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders")
587 }) 678 })
588 }) 679 })
589 680
590 }) 681 })
591 } 682 }
OLDNEW
« no previous file with comments | « go/src/infra/gae/libs/wrapper/memory/datastore_query.go ('k') | go/src/infra/gae/libs/wrapper/memory/doc.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698