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

Side by Side Diff: impl/cloud/datastore_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/cloud/datastore.go ('k') | impl/memory/datastore_data.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 2016 The LUCI Authors. All rights reserved. 1 // Copyright 2016 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 cloud 5 package cloud
6 6
7 import ( 7 import (
8 "crypto/rand" 8 "crypto/rand"
9 "encoding/hex" 9 "encoding/hex"
10 "fmt" 10 "fmt"
11 "os" 11 "os"
12 "testing" 12 "testing"
13 "time" 13 "time"
14 14
15 ds "github.com/luci/gae/service/datastore" 15 ds "github.com/luci/gae/service/datastore"
16 "github.com/luci/gae/service/info" 16 "github.com/luci/gae/service/info"
17 17
18 "cloud.google.com/go/datastore" 18 "cloud.google.com/go/datastore"
19 "github.com/luci/luci-go/common/errors" 19 "github.com/luci/luci-go/common/errors"
20 "golang.org/x/net/context" 20 "golang.org/x/net/context"
21 21
22 . "github.com/smartystreets/goconvey/convey" 22 . "github.com/smartystreets/goconvey/convey"
23 ) 23 )
24 24
25 func mkProperties(index bool, vals ...interface{}) []ds.Property { 25 func mkProperties(index bool, forceMulti bool, vals ...interface{}) ds.PropertyD ata {
26 indexSetting := ds.ShouldIndex 26 indexSetting := ds.ShouldIndex
27 if !index { 27 if !index {
28 indexSetting = ds.NoIndex 28 indexSetting = ds.NoIndex
29 } 29 }
30 30
31 » result := make([]ds.Property, len(vals)) 31 » if len(vals) == 1 && !forceMulti {
32 » » var prop ds.Property
33 » » prop.SetValue(vals[0], indexSetting)
34 » » return prop
35 » }
36
37 » result := make(ds.PropertySlice, len(vals))
32 for i, v := range vals { 38 for i, v := range vals {
33 result[i].SetValue(v, indexSetting) 39 result[i].SetValue(v, indexSetting)
34 } 40 }
35 return result 41 return result
36 } 42 }
37 43
38 func mkp(vals ...interface{}) []ds.Property { return mkProperties(true, vals.. .) } 44 func mkp(vals ...interface{}) ds.PropertyData { return mkProperties(true, fals e, vals...) }
39 func mkpNI(vals ...interface{}) []ds.Property { return mkProperties(false, vals. ..) } 45 func mkpNI(vals ...interface{}) ds.PropertyData { return mkProperties(false, fal se, vals...) }
40 46
41 // TestDatastore tests the cloud datastore implementation. 47 // TestDatastore tests the cloud datastore implementation.
42 // 48 //
43 // This test uses the gcloud datastore emulator. Like the Go datastore package, 49 // This test uses the gcloud datastore emulator. Like the Go datastore package,
44 // the emulator must use the gRPC interface. At the time of writing, the 50 // the emulator must use the gRPC interface. At the time of writing, the
45 // emulator included with the "gcloud" tool is an older emulator that does NOT 51 // emulator included with the "gcloud" tool is an older emulator that does NOT
46 // support gRPC. 52 // support gRPC.
47 // 53 //
48 // Download the emulator linked here: 54 // Download the emulator linked here:
49 // https://code.google.com/p/google-cloud-sdk/issues/detail?id=719#c3 55 // https://code.google.com/p/google-cloud-sdk/issues/detail?id=719#c3
(...skipping 17 matching lines...) Expand all
67 return 73 return
68 } 74 }
69 75
70 Convey(fmt.Sprintf(`A cloud installation using datastore emulator %q`, e mulatorHost), t, func() { 76 Convey(fmt.Sprintf(`A cloud installation using datastore emulator %q`, e mulatorHost), t, func() {
71 c := context.Background() 77 c := context.Background()
72 client, err := datastore.NewClient(c, "luci-gae-test") 78 client, err := datastore.NewClient(c, "luci-gae-test")
73 So(err, ShouldBeNil) 79 So(err, ShouldBeNil)
74 defer client.Close() 80 defer client.Close()
75 81
76 testTime := ds.RoundTime(time.Date(2016, 1, 1, 0, 0, 0, 0, time. UTC)) 82 testTime := ds.RoundTime(time.Date(2016, 1, 1, 0, 0, 0, 0, time. UTC))
83 _ = testTime
77 84
78 c = Use(c, client) 85 c = Use(c, client)
79 86
80 Convey(`Supports namespaces`, func() { 87 Convey(`Supports namespaces`, func() {
81 namespaces := []string{"foo", "bar", "baz"} 88 namespaces := []string{"foo", "bar", "baz"}
82 89
83 // Clear all used entities from all namespaces. 90 // Clear all used entities from all namespaces.
84 for _, ns := range namespaces { 91 for _, ns := range namespaces {
85 nsCtx := info.Get(c).MustNamespace(ns) 92 nsCtx := info.Get(c).MustNamespace(ns)
86 di := ds.Get(nsCtx) 93 di := ds.Get(nsCtx)
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 So(merr[1], ShouldEqual, ds.ErrNoSuchEntity) 191 So(merr[1], ShouldEqual, ds.ErrNoSuchEntity)
185 So(merr[2], ShouldBeNil) 192 So(merr[2], ShouldBeNil)
186 193
187 // put[1] will not be retrieved (delete) 194 // put[1] will not be retrieved (delete)
188 put[1] = get[1] 195 put[1] = get[1]
189 So(get, ShouldResemble, put) 196 So(get, ShouldResemble, put)
190 }) 197 })
191 198
192 Convey(`Can put and get all supported entity fields.`, f unc() { 199 Convey(`Can put and get all supported entity fields.`, f unc() {
193 put := ds.PropertyMap{ 200 put := ds.PropertyMap{
194 » » » » » "$id": mkpNI("foo"), 201 » » » » » "$id": mkpNI("foo"),
195 » » » » » "$kind": mkpNI("FooType"), 202 » » » » » "$kind": mkpNI("FooType"),
196 » » » » » "Number": mkp(1337), 203
197 » » » » » "String": mkpNI("hello"), 204 » » » » » "Number": mkp(1337),
198 » » » » » "Bytes": mkp([]byte("world")), 205 » » » » » "String": mkpNI("hello"),
199 » » » » » "Time": mkp(testTime), 206 » » » » » "Bytes": mkp([]byte("world")),
200 » » » » » "Float": mkpNI(3.14), 207 » » » » » "Time": mkp(testTime),
201 » » » » » "Key": mkp(di.MakeKey("Parent", "Pare ntID", "Child", 1337)), 208 » » » » » "Float": mkpNI(3.14),
209 » » » » » "Key": mkp(di.MakeKey("Parent", "P arentID", "Child", 1337)),
210 » » » » » "Null": mkp(nil),
211 » » » » » "NullSlice": mkp(nil, nil),
202 212
203 "ComplexSlice": mkp(1337, "string", []by te("bytes"), testTime, float32(3.14), 213 "ComplexSlice": mkp(1337, "string", []by te("bytes"), testTime, float32(3.14),
204 » » » » » » float64(2.71), true, di.MakeKey( "SomeKey", "SomeID")), 214 » » » » » » float64(2.71), true, nil, di.Mak eKey("SomeKey", "SomeID")),
215
216 » » » » » "Single": mkp("single"),
217 » » » » » "SingleSlice": mkProperties(true, true, "single"), // Force a single "multi" value.
218 » » » » » "EmptySlice": ds.PropertySlice(nil),
205 } 219 }
206 So(di.Put(put), ShouldBeNil) 220 So(di.Put(put), ShouldBeNil)
207 delete(put, "$key") 221 delete(put, "$key")
208 222
209 get := ds.PropertyMap{ 223 get := ds.PropertyMap{
210 "$id": mkpNI("foo"), 224 "$id": mkpNI("foo"),
211 "$kind": mkpNI("FooType"), 225 "$kind": mkpNI("FooType"),
212 } 226 }
213 So(di.Get(get), ShouldBeNil) 227 So(di.Get(get), ShouldBeNil)
214 So(get, ShouldResemble, put) 228 So(get, ShouldResemble, put)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 pmap := ds.PropertyMap{"$kind": mkp("Tes t"), "$id": mkp("quux")} 299 pmap := ds.PropertyMap{"$kind": mkp("Tes t"), "$id": mkp("quux")}
286 err = di.RunInTransaction(func(c context .Context) error { 300 err = di.RunInTransaction(func(c context .Context) error {
287 return ds.Get(c).Get(pmap) 301 return ds.Get(c).Get(pmap)
288 }, nil) 302 }, nil)
289 So(err, ShouldEqual, ds.ErrNoSuchEntity) 303 So(err, ShouldEqual, ds.ErrNoSuchEntity)
290 }) 304 })
291 }) 305 })
292 }) 306 })
293 }) 307 })
294 } 308 }
OLDNEW
« no previous file with comments | « impl/cloud/datastore.go ('k') | impl/memory/datastore_data.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698