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

Side by Side Diff: impl/prod/everything_test.go

Issue 2342063003: Differentiate between single- and multi- props. (Closed)
Patch Set: Slice is now always a clone. This is marginally worse performance, but a much safer UI. 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 | « impl/memory/testing_utils_test.go ('k') | impl/prod/raw_datastore_type_converter.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 // +build appengine 5 // +build appengine
6 6
7 package prod 7 package prod
8 8
9 import ( 9 import (
10 "testing" 10 "testing"
(...skipping 10 matching lines...) Expand all
21 ) 21 )
22 22
23 var ( 23 var (
24 mp = datastore.MkProperty 24 mp = datastore.MkProperty
25 mpNI = datastore.MkPropertyNI 25 mpNI = datastore.MkPropertyNI
26 ) 26 )
27 27
28 type TestStruct struct { 28 type TestStruct struct {
29 ID int64 `gae:"$id"` 29 ID int64 `gae:"$id"`
30 30
31 » ValueI []int64 31 » ValueI []int64
32 » ValueB []bool 32 » ValueB []bool
33 » ValueS []string 33 » ValueS []string
34 » ValueF []float64 34 » ValueF []float64
35 » ValueBS [][]byte // "ByteString" 35 » ValueBS [][]byte // "ByteString"
36 » ValueK []*datastore.Key 36 » ValueK []*datastore.Key
37 » ValueBK []blobstore.Key 37 » ValueBK []blobstore.Key
38 » ValueGP []datastore.GeoPoint 38 » ValueGP []datastore.GeoPoint
39 » ValueSingle string
40 » ValueSingleSlice []string
39 } 41 }
40 42
41 func TestBasicDatastore(t *testing.T) { 43 func TestBasicDatastore(t *testing.T) {
42 t.Parallel() 44 t.Parallel()
43 45
44 Convey("basic", t, func() { 46 Convey("basic", t, func() {
45 inst, err := aetest.NewInstance(&aetest.Options{ 47 inst, err := aetest.NewInstance(&aetest.Options{
46 StronglyConsistentDatastore: true, 48 StronglyConsistentDatastore: true,
47 }) 49 })
48 So(err, ShouldBeNil) 50 So(err, ShouldBeNil)
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 ValueK: []*datastore.Key{ 124 ValueK: []*datastore.Key{
123 ds.NewKey("Something", "Cool", 0, nil), 125 ds.NewKey("Something", "Cool", 0, nil),
124 ds.NewKey("Something", "", 1, nil), 126 ds.NewKey("Something", "", 1, nil),
125 ds.NewKey("Something", "Recursive", 0, 127 ds.NewKey("Something", "Recursive", 0,
126 ds.NewKey("Parent", "", 2, nil)) , 128 ds.NewKey("Parent", "", 2, nil)) ,
127 }, 129 },
128 ValueBK: []blobstore.Key{"bellow", "hello"}, 130 ValueBK: []blobstore.Key{"bellow", "hello"},
129 ValueGP: []datastore.GeoPoint{ 131 ValueGP: []datastore.GeoPoint{
130 {Lat: 120.7, Lng: 95.5}, 132 {Lat: 120.7, Lng: 95.5},
131 }, 133 },
134 ValueSingle: "ohai",
135 ValueSingleSlice: []string{"kthxbye"},
132 } 136 }
133 So(ds.Put(&orig), ShouldBeNil) 137 So(ds.Put(&orig), ShouldBeNil)
134 138
135 ret := TestStruct{ID: orig.ID} 139 ret := TestStruct{ID: orig.ID}
136 So(ds.Get(&ret), ShouldBeNil) 140 So(ds.Get(&ret), ShouldBeNil)
137 So(ret, ShouldResemble, orig) 141 So(ret, ShouldResemble, orig)
138 142
143 // make sure single- and multi- properties are preserved .
144 pmap := datastore.PropertyMap{
145 "$id": mpNI(orig.ID),
146 "$kind": mpNI("TestStruct"),
147 }
148 So(ds.Get(pmap), ShouldBeNil)
149 So(pmap["ValueSingle"], ShouldHaveSameTypeAs, datastore. Property{})
150 So(pmap["ValueSingleSlice"], ShouldHaveSameTypeAs, datas tore.PropertySlice(nil))
151
139 // can't be sure the indexes have caught up... so sleep 152 // can't be sure the indexes have caught up... so sleep
140 time.Sleep(time.Second) 153 time.Sleep(time.Second)
141 154
142 Convey("Can query", func() { 155 Convey("Can query", func() {
143 q := datastore.NewQuery("TestStruct") 156 q := datastore.NewQuery("TestStruct")
144 ds.Run(q, func(ts *TestStruct) { 157 ds.Run(q, func(ts *TestStruct) {
145 So(*ts, ShouldResemble, orig) 158 So(*ts, ShouldResemble, orig)
146 }) 159 })
147 count, err := ds.Count(q) 160 count, err := ds.Count(q)
148 So(err, ShouldBeNil) 161 So(err, ShouldBeNil)
149 So(count, ShouldEqual, 1) 162 So(count, ShouldEqual, 1)
150 }) 163 })
151 164
152 Convey("Can project", func() { 165 Convey("Can project", func() {
153 q := datastore.NewQuery("TestStruct").Project("V alueS") 166 q := datastore.NewQuery("TestStruct").Project("V alueS")
154 rslts := []datastore.PropertyMap{} 167 rslts := []datastore.PropertyMap{}
155 So(ds.GetAll(q, &rslts), ShouldBeNil) 168 So(ds.GetAll(q, &rslts), ShouldBeNil)
156 So(rslts, ShouldResemble, []datastore.PropertyMa p{ 169 So(rslts, ShouldResemble, []datastore.PropertyMa p{
157 { 170 {
158 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 171 » » » » » » "$key": mpNI(ds.KeyForObj(&ori g)),
159 » » » » » » "ValueS": {mp("hello")}, 172 » » » » » » "ValueS": mp("hello"),
160 }, 173 },
161 { 174 {
162 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 175 » » » » » » "$key": mpNI(ds.KeyForObj(&ori g)),
163 » » » » » » "ValueS": {mp("world")}, 176 » » » » » » "ValueS": mp("world"),
164 }, 177 },
165 }) 178 })
166 179
167 q = datastore.NewQuery("TestStruct").Project("Va lueBS") 180 q = datastore.NewQuery("TestStruct").Project("Va lueBS")
168 rslts = []datastore.PropertyMap{} 181 rslts = []datastore.PropertyMap{}
169 So(ds.GetAll(q, &rslts), ShouldBeNil) 182 So(ds.GetAll(q, &rslts), ShouldBeNil)
170 So(rslts, ShouldResemble, []datastore.PropertyMa p{ 183 So(rslts, ShouldResemble, []datastore.PropertyMa p{
171 { 184 {
172 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 185 » » » » » » "$key": mpNI(ds.KeyForObj(&or ig)),
173 » » » » » » "ValueBS": {mp("allo")}, 186 » » » » » » "ValueBS": mp("allo"),
174 }, 187 },
175 { 188 {
176 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 189 » » » » » » "$key": mpNI(ds.KeyForObj(&or ig)),
177 » » » » » » "ValueBS": {mp("hello")}, 190 » » » » » » "ValueBS": mp("hello"),
178 }, 191 },
179 { 192 {
180 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 193 » » » » » » "$key": mpNI(ds.KeyForObj(&or ig)),
181 » » » » » » "ValueBS": {mp("world")}, 194 » » » » » » "ValueBS": mp("world"),
182 }, 195 },
183 { 196 {
184 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 197 » » » » » » "$key": mpNI(ds.KeyForObj(&or ig)),
185 » » » » » » "ValueBS": {mp("zurple")}, 198 » » » » » » "ValueBS": mp("zurple"),
186 }, 199 },
187 }) 200 })
188 201
189 count, err := ds.Count(q) 202 count, err := ds.Count(q)
190 So(err, ShouldBeNil) 203 So(err, ShouldBeNil)
191 So(count, ShouldEqual, 4) 204 So(count, ShouldEqual, 4)
192 205
193 q = datastore.NewQuery("TestStruct").Lte("ValueI ", 7).Project("ValueS").Distinct(true) 206 q = datastore.NewQuery("TestStruct").Lte("ValueI ", 7).Project("ValueS").Distinct(true)
194 rslts = []datastore.PropertyMap{} 207 rslts = []datastore.PropertyMap{}
195 So(ds.GetAll(q, &rslts), ShouldBeNil) 208 So(ds.GetAll(q, &rslts), ShouldBeNil)
196 So(rslts, ShouldResemble, []datastore.PropertyMa p{ 209 So(rslts, ShouldResemble, []datastore.PropertyMa p{
197 { 210 {
198 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 211 » » » » » » "$key": mpNI(ds.KeyForObj(&ori g)),
199 » » » » » » "ValueI": {mp(1)}, 212 » » » » » » "ValueI": mp(1),
200 » » » » » » "ValueS": {mp("hello")}, 213 » » » » » » "ValueS": mp("hello"),
201 }, 214 },
202 { 215 {
203 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 216 » » » » » » "$key": mpNI(ds.KeyForObj(&ori g)),
204 » » » » » » "ValueI": {mp(1)}, 217 » » » » » » "ValueI": mp(1),
205 » » » » » » "ValueS": {mp("world")}, 218 » » » » » » "ValueS": mp("world"),
206 }, 219 },
207 { 220 {
208 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 221 » » » » » » "$key": mpNI(ds.KeyForObj(&ori g)),
209 » » » » » » "ValueI": {mp(7)}, 222 » » » » » » "ValueI": mp(7),
210 » » » » » » "ValueS": {mp("hello")}, 223 » » » » » » "ValueS": mp("hello"),
211 }, 224 },
212 { 225 {
213 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 226 » » » » » » "$key": mpNI(ds.KeyForObj(&ori g)),
214 » » » » » » "ValueI": {mp(7)}, 227 » » » » » » "ValueI": mp(7),
215 » » » » » » "ValueS": {mp("world")}, 228 » » » » » » "ValueS": mp("world"),
216 }, 229 },
217 }) 230 })
218 231
219 count, err = ds.Count(q) 232 count, err = ds.Count(q)
220 So(err, ShouldBeNil) 233 So(err, ShouldBeNil)
221 So(count, ShouldEqual, 4) 234 So(count, ShouldEqual, 4)
222 }) 235 })
223 }) 236 })
224 237
225 Convey("Can Put/Get (time)", func() { 238 Convey("Can Put/Get (time)", func() {
226 // time comparisons in Go are wonky, so this is pulled o ut 239 // time comparisons in Go are wonky, so this is pulled o ut
227 pm := datastore.PropertyMap{ 240 pm := datastore.PropertyMap{
228 » » » » "$key": {mpNI(ds.NewKey("Something", "value", 0, nil))}, 241 » » » » "$key": mpNI(ds.NewKey("Something", "value", 0, nil)),
229 » » » » "Time": { 242 » » » » "Time": datastore.PropertySlice{
230 mp(time.Date(1938, time.January, 1, 1, 1 , 1, 1, time.UTC)), 243 mp(time.Date(1938, time.January, 1, 1, 1 , 1, 1, time.UTC)),
231 mp(time.Time{}), 244 mp(time.Time{}),
232 }, 245 },
233 } 246 }
234 So(ds.Put(&pm), ShouldBeNil) 247 So(ds.Put(&pm), ShouldBeNil)
235 248
236 rslt := datastore.PropertyMap{} 249 rslt := datastore.PropertyMap{}
237 rslt.SetMeta("key", ds.KeyForObj(pm)) 250 rslt.SetMeta("key", ds.KeyForObj(pm))
238 So(ds.Get(&rslt), ShouldBeNil) 251 So(ds.Get(&rslt), ShouldBeNil)
239 252
240 » » » So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0 ].Value()) 253 » » » So(pm.Slice("Time")[0].Value(), ShouldResemble, rslt.Sli ce("Time")[0].Value())
241 254
242 q := datastore.NewQuery("Something").Project("Time") 255 q := datastore.NewQuery("Something").Project("Time")
243 all := []datastore.PropertyMap{} 256 all := []datastore.PropertyMap{}
244 So(ds.GetAll(q, &all), ShouldBeNil) 257 So(ds.GetAll(q, &all), ShouldBeNil)
245 So(len(all), ShouldEqual, 2) 258 So(len(all), ShouldEqual, 2)
246 » » » prop := all[0]["Time"][0] 259 » » » prop := all[0].Slice("Time")[0]
247 So(prop.Type(), ShouldEqual, datastore.PTInt) 260 So(prop.Type(), ShouldEqual, datastore.PTInt)
248 261
249 tval, err := prop.Project(datastore.PTTime) 262 tval, err := prop.Project(datastore.PTTime)
250 So(err, ShouldBeNil) 263 So(err, ShouldBeNil)
251 So(tval, ShouldResemble, time.Time{}.UTC()) 264 So(tval, ShouldResemble, time.Time{}.UTC())
252 265
253 » » » tval, err = all[1]["Time"][0].Project(datastore.PTTime) 266 » » » tval, err = all[1].Slice("Time")[0].Project(datastore.PT Time)
254 So(err, ShouldBeNil) 267 So(err, ShouldBeNil)
255 » » » So(tval, ShouldResemble, pm["Time"][0].Value()) 268 » » » So(tval, ShouldResemble, pm.Slice("Time")[0].Value())
256 269
257 ent := datastore.PropertyMap{ 270 ent := datastore.PropertyMap{
258 » » » » "$key": {mpNI(ds.MakeKey("Something", "value"))} , 271 » » » » "$key": mpNI(ds.MakeKey("Something", "value")),
259 } 272 }
260 So(ds.Get(&ent), ShouldBeNil) 273 So(ds.Get(&ent), ShouldBeNil)
261 So(ent["Time"], ShouldResemble, pm["Time"]) 274 So(ent["Time"], ShouldResemble, pm["Time"])
262 }) 275 })
263 276
264 Convey("memcache: Set (nil) is the same as Set ([]byte{})", func () { 277 Convey("memcache: Set (nil) is the same as Set ([]byte{})", func () {
265 So(mc.Set(mc.NewItem("bob")), ShouldBeNil) // normally w ould panic because Value is nil 278 So(mc.Set(mc.NewItem("bob")), ShouldBeNil) // normally w ould panic because Value is nil
266 279
267 bob, err := mc.Get("bob") 280 bob, err := mc.Get("bob")
268 So(err, ShouldBeNil) 281 So(err, ShouldBeNil)
269 So(bob.Value(), ShouldResemble, []byte{}) 282 So(bob.Value(), ShouldResemble, []byte{})
270 }) 283 })
271 }) 284 })
272 } 285 }
OLDNEW
« no previous file with comments | « impl/memory/testing_utils_test.go ('k') | impl/prod/raw_datastore_type_converter.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698