OLD | NEW |
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" |
11 | 11 |
12 » rdsS "github.com/luci/gae/service/rawdatastore" | 12 » dsS "github.com/luci/gae/service/datastore" |
13 . "github.com/smartystreets/goconvey/convey" | 13 . "github.com/smartystreets/goconvey/convey" |
14 "golang.org/x/net/context" | 14 "golang.org/x/net/context" |
15 ) | 15 ) |
16 | 16 |
17 func TestDatastoreKinder(t *testing.T) { | 17 func TestDatastoreKinder(t *testing.T) { |
18 t.Parallel() | 18 t.Parallel() |
19 | 19 |
20 Convey("Datastore keys", t, func() { | 20 Convey("Datastore keys", t, func() { |
21 c := Use(context.Background()) | 21 c := Use(context.Background()) |
22 » » rds := rdsS.Get(c) | 22 » » ds := dsS.Get(c) |
23 » » So(rds, ShouldNotBeNil) | 23 » » So(ds, ShouldNotBeNil) |
24 | 24 |
25 Convey("implements DSNewKeyer", func() { | 25 Convey("implements DSNewKeyer", func() { |
26 Convey("NewKey", func() { | 26 Convey("NewKey", func() { |
27 » » » » key := rds.NewKey("nerd", "stringID", 0, nil) | 27 » » » » key := ds.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(dsS.KeyIncomplete(key), ShouldBeFalse) |
37 » » » » So(rdsS.KeyValid(key, false, "dev~app", ""), Sho
uldBeTrue) | 37 » » » » So(dsS.KeyValid(key, false, "dev~app", ""), Shou
ldBeTrue) |
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 dsS.Key) int64 { |
45 » rds := rdsS.Get(c) | 45 » ds := dsS.Get(c) |
46 retval := int64(0) | 46 retval := int64(0) |
47 » err := rds.GetMulti([]rdsS.Key{rds.NewKey("__entity_group__", "", 1, rds
S.KeyRoot(k))}, func(val rdsS.PropertyMap, err error) { | 47 » err := ds.GetMulti([]dsS.Key{ds.NewKey("__entity_group__", "", 1, dsS.Ke
yRoot(k))}, func(val dsS.PropertyMap, err error) { |
48 if err != nil { | 48 if err != nil { |
49 panic(err) | 49 panic(err) |
50 } | 50 } |
51 retval = val["__version__"][0].Value().(int64) | 51 retval = val["__version__"][0].Value().(int64) |
52 }) | 52 }) |
53 if err != nil { | 53 if err != nil { |
54 panic(err) | 54 panic(err) |
55 } | 55 } |
56 return retval | 56 return retval |
57 } | 57 } |
58 | 58 |
59 var pls = rdsS.GetPLS | 59 var pls = dsS.GetPLS |
60 | 60 |
61 func TestDatastoreSingleReadWriter(t *testing.T) { | 61 func TestDatastoreSingleReadWriter(t *testing.T) { |
62 t.Parallel() | 62 t.Parallel() |
63 | 63 |
64 » getOnePM := func(rds rdsS.Interface, key rdsS.Key) (pmap rdsS.PropertyMa
p, err error) { | 64 » getOnePM := func(ds dsS.Interface, key dsS.Key) (pmap dsS.PropertyMap, e
rr error) { |
65 » » blankErr := rds.GetMulti([]rdsS.Key{key}, func(itmPmap rdsS.Prop
ertyMap, itmErr error) { | 65 » » blankErr := ds.GetMulti([]dsS.Key{key}, func(itmPmap dsS.Propert
yMap, itmErr error) { |
66 pmap = itmPmap | 66 pmap = itmPmap |
67 err = itmErr | 67 err = itmErr |
68 }) | 68 }) |
69 So(blankErr, ShouldBeNil) | 69 So(blankErr, ShouldBeNil) |
70 return | 70 return |
71 } | 71 } |
72 | 72 |
73 » delOneErr := func(rds rdsS.Interface, key rdsS.Key) (err error) { | 73 » delOneErr := func(ds dsS.Interface, key dsS.Key) (err error) { |
74 » » blankErr := rds.DeleteMulti([]rdsS.Key{key}, func(itmErr error)
{ | 74 » » blankErr := ds.DeleteMulti([]dsS.Key{key}, func(itmErr error) { |
75 err = itmErr | 75 err = itmErr |
76 }) | 76 }) |
77 So(blankErr, ShouldBeNil) | 77 So(blankErr, ShouldBeNil) |
78 return | 78 return |
79 } | 79 } |
80 | 80 |
81 » delOne := func(rds rdsS.Interface, key rdsS.Key) { | 81 » delOne := func(ds dsS.Interface, key dsS.Key) { |
82 » » So(delOneErr(rds, key), ShouldBeNil) | 82 » » So(delOneErr(ds, key), ShouldBeNil) |
83 } | 83 } |
84 | 84 |
85 » getOne := func(rds rdsS.Interface, key rdsS.Key, dst interface{}) { | 85 » getOne := func(ds dsS.Interface, key dsS.Key, dst interface{}) { |
86 » » pm, err := getOnePM(rds, key) | 86 » » pm, err := getOnePM(ds, key) |
87 So(err, ShouldBeNil) | 87 So(err, ShouldBeNil) |
88 So(pls(dst).Load(pm), ShouldBeNil) | 88 So(pls(dst).Load(pm), ShouldBeNil) |
89 } | 89 } |
90 | 90 |
91 » putOneErr := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (re
tKey rdsS.Key, err error) { | 91 » putOneErr := func(ds dsS.Interface, key dsS.Key, val interface{}) (retKe
y dsS.Key, err error) { |
92 » » blankErr := rds.PutMulti([]rdsS.Key{key}, []rdsS.PropertyLoadSav
er{pls(val)}, func(itmKey rdsS.Key, itmErr error) { | 92 » » blankErr := ds.PutMulti([]dsS.Key{key}, []dsS.PropertyLoadSaver{
pls(val)}, func(itmKey dsS.Key, itmErr error) { |
93 err = itmErr | 93 err = itmErr |
94 retKey = itmKey | 94 retKey = itmKey |
95 }) | 95 }) |
96 So(blankErr, ShouldBeNil) | 96 So(blankErr, ShouldBeNil) |
97 return | 97 return |
98 } | 98 } |
99 | 99 |
100 » putOne := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKe
y rdsS.Key) { | 100 » putOne := func(ds dsS.Interface, key dsS.Key, val interface{}) (retKey d
sS.Key) { |
101 » » key, err := putOneErr(rds, key, val) | 101 » » key, err := putOneErr(ds, key, val) |
102 So(err, ShouldBeNil) | 102 So(err, ShouldBeNil) |
103 return key | 103 return key |
104 } | 104 } |
105 | 105 |
106 Convey("Datastore single reads and writes", t, func() { | 106 Convey("Datastore single reads and writes", t, func() { |
107 c := Use(context.Background()) | 107 c := Use(context.Background()) |
108 » » rds := rdsS.Get(c) | 108 » » ds := dsS.Get(c) |
109 » » So(rds, ShouldNotBeNil) | 109 » » So(ds, ShouldNotBeNil) |
110 | 110 |
111 Convey("implements DSSingleReadWriter", func() { | 111 Convey("implements DSSingleReadWriter", func() { |
112 type Foo struct { | 112 type Foo struct { |
113 Val int | 113 Val int |
114 } | 114 } |
115 | 115 |
116 Convey("getting objects that DNE is an error", func() { | 116 Convey("getting objects that DNE is an error", func() { |
117 » » » » _, err := getOnePM(rds, rds.NewKey("Foo", "", 1,
nil)) | 117 » » » » _, err := getOnePM(ds, ds.NewKey("Foo", "", 1, n
il)) |
118 » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntity) | 118 » » » » So(err, ShouldEqual, dsS.ErrNoSuchEntity) |
119 }) | 119 }) |
120 | 120 |
121 Convey("Can Put stuff", func() { | 121 Convey("Can Put stuff", func() { |
122 // with an incomplete key! | 122 // with an incomplete key! |
123 » » » » k := rds.NewKey("Foo", "", 0, nil) | 123 » » » » k := ds.NewKey("Foo", "", 0, nil) |
124 f := &Foo{Val: 10} | 124 f := &Foo{Val: 10} |
125 » » » » k = putOne(rds, k, f) | 125 » » » » k = putOne(ds, k, f) |
126 So(k.String(), ShouldEqual, "/Foo,1") | 126 So(k.String(), ShouldEqual, "/Foo,1") |
127 | 127 |
128 Convey("and Get it back", func() { | 128 Convey("and Get it back", func() { |
129 newFoo := &Foo{} | 129 newFoo := &Foo{} |
130 » » » » » getOne(rds, k, newFoo) | 130 » » » » » getOne(ds, k, newFoo) |
131 So(newFoo, ShouldResemble, f) | 131 So(newFoo, ShouldResemble, f) |
132 | 132 |
133 Convey("and we can Delete it", func() { | 133 Convey("and we can Delete it", func() { |
134 » » » » » » delOne(rds, k) | 134 » » » » » » delOne(ds, k) |
135 » » » » » » _, err := getOnePM(rds, k) | 135 » » » » » » _, err := getOnePM(ds, k) |
136 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS
uchEntity) | 136 » » » » » » So(err, ShouldEqual, dsS.ErrNoSu
chEntity) |
137 }) | 137 }) |
138 }) | 138 }) |
139 Convey("Deleteing with a bogus key is bad", func
() { | 139 Convey("Deleteing with a bogus key is bad", func
() { |
140 » » » » » So(delOneErr(rds, rds.NewKey("Foo", "wat
", 100, nil)), ShouldEqual, rdsS.ErrInvalidKey) | 140 » » » » » So(delOneErr(ds, ds.NewKey("Foo", "wat",
100, nil)), ShouldEqual, dsS.ErrInvalidKey) |
141 }) | 141 }) |
142 Convey("Deleteing a DNE entity is fine", func()
{ | 142 Convey("Deleteing a DNE entity is fine", func()
{ |
143 » » » » » delOne(rds, rds.NewKey("Foo", "wat", 0,
nil)) | 143 » » » » » delOne(ds, ds.NewKey("Foo", "wat", 0, ni
l)) |
144 }) | 144 }) |
145 | 145 |
146 Convey("with multiple puts", func() { | 146 Convey("with multiple puts", func() { |
147 So(testGetMeta(c, k), ShouldEqual, 1) | 147 So(testGetMeta(c, k), ShouldEqual, 1) |
148 | 148 |
149 » » » » » keys := []rdsS.Key{} | 149 » » » » » keys := []dsS.Key{} |
150 » » » » » vals := []rdsS.PropertyLoadSaver{} | 150 » » » » » vals := []dsS.PropertyLoadSaver{} |
151 | 151 |
152 pkey := k | 152 pkey := k |
153 for i := 0; i < 10; i++ { | 153 for i := 0; i < 10; i++ { |
154 » » » » » » keys = append(keys, rds.NewKey("
Foo", "", 0, pkey)) | 154 » » » » » » keys = append(keys, ds.NewKey("F
oo", "", 0, pkey)) |
155 vals = append(vals, pls(&Foo{Val
: 10})) | 155 vals = append(vals, pls(&Foo{Val
: 10})) |
156 } | 156 } |
157 i := 0 | 157 i := 0 |
158 » » » » » err := rds.PutMulti(keys, vals, func(k r
dsS.Key, err error) { | 158 » » » » » err := ds.PutMulti(keys, vals, func(k ds
S.Key, err error) { |
159 So(err, ShouldBeNil) | 159 So(err, ShouldBeNil) |
160 keys[i] = k | 160 keys[i] = k |
161 i++ | 161 i++ |
162 }) | 162 }) |
163 So(err, ShouldBeNil) | 163 So(err, ShouldBeNil) |
164 So(testGetMeta(c, k), ShouldEqual, 11) | 164 So(testGetMeta(c, k), ShouldEqual, 11) |
165 | 165 |
166 Convey("ensure that group versions persi
st across deletes", func() { | 166 Convey("ensure that group versions persi
st across deletes", func() { |
167 keys = append(keys, pkey) | 167 keys = append(keys, pkey) |
168 » » » » » » err := rds.DeleteMulti(keys, fun
c(err error) { | 168 » » » » » » err := ds.DeleteMulti(keys, func
(err error) { |
169 So(err, ShouldBeNil) | 169 So(err, ShouldBeNil) |
170 }) | 170 }) |
171 So(err, ShouldBeNil) | 171 So(err, ShouldBeNil) |
172 | 172 |
173 // TODO(riannucci): replace with
a Count query instead of this cast | 173 // TODO(riannucci): replace with
a Count query instead of this cast |
174 /* | 174 /* |
175 » » » » » » » ents := rds.(*dsImpl).da
ta.store.GetCollection("ents:") | 175 » » » » » » » ents := ds.(*dsImpl).dat
a.store.GetCollection("ents:") |
176 num, _ := ents.GetTotals
() | 176 num, _ := ents.GetTotals
() |
177 // /__entity_root_ids__,
Foo | 177 // /__entity_root_ids__,
Foo |
178 // /Foo,1/__entity_group
__,1 | 178 // /Foo,1/__entity_group
__,1 |
179 // /Foo,1/__entity_group
_ids__,1 | 179 // /Foo,1/__entity_group
_ids__,1 |
180 So(num, ShouldEqual, 3) | 180 So(num, ShouldEqual, 3) |
181 */ | 181 */ |
182 | 182 |
183 So(testGetMeta(c, k), ShouldEqua
l, 22) | 183 So(testGetMeta(c, k), ShouldEqua
l, 22) |
184 | 184 |
185 » » » » » » putOne(rds, k, f) | 185 » » » » » » putOne(ds, k, f) |
186 So(testGetMeta(c, k), ShouldEqua
l, 23) | 186 So(testGetMeta(c, k), ShouldEqua
l, 23) |
187 }) | 187 }) |
188 | 188 |
189 Convey("can Get", func() { | 189 Convey("can Get", func() { |
190 » » » » » » vals := []rdsS.PropertyMap{} | 190 » » » » » » vals := []dsS.PropertyMap{} |
191 » » » » » » err := rds.GetMulti(keys, func(p
m rdsS.PropertyMap, err error) { | 191 » » » » » » err := ds.GetMulti(keys, func(pm
dsS.PropertyMap, err error) { |
192 So(err, ShouldBeNil) | 192 So(err, ShouldBeNil) |
193 vals = append(vals, pm) | 193 vals = append(vals, pm) |
194 }) | 194 }) |
195 So(err, ShouldBeNil) | 195 So(err, ShouldBeNil) |
196 | 196 |
197 for _, val := range vals { | 197 for _, val := range vals { |
198 » » » » » » » So(val, ShouldResemble,
rdsS.PropertyMap{"Val": {rdsS.MkProperty(10)}}) | 198 » » » » » » » So(val, ShouldResemble,
dsS.PropertyMap{"Val": {dsS.MkProperty(10)}}) |
199 } | 199 } |
200 }) | 200 }) |
201 }) | 201 }) |
202 }) | 202 }) |
203 }) | 203 }) |
204 | 204 |
205 Convey("implements DSTransactioner", func() { | 205 Convey("implements DSTransactioner", func() { |
206 type Foo struct { | 206 type Foo struct { |
207 Val int | 207 Val int |
208 } | 208 } |
209 Convey("Put", func() { | 209 Convey("Put", func() { |
210 f := &Foo{Val: 10} | 210 f := &Foo{Val: 10} |
211 » » » » origKey := rds.NewKey("Foo", "", 0, nil) | 211 » » » » origKey := ds.NewKey("Foo", "", 0, nil) |
212 » » » » k := putOne(rds, origKey, f) | 212 » » » » k := putOne(ds, origKey, f) |
213 So(k.String(), ShouldEqual, "/Foo,1") | 213 So(k.String(), ShouldEqual, "/Foo,1") |
214 | 214 |
215 Convey("can Put new entity groups", func() { | 215 Convey("can Put new entity groups", func() { |
216 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 216 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
217 » » » » » » rds := rdsS.Get(c) | 217 » » » » » » ds := dsS.Get(c) |
218 | 218 |
219 f1 := &Foo{Val: 100} | 219 f1 := &Foo{Val: 100} |
220 » » » » » » k := putOne(rds, origKey, f1) | 220 » » » » » » k := putOne(ds, origKey, f1) |
221 So(k.String(), ShouldEqual, "/Fo
o,2") | 221 So(k.String(), ShouldEqual, "/Fo
o,2") |
222 | 222 |
223 f2 := &Foo{Val: 200} | 223 f2 := &Foo{Val: 200} |
224 » » » » » » k = putOne(rds, origKey, f2) | 224 » » » » » » k = putOne(ds, origKey, f2) |
225 So(k.String(), ShouldEqual, "/Fo
o,3") | 225 So(k.String(), ShouldEqual, "/Fo
o,3") |
226 | 226 |
227 return nil | 227 return nil |
228 » » » » » }, &rdsS.TransactionOptions{XG: true}) | 228 » » » » » }, &dsS.TransactionOptions{XG: true}) |
229 So(err, ShouldBeNil) | 229 So(err, ShouldBeNil) |
230 | 230 |
231 f := &Foo{} | 231 f := &Foo{} |
232 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, nil
), f) | 232 » » » » » getOne(ds, ds.NewKey("Foo", "", 2, nil),
f) |
233 So(f.Val, ShouldEqual, 100) | 233 So(f.Val, ShouldEqual, 100) |
234 | 234 |
235 » » » » » getOne(rds, rds.NewKey("Foo", "", 3, nil
), f) | 235 » » » » » getOne(ds, ds.NewKey("Foo", "", 3, nil),
f) |
236 So(f.Val, ShouldEqual, 200) | 236 So(f.Val, ShouldEqual, 200) |
237 }) | 237 }) |
238 | 238 |
239 Convey("can Put new entities in a current group"
, func() { | 239 Convey("can Put new entities in a current group"
, func() { |
240 par := k | 240 par := k |
241 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 241 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
242 » » » » » » rds := rdsS.Get(c) | 242 » » » » » » ds := dsS.Get(c) |
243 » » » » » » So(rds, ShouldNotBeNil) | 243 » » » » » » So(ds, ShouldNotBeNil) |
244 | 244 |
245 f1 := &Foo{Val: 100} | 245 f1 := &Foo{Val: 100} |
246 » » » » » » k := putOne(rds, rds.NewKey("Foo
", "", 0, par), f1) | 246 » » » » » » k := putOne(ds, ds.NewKey("Foo",
"", 0, par), f1) |
247 So(k.String(), ShouldEqual, "/Fo
o,1/Foo,1") | 247 So(k.String(), ShouldEqual, "/Fo
o,1/Foo,1") |
248 | 248 |
249 f2 := &Foo{Val: 200} | 249 f2 := &Foo{Val: 200} |
250 » » » » » » k = putOne(rds, rds.NewKey("Foo"
, "", 0, par), f2) | 250 » » » » » » k = putOne(ds, ds.NewKey("Foo",
"", 0, par), f2) |
251 So(k.String(), ShouldEqual, "/Fo
o,1/Foo,2") | 251 So(k.String(), ShouldEqual, "/Fo
o,1/Foo,2") |
252 | 252 |
253 return nil | 253 return nil |
254 }, nil) | 254 }, nil) |
255 So(err, ShouldBeNil) | 255 So(err, ShouldBeNil) |
256 | 256 |
257 f := &Foo{} | 257 f := &Foo{} |
258 » » » » » getOne(rds, rds.NewKey("Foo", "", 1, k),
f) | 258 » » » » » getOne(ds, ds.NewKey("Foo", "", 1, k), f
) |
259 So(f.Val, ShouldEqual, 100) | 259 So(f.Val, ShouldEqual, 100) |
260 | 260 |
261 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, k),
f) | 261 » » » » » getOne(ds, ds.NewKey("Foo", "", 2, k), f
) |
262 So(f.Val, ShouldEqual, 200) | 262 So(f.Val, ShouldEqual, 200) |
263 }) | 263 }) |
264 | 264 |
265 Convey("Deletes work too", func() { | 265 Convey("Deletes work too", func() { |
266 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 266 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
267 » » » » » » rds := rdsS.Get(c) | 267 » » » » » » ds := dsS.Get(c) |
268 » » » » » » So(rds, ShouldNotBeNil) | 268 » » » » » » So(ds, ShouldNotBeNil) |
269 » » » » » » delOne(rds, k) | 269 » » » » » » delOne(ds, k) |
270 return nil | 270 return nil |
271 }, nil) | 271 }, nil) |
272 So(err, ShouldBeNil) | 272 So(err, ShouldBeNil) |
273 » » » » » _, err = getOnePM(rds, k) | 273 » » » » » _, err = getOnePM(ds, k) |
274 » » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntit
y) | 274 » » » » » So(err, ShouldEqual, dsS.ErrNoSuchEntity
) |
275 }) | 275 }) |
276 | 276 |
277 Convey("A Get counts against your group count",
func() { | 277 Convey("A Get counts against your group count",
func() { |
278 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 278 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
279 » » » » » » rds := rdsS.Get(c) | 279 » » » » » » ds := dsS.Get(c) |
280 | 280 |
281 » » » » » » _, err := getOnePM(rds, rds.NewK
ey("Foo", "", 20, nil)) | 281 » » » » » » _, err := getOnePM(ds, ds.NewKey
("Foo", "", 20, nil)) |
282 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS
uchEntity) | 282 » » » » » » So(err, ShouldEqual, dsS.ErrNoSu
chEntity) |
283 | 283 |
284 » » » » » » err = rds.GetMulti([]rdsS.Key{k}
, func(_ rdsS.PropertyMap, err error) { | 284 » » » » » » err = ds.GetMulti([]dsS.Key{k},
func(_ dsS.PropertyMap, err error) { |
285 So(err, ShouldBeNil) | 285 So(err, ShouldBeNil) |
286 }) | 286 }) |
287 So(err.Error(), ShouldContainSub
string, "cross-group") | 287 So(err.Error(), ShouldContainSub
string, "cross-group") |
288 return nil | 288 return nil |
289 }, nil) | 289 }, nil) |
290 So(err, ShouldBeNil) | 290 So(err, ShouldBeNil) |
291 }) | 291 }) |
292 | 292 |
293 Convey("Get takes a snapshot", func() { | 293 Convey("Get takes a snapshot", func() { |
294 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 294 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
295 » » » » » » txnDS := rdsS.Get(c) | 295 » » » » » » txnDS := dsS.Get(c) |
296 So(txnDS, ShouldNotBeNil) | 296 So(txnDS, ShouldNotBeNil) |
297 | 297 |
298 getOne(txnDS, k, f) | 298 getOne(txnDS, k, f) |
299 So(f.Val, ShouldEqual, 10) | 299 So(f.Val, ShouldEqual, 10) |
300 | 300 |
301 // 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 |
302 // a failed transaction :) | 302 // a failed transaction :) |
303 f.Val = 11 | 303 f.Val = 11 |
304 » » » » » » putOne(rds, k, f) | 304 » » » » » » putOne(ds, k, f) |
305 | 305 |
306 getOne(txnDS, k, f) | 306 getOne(txnDS, k, f) |
307 So(f.Val, ShouldEqual, 10) | 307 So(f.Val, ShouldEqual, 10) |
308 | 308 |
309 return nil | 309 return nil |
310 }, nil) | 310 }, nil) |
311 So(err, ShouldBeNil) | 311 So(err, ShouldBeNil) |
312 | 312 |
313 f := &Foo{} | 313 f := &Foo{} |
314 » » » » » getOne(rds, k, f) | 314 » » » » » getOne(ds, k, f) |
315 So(f.Val, ShouldEqual, 11) | 315 So(f.Val, ShouldEqual, 11) |
316 }) | 316 }) |
317 | 317 |
318 Convey("and snapshots are consistent even after
Puts", func() { | 318 Convey("and snapshots are consistent even after
Puts", func() { |
319 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 319 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
320 » » » » » » txnDS := rdsS.Get(c) | 320 » » » » » » txnDS := dsS.Get(c) |
321 So(txnDS, ShouldNotBeNil) | 321 So(txnDS, ShouldNotBeNil) |
322 | 322 |
323 f := &Foo{} | 323 f := &Foo{} |
324 getOne(txnDS, k, f) | 324 getOne(txnDS, k, f) |
325 So(f.Val, ShouldEqual, 10) | 325 So(f.Val, ShouldEqual, 10) |
326 | 326 |
327 // 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 |
328 // a failed transaction :) | 328 // a failed transaction :) |
329 f.Val = 11 | 329 f.Val = 11 |
330 » » » » » » putOne(rds, k, f) | 330 » » » » » » putOne(ds, k, f) |
331 | 331 |
332 getOne(txnDS, k, f) | 332 getOne(txnDS, k, f) |
333 So(f.Val, ShouldEqual, 10) | 333 So(f.Val, ShouldEqual, 10) |
334 | 334 |
335 f.Val = 20 | 335 f.Val = 20 |
336 putOne(txnDS, k, f) | 336 putOne(txnDS, k, f) |
337 | 337 |
338 getOne(txnDS, k, f) | 338 getOne(txnDS, k, f) |
339 So(f.Val, ShouldEqual, 10) // st
ill gets 10 | 339 So(f.Val, ShouldEqual, 10) // st
ill gets 10 |
340 | 340 |
341 return nil | 341 return nil |
342 }, nil) | 342 }, nil) |
343 So(err.Error(), ShouldContainSubstring,
"concurrent") | 343 So(err.Error(), ShouldContainSubstring,
"concurrent") |
344 | 344 |
345 f := &Foo{} | 345 f := &Foo{} |
346 » » » » » getOne(rds, k, f) | 346 » » » » » getOne(ds, k, f) |
347 So(f.Val, ShouldEqual, 11) | 347 So(f.Val, ShouldEqual, 11) |
348 }) | 348 }) |
349 | 349 |
350 Convey("Reusing a transaction context is bad new
s", func() { | 350 Convey("Reusing a transaction context is bad new
s", func() { |
351 » » » » » k := rds.NewKey("Foo", "", 1, nil) | 351 » » » » » k := ds.NewKey("Foo", "", 1, nil) |
352 » » » » » txnDS := rdsS.Interface(nil) | 352 » » » » » txnDS := dsS.Interface(nil) |
353 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 353 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
354 » » » » » » txnDS = rdsS.Get(c) | 354 » » » » » » txnDS = dsS.Get(c) |
355 getOnePM(txnDS, k) | 355 getOnePM(txnDS, k) |
356 return nil | 356 return nil |
357 }, nil) | 357 }, nil) |
358 So(err, ShouldBeNil) | 358 So(err, ShouldBeNil) |
359 » » » » » err = txnDS.GetMulti([]rdsS.Key{k}, func
(_ rdsS.PropertyMap, err error) { | 359 » » » » » err = txnDS.GetMulti([]dsS.Key{k}, func(
_ dsS.PropertyMap, err error) { |
360 So(err, ShouldBeNil) | 360 So(err, ShouldBeNil) |
361 }) | 361 }) |
362 So(err.Error(), ShouldContainSubstring,
"expired") | 362 So(err.Error(), ShouldContainSubstring,
"expired") |
363 }) | 363 }) |
364 | 364 |
365 Convey("Nested transactions are rejected", func(
) { | 365 Convey("Nested transactions are rejected", func(
) { |
366 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 366 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
367 » » » » » » err := rdsS.Get(c).RunInTransact
ion(func(c context.Context) error { | 367 » » » » » » err := dsS.Get(c).RunInTransacti
on(func(c context.Context) error { |
368 panic("noooo") | 368 panic("noooo") |
369 }, nil) | 369 }, nil) |
370 So(err.Error(), ShouldContainSub
string, "nested transactions") | 370 So(err.Error(), ShouldContainSub
string, "nested transactions") |
371 return nil | 371 return nil |
372 }, nil) | 372 }, nil) |
373 So(err, ShouldBeNil) | 373 So(err, ShouldBeNil) |
374 }) | 374 }) |
375 | 375 |
376 Convey("Concurrent transactions only accept one
set of changes", func() { | 376 Convey("Concurrent transactions only accept one
set of changes", func() { |
377 // Note: I think this implementation is
actually /slightly/ wrong. | 377 // Note: I think this implementation is
actually /slightly/ wrong. |
378 // 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 |
379 // transaction it actually (essentially)
holds a reference to the | 379 // transaction it actually (essentially)
holds a reference to the |
380 // entire datastore. Our implementation
takes a snapshot of the | 380 // entire datastore. Our implementation
takes a snapshot of the |
381 // entity group as soon as something obs
erves/affects it. | 381 // entity group as soon as something obs
erves/affects it. |
382 // | 382 // |
383 // 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. |
384 » » » » » err := rds.RunInTransaction(func(c conte
xt.Context) error { | 384 » » » » » err := ds.RunInTransaction(func(c contex
t.Context) error { |
385 » » » » » » txnDS := rdsS.Get(c) | 385 » » » » » » txnDS := dsS.Get(c) |
386 f := &Foo{Val: 21} | 386 f := &Foo{Val: 21} |
387 putOne(txnDS, k, f) | 387 putOne(txnDS, k, f) |
388 | 388 |
389 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 389 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
390 » » » » » » » txnDS := rdsS.Get(c) | 390 » » » » » » » txnDS := dsS.Get(c) |
391 f := &Foo{Val: 27} | 391 f := &Foo{Val: 27} |
392 putOne(txnDS, k, f) | 392 putOne(txnDS, k, f) |
393 return nil | 393 return nil |
394 }, nil) | 394 }, nil) |
395 So(err, ShouldBeNil) | 395 So(err, ShouldBeNil) |
396 | 396 |
397 return nil | 397 return nil |
398 }, nil) | 398 }, nil) |
399 So(err.Error(), ShouldContainSubstring,
"concurrent") | 399 So(err.Error(), ShouldContainSubstring,
"concurrent") |
400 | 400 |
401 f := &Foo{} | 401 f := &Foo{} |
402 » » » » » getOne(rds, k, f) | 402 » » » » » getOne(ds, k, f) |
403 So(f.Val, ShouldEqual, 27) | 403 So(f.Val, ShouldEqual, 27) |
404 }) | 404 }) |
405 | 405 |
406 Convey("XG", func() { | 406 Convey("XG", func() { |
407 Convey("Modifying two groups with XG=fal
se is invalid", func() { | 407 Convey("Modifying two groups with XG=fal
se is invalid", func() { |
408 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 408 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
409 » » » » » » » rds := rdsS.Get(c) | 409 » » » » » » » ds := dsS.Get(c) |
410 f := &Foo{Val: 200} | 410 f := &Foo{Val: 200} |
411 » » » » » » » putOne(rds, k, f) | 411 » » » » » » » putOne(ds, k, f) |
412 | 412 |
413 » » » » » » » _, err := putOneErr(rds,
rds.NewKey("Foo", "", 2, nil), f) | 413 » » » » » » » _, err := putOneErr(ds,
ds.NewKey("Foo", "", 2, nil), f) |
414 So(err.Error(), ShouldCo
ntainSubstring, "cross-group") | 414 So(err.Error(), ShouldCo
ntainSubstring, "cross-group") |
415 return err | 415 return err |
416 }, nil) | 416 }, nil) |
417 So(err.Error(), ShouldContainSub
string, "cross-group") | 417 So(err.Error(), ShouldContainSub
string, "cross-group") |
418 }) | 418 }) |
419 | 419 |
420 Convey("Modifying >25 groups with XG=tru
e is invald", func() { | 420 Convey("Modifying >25 groups with XG=tru
e is invald", func() { |
421 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 421 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
422 » » » » » » » rds := rdsS.Get(c) | 422 » » » » » » » ds := dsS.Get(c) |
423 for i := int64(1); i < 2
6; i++ { | 423 for i := int64(1); i < 2
6; i++ { |
424 » » » » » » » » k := rds.NewKey(
"Foo", "", i, nil) | 424 » » » » » » » » k := ds.NewKey("
Foo", "", i, nil) |
425 f := &Foo{Val: 2
00} | 425 f := &Foo{Val: 2
00} |
426 » » » » » » » » putOne(rds, k, f
) | 426 » » » » » » » » putOne(ds, k, f) |
427 } | 427 } |
428 f := &Foo{Val: 200} | 428 f := &Foo{Val: 200} |
429 » » » » » » » _, err := putOneErr(rds,
rds.NewKey("Foo", "", 27, nil), f) | 429 » » » » » » » _, err := putOneErr(ds,
ds.NewKey("Foo", "", 27, nil), f) |
430 So(err.Error(), ShouldCo
ntainSubstring, "too many entity groups") | 430 So(err.Error(), ShouldCo
ntainSubstring, "too many entity groups") |
431 return err | 431 return err |
432 » » » » » » }, &rdsS.TransactionOptions{XG:
true}) | 432 » » » » » » }, &dsS.TransactionOptions{XG: t
rue}) |
433 So(err.Error(), ShouldContainSub
string, "too many entity groups") | 433 So(err.Error(), ShouldContainSub
string, "too many entity groups") |
434 }) | 434 }) |
435 }) | 435 }) |
436 | 436 |
437 Convey("Errors and panics", func() { | 437 Convey("Errors and panics", func() { |
438 Convey("returning an error aborts", func
() { | 438 Convey("returning an error aborts", func
() { |
439 » » » » » » err := rds.RunInTransaction(func
(c context.Context) error { | 439 » » » » » » err := ds.RunInTransaction(func(
c context.Context) error { |
440 » » » » » » » rds := rdsS.Get(c) | 440 » » » » » » » ds := dsS.Get(c) |
441 f := &Foo{Val: 200} | 441 f := &Foo{Val: 200} |
442 » » » » » » » putOne(rds, k, f) | 442 » » » » » » » putOne(ds, k, f) |
443 | 443 |
444 return fmt.Errorf("thing
y") | 444 return fmt.Errorf("thing
y") |
445 }, nil) | 445 }, nil) |
446 So(err.Error(), ShouldEqual, "th
ingy") | 446 So(err.Error(), ShouldEqual, "th
ingy") |
447 | 447 |
448 f := &Foo{} | 448 f := &Foo{} |
449 » » » » » » getOne(rds, k, f) | 449 » » » » » » getOne(ds, k, f) |
450 So(f.Val, ShouldEqual, 10) | 450 So(f.Val, ShouldEqual, 10) |
451 }) | 451 }) |
452 | 452 |
453 Convey("panicing aborts", func() { | 453 Convey("panicing aborts", func() { |
454 So(func() { | 454 So(func() { |
455 » » » » » » » rds.RunInTransaction(fun
c(c context.Context) error { | 455 » » » » » » » ds.RunInTransaction(func
(c context.Context) error { |
456 » » » » » » » » rds := rdsS.Get(
c) | 456 » » » » » » » » ds := dsS.Get(c) |
457 f := &Foo{Val: 2
00} | 457 f := &Foo{Val: 2
00} |
458 » » » » » » » » putOne(rds, k, f
) | 458 » » » » » » » » putOne(ds, k, f) |
459 panic("wheeeeee"
) | 459 panic("wheeeeee"
) |
460 }, nil) | 460 }, nil) |
461 }, ShouldPanic) | 461 }, ShouldPanic) |
462 | 462 |
463 f := &Foo{} | 463 f := &Foo{} |
464 » » » » » » getOne(rds, k, f) | 464 » » » » » » getOne(ds, k, f) |
465 So(f.Val, ShouldEqual, 10) | 465 So(f.Val, ShouldEqual, 10) |
466 }) | 466 }) |
467 }) | 467 }) |
468 }) | 468 }) |
469 }) | 469 }) |
470 | 470 |
471 }) | 471 }) |
472 } | 472 } |
473 | 473 |
474 const MaxUint = ^uint(0) | 474 const MaxUint = ^uint(0) |
475 const MaxInt = int(MaxUint >> 1) | 475 const MaxInt = int(MaxUint >> 1) |
476 const IntIs32Bits = int64(MaxInt) < math.MaxInt64 | 476 const IntIs32Bits = int64(MaxInt) < math.MaxInt64 |
477 | 477 |
478 func TestDatastoreQueryer(t *testing.T) { | 478 func TestDatastoreQueryer(t *testing.T) { |
479 Convey("Datastore Query suport", t, func() { | 479 Convey("Datastore Query suport", t, func() { |
480 c := Use(context.Background()) | 480 c := Use(context.Background()) |
481 » » rds := rdsS.Get(c) | 481 » » ds := dsS.Get(c) |
482 » » So(rds, ShouldNotBeNil) | 482 » » So(ds, ShouldNotBeNil) |
483 | 483 |
484 Convey("can create good queries", func() { | 484 Convey("can create good queries", func() { |
485 » » » q := rds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) | 485 » » » q := ds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) |
486 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab
s")) | 486 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab
s")) |
487 So(q, ShouldNotBeNil) | 487 So(q, ShouldNotBeNil) |
488 So(q.(*queryImpl).err, ShouldBeNil) | 488 So(q.(*queryImpl).err, ShouldBeNil) |
489 qi := q.(*queryImpl).checkCorrectness("", false) | 489 qi := q.(*queryImpl).checkCorrectness("", false) |
490 So(qi.err, ShouldBeNil) | 490 So(qi.err, ShouldBeNil) |
491 }) | 491 }) |
492 | 492 |
493 Convey("normalize ensures orders make sense", func() { | 493 Convey("normalize ensures orders make sense", func() { |
494 » » » q := rds.NewQuery("Cool") | 494 » » » q := ds.NewQuery("Cool") |
495 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob
").Order("bob") | 495 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob
").Order("bob") |
496 | 496 |
497 Convey("removes dups and equality orders", func() { | 497 Convey("removes dups and equality orders", func() { |
498 q = q.Order("wat") | 498 q = q.Order("wat") |
499 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 499 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
500 So(qi.err, ShouldBeNil) | 500 So(qi.err, ShouldBeNil) |
501 So(qi.order, ShouldResemble, []queryOrder{{"wat"
, qASC}}) | 501 So(qi.order, ShouldResemble, []queryOrder{{"wat"
, qASC}}) |
502 }) | 502 }) |
503 | 503 |
504 Convey("keeps inequality orders", func() { | 504 Convey("keeps inequality orders", func() { |
505 q = q.Order("wat") | 505 q = q.Order("wat") |
506 q := q.Filter("bob >", 10).Filter("wat <", 29) | 506 q := q.Filter("bob >", 10).Filter("wat <", 29) |
507 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 507 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
508 So(qi.order, ShouldResemble, []queryOrder{{"bob"
, qASC}, {"wat", qASC}}) | 508 So(qi.order, ShouldResemble, []queryOrder{{"bob"
, qASC}, {"wat", qASC}}) |
509 So(qi.err.Error(), ShouldContainSubstring, "Only
one inequality") | 509 So(qi.err.Error(), ShouldContainSubstring, "Only
one inequality") |
510 }) | 510 }) |
511 | 511 |
512 Convey("if we equality-filter on __key__, order is ditch
ed", func() { | 512 Convey("if we equality-filter on __key__, order is ditch
ed", func() { |
513 q = q.Order("wat") | 513 q = q.Order("wat") |
514 » » » » q := q.Filter("__key__ =", rds.NewKey("Foo", "wa
t", 0, nil)) | 514 » » » » q := q.Filter("__key__ =", ds.NewKey("Foo", "wat
", 0, nil)) |
515 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 515 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
516 So(qi.order, ShouldResemble, []queryOrder(nil)) | 516 So(qi.order, ShouldResemble, []queryOrder(nil)) |
517 So(qi.err, ShouldBeNil) | 517 So(qi.err, ShouldBeNil) |
518 }) | 518 }) |
519 | 519 |
520 Convey("if we order by key and something else, key domin
ates", func() { | 520 Convey("if we order by key and something else, key domin
ates", func() { |
521 q := q.Order("__key__").Order("wat") | 521 q := q.Order("__key__").Order("wat") |
522 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) | 522 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
523 So(qi.order, ShouldResemble, []queryOrder{{"__ke
y__", qASC}}) | 523 So(qi.order, ShouldResemble, []queryOrder{{"__ke
y__", qASC}}) |
524 So(qi.err, ShouldBeNil) | 524 So(qi.err, ShouldBeNil) |
525 }) | 525 }) |
526 }) | 526 }) |
527 | 527 |
528 Convey("can create bad queries", func() { | 528 Convey("can create bad queries", func() { |
529 » » » q := rds.NewQuery("Foo") | 529 » » » q := ds.NewQuery("Foo") |
530 | 530 |
531 Convey("bad filter ops", func() { | 531 Convey("bad filter ops", func() { |
532 q := q.Filter("Bob !", "value") | 532 q := q.Filter("Bob !", "value") |
533 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid operator \"!\"") | 533 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid operator \"!\"") |
534 }) | 534 }) |
535 Convey("bad filter", func() { | 535 Convey("bad filter", func() { |
536 q := q.Filter("Bob", "value") | 536 q := q.Filter("Bob", "value") |
537 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid filter") | 537 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid filter") |
538 }) | 538 }) |
539 Convey("bad order", func() { | 539 Convey("bad order", func() { |
(...skipping 20 matching lines...) Expand all Loading... |
560 if !IntIs32Bits { | 560 if !IntIs32Bits { |
561 q := q.Offset(MaxInt) | 561 q := q.Offset(MaxInt) |
562 So(q.(*queryImpl).err.Error(), ShouldCon
tainSubstring, "query offset overflow") | 562 So(q.(*queryImpl).err.Error(), ShouldCon
tainSubstring, "query offset overflow") |
563 } | 563 } |
564 }) | 564 }) |
565 Convey("Bad cursors", func() { | 565 Convey("Bad cursors", func() { |
566 q := q.Start(queryCursor("")).End(queryCursor(""
)) | 566 q := q.Start(queryCursor("")).End(queryCursor(""
)) |
567 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid cursor") | 567 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid cursor") |
568 }) | 568 }) |
569 Convey("Bad ancestors", func() { | 569 Convey("Bad ancestors", func() { |
570 » » » » q := q.Ancestor(rds.NewKey("Goop", "wat", 10, ni
l)) | 570 » » » » q := q.Ancestor(ds.NewKey("Goop", "wat", 10, nil
)) |
571 So(q, ShouldNotBeNil) | 571 So(q, ShouldNotBeNil) |
572 qi := q.(*queryImpl).checkCorrectness("", false) | 572 qi := q.(*queryImpl).checkCorrectness("", false) |
573 » » » » So(qi.err, ShouldEqual, rdsS.ErrInvalidKey) | 573 » » » » So(qi.err, ShouldEqual, dsS.ErrInvalidKey) |
574 }) | 574 }) |
575 Convey("nil ancestors", func() { | 575 Convey("nil ancestors", func() { |
576 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn
ess("", false) | 576 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn
ess("", false) |
577 So(qi.err.Error(), ShouldContainSubstring, "nil
query ancestor") | 577 So(qi.err.Error(), ShouldContainSubstring, "nil
query ancestor") |
578 }) | 578 }) |
579 Convey("Bad key filters", func() { | 579 Convey("Bad key filters", func() { |
580 » » » » q := q.Filter("__key__ =", rds.NewKey("Goop", "w
at", 10, nil)) | 580 » » » » q := q.Filter("__key__ =", ds.NewKey("Goop", "wa
t", 10, nil)) |
581 qi := q.(*queryImpl).checkCorrectness("", false) | 581 qi := q.(*queryImpl).checkCorrectness("", false) |
582 » » » » So(qi.err, ShouldEqual, rdsS.ErrInvalidKey) | 582 » » » » So(qi.err, ShouldEqual, dsS.ErrInvalidKey) |
583 }) | 583 }) |
584 Convey("non-ancestor queries in a transaction", func() { | 584 Convey("non-ancestor queries in a transaction", func() { |
585 qi := q.(*queryImpl).checkCorrectness("", true) | 585 qi := q.(*queryImpl).checkCorrectness("", true) |
586 So(qi.err.Error(), ShouldContainSubstring, "Only
ancestor queries") | 586 So(qi.err.Error(), ShouldContainSubstring, "Only
ancestor queries") |
587 }) | 587 }) |
588 Convey("absurd numbers of filters are prohibited", func(
) { | 588 Convey("absurd numbers of filters are prohibited", func(
) { |
589 » » » » q := q.Ancestor(rds.NewKey("thing", "wat", 0, ni
l)) | 589 » » » » q := q.Ancestor(ds.NewKey("thing", "wat", 0, nil
)) |
590 for i := 0; i < 100; i++ { | 590 for i := 0; i < 100; i++ { |
591 q = q.Filter("something =", 10) | 591 q = q.Filter("something =", 10) |
592 } | 592 } |
593 qi := q.(*queryImpl).checkCorrectness("", false) | 593 qi := q.(*queryImpl).checkCorrectness("", false) |
594 So(qi.err.Error(), ShouldContainSubstring, "quer
y is too large") | 594 So(qi.err.Error(), ShouldContainSubstring, "quer
y is too large") |
595 }) | 595 }) |
596 Convey("filters for __key__ that aren't keys", func() { | 596 Convey("filters for __key__ that aren't keys", func() { |
597 q := q.Filter("__key__ = ", 10) | 597 q := q.Filter("__key__ = ", 10) |
598 qi := q.(*queryImpl).checkCorrectness("", false) | 598 qi := q.(*queryImpl).checkCorrectness("", false) |
599 So(qi.err.Error(), ShouldContainSubstring, "must
be a Key") | 599 So(qi.err.Error(), ShouldContainSubstring, "must
be a Key") |
600 }) | 600 }) |
601 Convey("multiple inequalities", func() { | 601 Convey("multiple inequalities", func() { |
602 q := q.Filter("bob > ", 19).Filter("charlie < ",
20) | 602 q := q.Filter("bob > ", 19).Filter("charlie < ",
20) |
603 qi := q.(*queryImpl).checkCorrectness("", false) | 603 qi := q.(*queryImpl).checkCorrectness("", false) |
604 So(qi.err.Error(), ShouldContainSubstring, "one
inequality filter") | 604 So(qi.err.Error(), ShouldContainSubstring, "one
inequality filter") |
605 }) | 605 }) |
606 Convey("bad sort orders", func() { | 606 Convey("bad sort orders", func() { |
607 q := q.Filter("bob > ", 19).Order("-charlie") | 607 q := q.Filter("bob > ", 19).Order("-charlie") |
608 qi := q.(*queryImpl).checkCorrectness("", false) | 608 qi := q.(*queryImpl).checkCorrectness("", false) |
609 So(qi.err.Error(), ShouldContainSubstring, "firs
t sort property") | 609 So(qi.err.Error(), ShouldContainSubstring, "firs
t sort property") |
610 }) | 610 }) |
611 Convey("kindless with non-__key__ filters", func() { | 611 Convey("kindless with non-__key__ filters", func() { |
612 » » » » q := rds.NewQuery("").Filter("face <", 25.3) | 612 » » » » q := ds.NewQuery("").Filter("face <", 25.3) |
613 qi := q.(*queryImpl).checkCorrectness("", false) | 613 qi := q.(*queryImpl).checkCorrectness("", false) |
614 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for non-__key__") | 614 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for non-__key__") |
615 }) | 615 }) |
616 Convey("kindless with non-__key__ orders", func() { | 616 Convey("kindless with non-__key__ orders", func() { |
617 » » » » q := rds.NewQuery("").Order("face") | 617 » » » » q := ds.NewQuery("").Order("face") |
618 qi := q.(*queryImpl).checkCorrectness("", false) | 618 qi := q.(*queryImpl).checkCorrectness("", false) |
619 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") | 619 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") |
620 }) | 620 }) |
621 Convey("kindless with decending-__key__ orders", func()
{ | 621 Convey("kindless with decending-__key__ orders", func()
{ |
622 » » » » q := rds.NewQuery("").Order("-__key__") | 622 » » » » q := ds.NewQuery("").Order("-__key__") |
623 qi := q.(*queryImpl).checkCorrectness("", false) | 623 qi := q.(*queryImpl).checkCorrectness("", false) |
624 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") | 624 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") |
625 }) | 625 }) |
626 }) | 626 }) |
627 | 627 |
628 }) | 628 }) |
629 } | 629 } |
OLD | NEW |