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

Side by Side Diff: filter/txnBuf/txnbuf_test.go

Issue 2302743002: Interface update, per-method Contexts. (Closed)
Patch Set: Lightning talk licenses. Created 4 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 | « filter/txnBuf/state.go ('k') | impl/cloud/datastore.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 LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package txnBuf 5 package txnBuf
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "math/rand" 10 "math/rand"
11 "testing" 11 "testing"
12 12
13 "github.com/luci/gae/filter/count" 13 "github.com/luci/gae/filter/count"
14 "github.com/luci/gae/impl/memory" 14 "github.com/luci/gae/impl/memory"
15 » "github.com/luci/gae/service/datastore" 15 » ds "github.com/luci/gae/service/datastore"
16
16 "github.com/luci/luci-go/common/data/cmpbin" 17 "github.com/luci/luci-go/common/data/cmpbin"
17 "github.com/luci/luci-go/common/errors" 18 "github.com/luci/luci-go/common/errors"
19
20 "golang.org/x/net/context"
21
18 . "github.com/luci/luci-go/common/testing/assertions" 22 . "github.com/luci/luci-go/common/testing/assertions"
19 . "github.com/smartystreets/goconvey/convey" 23 . "github.com/smartystreets/goconvey/convey"
20 "golang.org/x/net/context"
21 ) 24 )
22 25
23 type Foo struct { 26 type Foo struct {
24 » ID int64 `gae:"$id"` 27 » ID int64 `gae:"$id"`
25 » Parent *datastore.Key `gae:"$parent"` 28 » Parent *ds.Key `gae:"$parent"`
26 29
27 Value []int64 30 Value []int64
28 ValueNI []byte `gae:",noindex"` 31 ValueNI []byte `gae:",noindex"`
29 Sort []string 32 Sort []string
30 } 33 }
31 34
32 func toIntSlice(stuff []interface{}) []int64 { 35 func toIntSlice(stuff []interface{}) []int64 {
33 vals, ok := stuff[0].([]int64) 36 vals, ok := stuff[0].([]int64)
34 if !ok { 37 if !ok {
35 vals = make([]int64, len(stuff)) 38 vals = make([]int64, len(stuff))
36 for i := range vals { 39 for i := range vals {
37 vals[i] = int64(stuff[i].(int)) 40 vals[i] = int64(stuff[i].(int))
38 } 41 }
39 } 42 }
40 return vals 43 return vals
41 } 44 }
42 45
43 func toInt64(thing interface{}) int64 { 46 func toInt64(thing interface{}) int64 {
44 switch x := thing.(type) { 47 switch x := thing.(type) {
45 case int: 48 case int:
46 return int64(x) 49 return int64(x)
47 case int64: 50 case int64:
48 return x 51 return x
49 default: 52 default:
50 panic(fmt.Errorf("wat r it? %v", x)) 53 panic(fmt.Errorf("wat r it? %v", x))
51 } 54 }
52 } 55 }
53 56
54 func fooShouldHave(ds datastore.Interface) func(interface{}, ...interface{}) str ing { 57 func fooShouldHave(c context.Context) func(interface{}, ...interface{}) string {
55 return func(id interface{}, values ...interface{}) string { 58 return func(id interface{}, values ...interface{}) string {
56 f := &Foo{ID: toInt64(id)} 59 f := &Foo{ID: toInt64(id)}
57 » » err := ds.Get(f) 60 » » err := ds.Get(c, f)
58 if len(values) == 0 { 61 if len(values) == 0 {
59 » » » return ShouldEqual(err, datastore.ErrNoSuchEntity) 62 » » » return ShouldEqual(err, ds.ErrNoSuchEntity)
60 } 63 }
61 64
62 ret := ShouldBeNil(err) 65 ret := ShouldBeNil(err)
63 if ret == "" { 66 if ret == "" {
64 if data, ok := values[0].([]byte); ok { 67 if data, ok := values[0].([]byte); ok {
65 ret = ShouldResemble(f.ValueNI, data) 68 ret = ShouldResemble(f.ValueNI, data)
66 } else { 69 } else {
67 ret = ShouldResemble(f.Value, toIntSlice(values) ) 70 ret = ShouldResemble(f.Value, toIntSlice(values) )
68 } 71 }
69 } 72 }
70 return ret 73 return ret
71 } 74 }
72 } 75 }
73 76
74 func fooSetTo(ds datastore.Interface) func(interface{}, ...interface{}) string { 77 func fooSetTo(c context.Context) func(interface{}, ...interface{}) string {
75 return func(id interface{}, values ...interface{}) string { 78 return func(id interface{}, values ...interface{}) string {
76 f := &Foo{ID: toInt64(id)} 79 f := &Foo{ID: toInt64(id)}
77 if len(values) == 0 { 80 if len(values) == 0 {
78 » » » return ShouldBeNil(ds.Delete(ds.KeyForObj(f))) 81 » » » return ShouldBeNil(ds.Delete(c, ds.KeyForObj(c, f)))
79 } 82 }
80 if data, ok := values[0].([]byte); ok { 83 if data, ok := values[0].([]byte); ok {
81 f.ValueNI = data 84 f.ValueNI = data
82 } else { 85 } else {
83 f.Value = toIntSlice(values) 86 f.Value = toIntSlice(values)
84 } 87 }
85 » » return ShouldBeNil(ds.Put(f)) 88 » » return ShouldBeNil(ds.Put(c, f))
86 } 89 }
87 } 90 }
88 91
89 var ( 92 var (
90 dataMultiRoot = make([]*Foo, 20) 93 dataMultiRoot = make([]*Foo, 20)
91 dataSingleRoot = make([]*Foo, 20) 94 dataSingleRoot = make([]*Foo, 20)
92 hugeField = make([]byte, DefaultSizeBudget/8) 95 hugeField = make([]byte, DefaultSizeBudget/8)
93 hugeData = make([]*Foo, 11) 96 hugeData = make([]*Foo, 11)
94 » root = datastore.MakeKey("something~else", "", "Parent", 1) 97 » root = ds.KeyContext{"something~else", ""}.MakeKey("Parent", 1 )
95 ) 98 )
96 99
97 func init() { 100 func init() {
98 cb := func(i int64) string { 101 cb := func(i int64) string {
99 buf := &bytes.Buffer{} 102 buf := &bytes.Buffer{}
100 cmpbin.WriteInt(buf, i) 103 cmpbin.WriteInt(buf, i)
101 return buf.String() 104 return buf.String()
102 } 105 }
103 106
104 rs := rand.NewSource(0) 107 rs := rand.NewSource(0)
105 root := datastore.MakeKey("something~else", "", "Parent", 1)
106 nums := make([]string, 20) 108 nums := make([]string, 20)
107 for i := range dataMultiRoot { 109 for i := range dataMultiRoot {
108 id := int64(i + 1) 110 id := int64(i + 1)
109 nums[i] = cb(id) 111 nums[i] = cb(id)
110 112
111 val := make([]int64, rs.Int63()%20) 113 val := make([]int64, rs.Int63()%20)
112 for j := range val { 114 for j := range val {
113 r := rs.Int63() 115 r := rs.Int63()
114 val[j] = r 116 val[j] = r
115 } 117 }
116 118
117 dataMultiRoot[i] = &Foo{ID: id, Value: val} 119 dataMultiRoot[i] = &Foo{ID: id, Value: val}
118 dataSingleRoot[i] = &Foo{ID: id, Parent: root, Value: val} 120 dataSingleRoot[i] = &Foo{ID: id, Parent: root, Value: val}
119 } 121 }
120 122
121 for i := range hugeField { 123 for i := range hugeField {
122 hugeField[i] = byte(i) 124 hugeField[i] = byte(i)
123 } 125 }
124 126
125 for i := range hugeData { 127 for i := range hugeData {
126 hugeData[i] = &Foo{ID: int64(i + 1), ValueNI: hugeField} 128 hugeData[i] = &Foo{ID: int64(i + 1), ValueNI: hugeField}
127 } 129 }
128 } 130 }
129 131
130 func mkds(data []*Foo) (under, over *count.DSCounter, ds datastore.Interface) { 132 func mkds(data []*Foo) (under, over *count.DSCounter, c context.Context) {
131 » c := memory.UseWithAppID(context.Background(), "something~else") 133 » c = memory.UseWithAppID(context.Background(), "something~else")
132 » ds = datastore.Get(c)
133 134
134 » dataKey := ds.KeyForObj(data[0]) 135 » dataKey := ds.KeyForObj(c, data[0])
135 » if err := ds.AllocateIDs(ds.NewIncompleteKeys(100, dataKey.Kind(), dataK ey.Parent())); err != nil { 136 » if err := ds.AllocateIDs(c, ds.NewIncompleteKeys(c, 100, dataKey.Kind(), dataKey.Parent())); err != nil {
136 panic(err) 137 panic(err)
137 } 138 }
138 » if err := ds.PutMulti(data); err != nil { 139 » if err := ds.Put(c, data); err != nil {
139 panic(err) 140 panic(err)
140 } 141 }
141 142
142 c, under = count.FilterRDS(c) 143 c, under = count.FilterRDS(c)
143 c = FilterRDS(c) 144 c = FilterRDS(c)
144 c, over = count.FilterRDS(c) 145 c, over = count.FilterRDS(c)
145 ds = datastore.Get(c)
146 return 146 return
147 } 147 }
148 148
149 func TestTransactionBuffers(t *testing.T) { 149 func TestTransactionBuffers(t *testing.T) {
150 t.Parallel() 150 t.Parallel()
151 151
152 Convey("Get/Put/Delete", t, func() { 152 Convey("Get/Put/Delete", t, func() {
153 » » under, over, ds := mkds(dataMultiRoot) 153 » » under, over, c := mkds(dataMultiRoot)
154 » » ds.Testable().SetTransactionRetryCount(1) 154 » » ds.GetTestable(c).SetTransactionRetryCount(1)
155 155
156 So(under.PutMulti.Total(), ShouldEqual, 0) 156 So(under.PutMulti.Total(), ShouldEqual, 0)
157 So(over.PutMulti.Total(), ShouldEqual, 0) 157 So(over.PutMulti.Total(), ShouldEqual, 0)
158 158
159 Convey("Good", func() { 159 Convey("Good", func() {
160 Convey("read-only", func() { 160 Convey("read-only", func() {
161 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 161 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
162 » » » » » ds := datastore.Get(c) 162 » » » » » So(4, fooShouldHave(c), dataMultiRoot[3] .Value)
163
164 » » » » » So(4, fooShouldHave(ds), dataMultiRoot[3 ].Value)
165 return nil 163 return nil
166 }, nil), ShouldBeNil) 164 }, nil), ShouldBeNil)
167 }) 165 })
168 166
169 Convey("single-level read/write", func() { 167 Convey("single-level read/write", func() {
170 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 168 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
171 » » » » » ds := datastore.Get(c) 169 » » » » » So(4, fooShouldHave(c), dataMultiRoot[3] .Value)
172 170
173 » » » » » So(4, fooShouldHave(ds), dataMultiRoot[3 ].Value) 171 » » » » » So(4, fooSetTo(c), 1, 2, 3, 4)
174 172
175 » » » » » So(4, fooSetTo(ds), 1, 2, 3, 4) 173 » » » » » So(3, fooSetTo(c), 1, 2, 3, 4)
176
177 » » » » » So(3, fooSetTo(ds), 1, 2, 3, 4)
178 174
179 // look! it remembers :) 175 // look! it remembers :)
180 » » » » » So(4, fooShouldHave(ds), 1, 2, 3, 4) 176 » » » » » So(4, fooShouldHave(c), 1, 2, 3, 4)
181 return nil 177 return nil
182 » » » » }, &datastore.TransactionOptions{XG: true}), Sho uldBeNil) 178 » » » » }, &ds.TransactionOptions{XG: true}), ShouldBeNi l)
183 179
184 // 2 because we are simulating a transaction fai lure 180 // 2 because we are simulating a transaction fai lure
185 So(under.PutMulti.Total(), ShouldEqual, 2) 181 So(under.PutMulti.Total(), ShouldEqual, 2)
186 182
187 » » » » So(3, fooShouldHave(ds), 1, 2, 3, 4) 183 » » » » So(3, fooShouldHave(c), 1, 2, 3, 4)
188 » » » » So(4, fooShouldHave(ds), 1, 2, 3, 4) 184 » » » » So(4, fooShouldHave(c), 1, 2, 3, 4)
189 }) 185 })
190 186
191 Convey("multi-level read/write", func() { 187 Convey("multi-level read/write", func() {
192 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 188 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
193 » » » » » ds := datastore.Get(c) 189 » » » » » So(3, fooShouldHave(c), dataMultiRoot[2] .Value)
194 190
195 » » » » » So(3, fooShouldHave(ds), dataMultiRoot[2 ].Value) 191 » » » » » So(3, fooSetTo(c), 1, 2, 3, 4)
196 192 » » » » » So(7, fooSetTo(c))
197 » » » » » So(3, fooSetTo(ds), 1, 2, 3, 4)
198 » » » » » So(7, fooSetTo(ds))
199 193
200 vals := []*Foo{ 194 vals := []*Foo{
201 {ID: 793}, 195 {ID: 793},
202 {ID: 7}, 196 {ID: 7},
203 {ID: 3}, 197 {ID: 3},
204 {ID: 4}, 198 {ID: 4},
205 } 199 }
206 » » » » » So(ds.GetMulti(vals), ShouldResemble, er rors.NewMultiError( 200 » » » » » So(ds.Get(c, vals), ShouldResemble, erro rs.NewMultiError(
207 » » » » » » datastore.ErrNoSuchEntity, 201 » » » » » » ds.ErrNoSuchEntity,
208 » » » » » » datastore.ErrNoSuchEntity, 202 » » » » » » ds.ErrNoSuchEntity,
209 nil, 203 nil,
210 nil, 204 nil,
211 )) 205 ))
212 206
213 So(vals[0].Value, ShouldBeNil) 207 So(vals[0].Value, ShouldBeNil)
214 So(vals[1].Value, ShouldBeNil) 208 So(vals[1].Value, ShouldBeNil)
215 So(vals[2].Value, ShouldResemble, []int6 4{1, 2, 3, 4}) 209 So(vals[2].Value, ShouldResemble, []int6 4{1, 2, 3, 4})
216 So(vals[3].Value, ShouldResemble, dataSi ngleRoot[3].Value) 210 So(vals[3].Value, ShouldResemble, dataSi ngleRoot[3].Value)
217 211
218 // inner, failing, transaction 212 // inner, failing, transaction
219 » » » » » So(ds.RunInTransaction(func(c context.Co ntext) error { 213 » » » » » So(ds.RunInTransaction(c, func(c context .Context) error {
220 » » » » » » ds := datastore.Get(c) 214 » » » » » » // we can see stuff written in t he outer txn
215 » » » » » » So(7, fooShouldHave(c))
216 » » » » » » So(3, fooShouldHave(c), 1, 2, 3, 4)
221 217
222 » » » » » » // we can see stuff written in t he outer txn 218 » » » » » » So(3, fooSetTo(c), 10, 20, 30, 4 0)
223 » » » » » » So(7, fooShouldHave(ds))
224 » » » » » » So(3, fooShouldHave(ds), 1, 2, 3 , 4)
225
226 » » » » » » So(3, fooSetTo(ds), 10, 20, 30, 40)
227 219
228 // disaster strikes! 220 // disaster strikes!
229 return errors.New("whaaaa") 221 return errors.New("whaaaa")
230 }, nil), ShouldErrLike, "whaaaa") 222 }, nil), ShouldErrLike, "whaaaa")
231 223
232 » » » » » So(3, fooShouldHave(ds), 1, 2, 3, 4) 224 » » » » » So(3, fooShouldHave(c), 1, 2, 3, 4)
233 225
234 // inner, successful, transaction 226 // inner, successful, transaction
235 » » » » » So(ds.RunInTransaction(func(c context.Co ntext) error { 227 » » » » » So(ds.RunInTransaction(c, func(c context .Context) error {
236 » » » » » » ds := datastore.Get(c) 228 » » » » » » So(3, fooShouldHave(c), 1, 2, 3, 4)
237 » » » » » » So(3, fooShouldHave(ds), 1, 2, 3 , 4) 229 » » » » » » So(3, fooSetTo(c), 10, 20, 30, 4 0)
238 » » » » » » So(3, fooSetTo(ds), 10, 20, 30, 40)
239 return nil 230 return nil
240 }, nil), ShouldBeNil) 231 }, nil), ShouldBeNil)
241 232
242 // now we see it 233 // now we see it
243 » » » » » So(3, fooShouldHave(ds), 10, 20, 30, 40) 234 » » » » » So(3, fooShouldHave(c), 10, 20, 30, 40)
244 return nil 235 return nil
245 » » » » }, &datastore.TransactionOptions{XG: true}), Sho uldBeNil) 236 » » » » }, &ds.TransactionOptions{XG: true}), ShouldBeNi l)
246 237
247 // 2 because we are simulating a transaction fai lure 238 // 2 because we are simulating a transaction fai lure
248 So(under.PutMulti.Total(), ShouldEqual, 2) 239 So(under.PutMulti.Total(), ShouldEqual, 2)
249 So(under.DeleteMulti.Total(), ShouldEqual, 2) 240 So(under.DeleteMulti.Total(), ShouldEqual, 2)
250 241
251 So(over.PutMulti.Total(), ShouldEqual, 8) 242 So(over.PutMulti.Total(), ShouldEqual, 8)
252 243
253 » » » » So(7, fooShouldHave(ds)) 244 » » » » So(7, fooShouldHave(c))
254 » » » » So(3, fooShouldHave(ds), 10, 20, 30, 40) 245 » » » » So(3, fooShouldHave(c), 10, 20, 30, 40)
255 }) 246 })
256 247
257 Convey("can allocate IDs from an inner transaction", fun c() { 248 Convey("can allocate IDs from an inner transaction", fun c() {
258 nums := []int64{4, 8, 15, 16, 23, 42} 249 nums := []int64{4, 8, 15, 16, 23, 42}
259 » » » » k := (*datastore.Key)(nil) 250 » » » » k := (*ds.Key)(nil)
260 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 251 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
261 » » » » » ds := datastore.Get(c) 252 » » » » » So(ds.RunInTransaction(c, func(c context .Context) error {
262
263 » » » » » So(ds.RunInTransaction(func(c context.Co ntext) error {
264 » » » » » » ds := datastore.Get(c)
265 f := &Foo{Value: nums} 253 f := &Foo{Value: nums}
266 » » » » » » So(ds.Put(f), ShouldBeNil) 254 » » » » » » So(ds.Put(c, f), ShouldBeNil)
267 » » » » » » k = ds.KeyForObj(f) 255 » » » » » » k = ds.KeyForObj(c, f)
268 return nil 256 return nil
269 }, nil), ShouldBeNil) 257 }, nil), ShouldBeNil)
270 258
271 » » » » » So(k.IntID(), fooShouldHave(ds), nums) 259 » » » » » So(k.IntID(), fooShouldHave(c), nums)
272 260
273 return nil 261 return nil
274 }, nil), ShouldBeNil) 262 }, nil), ShouldBeNil)
275 263
276 » » » » So(k.IntID(), fooShouldHave(ds), nums) 264 » » » » So(k.IntID(), fooShouldHave(c), nums)
277 }) 265 })
278 266
279 }) 267 })
280 268
281 Convey("Bad", func() { 269 Convey("Bad", func() {
282 270
283 Convey("too many roots", func() { 271 Convey("too many roots", func() {
284 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 272 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
285 » » » » » ds := datastore.Get(c)
286
287 f := &Foo{ID: 7} 273 f := &Foo{ID: 7}
288 » » » » » So(ds.Get(f), ShouldBeNil) 274 » » » » » So(ds.Get(c, f), ShouldBeNil)
289 So(f, ShouldResemble, dataMultiRoot[6]) 275 So(f, ShouldResemble, dataMultiRoot[6])
290 276
291 » » » » » So(ds.RunInTransaction(func(c context.Co ntext) error { 277 » » » » » So(ds.RunInTransaction(c, func(c context .Context) error {
292 » » » » » » return datastore.Get(c).Get(&Foo {ID: 6}) 278 » » » » » » return ds.Get(c, &Foo{ID: 5})
293 }, nil), ShouldErrLike, "too many entity groups") 279 }, nil), ShouldErrLike, "too many entity groups")
294 280
295 f.Value = []int64{9} 281 f.Value = []int64{9}
296 » » » » » So(ds.Put(f), ShouldBeNil) 282 » » » » » So(ds.Put(c, f), ShouldBeNil)
297 283
298 return nil 284 return nil
299 }, nil), ShouldBeNil) 285 }, nil), ShouldBeNil)
300 286
301 f := &Foo{ID: 7} 287 f := &Foo{ID: 7}
302 » » » » So(ds.Get(f), ShouldBeNil) 288 » » » » So(ds.Get(c, f), ShouldBeNil)
303 So(f.Value, ShouldResemble, []int64{9}) 289 So(f.Value, ShouldResemble, []int64{9})
304 }) 290 })
305 291
306 Convey("buffered errors never reach the datastore", func () { 292 Convey("buffered errors never reach the datastore", func () {
307 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 293 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
308 » » » » » ds := datastore.Get(c) 294 » » » » » So(ds.Put(c, &Foo{ID: 1, Value: []int64{ 1, 2, 3, 4}}), ShouldBeNil)
309
310 » » » » » So(ds.Put(&Foo{ID: 1, Value: []int64{1, 2, 3, 4}}), ShouldBeNil)
311 return errors.New("boop") 295 return errors.New("boop")
312 }, nil), ShouldErrLike, "boop") 296 }, nil), ShouldErrLike, "boop")
313 So(under.PutMulti.Total(), ShouldEqual, 0) 297 So(under.PutMulti.Total(), ShouldEqual, 0)
314 So(over.PutMulti.Successes(), ShouldEqual, 1) 298 So(over.PutMulti.Successes(), ShouldEqual, 1)
315 }) 299 })
316 300
317 }) 301 })
318 302
319 }) 303 })
320 } 304 }
321 305
322 func TestHuge(t *testing.T) { 306 func TestHuge(t *testing.T) {
323 t.Parallel() 307 t.Parallel()
324 308
325 Convey("testing datastore enforces thresholds", t, func() { 309 Convey("testing datastore enforces thresholds", t, func() {
326 » » _, _, ds := mkds(dataMultiRoot) 310 » » _, _, c := mkds(dataMultiRoot)
327 311
328 Convey("exceeding inner txn size threshold still allows outer", func() { 312 Convey("exceeding inner txn size threshold still allows outer", func() {
329 » » » So(ds.RunInTransaction(func(c context.Context) error { 313 » » » So(ds.RunInTransaction(c, func(c context.Context) error {
330 » » » » ds := datastore.Get(c) 314 » » » » So(18, fooSetTo(c), hugeField)
331 315
332 » » » » So(18, fooSetTo(ds), hugeField) 316 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
333 317 » » » » » So(ds.Put(c, hugeData), ShouldBeNil)
334 » » » » So(ds.RunInTransaction(func(c context.Context) e rror {
335 » » » » » ds := datastore.Get(c)
336 » » » » » So(ds.PutMulti(hugeData), ShouldBeNil)
337 return nil 318 return nil
338 }, nil), ShouldErrLike, ErrTransactionTooLarge) 319 }, nil), ShouldErrLike, ErrTransactionTooLarge)
339 320
340 return nil 321 return nil
341 » » » }, &datastore.TransactionOptions{XG: true}), ShouldBeNil ) 322 » » » }, &ds.TransactionOptions{XG: true}), ShouldBeNil)
342 323
343 » » » So(18, fooShouldHave(ds), hugeField) 324 » » » So(18, fooShouldHave(c), hugeField)
344 }) 325 })
345 326
346 Convey("exceeding inner txn count threshold still allows outer", func() { 327 Convey("exceeding inner txn count threshold still allows outer", func() {
347 » » » So(ds.RunInTransaction(func(c context.Context) error { 328 » » » So(ds.RunInTransaction(c, func(c context.Context) error {
348 » » » » ds := datastore.Get(c) 329 » » » » So(18, fooSetTo(c), hugeField)
349 330
350 » » » » So(18, fooSetTo(ds), hugeField) 331 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
351 332 » » » » » p := ds.MakeKey(c, "mom", 1)
352 » » » » So(ds.RunInTransaction(func(c context.Context) e rror {
353 » » » » » ds := datastore.Get(c)
354 » » » » » p := ds.MakeKey("mom", 1)
355 333
356 // This will exceed the budget, since we 've already done one write in 334 // This will exceed the budget, since we 've already done one write in
357 // the parent. 335 // the parent.
358 for i := 1; i <= DefaultWriteCountBudget ; i++ { 336 for i := 1; i <= DefaultWriteCountBudget ; i++ {
359 » » » » » » So(ds.Put(&Foo{ID: int64(i), Par ent: p}), ShouldBeNil) 337 » » » » » » So(ds.Put(c, &Foo{ID: int64(i), Parent: p}), ShouldBeNil)
360 } 338 }
361 return nil 339 return nil
362 }, nil), ShouldErrLike, ErrTransactionTooLarge) 340 }, nil), ShouldErrLike, ErrTransactionTooLarge)
363 341
364 return nil 342 return nil
365 » » » }, &datastore.TransactionOptions{XG: true}), ShouldBeNil ) 343 » » » }, &ds.TransactionOptions{XG: true}), ShouldBeNil)
366 344
367 » » » So(18, fooShouldHave(ds), hugeField) 345 » » » So(18, fooShouldHave(c), hugeField)
368 }) 346 })
369 347
370 Convey("exceeding threshold in the parent, then retreating in th e child is okay", func() { 348 Convey("exceeding threshold in the parent, then retreating in th e child is okay", func() {
371 » » » So(ds.RunInTransaction(func(c context.Context) error { 349 » » » So(ds.RunInTransaction(c, func(c context.Context) error {
372 » » » » ds := datastore.Get(c) 350 » » » » So(ds.Put(c, hugeData), ShouldBeNil)
373 351 » » » » So(18, fooSetTo(c), hugeField)
374 » » » » So(ds.PutMulti(hugeData), ShouldBeNil)
375 » » » » So(18, fooSetTo(ds), hugeField)
376 352
377 // We're over threshold! But the child will dele te most of this and 353 // We're over threshold! But the child will dele te most of this and
378 // bring us back to normal. 354 // bring us back to normal.
379 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 355 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
380 » » » » » ds := datastore.Get(c) 356 » » » » » keys := make([]*ds.Key, len(hugeData))
381 » » » » » keys := make([]*datastore.Key, len(hugeD ata))
382 for i, d := range hugeData { 357 for i, d := range hugeData {
383 » » » » » » keys[i] = ds.KeyForObj(d) 358 » » » » » » keys[i] = ds.KeyForObj(c, d)
384 } 359 }
385 » » » » » return ds.DeleteMulti(keys) 360 » » » » » return ds.Delete(c, keys)
386 }, nil), ShouldBeNil) 361 }, nil), ShouldBeNil)
387 362
388 return nil 363 return nil
389 » » » }, &datastore.TransactionOptions{XG: true}), ShouldBeNil ) 364 » » » }, &ds.TransactionOptions{XG: true}), ShouldBeNil)
390 365
391 » » » So(18, fooShouldHave(ds), hugeField) 366 » » » So(18, fooShouldHave(c), hugeField)
392 }) 367 })
393 }) 368 })
394 } 369 }
395 370
396 func TestQuerySupport(t *testing.T) { 371 func TestQuerySupport(t *testing.T) {
397 t.Parallel() 372 t.Parallel()
398 373
399 Convey("Queries", t, func() { 374 Convey("Queries", t, func() {
400 Convey("Good", func() { 375 Convey("Good", func() {
401 » » » q := datastore.NewQuery("Foo").Ancestor(root) 376 » » » q := ds.NewQuery("Foo").Ancestor(root)
402 377
403 Convey("normal", func() { 378 Convey("normal", func() {
404 » » » » _, _, ds := mkds(dataSingleRoot) 379 » » » » _, _, c := mkds(dataSingleRoot)
405 » » » » ds.Testable().AddIndexes(&datastore.IndexDefinit ion{ 380 » » » » ds.GetTestable(c).AddIndexes(&ds.IndexDefinition {
406 Kind: "Foo", 381 Kind: "Foo",
407 Ancestor: true, 382 Ancestor: true,
408 » » » » » SortBy: []datastore.IndexColumn{ 383 » » » » » SortBy: []ds.IndexColumn{
409 {Property: "Value"}, 384 {Property: "Value"},
410 }, 385 },
411 }) 386 })
412 387
413 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 388 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
414 » » » » » ds := datastore.Get(c)
415
416 q = q.Lt("Value", 400000000000000000) 389 q = q.Lt("Value", 400000000000000000)
417 390
418 vals := []*Foo{} 391 vals := []*Foo{}
419 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 392 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
420 So(len(vals), ShouldEqual, 8) 393 So(len(vals), ShouldEqual, 8)
421 394
422 » » » » » count, err := ds.Count(q) 395 » » » » » count, err := ds.Count(c, q)
423 So(err, ShouldBeNil) 396 So(err, ShouldBeNil)
424 So(count, ShouldEqual, 8) 397 So(count, ShouldEqual, 8)
425 398
426 f := &Foo{ID: 1, Parent: root} 399 f := &Foo{ID: 1, Parent: root}
427 » » » » » So(ds.Get(f), ShouldBeNil) 400 » » » » » So(ds.Get(c, f), ShouldBeNil)
428 f.Value = append(f.Value, 100) 401 f.Value = append(f.Value, 100)
429 » » » » » So(ds.Put(f), ShouldBeNil) 402 » » » » » So(ds.Put(c, f), ShouldBeNil)
430 403
431 // Wowee, zowee, merged queries! 404 // Wowee, zowee, merged queries!
432 vals2 := []*Foo{} 405 vals2 := []*Foo{}
433 » » » » » So(ds.GetAll(q, &vals2), ShouldBeNil) 406 » » » » » So(ds.GetAll(c, q, &vals2), ShouldBeNil)
434 So(len(vals2), ShouldEqual, 9) 407 So(len(vals2), ShouldEqual, 9)
435 So(vals2[0], ShouldResemble, f) 408 So(vals2[0], ShouldResemble, f)
436 409
437 vals2 = []*Foo{} 410 vals2 = []*Foo{}
438 » » » » » So(ds.GetAll(q.Limit(2).Offset(1), &vals 2), ShouldBeNil) 411 » » » » » So(ds.GetAll(c, q.Limit(2).Offset(1), &v als2), ShouldBeNil)
439 So(len(vals2), ShouldEqual, 2) 412 So(len(vals2), ShouldEqual, 2)
440 So(vals2, ShouldResemble, vals[:2]) 413 So(vals2, ShouldResemble, vals[:2])
441 414
442 return nil 415 return nil
443 }, nil), ShouldBeNil) 416 }, nil), ShouldBeNil)
444 }) 417 })
445 418
446 Convey("keysOnly", func() { 419 Convey("keysOnly", func() {
447 » » » » _, _, ds := mkds([]*Foo{ 420 » » » » _, _, c := mkds([]*Foo{
448 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}}, 421 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}},
449 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}}, 422 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}},
450 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1}}, 423 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1}},
451 {ID: 5, Parent: root, Value: []int64{1, 70, 101}}, 424 {ID: 5, Parent: root, Value: []int64{1, 70, 101}},
452 }) 425 })
453 426
454 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 427 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
455 » » » » » ds := datastore.Get(c)
456
457 q = q.Eq("Value", 1).KeysOnly(true) 428 q = q.Eq("Value", 1).KeysOnly(true)
458 » » » » » vals := []*datastore.Key{} 429 » » » » » vals := []*ds.Key{}
459 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 430 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
460 So(len(vals), ShouldEqual, 3) 431 So(len(vals), ShouldEqual, 3)
461 » » » » » So(vals[2], ShouldResemble, ds.MakeKey(" Parent", 1, "Foo", 5)) 432 » » » » » So(vals[2], ShouldResemble, ds.MakeKey(c , "Parent", 1, "Foo", 5))
462 433
463 // can remove keys 434 // can remove keys
464 » » » » » So(ds.Delete(ds.MakeKey("Parent", 1, "Fo o", 2)), ShouldBeNil) 435 » » » » » So(ds.Delete(c, ds.MakeKey(c, "Parent", 1, "Foo", 2)), ShouldBeNil)
465 » » » » » vals = []*datastore.Key{} 436 » » » » » vals = []*ds.Key{}
466 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 437 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
467 So(len(vals), ShouldEqual, 2) 438 So(len(vals), ShouldEqual, 2)
468 439
469 // and add new ones 440 // and add new ones
470 » » » » » So(ds.Put(&Foo{ID: 1, Parent: root, Valu e: []int64{1, 7, 100}}), ShouldBeNil) 441 » » » » » So(ds.Put(c, &Foo{ID: 1, Parent: root, V alue: []int64{1, 7, 100}}), ShouldBeNil)
471 » » » » » So(ds.Put(&Foo{ID: 7, Parent: root, Valu e: []int64{20, 1}}), ShouldBeNil) 442 » » » » » So(ds.Put(c, &Foo{ID: 7, Parent: root, V alue: []int64{20, 1}}), ShouldBeNil)
472 » » » » » vals = []*datastore.Key{} 443 » » » » » vals = []*ds.Key{}
473 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 444 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
474 So(len(vals), ShouldEqual, 4) 445 So(len(vals), ShouldEqual, 4)
475 446
476 So(vals[0].IntID(), ShouldEqual, 1) 447 So(vals[0].IntID(), ShouldEqual, 1)
477 So(vals[1].IntID(), ShouldEqual, 4) 448 So(vals[1].IntID(), ShouldEqual, 4)
478 So(vals[2].IntID(), ShouldEqual, 5) 449 So(vals[2].IntID(), ShouldEqual, 5)
479 So(vals[3].IntID(), ShouldEqual, 7) 450 So(vals[3].IntID(), ShouldEqual, 7)
480 451
481 return nil 452 return nil
482 }, nil), ShouldBeNil) 453 }, nil), ShouldBeNil)
483 }) 454 })
484 455
485 Convey("project", func() { 456 Convey("project", func() {
486 » » » » _, _, ds := mkds([]*Foo{ 457 » » » » _, _, c := mkds([]*Foo{
487 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}}, 458 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}},
488 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}}, 459 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}},
489 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1}}, 460 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1}},
490 {ID: 5, Parent: root, Value: []int64{1, 70, 101}}, 461 {ID: 5, Parent: root, Value: []int64{1, 70, 101}},
491 }) 462 })
492 463
493 » » » » ds.Testable().AddIndexes(&datastore.IndexDefinit ion{ 464 » » » » ds.GetTestable(c).AddIndexes(&ds.IndexDefinition {
494 Kind: "Foo", 465 Kind: "Foo",
495 Ancestor: true, 466 Ancestor: true,
496 » » » » » SortBy: []datastore.IndexColumn{ 467 » » » » » SortBy: []ds.IndexColumn{
497 {Property: "Value"}, 468 {Property: "Value"},
498 }, 469 },
499 }) 470 })
500 471
501 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 472 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
502 » » » » » ds := datastore.Get(c) 473 » » » » » count, err := ds.Count(c, q.Project("Val ue"))
503
504 » » » » » count, err := ds.Count(q.Project("Value" ))
505 So(err, ShouldBeNil) 474 So(err, ShouldBeNil)
506 So(count, ShouldEqual, 24) 475 So(count, ShouldEqual, 24)
507 476
508 q = q.Project("Value").Offset(4).Limit(1 0) 477 q = q.Project("Value").Offset(4).Limit(1 0)
509 478
510 » » » » » vals := []datastore.PropertyMap{} 479 » » » » » vals := []ds.PropertyMap{}
511 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 480 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
512 So(len(vals), ShouldEqual, 10) 481 So(len(vals), ShouldEqual, 10)
513 482
514 expect := []struct { 483 expect := []struct {
515 id int64 484 id int64
516 val int64 485 val int64
517 }{ 486 }{
518 {2, 3}, 487 {2, 3},
519 {3, 3}, 488 {3, 3},
520 {4, 3}, 489 {4, 3},
521 {2, 4}, 490 {2, 4},
522 {3, 4}, 491 {3, 4},
523 {2, 5}, 492 {2, 5},
524 {3, 5}, 493 {3, 5},
525 {4, 5}, 494 {4, 5},
526 {2, 6}, 495 {2, 6},
527 {3, 6}, 496 {3, 6},
528 } 497 }
529 498
530 for i, pm := range vals { 499 for i, pm := range vals {
531 » » » » » » So(datastore.GetMetaDefault(pm, "key", nil), ShouldResemble, 500 » » » » » » So(ds.GetMetaDefault(pm, "key", nil), ShouldResemble,
532 » » » » » » » ds.MakeKey("Parent", 1, "Foo", expect[i].id)) 501 » » » » » » » ds.MakeKey(c, "Parent", 1, "Foo", expect[i].id))
533 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val) 502 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val)
534 } 503 }
535 504
536 // should remove 4 entries, but there ar e plenty more to fill 505 // should remove 4 entries, but there ar e plenty more to fill
537 » » » » » So(ds.Delete(ds.MakeKey("Parent", 1, "Fo o", 2)), ShouldBeNil) 506 » » » » » So(ds.Delete(c, ds.MakeKey(c, "Parent", 1, "Foo", 2)), ShouldBeNil)
538 507
539 » » » » » vals = []datastore.PropertyMap{} 508 » » » » » vals = []ds.PropertyMap{}
540 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 509 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
541 So(len(vals), ShouldEqual, 10) 510 So(len(vals), ShouldEqual, 10)
542 511
543 expect = []struct { 512 expect = []struct {
544 id int64 513 id int64
545 val int64 514 val int64
546 }{ 515 }{
547 // note (3, 3) and (4, 3) are co rrectly missing because deleting 516 // note (3, 3) and (4, 3) are co rrectly missing because deleting
548 // 2 removed two entries which a re hidden by the Offset(4). 517 // 2 removed two entries which a re hidden by the Offset(4).
549 {3, 4}, 518 {3, 4},
550 {3, 5}, 519 {3, 5},
551 {4, 5}, 520 {4, 5},
552 {3, 6}, 521 {3, 6},
553 {3, 7}, 522 {3, 7},
554 {4, 7}, 523 {4, 7},
555 {3, 8}, 524 {3, 8},
556 {3, 9}, 525 {3, 9},
557 {4, 9}, 526 {4, 9},
558 {4, 11}, 527 {4, 11},
559 } 528 }
560 529
561 for i, pm := range vals { 530 for i, pm := range vals {
562 » » » » » » So(datastore.GetMetaDefault(pm, "key", nil), ShouldResemble, 531 » » » » » » So(ds.GetMetaDefault(pm, "key", nil), ShouldResemble,
563 » » » » » » » ds.MakeKey("Parent", 1, "Foo", expect[i].id)) 532 » » » » » » » ds.MakeKey(c, "Parent", 1, "Foo", expect[i].id))
564 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val) 533 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val)
565 } 534 }
566 535
567 » » » » » So(ds.Put(&Foo{ID: 1, Parent: root, Valu e: []int64{3, 9}}), ShouldBeNil) 536 » » » » » So(ds.Put(c, &Foo{ID: 1, Parent: root, V alue: []int64{3, 9}}), ShouldBeNil)
568 537
569 » » » » » vals = []datastore.PropertyMap{} 538 » » » » » vals = []ds.PropertyMap{}
570 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 539 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
571 So(len(vals), ShouldEqual, 10) 540 So(len(vals), ShouldEqual, 10)
572 541
573 expect = []struct { 542 expect = []struct {
574 id int64 543 id int64
575 val int64 544 val int64
576 }{ 545 }{
577 // 'invisible' {1, 3} entry bump s the {4, 3} into view. 546 // 'invisible' {1, 3} entry bump s the {4, 3} into view.
578 {4, 3}, 547 {4, 3},
579 {3, 4}, 548 {3, 4},
580 {3, 5}, 549 {3, 5},
581 {4, 5}, 550 {4, 5},
582 {3, 6}, 551 {3, 6},
583 {3, 7}, 552 {3, 7},
584 {4, 7}, 553 {4, 7},
585 {3, 8}, 554 {3, 8},
586 {1, 9}, 555 {1, 9},
587 {3, 9}, 556 {3, 9},
588 {4, 9}, 557 {4, 9},
589 } 558 }
590 559
591 for i, pm := range vals { 560 for i, pm := range vals {
592 » » » » » » So(datastore.GetMetaDefault(pm, "key", nil), ShouldResemble, 561 » » » » » » So(ds.GetMetaDefault(pm, "key", nil), ShouldResemble,
593 » » » » » » » ds.MakeKey("Parent", 1, "Foo", expect[i].id)) 562 » » » » » » » ds.MakeKey(c, "Parent", 1, "Foo", expect[i].id))
594 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val) 563 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val)
595 } 564 }
596 565
597 return nil 566 return nil
598 }, nil), ShouldBeNil) 567 }, nil), ShouldBeNil)
599 568
600 }) 569 })
601 570
602 Convey("project+distinct", func() { 571 Convey("project+distinct", func() {
603 » » » » _, _, ds := mkds([]*Foo{ 572 » » » » _, _, c := mkds([]*Foo{
604 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}}, 573 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}},
605 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}}, 574 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}},
606 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1}}, 575 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1}},
607 {ID: 5, Parent: root, Value: []int64{1, 70, 101}}, 576 {ID: 5, Parent: root, Value: []int64{1, 70, 101}},
608 }) 577 })
609 578
610 » » » » ds.Testable().AddIndexes(&datastore.IndexDefinit ion{ 579 » » » » ds.GetTestable(c).AddIndexes(&ds.IndexDefinition {
611 Kind: "Foo", 580 Kind: "Foo",
612 Ancestor: true, 581 Ancestor: true,
613 » » » » » SortBy: []datastore.IndexColumn{ 582 » » » » » SortBy: []ds.IndexColumn{
614 {Property: "Value"}, 583 {Property: "Value"},
615 }, 584 },
616 }) 585 })
617 586
618 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 587 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
619 » » » » » ds := datastore.Get(c)
620
621 q = q.Project("Value").Distinct(true) 588 q = q.Project("Value").Distinct(true)
622 589
623 » » » » » vals := []datastore.PropertyMap{} 590 » » » » » vals := []ds.PropertyMap{}
624 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 591 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
625 So(len(vals), ShouldEqual, 13) 592 So(len(vals), ShouldEqual, 13)
626 593
627 expect := []struct { 594 expect := []struct {
628 id int64 595 id int64
629 val int64 596 val int64
630 }{ 597 }{
631 {2, 1}, 598 {2, 1},
632 {2, 2}, 599 {2, 2},
633 {2, 3}, 600 {2, 3},
634 {2, 4}, 601 {2, 4},
635 {2, 5}, 602 {2, 5},
636 {2, 6}, 603 {2, 6},
637 {2, 7}, 604 {2, 7},
638 {3, 8}, 605 {3, 8},
639 {3, 9}, 606 {3, 9},
640 {4, 11}, 607 {4, 11},
641 {5, 70}, 608 {5, 70},
642 {4, 100}, 609 {4, 100},
643 {5, 101}, 610 {5, 101},
644 } 611 }
645 612
646 for i, pm := range vals { 613 for i, pm := range vals {
647 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val) 614 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val)
648 » » » » » » So(datastore.GetMetaDefault(pm, "key", nil), ShouldResemble, 615 » » » » » » So(ds.GetMetaDefault(pm, "key", nil), ShouldResemble,
649 » » » » » » » ds.MakeKey("Parent", 1, "Foo", expect[i].id)) 616 » » » » » » » ds.MakeKey(c, "Parent", 1, "Foo", expect[i].id))
650 } 617 }
651 618
652 return nil 619 return nil
653 }, nil), ShouldBeNil) 620 }, nil), ShouldBeNil)
654 }) 621 })
655 622
656 Convey("overwrite", func() { 623 Convey("overwrite", func() {
657 data := []*Foo{ 624 data := []*Foo{
658 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}}, 625 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}},
659 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}}, 626 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}},
660 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1, 2}}, 627 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1, 2}},
661 {ID: 5, Parent: root, Value: []int64{1, 70, 101}}, 628 {ID: 5, Parent: root, Value: []int64{1, 70, 101}},
662 } 629 }
663 630
664 » » » » _, _, ds := mkds(data) 631 » » » » _, _, c := mkds(data)
665 632
666 q = q.Eq("Value", 2, 3) 633 q = q.Eq("Value", 2, 3)
667 634
668 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 635 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
669 » » » » » ds := datastore.Get(c)
670
671 vals := []*Foo{} 636 vals := []*Foo{}
672 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 637 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
673 So(len(vals), ShouldEqual, 2) 638 So(len(vals), ShouldEqual, 2)
674 639
675 So(vals[0], ShouldResemble, data[0]) 640 So(vals[0], ShouldResemble, data[0])
676 So(vals[1], ShouldResemble, data[2]) 641 So(vals[1], ShouldResemble, data[2])
677 642
678 foo2 := &Foo{ID: 2, Parent: root, Value: []int64{2, 3}} 643 foo2 := &Foo{ID: 2, Parent: root, Value: []int64{2, 3}}
679 » » » » » So(ds.Put(foo2), ShouldBeNil) 644 » » » » » So(ds.Put(c, foo2), ShouldBeNil)
680 645
681 vals = []*Foo{} 646 vals = []*Foo{}
682 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 647 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
683 So(len(vals), ShouldEqual, 2) 648 So(len(vals), ShouldEqual, 2)
684 649
685 So(vals[0], ShouldResemble, foo2) 650 So(vals[0], ShouldResemble, foo2)
686 So(vals[1], ShouldResemble, data[2]) 651 So(vals[1], ShouldResemble, data[2])
687 652
688 foo1 := &Foo{ID: 1, Parent: root, Value: []int64{2, 3}} 653 foo1 := &Foo{ID: 1, Parent: root, Value: []int64{2, 3}}
689 » » » » » So(ds.Put(foo1), ShouldBeNil) 654 » » » » » So(ds.Put(c, foo1), ShouldBeNil)
690 655
691 vals = []*Foo{} 656 vals = []*Foo{}
692 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 657 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
693 So(len(vals), ShouldEqual, 3) 658 So(len(vals), ShouldEqual, 3)
694 659
695 So(vals[0], ShouldResemble, foo1) 660 So(vals[0], ShouldResemble, foo1)
696 So(vals[1], ShouldResemble, foo2) 661 So(vals[1], ShouldResemble, foo2)
697 So(vals[2], ShouldResemble, data[2]) 662 So(vals[2], ShouldResemble, data[2])
698 663
699 return nil 664 return nil
700 }, nil), ShouldBeNil) 665 }, nil), ShouldBeNil)
701 }) 666 })
702 667
703 projectData := []*Foo{ 668 projectData := []*Foo{
704 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}, Sort: []string{"x", "z"}}, 669 {ID: 2, Parent: root, Value: []int64{1, 2, 3, 4, 5, 6, 7}, Sort: []string{"x", "z"}},
705 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}, Sort: []string{"b"}}, 670 {ID: 3, Parent: root, Value: []int64{3, 4, 5, 6, 7, 8, 9}, Sort: []string{"b"}},
706 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1, 2}, Sort: []string{"aa", "a"}}, 671 {ID: 4, Parent: root, Value: []int64{3, 5, 7, 9, 11, 100, 1, 2}, Sort: []string{"aa", "a"}},
707 {ID: 5, Parent: root, Value: []int64{1, 70, 101} , Sort: []string{"c"}}, 672 {ID: 5, Parent: root, Value: []int64{1, 70, 101} , Sort: []string{"c"}},
708 } 673 }
709 674
710 Convey("project+extra orders", func() { 675 Convey("project+extra orders", func() {
711 676
712 » » » » _, _, ds := mkds(projectData) 677 » » » » _, _, c := mkds(projectData)
713 » » » » ds.Testable().AddIndexes(&datastore.IndexDefinit ion{ 678 » » » » ds.GetTestable(c).AddIndexes(&ds.IndexDefinition {
714 Kind: "Foo", 679 Kind: "Foo",
715 Ancestor: true, 680 Ancestor: true,
716 » » » » » SortBy: []datastore.IndexColumn{ 681 » » » » » SortBy: []ds.IndexColumn{
717 {Property: "Sort", Descending: t rue}, 682 {Property: "Sort", Descending: t rue},
718 {Property: "Value", Descending: true}, 683 {Property: "Value", Descending: true},
719 }, 684 },
720 }) 685 })
721 686
722 q = q.Project("Value").Order("-Sort", "-Value"). Distinct(true) 687 q = q.Project("Value").Order("-Sort", "-Value"). Distinct(true)
723 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 688 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
724 » » » » » ds = datastore.Get(c) 689 » » » » » So(ds.Put(c, &Foo{
725
726 » » » » » So(ds.Put(&Foo{
727 ID: 1, Parent: root, Value: []in t64{0, 1, 1000}, 690 ID: 1, Parent: root, Value: []in t64{0, 1, 1000},
728 Sort: []string{"zz"}}), ShouldBe Nil) 691 Sort: []string{"zz"}}), ShouldBe Nil)
729 692
730 » » » » » vals := []datastore.PropertyMap{} 693 » » » » » vals := []ds.PropertyMap{}
731 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 694 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
732 695
733 expect := []struct { 696 expect := []struct {
734 id int64 697 id int64
735 val int64 698 val int64
736 }{ 699 }{
737 {1, 1000}, 700 {1, 1000},
738 {1, 1}, 701 {1, 1},
739 {1, 0}, 702 {1, 0},
740 {2, 7}, 703 {2, 7},
741 {2, 6}, 704 {2, 6},
742 {2, 5}, 705 {2, 5},
743 {2, 4}, 706 {2, 4},
744 {2, 3}, 707 {2, 3},
745 {2, 2}, 708 {2, 2},
746 {5, 101}, 709 {5, 101},
747 {5, 70}, 710 {5, 70},
748 {3, 9}, 711 {3, 9},
749 {3, 8}, 712 {3, 8},
750 {4, 100}, 713 {4, 100},
751 {4, 11}, 714 {4, 11},
752 } 715 }
753 716
754 for i, pm := range vals { 717 for i, pm := range vals {
755 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val) 718 So(pm.Slice("Value")[0].Value(), ShouldEqual, expect[i].val)
756 » » » » » » So(datastore.GetMetaDefault(pm, "key", nil), ShouldResemble, 719 » » » » » » So(ds.GetMetaDefault(pm, "key", nil), ShouldResemble,
757 » » » » » » » ds.MakeKey("Parent", 1, "Foo", expect[i].id)) 720 » » » » » » » ds.MakeKey(c, "Parent", 1, "Foo", expect[i].id))
758 } 721 }
759 722
760 return nil 723 return nil
761 }, nil), ShouldBeNil) 724 }, nil), ShouldBeNil)
762 }) 725 })
763 726
764 Convey("buffered entity sorts before ineq, but after fir st parent entity", func() { 727 Convey("buffered entity sorts before ineq, but after fir st parent entity", func() {
765 // If we got this wrong, we'd see Foo,3 come bef ore Foo,2. This might 728 // If we got this wrong, we'd see Foo,3 come bef ore Foo,2. This might
766 // happen because we calculate the comparison st ring for each entity 729 // happen because we calculate the comparison st ring for each entity
767 // based on the whole entity, but we forgot to l imit the comparison 730 // based on the whole entity, but we forgot to l imit the comparison
768 // string generation by the inequality criteria. 731 // string generation by the inequality criteria.
769 data := []*Foo{ 732 data := []*Foo{
770 {ID: 2, Parent: root, Value: []int64{2, 3, 5, 6}, Sort: []string{"z"}}, 733 {ID: 2, Parent: root, Value: []int64{2, 3, 5, 6}, Sort: []string{"z"}},
771 } 734 }
772 735
773 » » » » _, _, ds := mkds(data) 736 » » » » _, _, c := mkds(data)
774 » » » » ds.Testable().AddIndexes(&datastore.IndexDefinit ion{ 737 » » » » ds.GetTestable(c).AddIndexes(&ds.IndexDefinition {
775 Kind: "Foo", 738 Kind: "Foo",
776 Ancestor: true, 739 Ancestor: true,
777 » » » » » SortBy: []datastore.IndexColumn{ 740 » » » » » SortBy: []ds.IndexColumn{
778 {Property: "Value"}, 741 {Property: "Value"},
779 }, 742 },
780 }) 743 })
781 744
782 q = q.Gt("Value", 2).Limit(2) 745 q = q.Gt("Value", 2).Limit(2)
783 746
784 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 747 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
785 » » » » » ds = datastore.Get(c)
786
787 foo1 := &Foo{ID: 3, Parent: root, Value: []int64{0, 2, 3, 4}} 748 foo1 := &Foo{ID: 3, Parent: root, Value: []int64{0, 2, 3, 4}}
788 » » » » » So(ds.Put(foo1), ShouldBeNil) 749 » » » » » So(ds.Put(c, foo1), ShouldBeNil)
789 750
790 vals := []*Foo{} 751 vals := []*Foo{}
791 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 752 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
792 So(len(vals), ShouldEqual, 2) 753 So(len(vals), ShouldEqual, 2)
793 754
794 So(vals[0], ShouldResemble, data[0]) 755 So(vals[0], ShouldResemble, data[0])
795 So(vals[1], ShouldResemble, foo1) 756 So(vals[1], ShouldResemble, foo1)
796 757
797 return nil 758 return nil
798 }, nil), ShouldBeNil) 759 }, nil), ShouldBeNil)
799 }) 760 })
800 761
801 Convey("keysOnly+extra orders", func() { 762 Convey("keysOnly+extra orders", func() {
802 » » » » _, _, ds := mkds(projectData) 763 » » » » _, _, c := mkds(projectData)
803 » » » » ds.Testable().AddIndexes(&datastore.IndexDefinit ion{ 764 » » » » ds.GetTestable(c).AddIndexes(&ds.IndexDefinition {
804 Kind: "Foo", 765 Kind: "Foo",
805 Ancestor: true, 766 Ancestor: true,
806 » » » » » SortBy: []datastore.IndexColumn{ 767 » » » » » SortBy: []ds.IndexColumn{
807 {Property: "Sort"}, 768 {Property: "Sort"},
808 }, 769 },
809 }) 770 })
810 771
811 q = q.Order("Sort").KeysOnly(true) 772 q = q.Order("Sort").KeysOnly(true)
812 773
813 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 774 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
814 » » » » » ds = datastore.Get(c) 775 » » » » » So(ds.Put(c, &Foo{
815
816 » » » » » So(ds.Put(&Foo{
817 ID: 1, Parent: root, Value: []in t64{0, 1, 1000}, 776 ID: 1, Parent: root, Value: []in t64{0, 1, 1000},
818 Sort: []string{"x", "zz"}}), Sho uldBeNil) 777 Sort: []string{"x", "zz"}}), Sho uldBeNil)
819 778
820 » » » » » So(ds.Put(&Foo{ 779 » » » » » So(ds.Put(c, &Foo{
821 ID: 2, Parent: root, Value: []in t64{0, 1, 1000}, 780 ID: 2, Parent: root, Value: []in t64{0, 1, 1000},
822 Sort: []string{"zz", "zzz", "zzz z"}}), ShouldBeNil) 781 Sort: []string{"zz", "zzz", "zzz z"}}), ShouldBeNil)
823 782
824 » » » » » vals := []*datastore.Key{} 783 » » » » » vals := []*ds.Key{}
825 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 784 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
826 So(len(vals), ShouldEqual, 5) 785 So(len(vals), ShouldEqual, 5)
827 786
828 » » » » » So(vals, ShouldResemble, []*datastore.Ke y{ 787 » » » » » kc := ds.GetKeyContext(c)
829 » » » » » » ds.MakeKey("Parent", 1, "Foo", 4 ), 788 » » » » » So(vals, ShouldResemble, []*ds.Key{
830 » » » » » » ds.MakeKey("Parent", 1, "Foo", 3 ), 789 » » » » » » kc.MakeKey("Parent", 1, "Foo", 4 ),
831 » » » » » » ds.MakeKey("Parent", 1, "Foo", 5 ), 790 » » » » » » kc.MakeKey("Parent", 1, "Foo", 3 ),
832 » » » » » » ds.MakeKey("Parent", 1, "Foo", 1 ), 791 » » » » » » kc.MakeKey("Parent", 1, "Foo", 5 ),
833 » » » » » » ds.MakeKey("Parent", 1, "Foo", 2 ), 792 » » » » » » kc.MakeKey("Parent", 1, "Foo", 1 ),
793 » » » » » » kc.MakeKey("Parent", 1, "Foo", 2 ),
834 }) 794 })
835 795
836 return nil 796 return nil
837 }, nil), ShouldBeNil) 797 }, nil), ShouldBeNil)
838 }) 798 })
839 799
840 Convey("query accross nested transactions", func() { 800 Convey("query accross nested transactions", func() {
841 » » » » _, _, ds := mkds(projectData) 801 » » » » _, _, c := mkds(projectData)
842 q = q.Eq("Value", 2, 3) 802 q = q.Eq("Value", 2, 3)
843 803
844 foo1 := &Foo{ID: 1, Parent: root, Value: []int64 {2, 3}} 804 foo1 := &Foo{ID: 1, Parent: root, Value: []int64 {2, 3}}
845 foo7 := &Foo{ID: 7, Parent: root, Value: []int64 {2, 3}} 805 foo7 := &Foo{ID: 7, Parent: root, Value: []int64 {2, 3}}
846 806
847 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 807 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
848 » » » » » ds := datastore.Get(c) 808 » » » » » So(ds.Put(c, foo1), ShouldBeNil)
849
850 » » » » » So(ds.Put(foo1), ShouldBeNil)
851 809
852 vals := []*Foo{} 810 vals := []*Foo{}
853 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 811 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
854 So(vals, ShouldResemble, []*Foo{foo1, pr ojectData[0], projectData[2]}) 812 So(vals, ShouldResemble, []*Foo{foo1, pr ojectData[0], projectData[2]})
855 813
856 » » » » » So(ds.RunInTransaction(func(c context.Co ntext) error { 814 » » » » » So(ds.RunInTransaction(c, func(c context .Context) error {
857 » » » » » » ds := datastore.Get(c)
858
859 vals := []*Foo{} 815 vals := []*Foo{}
860 » » » » » » So(ds.GetAll(q, &vals), ShouldBe Nil) 816 » » » » » » So(ds.GetAll(c, q, &vals), Shoul dBeNil)
861 So(vals, ShouldResemble, []*Foo{ foo1, projectData[0], projectData[2]}) 817 So(vals, ShouldResemble, []*Foo{ foo1, projectData[0], projectData[2]})
862 818
863 » » » » » » So(ds.Delete(ds.MakeKey("Parent" , 1, "Foo", 4)), ShouldBeNil) 819 » » » » » » So(ds.Delete(c, ds.MakeKey(c, "P arent", 1, "Foo", 4)), ShouldBeNil)
864 » » » » » » So(ds.Put(foo7), ShouldBeNil) 820 » » » » » » So(ds.Put(c, foo7), ShouldBeNil)
865 821
866 vals = []*Foo{} 822 vals = []*Foo{}
867 » » » » » » So(ds.GetAll(q, &vals), ShouldBe Nil) 823 » » » » » » So(ds.GetAll(c, q, &vals), Shoul dBeNil)
868 So(vals, ShouldResemble, []*Foo{ foo1, projectData[0], foo7}) 824 So(vals, ShouldResemble, []*Foo{ foo1, projectData[0], foo7})
869 825
870 return nil 826 return nil
871 }, nil), ShouldBeNil) 827 }, nil), ShouldBeNil)
872 828
873 vals = []*Foo{} 829 vals = []*Foo{}
874 » » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 830 » » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
875 So(vals, ShouldResemble, []*Foo{foo1, pr ojectData[0], foo7}) 831 So(vals, ShouldResemble, []*Foo{foo1, pr ojectData[0], foo7})
876 832
877 return nil 833 return nil
878 }, nil), ShouldBeNil) 834 }, nil), ShouldBeNil)
879 835
880 vals := []*Foo{} 836 vals := []*Foo{}
881 » » » » So(ds.GetAll(q, &vals), ShouldBeNil) 837 » » » » So(ds.GetAll(c, q, &vals), ShouldBeNil)
882 So(vals, ShouldResemble, []*Foo{foo1, projectDat a[0], foo7}) 838 So(vals, ShouldResemble, []*Foo{foo1, projectDat a[0], foo7})
883 839
884 }) 840 })
885 841
886 Convey("start transaction from inside query", func() { 842 Convey("start transaction from inside query", func() {
887 » » » » _, _, ds := mkds(projectData) 843 » » » » _, _, c := mkds(projectData)
888 » » » » So(ds.RunInTransaction(func(c context.Context) e rror { 844 » » » » So(ds.RunInTransaction(c, func(c context.Context ) error {
889 » » » » » ds := datastore.Get(c) 845 » » » » » q := ds.NewQuery("Foo").Ancestor(root)
890 846 » » » » » return ds.Run(c, q, func(pm ds.PropertyM ap) {
891 » » » » » q := datastore.NewQuery("Foo").Ancestor( root) 847 » » » » » » So(ds.RunInTransaction(c, func(c context.Context) error {
892 » » » » » return ds.Run(q, func(pm datastore.Prope rtyMap) { 848 » » » » » » » pm["Value"] = append(pm. Slice("Value"), ds.MkProperty("wat"))
893 » » » » » » So(ds.RunInTransaction(func(c co ntext.Context) error { 849 » » » » » » » return ds.Put(c, pm)
894 » » » » » » » ds := datastore.Get(c)
895 » » » » » » » pm["Value"] = append(pm. Slice("Value"), datastore.MkProperty("wat"))
896 » » » » » » » return ds.Put(pm)
897 }, nil), ShouldBeNil) 850 }, nil), ShouldBeNil)
898 }) 851 })
899 » » » » }, &datastore.TransactionOptions{XG: true}), Sho uldBeNil) 852 » » » » }, &ds.TransactionOptions{XG: true}), ShouldBeNi l)
900 853
901 » » » » So(ds.Run(datastore.NewQuery("Foo"), func(pm dat astore.PropertyMap) { 854 » » » » So(ds.Run(c, ds.NewQuery("Foo"), func(pm ds.Prop ertyMap) {
902 val := pm.Slice("Value") 855 val := pm.Slice("Value")
903 So(val[len(val)-1].Value(), ShouldResemb le, "wat") 856 So(val[len(val)-1].Value(), ShouldResemb le, "wat")
904 }), ShouldBeNil) 857 }), ShouldBeNil)
905 }) 858 })
906 859
907 }) 860 })
908 861
909 }) 862 })
910 863
911 } 864 }
OLDNEW
« no previous file with comments | « filter/txnBuf/state.go ('k') | impl/cloud/datastore.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698