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

Side by Side Diff: service/datastore/datastore_test.go

Issue 1516173002: Fix error message from KeyForObj when passing an invalid struct. (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: Fix GetMetaDefault silliness Created 5 years 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 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 // adapted from github.com/golang/appengine/datastore 5 // adapted from github.com/golang/appengine/datastore
6 6
7 package datastore 7 package datastore
8 8
9 import ( 9 import (
10 "fmt" 10 "fmt"
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 if f.Kind == "" { 173 if f.Kind == "" {
174 So(ret.SetMeta("kind", "FakePLS"), ShouldBeNil) 174 So(ret.SetMeta("kind", "FakePLS"), ShouldBeNil)
175 } else { 175 } else {
176 So(ret.SetMeta("kind", f.Kind), ShouldBeNil) 176 So(ret.SetMeta("kind", f.Kind), ShouldBeNil)
177 } 177 }
178 So(ret.SetMeta("assertExtra", true), ShouldBeNil) 178 So(ret.SetMeta("assertExtra", true), ShouldBeNil)
179 } 179 }
180 return ret, nil 180 return ret, nil
181 } 181 }
182 182
183 func (f *FakePLS) GetMetaDefault(key string, dflt interface{}) interface{} {
184 return GetMetaDefaultImpl(f.GetMeta, key, dflt)
185 }
186
187 func (f *FakePLS) GetMeta(key string) (interface{}, error) { 183 func (f *FakePLS) GetMeta(key string) (interface{}, error) {
188 if f.failGetMeta { 184 if f.failGetMeta {
189 return nil, errors.New("FakePLS.GetMeta") 185 return nil, errors.New("FakePLS.GetMeta")
190 } 186 }
191 switch key { 187 switch key {
192 case "id": 188 case "id":
193 if f.StringID != "" { 189 if f.StringID != "" {
194 return f.StringID, nil 190 return f.StringID, nil
195 } 191 }
196 return f.IntID, nil 192 return f.IntID, nil
(...skipping 12 matching lines...) Expand all
209 So(ret.SetMeta("id", id), ShouldBeNil) 205 So(ret.SetMeta("id", id), ShouldBeNil)
210 } 206 }
211 if kind, err := f.GetMeta("kind"); err != nil { 207 if kind, err := f.GetMeta("kind"); err != nil {
212 So(ret.SetMeta("kind", kind), ShouldBeNil) 208 So(ret.SetMeta("kind", kind), ShouldBeNil)
213 } 209 }
214 return ret 210 return ret
215 } 211 }
216 212
217 func (f *FakePLS) SetMeta(key string, val interface{}) error { 213 func (f *FakePLS) SetMeta(key string, val interface{}) error {
218 if f.failSetMeta { 214 if f.failSetMeta {
219 » » return errors.New("FakePL.SetMeta") 215 » » return errors.New("FakePLS.SetMeta")
220 } 216 }
221 if key == "id" { 217 if key == "id" {
222 switch x := val.(type) { 218 switch x := val.(type) {
223 case int64: 219 case int64:
224 f.IntID = x 220 f.IntID = x
225 case string: 221 case string:
226 f.StringID = x 222 f.StringID = x
227 } 223 }
228 return nil 224 return nil
229 } 225 }
230 if key == "kind" { 226 if key == "kind" {
231 f.Kind = val.(string) 227 f.Kind = val.(string)
232 return nil 228 return nil
233 } 229 }
234 return ErrMetaFieldUnset 230 return ErrMetaFieldUnset
235 } 231 }
236 232
237 func (f *FakePLS) Problem() error { 233 func (f *FakePLS) Problem() error {
238 if f.failProblem { 234 if f.failProblem {
239 return errors.New("FakePLS.Problem") 235 return errors.New("FakePLS.Problem")
240 } 236 }
241 return nil 237 return nil
242 } 238 }
243 239
244 type MGSWithNoKind struct { 240 type MGSWithNoKind struct {
245 S string 241 S string
246 } 242 }
247 243
248 func (s *MGSWithNoKind) GetMetaDefault(key string, dflt interface{}) interface{} {
249 return GetMetaDefaultImpl(s.GetMeta, key, dflt)
250 }
251
252 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, error) { 244 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, error) {
253 return nil, ErrMetaFieldUnset 245 return nil, ErrMetaFieldUnset
254 } 246 }
255 247
256 func (s *MGSWithNoKind) GetAllMeta() PropertyMap { 248 func (s *MGSWithNoKind) GetAllMeta() PropertyMap {
257 return PropertyMap{} 249 return PropertyMap{}
258 } 250 }
259 251
260 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) error { 252 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) error {
261 return ErrMetaFieldUnset 253 return ErrMetaFieldUnset
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 }) 328 })
337 329
338 }) 330 })
339 331
340 Convey("bad", func() { 332 Convey("bad", func() {
341 Convey("a propmap without $kind", func() { 333 Convey("a propmap without $kind", func() {
342 pm := PropertyMap{} 334 pm := PropertyMap{}
343 So(pm.SetMeta("id", 100), ShouldBeNil) 335 So(pm.SetMeta("id", 100), ShouldBeNil)
344 So(func() { ds.KeyForObj(pm) }, ShouldPanic) 336 So(func() { ds.KeyForObj(pm) }, ShouldPanic)
345 }) 337 })
338
339 Convey("a bad object", func() {
340 type BadObj struct {
341 ID int64 `gae:"$id"`
342
343 NonSerializableField complex64
344 }
345
346 _, err := ds.KeyForObjErr(&BadObj{ID: 1})
347 So(err, ShouldErrLike, `field "NonSerializableFi eld" has invalid type: complex64`)
348 })
346 }) 349 })
347 }) 350 })
348 } 351 }
349 352
350 func TestPut(t *testing.T) { 353 func TestPut(t *testing.T) {
351 t.Parallel() 354 t.Parallel()
352 355
353 Convey("Test Put/PutMulti", t, func() { 356 Convey("Test Put/PutMulti", t, func() {
354 c := info.Set(context.Background(), fakeInfo{}) 357 c := info.Set(context.Background(), fakeInfo{})
355 c = SetRawFactory(c, fakeDatastoreFactory) 358 c = SetRawFactory(c, fakeDatastoreFactory)
356 ds := Get(c) 359 ds := Get(c)
357 360
358 Convey("bad", func() { 361 Convey("bad", func() {
359 Convey("static can't serialize", func() { 362 Convey("static can't serialize", func() {
360 bss := []badStruct{{}, {}} 363 bss := []badStruct{{}, {}}
361 » » » » So(ds.PutMulti(bss).Error(), ShouldContainSubstr ing, "invalid PutMulti input") 364 » » » » So(ds.PutMulti(bss), ShouldErrLike, "invalid Put Multi input")
362 }) 365 })
363 366
364 Convey("static ptr can't serialize", func() { 367 Convey("static ptr can't serialize", func() {
365 bss := []*badStruct{{}, {}} 368 bss := []*badStruct{{}, {}}
366 » » » » So(ds.PutMulti(bss).Error(), ShouldContainSubstr ing, "invalid PutMulti input") 369 » » » » So(ds.PutMulti(bss), ShouldErrLike, "invalid Put Multi input")
367 }) 370 })
368 371
369 Convey("static bad type (non-slice)", func() { 372 Convey("static bad type (non-slice)", func() {
370 » » » » So(ds.PutMulti(100).Error(), ShouldContainSubstr ing, "invalid PutMulti input") 373 » » » » So(ds.PutMulti(100), ShouldErrLike, "invalid Put Multi input")
371 }) 374 })
372 375
373 Convey("static bad type (slice of bad type)", func() { 376 Convey("static bad type (slice of bad type)", func() {
374 » » » » So(ds.PutMulti([]int{}).Error(), ShouldContainSu bstring, "invalid PutMulti input") 377 » » » » So(ds.PutMulti([]int{}), ShouldErrLike, "invalid PutMulti input")
375 }) 378 })
376 379
377 Convey("dynamic can't serialize", func() { 380 Convey("dynamic can't serialize", func() {
378 fplss := []FakePLS{{failSave: true}, {}} 381 fplss := []FakePLS{{failSave: true}, {}}
379 » » » » So(ds.PutMulti(fplss).Error(), ShouldContainSubs tring, "FakePLS.Save") 382 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "FakePLS.S ave")
380 }) 383 })
381 384
382 Convey("can't get keys", func() { 385 Convey("can't get keys", func() {
383 fplss := []FakePLS{{failGetMeta: true}, {}} 386 fplss := []FakePLS{{failGetMeta: true}, {}}
384 » » » » So(ds.PutMulti(fplss).Error(), ShouldContainSubs tring, "unable to extract $kind") 387 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "FakePLS.G etMeta")
385 }) 388 })
386 389
387 Convey("get single error for RPC failure", func() { 390 Convey("get single error for RPC failure", func() {
388 fplss := []FakePLS{{Kind: "FailAll"}, {}} 391 fplss := []FakePLS{{Kind: "FailAll"}, {}}
389 » » » » So(ds.PutMulti(fplss).Error(), ShouldEqual, "Put Multi fail all") 392 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "PutMulti fail all")
390 }) 393 })
391 394
392 Convey("get multi error for individual failures", func() { 395 Convey("get multi error for individual failures", func() {
393 fplss := []FakePLS{{}, {Kind: "Fail"}} 396 fplss := []FakePLS{{}, {Kind: "Fail"}}
394 So(ds.PutMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("PutMulti fail")}) 397 So(ds.PutMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("PutMulti fail")})
395 }) 398 })
396 399
397 Convey("put with non-modifyable type is an error", func( ) { 400 Convey("put with non-modifyable type is an error", func( ) {
398 cs := CommonStruct{} 401 cs := CommonStruct{}
399 » » » » So(ds.Put(cs).Error(), ShouldContainSubstring, " invalid Put input type") 402 » » » » So(ds.Put(cs), ShouldErrLike, "invalid Put input type")
400 }) 403 })
401 404
402 Convey("struct with no $kind is an error", func() { 405 Convey("struct with no $kind is an error", func() {
403 s := MGSWithNoKind{} 406 s := MGSWithNoKind{}
404 » » » » So(ds.Put(&s).Error(), ShouldContainSubstring, " unable to extract $kind") 407 » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind")
405 }) 408 })
406 }) 409 })
407 410
408 Convey("ok", func() { 411 Convey("ok", func() {
409 Convey("[]S", func() { 412 Convey("[]S", func() {
410 css := make([]CommonStruct, 7) 413 css := make([]CommonStruct, 7)
411 for i := range css { 414 for i := range css {
412 if i == 4 { 415 if i == 4 {
413 css[i].ID = 200 416 css[i].ID = 200
414 } 417 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 599
597 Convey("Test Get/GetMulti", t, func() { 600 Convey("Test Get/GetMulti", t, func() {
598 c := info.Set(context.Background(), fakeInfo{}) 601 c := info.Set(context.Background(), fakeInfo{})
599 c = SetRawFactory(c, fakeDatastoreFactory) 602 c = SetRawFactory(c, fakeDatastoreFactory)
600 ds := Get(c) 603 ds := Get(c)
601 So(ds, ShouldNotBeNil) 604 So(ds, ShouldNotBeNil)
602 605
603 Convey("bad", func() { 606 Convey("bad", func() {
604 Convey("static can't serialize", func() { 607 Convey("static can't serialize", func() {
605 toGet := []badStruct{{}, {}} 608 toGet := []badStruct{{}, {}}
606 » » » » So(ds.GetMulti(toGet).Error(), ShouldContainSubs tring, "invalid GetMulti input") 609 » » » » So(ds.GetMulti(toGet), ShouldErrLike, "invalid G etMulti input")
607 }) 610 })
608 611
609 Convey("can't get keys", func() { 612 Convey("can't get keys", func() {
610 fplss := []FakePLS{{failGetMeta: true}, {}} 613 fplss := []FakePLS{{failGetMeta: true}, {}}
611 » » » » So(ds.GetMulti(fplss).Error(), ShouldContainSubs tring, "unable to extract $kind") 614 » » » » So(ds.GetMulti(fplss), ShouldErrLike, "FakePLS.G etMeta")
612 }) 615 })
613 616
614 Convey("get single error for RPC failure", func() { 617 Convey("get single error for RPC failure", func() {
615 fplss := []FakePLS{ 618 fplss := []FakePLS{
616 {IntID: 1, Kind: "FailAll"}, 619 {IntID: 1, Kind: "FailAll"},
617 {IntID: 2}, 620 {IntID: 2},
618 } 621 }
619 So(ds.GetMulti(fplss).Error(), ShouldEqual, "Get Multi fail all") 622 So(ds.GetMulti(fplss).Error(), ShouldEqual, "Get Multi fail all")
620 }) 623 })
621 624
622 Convey("get multi error for individual failures", func() { 625 Convey("get multi error for individual failures", func() {
623 fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}} 626 fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}}
624 So(ds.GetMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("GetMulti fail")}) 627 So(ds.GetMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("GetMulti fail")})
625 }) 628 })
626 629
627 Convey("get with non-modifiable type is an error", func( ) { 630 Convey("get with non-modifiable type is an error", func( ) {
628 cs := CommonStruct{} 631 cs := CommonStruct{}
629 » » » » So(ds.Get(cs).Error(), ShouldContainSubstring, " invalid Get input type") 632 » » » » So(ds.Get(cs), ShouldErrLike, "invalid Get input type")
630 }) 633 })
631 634
632 » » » Convey("failure to save metadata is an issue too", func( ) { 635 » » » Convey("failure to save metadata is no problem though", func() {
633 » » » » cs := &FakePLS{failGetMeta: true} 636 » » » » // It just won't save the key
634 » » » » So(ds.Get(cs).Error(), ShouldContainSubstring, " unable to extract $kind") 637 » » » » cs := &FakePLS{IntID: 10, failSetMeta: true}
638 » » » » So(ds.Get(cs), ShouldBeNil)
635 }) 639 })
636 }) 640 })
637 641
638 Convey("ok", func() { 642 Convey("ok", func() {
639 Convey("Get", func() { 643 Convey("Get", func() {
640 cs := &CommonStruct{ID: 1} 644 cs := &CommonStruct{ID: 1}
641 So(ds.Get(cs), ShouldBeNil) 645 So(ds.Get(cs), ShouldBeNil)
642 So(cs.Value, ShouldEqual, 1) 646 So(cs.Value, ShouldEqual, 1)
643 }) 647 })
644 648
(...skipping 21 matching lines...) Expand all
666 Convey("Test GetAll", t, func() { 670 Convey("Test GetAll", t, func() {
667 c := info.Set(context.Background(), fakeInfo{}) 671 c := info.Set(context.Background(), fakeInfo{})
668 c = SetRawFactory(c, fakeDatastoreFactory) 672 c = SetRawFactory(c, fakeDatastoreFactory)
669 ds := Get(c) 673 ds := Get(c)
670 So(ds, ShouldNotBeNil) 674 So(ds, ShouldNotBeNil)
671 675
672 q := NewQuery("").Limit(5) 676 q := NewQuery("").Limit(5)
673 677
674 Convey("bad", func() { 678 Convey("bad", func() {
675 Convey("nil target", func() { 679 Convey("nil target", func() {
676 » » » » So(ds.GetAll(q, (*[]PropertyMap)(nil)).Error(), ShouldContainSubstring, "dst: <nil>") 680 » » » » So(ds.GetAll(q, (*[]PropertyMap)(nil)), ShouldEr rLike, "dst: <nil>")
677 }) 681 })
678 682
679 Convey("bad type", func() { 683 Convey("bad type", func() {
680 output := 100 684 output := 100
681 » » » » So(ds.GetAll(q, &output).Error(), ShouldContainS ubstring, "invalid GetAll input type") 685 » » » » So(ds.GetAll(q, &output), ShouldErrLike, "invali d GetAll input type")
682 }) 686 })
683 687
684 Convey("bad type (non pointer)", func() { 688 Convey("bad type (non pointer)", func() {
685 » » » » So(ds.GetAll(q, "moo").Error(), ShouldContainSub string, "must have a ptr-to-slice") 689 » » » » So(ds.GetAll(q, "moo"), ShouldErrLike, "must hav e a ptr-to-slice")
686 }) 690 })
687 691
688 Convey("bad type (underspecified)", func() { 692 Convey("bad type (underspecified)", func() {
689 output := []PropertyLoadSaver(nil) 693 output := []PropertyLoadSaver(nil)
690 » » » » So(ds.GetAll(q, &output).Error(), ShouldContainS ubstring, "invalid GetAll input type") 694 » » » » So(ds.GetAll(q, &output), ShouldErrLike, "invali d GetAll input type")
691 }) 695 })
692 }) 696 })
693 697
694 Convey("ok", func() { 698 Convey("ok", func() {
695 Convey("*[]S", func() { 699 Convey("*[]S", func() {
696 output := []CommonStruct(nil) 700 output := []CommonStruct(nil)
697 So(ds.GetAll(q, &output), ShouldBeNil) 701 So(ds.GetAll(q, &output), ShouldBeNil)
698 So(len(output), ShouldEqual, 5) 702 So(len(output), ShouldEqual, 5)
699 for i, o := range output { 703 for i, o := range output {
700 So(o.ID, ShouldEqual, i+1) 704 So(o.ID, ShouldEqual, i+1)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 ds := Get(c) 785 ds := Get(c)
782 So(ds, ShouldNotBeNil) 786 So(ds, ShouldNotBeNil)
783 787
784 q := NewQuery("kind").Limit(5) 788 q := NewQuery("kind").Limit(5)
785 789
786 Convey("bad", func() { 790 Convey("bad", func() {
787 assertBadTypePanics := func(cb interface{}) { 791 assertBadTypePanics := func(cb interface{}) {
788 defer func() { 792 defer func() {
789 err, _ := recover().(error) 793 err, _ := recover().(error)
790 So(err, ShouldNotBeNil) 794 So(err, ShouldNotBeNil)
791 » » » » » So(err.Error(), ShouldContainSubstring, 795 » » » » » So(err, ShouldErrLike, "cb does not matc h the required callback signature")
792 » » » » » » "cb does not match the required callback signature")
793 }() 796 }()
794 So(ds.Run(q, cb), ShouldBeNil) 797 So(ds.Run(q, cb), ShouldBeNil)
795 } 798 }
796 799
797 Convey("not a function", func() { 800 Convey("not a function", func() {
798 assertBadTypePanics("I am a potato") 801 assertBadTypePanics("I am a potato")
799 }) 802 })
800 803
801 Convey("bad proto type", func() { 804 Convey("bad proto type", func() {
802 assertBadTypePanics(func(v int, _ CursorCB) bool { 805 assertBadTypePanics(func(v int, _ CursorCB) bool {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 So(ds.Run(q, func(k *Key, _ CursorCB) bool { 918 So(ds.Run(q, func(k *Key, _ CursorCB) bool {
916 So(k.IntID(), ShouldEqual, i+1) 919 So(k.IntID(), ShouldEqual, i+1)
917 i++ 920 i++
918 return true 921 return true
919 }), ShouldBeNil) 922 }), ShouldBeNil)
920 }) 923 })
921 924
922 }) 925 })
923 }) 926 })
924 } 927 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698