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

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

Issue 2302743002: Interface update, per-method Contexts. (Closed)
Patch Set: WithoutTransaction, comments, fixes, cleanup. 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
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"
11 "time" 11 "time"
12 12
13 "github.com/luci/gae/service/blobstore" 13 "github.com/luci/gae/service/blobstore"
14 » "github.com/luci/gae/service/datastore" 14 » ds "github.com/luci/gae/service/datastore"
15 "github.com/luci/gae/service/info" 15 "github.com/luci/gae/service/info"
16 » "github.com/luci/gae/service/memcache" 16 » mc "github.com/luci/gae/service/memcache"
17
17 "github.com/luci/luci-go/common/logging" 18 "github.com/luci/luci-go/common/logging"
18 » . "github.com/smartystreets/goconvey/convey" 19
19 "golang.org/x/net/context" 20 "golang.org/x/net/context"
20 "google.golang.org/appengine/aetest" 21 "google.golang.org/appengine/aetest"
22
23 . "github.com/smartystreets/goconvey/convey"
21 ) 24 )
22 25
23 var ( 26 var (
24 » mp = datastore.MkProperty 27 » mp = ds.MkProperty
25 » mpNI = datastore.MkPropertyNI 28 » mpNI = ds.MkPropertyNI
26 ) 29 )
27 30
28 type TestStruct struct { 31 type TestStruct struct {
29 ID int64 `gae:"$id"` 32 ID int64 `gae:"$id"`
30 33
31 ValueI []int64 34 ValueI []int64
32 ValueB []bool 35 ValueB []bool
33 ValueS []string 36 ValueS []string
34 ValueF []float64 37 ValueF []float64
35 ValueBS [][]byte // "ByteString" 38 ValueBS [][]byte // "ByteString"
36 » ValueK []*datastore.Key 39 » ValueK []*ds.Key
37 ValueBK []blobstore.Key 40 ValueBK []blobstore.Key
38 » ValueGP []datastore.GeoPoint 41 » ValueGP []ds.GeoPoint
39 } 42 }
40 43
41 func TestBasicDatastore(t *testing.T) { 44 func TestBasicDatastore(t *testing.T) {
42 t.Parallel() 45 t.Parallel()
43 46
44 Convey("basic", t, func() { 47 Convey("basic", t, func() {
45 inst, err := aetest.NewInstance(&aetest.Options{ 48 inst, err := aetest.NewInstance(&aetest.Options{
46 StronglyConsistentDatastore: true, 49 StronglyConsistentDatastore: true,
47 }) 50 })
48 So(err, ShouldBeNil) 51 So(err, ShouldBeNil)
49 defer inst.Close() 52 defer inst.Close()
50 53
51 req, err := inst.NewRequest("GET", "/", nil) 54 req, err := inst.NewRequest("GET", "/", nil)
52 So(err, ShouldBeNil) 55 So(err, ShouldBeNil)
53 56
54 ctx := Use(context.Background(), req) 57 ctx := Use(context.Background(), req)
55 ds := datastore.Get(ctx)
56 mc := memcache.Get(ctx)
57 inf := info.Get(ctx)
58 58
59 Convey("logging allows you to tweak the level", func() { 59 Convey("logging allows you to tweak the level", func() {
60 // You have to visually confirm that this actually happe ns in the stdout 60 // You have to visually confirm that this actually happe ns in the stdout
61 // of the test... yeah I know. 61 // of the test... yeah I know.
62 logging.Debugf(ctx, "SHOULD NOT SEE") 62 logging.Debugf(ctx, "SHOULD NOT SEE")
63 logging.Infof(ctx, "SHOULD SEE") 63 logging.Infof(ctx, "SHOULD SEE")
64 64
65 ctx = logging.SetLevel(ctx, logging.Debug) 65 ctx = logging.SetLevel(ctx, logging.Debug)
66 logging.Debugf(ctx, "SHOULD SEE") 66 logging.Debugf(ctx, "SHOULD SEE")
67 logging.Infof(ctx, "SHOULD SEE (2)") 67 logging.Infof(ctx, "SHOULD SEE (2)")
68 }) 68 })
69 69
70 Convey("Can probe/change Namespace", func() { 70 Convey("Can probe/change Namespace", func() {
71 » » » ns, has := inf.GetNamespace() 71 » » » So(info.GetNamespace(ctx), ShouldEqual, "")
72 » » » So(ns, ShouldEqual, "")
73 » » » So(has, ShouldBeFalse)
74 72
75 » » » ctx, err = inf.Namespace("wat") 73 » » » ctx, err = info.Namespace(ctx, "wat")
76 So(err, ShouldBeNil) 74 So(err, ShouldBeNil)
77 inf = info.Get(ctx)
78 75
79 » » » ns, has = inf.GetNamespace() 76 » » » So(info.GetNamespace(ctx), ShouldEqual, "wat")
80 » » » So(ns, ShouldEqual, "wat") 77 » » » So(ds.MakeKey(ctx, "Hello", "world").Namespace(), Should Equal, "wat")
81 » » » So(has, ShouldBeTrue)
82
83 » » » ds = datastore.Get(ctx)
84 » » » So(ds.MakeKey("Hello", "world").Namespace(), ShouldEqual , "wat")
85 }) 78 })
86 79
87 Convey("Can get non-transactional context", func() { 80 Convey("Can get non-transactional context", func() {
88 » » » ctx, err := inf.Namespace("foo") 81 » » » ctx, err := info.Namespace(ctx, "foo")
89 So(err, ShouldBeNil) 82 So(err, ShouldBeNil)
90 ds = datastore.Get(ctx)
91 inf = info.Get(ctx)
92 83
93 » » » ds.RunInTransaction(func(ctx context.Context) error { 84 » » » So(ds.CurrentTransaction(ctx), ShouldBeNil)
94 » » » » So(ds.MakeKey("Foo", "bar").Namespace(), ShouldE qual, "foo")
95 85
96 » » » » So(ds.Put(&TestStruct{ValueI: []int64{100}}), Sh ouldBeNil) 86 » » » ds.RunInTransaction(ctx, func(ctx context.Context) error {
87 » » » » So(ds.CurrentTransaction(ctx), ShouldNotBeNil)
88 » » » » So(ds.MakeKey(ctx, "Foo", "bar").Namespace(), Sh ouldEqual, "foo")
97 89
98 » » » » err = datastore.GetNoTxn(ctx).RunInTransaction(f unc(ctx context.Context) error { 90 » » » » So(ds.Put(ctx, &TestStruct{ValueI: []int64{100}} ), ShouldBeNil)
99 » » » » » ds = datastore.Get(ctx) 91
100 » » » » » So(ds.MakeKey("Foo", "bar").Namespace(), ShouldEqual, "foo") 92 » » » » noTxnCtx := ds.WithoutTransaction(ctx)
101 » » » » » So(ds.Put(&TestStruct{ValueI: []int64{10 0}}), ShouldBeNil) 93 » » » » So(ds.CurrentTransaction(noTxnCtx), ShouldBeNil)
94
95 » » » » err = ds.RunInTransaction(noTxnCtx, func(ctx con text.Context) error {
96 » » » » » So(ds.CurrentTransaction(ctx), ShouldNot BeNil)
97 » » » » » So(ds.MakeKey(ctx, "Foo", "bar").Namespa ce(), ShouldEqual, "foo")
98 » » » » » So(ds.Put(ctx, &TestStruct{ValueI: []int 64{100}}), ShouldBeNil)
102 return nil 99 return nil
103 }, nil) 100 }, nil)
104 So(err, ShouldBeNil) 101 So(err, ShouldBeNil)
105 102
106 return nil 103 return nil
107 }, nil) 104 }, nil)
108 }) 105 })
109 106
110 Convey("Can Put/Get", func() { 107 Convey("Can Put/Get", func() {
111 orig := TestStruct{ 108 orig := TestStruct{
112 ValueI: []int64{1, 7, 946688461000000, 996688461 000000}, 109 ValueI: []int64{1, 7, 946688461000000, 996688461 000000},
113 ValueB: []bool{true, false}, 110 ValueB: []bool{true, false},
114 ValueS: []string{"hello", "world"}, 111 ValueS: []string{"hello", "world"},
115 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9 96688461000000.0}, 112 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9 96688461000000.0},
116 ValueBS: [][]byte{ 113 ValueBS: [][]byte{
117 []byte("allo"), 114 []byte("allo"),
118 []byte("hello"), 115 []byte("hello"),
119 []byte("world"), 116 []byte("world"),
120 []byte("zurple"), 117 []byte("zurple"),
121 }, 118 },
122 » » » » ValueK: []*datastore.Key{ 119 » » » » ValueK: []*ds.Key{
123 » » » » » ds.NewKey("Something", "Cool", 0, nil), 120 » » » » » ds.NewKey(ctx, "Something", "Cool", 0, n il),
124 » » » » » ds.NewKey("Something", "", 1, nil), 121 » » » » » ds.NewKey(ctx, "Something", "", 1, nil),
125 » » » » » ds.NewKey("Something", "Recursive", 0, 122 » » » » » ds.NewKey(ctx, "Something", "Recursive", 0,
126 » » » » » » ds.NewKey("Parent", "", 2, nil)) , 123 » » » » » » ds.NewKey(ctx, "Parent", "", 2, nil)),
127 }, 124 },
128 ValueBK: []blobstore.Key{"bellow", "hello"}, 125 ValueBK: []blobstore.Key{"bellow", "hello"},
129 » » » » ValueGP: []datastore.GeoPoint{ 126 » » » » ValueGP: []ds.GeoPoint{
130 {Lat: 120.7, Lng: 95.5}, 127 {Lat: 120.7, Lng: 95.5},
131 }, 128 },
132 } 129 }
133 » » » So(ds.Put(&orig), ShouldBeNil) 130 » » » So(ds.Put(ctx, &orig), ShouldBeNil)
134 131
135 ret := TestStruct{ID: orig.ID} 132 ret := TestStruct{ID: orig.ID}
136 » » » So(ds.Get(&ret), ShouldBeNil) 133 » » » So(ds.Get(ctx, &ret), ShouldBeNil)
137 So(ret, ShouldResemble, orig) 134 So(ret, ShouldResemble, orig)
138 135
139 // can't be sure the indexes have caught up... so sleep 136 // can't be sure the indexes have caught up... so sleep
140 time.Sleep(time.Second) 137 time.Sleep(time.Second)
141 138
142 Convey("Can query", func() { 139 Convey("Can query", func() {
143 » » » » q := datastore.NewQuery("TestStruct") 140 » » » » q := ds.NewQuery("TestStruct")
144 » » » » ds.Run(q, func(ts *TestStruct) { 141 » » » » ds.Run(ctx, q, func(ts *TestStruct) {
145 So(*ts, ShouldResemble, orig) 142 So(*ts, ShouldResemble, orig)
146 }) 143 })
147 » » » » count, err := ds.Count(q) 144 » » » » count, err := ds.Count(ctx, q)
148 So(err, ShouldBeNil) 145 So(err, ShouldBeNil)
149 So(count, ShouldEqual, 1) 146 So(count, ShouldEqual, 1)
150 }) 147 })
151 148
152 Convey("Can project", func() { 149 Convey("Can project", func() {
153 » » » » q := datastore.NewQuery("TestStruct").Project("V alueS") 150 » » » » q := ds.NewQuery("TestStruct").Project("ValueS")
154 » » » » rslts := []datastore.PropertyMap{} 151 » » » » rslts := []ds.PropertyMap{}
155 » » » » So(ds.GetAll(q, &rslts), ShouldBeNil) 152 » » » » So(ds.GetAll(ctx, q, &rslts), ShouldBeNil)
156 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa p{ 153 » » » » So(rslts, ShouldResemble, []ds.PropertyMap{
157 { 154 {
158 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 155 » » » » » » "$key": {mpNI(ds.KeyForObj(ctx , &orig))},
159 "ValueS": {mp("hello")}, 156 "ValueS": {mp("hello")},
160 }, 157 },
161 { 158 {
162 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 159 » » » » » » "$key": {mpNI(ds.KeyForObj(ctx , &orig))},
163 "ValueS": {mp("world")}, 160 "ValueS": {mp("world")},
164 }, 161 },
165 }) 162 })
166 163
167 » » » » q = datastore.NewQuery("TestStruct").Project("Va lueBS") 164 » » » » q = ds.NewQuery("TestStruct").Project("ValueBS")
168 » » » » rslts = []datastore.PropertyMap{} 165 » » » » rslts = []ds.PropertyMap{}
169 » » » » So(ds.GetAll(q, &rslts), ShouldBeNil) 166 » » » » So(ds.GetAll(ctx, q, &rslts), ShouldBeNil)
170 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa p{ 167 » » » » So(rslts, ShouldResemble, []ds.PropertyMap{
171 { 168 {
172 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 169 » » » » » » "$key": {mpNI(ds.KeyForObj(ct x, &orig))},
173 "ValueBS": {mp("allo")}, 170 "ValueBS": {mp("allo")},
174 }, 171 },
175 { 172 {
176 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 173 » » » » » » "$key": {mpNI(ds.KeyForObj(ct x, &orig))},
177 "ValueBS": {mp("hello")}, 174 "ValueBS": {mp("hello")},
178 }, 175 },
179 { 176 {
180 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 177 » » » » » » "$key": {mpNI(ds.KeyForObj(ct x, &orig))},
181 "ValueBS": {mp("world")}, 178 "ValueBS": {mp("world")},
182 }, 179 },
183 { 180 {
184 » » » » » » "$key": {mpNI(ds.KeyForObj(&o rig))}, 181 » » » » » » "$key": {mpNI(ds.KeyForObj(ct x, &orig))},
185 "ValueBS": {mp("zurple")}, 182 "ValueBS": {mp("zurple")},
186 }, 183 },
187 }) 184 })
188 185
189 » » » » count, err := ds.Count(q) 186 » » » » count, err := ds.Count(ctx, q)
190 So(err, ShouldBeNil) 187 So(err, ShouldBeNil)
191 So(count, ShouldEqual, 4) 188 So(count, ShouldEqual, 4)
192 189
193 » » » » q = datastore.NewQuery("TestStruct").Lte("ValueI ", 7).Project("ValueS").Distinct(true) 190 » » » » q = ds.NewQuery("TestStruct").Lte("ValueI", 7).P roject("ValueS").Distinct(true)
194 » » » » rslts = []datastore.PropertyMap{} 191 » » » » rslts = []ds.PropertyMap{}
195 » » » » So(ds.GetAll(q, &rslts), ShouldBeNil) 192 » » » » So(ds.GetAll(ctx, q, &rslts), ShouldBeNil)
196 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa p{ 193 » » » » So(rslts, ShouldResemble, []ds.PropertyMap{
197 { 194 {
198 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 195 » » » » » » "$key": {mpNI(ds.KeyForObj(ctx , &orig))},
199 "ValueI": {mp(1)}, 196 "ValueI": {mp(1)},
200 "ValueS": {mp("hello")}, 197 "ValueS": {mp("hello")},
201 }, 198 },
202 { 199 {
203 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 200 » » » » » » "$key": {mpNI(ds.KeyForObj(ctx , &orig))},
204 "ValueI": {mp(1)}, 201 "ValueI": {mp(1)},
205 "ValueS": {mp("world")}, 202 "ValueS": {mp("world")},
206 }, 203 },
207 { 204 {
208 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 205 » » » » » » "$key": {mpNI(ds.KeyForObj(ctx , &orig))},
209 "ValueI": {mp(7)}, 206 "ValueI": {mp(7)},
210 "ValueS": {mp("hello")}, 207 "ValueS": {mp("hello")},
211 }, 208 },
212 { 209 {
213 » » » » » » "$key": {mpNI(ds.KeyForObj(&or ig))}, 210 » » » » » » "$key": {mpNI(ds.KeyForObj(ctx , &orig))},
214 "ValueI": {mp(7)}, 211 "ValueI": {mp(7)},
215 "ValueS": {mp("world")}, 212 "ValueS": {mp("world")},
216 }, 213 },
217 }) 214 })
218 215
219 » » » » count, err = ds.Count(q) 216 » » » » count, err = ds.Count(ctx, q)
220 So(err, ShouldBeNil) 217 So(err, ShouldBeNil)
221 So(count, ShouldEqual, 4) 218 So(count, ShouldEqual, 4)
222 }) 219 })
223 }) 220 })
224 221
225 Convey("Can Put/Get (time)", func() { 222 Convey("Can Put/Get (time)", func() {
226 // time comparisons in Go are wonky, so this is pulled o ut 223 // time comparisons in Go are wonky, so this is pulled o ut
227 » » » pm := datastore.PropertyMap{ 224 » » » pm := ds.PropertyMap{
228 » » » » "$key": {mpNI(ds.NewKey("Something", "value", 0, nil))}, 225 » » » » "$key": {mpNI(ds.NewKey(ctx, "Something", "value ", 0, nil))},
229 "Time": { 226 "Time": {
230 mp(time.Date(1938, time.January, 1, 1, 1 , 1, 1, time.UTC)), 227 mp(time.Date(1938, time.January, 1, 1, 1 , 1, 1, time.UTC)),
231 mp(time.Time{}), 228 mp(time.Time{}),
232 }, 229 },
233 } 230 }
234 » » » So(ds.Put(&pm), ShouldBeNil) 231 » » » So(ds.Put(ctx, &pm), ShouldBeNil)
235 232
236 » » » rslt := datastore.PropertyMap{} 233 » » » rslt := ds.PropertyMap{}
237 » » » rslt.SetMeta("key", ds.KeyForObj(pm)) 234 » » » rslt.SetMeta("key", ds.KeyForObj(ctx, pm))
238 » » » So(ds.Get(&rslt), ShouldBeNil) 235 » » » So(ds.Get(ctx, &rslt), ShouldBeNil)
239 236
240 So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0 ].Value()) 237 So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0 ].Value())
241 238
242 » » » q := datastore.NewQuery("Something").Project("Time") 239 » » » q := ds.NewQuery("Something").Project("Time")
243 » » » all := []datastore.PropertyMap{} 240 » » » all := []ds.PropertyMap{}
244 » » » So(ds.GetAll(q, &all), ShouldBeNil) 241 » » » So(ds.GetAll(ctx, q, &all), ShouldBeNil)
245 So(len(all), ShouldEqual, 2) 242 So(len(all), ShouldEqual, 2)
246 prop := all[0]["Time"][0] 243 prop := all[0]["Time"][0]
247 » » » So(prop.Type(), ShouldEqual, datastore.PTInt) 244 » » » So(prop.Type(), ShouldEqual, ds.PTInt)
248 245
249 » » » tval, err := prop.Project(datastore.PTTime) 246 » » » tval, err := prop.Project(ds.PTTime)
250 So(err, ShouldBeNil) 247 So(err, ShouldBeNil)
251 So(tval, ShouldResemble, time.Time{}.UTC()) 248 So(tval, ShouldResemble, time.Time{}.UTC())
252 249
253 » » » tval, err = all[1]["Time"][0].Project(datastore.PTTime) 250 » » » tval, err = all[1]["Time"][0].Project(ds.PTTime)
254 So(err, ShouldBeNil) 251 So(err, ShouldBeNil)
255 So(tval, ShouldResemble, pm["Time"][0].Value()) 252 So(tval, ShouldResemble, pm["Time"][0].Value())
256 253
257 » » » ent := datastore.PropertyMap{ 254 » » » ent := ds.PropertyMap{
258 » » » » "$key": {mpNI(ds.MakeKey("Something", "value"))} , 255 » » » » "$key": {mpNI(ds.MakeKey(ctx, "Something", "valu e"))},
259 } 256 }
260 » » » So(ds.Get(&ent), ShouldBeNil) 257 » » » So(ds.Get(ctx, &ent), ShouldBeNil)
261 So(ent["Time"], ShouldResemble, pm["Time"]) 258 So(ent["Time"], ShouldResemble, pm["Time"])
262 }) 259 })
263 260
264 Convey("memcache: Set (nil) is the same as Set ([]byte{})", func () { 261 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 262 » » » So(mc.Set(ctx, mc.NewItem(ctx, "bob")), ShouldBeNil) // normally would panic because Value is nil
266 263
267 » » » bob, err := mc.Get("bob") 264 » » » bob, err := mc.GetKey(ctx, "bob")
268 So(err, ShouldBeNil) 265 So(err, ShouldBeNil)
269 So(bob.Value(), ShouldResemble, []byte{}) 266 So(bob.Value(), ShouldResemble, []byte{})
270 }) 267 })
271 }) 268 })
272 } 269 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698