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

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

Issue 2011773002: datastore: variadic Get, Put, Exists, Delete. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/gae@master
Patch Set: Created 4 years, 7 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 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 "bytes" 10 "bytes"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 if err := cb(k, pm, cursCB); err != nil { 63 if err := cb(k, pm, cursCB); err != nil {
64 if err == Stop { 64 if err == Stop {
65 err = nil 65 err = nil
66 } 66 }
67 return err 67 return err
68 } 68 }
69 } 69 }
70 return nil 70 return nil
71 } 71 }
72 72
73 var (
74 errPutMultiFail = errors.New("PutMulti fail")
75 errPutMultiFailAll = errors.New("PutMulti fail all")
76 )
77
73 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB) error { 78 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB) error {
74 if keys[0].Kind() == "FailAll" { 79 if keys[0].Kind() == "FailAll" {
75 return errors.New("PutMulti fail all") 80 return errors.New("PutMulti fail all")
76 } 81 }
77 _, assertExtra := vals[0].GetMeta("assertExtra") 82 _, assertExtra := vals[0].GetMeta("assertExtra")
78 for i, k := range keys { 83 for i, k := range keys {
79 err := error(nil) 84 err := error(nil)
80 if k.Kind() == "Fail" { 85 if k.Kind() == "Fail" {
81 » » » err = errors.New("PutMulti fail") 86 » » » err = errPutMultiFail
82 } else { 87 } else {
83 So(vals[i]["Value"], ShouldResemble, []Property{MkProper ty(i)}) 88 So(vals[i]["Value"], ShouldResemble, []Property{MkProper ty(i)})
84 if assertExtra { 89 if assertExtra {
85 So(vals[i]["Extra"], ShouldResemble, []Property{ MkProperty("whoa")}) 90 So(vals[i]["Extra"], ShouldResemble, []Property{ MkProperty("whoa")})
86 } 91 }
87 if k.Incomplete() { 92 if k.Incomplete() {
88 k = NewKey(k.AppID(), k.Namespace(), k.Kind(), " ", int64(i+1), k.Parent()) 93 k = NewKey(k.AppID(), k.Namespace(), k.Kind(), " ", int64(i+1), k.Parent())
89 } 94 }
90 } 95 }
91 cb(k, err) 96 cb(k, err)
92 } 97 }
93 return nil 98 return nil
94 } 99 }
95 100
101 const noSuchEntityID = 0xdead
102
96 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti CB) error { 103 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti CB) error {
97 if keys[0].Kind() == "FailAll" { 104 if keys[0].Kind() == "FailAll" {
98 return errors.New("GetMulti fail all") 105 return errors.New("GetMulti fail all")
99 } 106 }
100 for i, k := range keys { 107 for i, k := range keys {
101 if k.Kind() == "Fail" { 108 if k.Kind() == "Fail" {
102 cb(nil, errors.New("GetMulti fail")) 109 cb(nil, errors.New("GetMulti fail"))
103 » » } else if k.Kind() == "DNE" { 110 » » } else if k.Kind() == "DNE" || k.IntID() == noSuchEntityID {
104 cb(nil, ErrNoSuchEntity) 111 cb(nil, ErrNoSuchEntity)
105 } else { 112 } else {
106 cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil) 113 cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil)
107 } 114 }
108 } 115 }
109 return nil 116 return nil
110 } 117 }
111 118
112 func (f *fakeDatastore) DeleteMulti(keys []*Key, cb DeleteMultiCB) error { 119 func (f *fakeDatastore) DeleteMulti(keys []*Key, cb DeleteMultiCB) error {
113 if keys[0].Kind() == "FailAll" { 120 if keys[0].Kind() == "FailAll" {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 260
254 type MGSWithNoKind struct { 261 type MGSWithNoKind struct {
255 S string 262 S string
256 } 263 }
257 264
258 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) { 265 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) {
259 return nil, false 266 return nil, false
260 } 267 }
261 268
262 func (s *MGSWithNoKind) GetAllMeta() PropertyMap { 269 func (s *MGSWithNoKind) GetAllMeta() PropertyMap {
263 » return PropertyMap{} 270 » return PropertyMap{"$kind": []Property{MkProperty("wang")}}
264 } 271 }
265 272
266 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool { 273 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool {
267 return false 274 return false
268 } 275 }
269 276
270 var _ MetaGetterSetter = (*MGSWithNoKind)(nil) 277 var _ MetaGetterSetter = (*MGSWithNoKind)(nil)
271 278
272 func TestKeyForObj(t *testing.T) { 279 func TestKeyForObj(t *testing.T) {
273 t.Parallel() 280 t.Parallel()
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 333
327 So(pls.SetMeta("parent", k), ShouldBeTrue) 334 So(pls.SetMeta("parent", k), ShouldBeTrue)
328 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/Hello,"world"/CommonStruct,1`) 335 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/Hello,"world"/CommonStruct,1`)
329 }) 336 })
330 337
331 Convey("can see if things exist", func() { 338 Convey("can see if things exist", func() {
332 e, err := ds.Exists(k) 339 e, err := ds.Exists(k)
333 So(err, ShouldBeNil) 340 So(err, ShouldBeNil)
334 So(e, ShouldBeTrue) 341 So(e, ShouldBeTrue)
335 342
336 » » » » bl, err := ds.ExistsMulti([]*Key{k, ds.MakeKey(" hello", "other")}) 343 » » » » bl, err := ds.ExistsMulti(k, ds.MakeKey("hello", "other"))
337 So(err, ShouldBeNil) 344 So(err, ShouldBeNil)
338 So(bl, ShouldResemble, BoolList{true, true}) 345 So(bl, ShouldResemble, BoolList{true, true})
339 So(bl.All(), ShouldBeTrue) 346 So(bl.All(), ShouldBeTrue)
340 So(bl.Any(), ShouldBeTrue) 347 So(bl.Any(), ShouldBeTrue)
341 348
342 » » » » bl, err = ds.ExistsMulti([]*Key{k, ds.MakeKey("D NE", "other")}) 349 » » » » bl, err = ds.ExistsMulti(k, ds.MakeKey("DNE", "o ther"))
343 So(err, ShouldBeNil) 350 So(err, ShouldBeNil)
344 So(bl, ShouldResemble, BoolList{true, false}) 351 So(bl, ShouldResemble, BoolList{true, false})
345 So(bl.All(), ShouldBeFalse) 352 So(bl.All(), ShouldBeFalse)
346 So(bl.Any(), ShouldBeTrue) 353 So(bl.Any(), ShouldBeTrue)
347 354
348 e, err = ds.Exists(ds.MakeKey("DNE", "nope")) 355 e, err = ds.Exists(ds.MakeKey("DNE", "nope"))
349 So(err, ShouldBeNil) 356 So(err, ShouldBeNil)
350 So(e, ShouldBeFalse) 357 So(e, ShouldBeFalse)
351 358
352 » » » » bl, err = ds.ExistsMulti([]*Key{ds.MakeKey("DNE" , "nope"), ds.MakeKey("DNE", "other")}) 359 » » » » bl, err = ds.ExistsMulti(ds.MakeKey("DNE", "nope "), ds.MakeKey("DNE", "other"))
353 So(err, ShouldBeNil) 360 So(err, ShouldBeNil)
354 So(bl, ShouldResemble, BoolList{false, false}) 361 So(bl, ShouldResemble, BoolList{false, false})
355 So(bl.All(), ShouldBeFalse) 362 So(bl.All(), ShouldBeFalse)
356 So(bl.Any(), ShouldBeFalse) 363 So(bl.Any(), ShouldBeFalse)
357 364
358 _, err = ds.Exists(ds.MakeKey("Fail", "boom")) 365 _, err = ds.Exists(ds.MakeKey("Fail", "boom"))
359 So(err, ShouldErrLike, "GetMulti fail") 366 So(err, ShouldErrLike, "GetMulti fail")
360 }) 367 })
361 368
362 }) 369 })
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 var broken permaBad 419 var broken permaBad
413 420
414 So(func() { PopulateKey(&broken, k) }, ShouldPanic) 421 So(func() { PopulateKey(&broken, k) }, ShouldPanic)
415 }) 422 })
416 }) 423 })
417 } 424 }
418 425
419 func TestPut(t *testing.T) { 426 func TestPut(t *testing.T) {
420 t.Parallel() 427 t.Parallel()
421 428
422 » Convey("Test Put/PutMulti", t, func() { 429 » Convey("A testing environment", t, func() {
423 c := info.Set(context.Background(), fakeInfo{}) 430 c := info.Set(context.Background(), fakeInfo{})
424 c = SetRawFactory(c, fakeDatastoreFactory) 431 c = SetRawFactory(c, fakeDatastoreFactory)
425 ds := Get(c) 432 ds := Get(c)
426 433
427 » » Convey("bad", func() { 434 » » Convey("Testing Put", func() {
dnj 2016/05/25 05:27:16 (Most of this is just an indentation. The new stuf
428 » » » Convey("static can't serialize", func() { 435 » » » Convey("bad", func() {
429 » » » » bss := []badStruct{{}, {}} 436 » » » » Convey("static can't serialize", func() {
430 » » » » So(func() { ds.PutMulti(bss) }, ShouldPanicLike, 437 » » » » » bss := []badStruct{{}, {}}
431 » » » » » `field "Compy" has invalid type`) 438 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi ke,
432 » » » }) 439 » » » » » » `field "Compy" has invalid type` )
433 440 » » » » })
434 » » » Convey("static ptr can't serialize", func() { 441
435 » » » » bss := []*badStruct{{}, {}} 442 » » » » Convey("static ptr can't serialize", func() {
436 » » » » So(func() { ds.PutMulti(bss) }, ShouldPanicLike, 443 » » » » » bss := []*badStruct{{}, {}}
437 » » » » » `field "Compy" has invalid type: complex 64`) 444 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi ke,
438 » » » }) 445 » » » » » » `field "Compy" has invalid type: complex64`)
439 446 » » » » })
440 » » » Convey("static bad type (non-slice)", func() { 447
441 » » » » So(func() { ds.PutMulti(100) }, ShouldPanicLike, 448 » » » » Convey("static bad type", func() {
442 » » » » » "invalid argument type: expected slice, got int") 449 » » » » » So(func() { ds.Put(100) }, ShouldPanicLi ke,
443 » » » }) 450 » » » » » » "invalid input type (int): not a PLS or pointer-to-struct")
444 451 » » » » })
445 » » » Convey("static bad type (slice of bad type)", func() { 452
446 » » » » So(func() { ds.PutMulti([]int{}) }, ShouldPanicL ike, 453 » » » » Convey("static bad type (slice of bad type)", fu nc() {
447 » » » » » "invalid argument type: []int") 454 » » » » » So(func() { ds.Put([]int{}) }, ShouldPan icLike,
448 » » » }) 455 » » » » » » "invalid input type ([]int): not a PLS or pointer-to-struct")
449 456 » » » » })
450 » » » Convey("dynamic can't serialize", func() { 457
451 » » » » fplss := []FakePLS{{failSave: true}, {}} 458 » » » » Convey("dynamic can't serialize", func() {
452 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "FakePLS.S ave") 459 » » » » » fplss := []FakePLS{{failSave: true}, {}}
453 » » » }) 460 » » » » » So(ds.Put(fplss), ShouldErrLike, "FakePL S.Save")
454 461 » » » » })
455 » » » Convey("can't get keys", func() { 462
456 » » » » fplss := []FakePLS{{failGetMeta: true}, {}} 463 » » » » Convey("can't get keys", func() {
457 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "unable to extract $kind") 464 » » » » » fplss := []FakePLS{{failGetMeta: true}, {}}
458 » » » }) 465 » » » » » So(ds.Put(fplss), ShouldErrLike, "unable to extract $kind")
459 466 » » » » })
460 » » » Convey("get single error for RPC failure", func() { 467
461 » » » » fplss := []FakePLS{{Kind: "FailAll"}, {}} 468 » » » » Convey("get single error for RPC failure", func( ) {
462 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "PutMulti fail all") 469 » » » » » fplss := []FakePLS{{Kind: "FailAll"}, {} }
463 » » » }) 470 » » » » » So(ds.Put(fplss), ShouldResemble, errPut MultiFailAll)
464 471 » » » » })
465 » » » Convey("get multi error for individual failures", func() { 472
466 » » » » fplss := []FakePLS{{}, {Kind: "Fail"}} 473 » » » » Convey("get multi error for individual failures" , func() {
467 » » » » So(ds.PutMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("PutMulti fail")}) 474 » » » » » fplss := []FakePLS{{}, {Kind: "Fail"}}
468 » » » }) 475 » » » » » So(ds.Put(fplss), ShouldResemble, errors .MultiError{nil, errPutMultiFail})
469 476 » » » » })
470 » » » Convey("put with non-modifyable type is an error", func( ) { 477
478 » » » » Convey("put with non-modifyable type is an error ", func() {
479 » » » » » cs := CommonStruct{}
480 » » » » » So(func() { ds.Put(cs) }, ShouldPanicLik e,
481 » » » » » » "invalid input type (datastore.C ommonStruct): not a pointer")
482 » » » » })
483
484 » » » » Convey("get with *Key is an error", func() {
485 » » » » » So(func() { ds.Get(&Key{}) }, ShouldPani cLike,
486 » » » » » » "invalid input type (*datastore. Key): not user datatype")
487 » » » » })
488
489 » » » » Convey("struct with no $kind is an error", func( ) {
490 » » » » » s := MGSWithNoKind{}
491 » » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind")
492 » » » » })
493
494 » » » » Convey("struct with invalid but non-nil key is a n error", func() {
495 » » » » » type BadParent struct {
496 » » » » » » ID int64 `gae:"$id"`
497 » » » » » » Parent *Key `gae:"$parent"`
498 » » » » » }
499 » » » » » // having an Incomplete parent makes an invalid key
500 » » » » » bp := &BadParent{ID: 1, Parent: ds.MakeK ey("Something", 0)}
501 » » » » » So(ds.Put(bp), ShouldErrLike, ErrInvalid Key)
502 » » » » })
503
504 » » » » Convey("vararg with errors", func() {
505 » » » » » successSlice := []CommonStruct{{Value: 0 }, {Value: 1}}
506 » » » » » failSlice := []FakePLS{{Kind: "Fail"}, { Value: 3}}
507 » » » » » cs0 := CommonStruct{Value: 4}
508 » » » » » cs1 := FakePLS{Kind: "Fail", Value: 5}
509 » » » » » fpls := FakePLS{StringID: "ohai", Value: 6}
510
511 » » » » » err := ds.Put(successSlice, failSlice, & cs0, &cs1, &fpls)
512 » » » » » So(err, ShouldResemble, errors.MultiErro r{
513 » » » » » » nil, errors.MultiError{errPutMul tiFail, nil}, nil, errPutMultiFail, nil})
514 » » » » » So(successSlice[0].ID, ShouldEqual, 1)
515 » » » » » So(successSlice[1].ID, ShouldEqual, 2)
516 » » » » » So(cs0.ID, ShouldEqual, 5)
517 » » » » })
518 » » » })
519
520 » » » Convey("ok", func() {
521 » » » » Convey("[]S", func() {
522 » » » » » css := make([]CommonStruct, 7)
523 » » » » » for i := range css {
524 » » » » » » if i == 4 {
525 » » » » » » » css[i].ID = 200
526 » » » » » » }
527 » » » » » » css[i].Value = int64(i)
528 » » » » » }
529 » » » » » So(ds.Put(css), ShouldBeNil)
530 » » » » » for i, cs := range css {
531 » » » » » » expect := int64(i + 1)
532 » » » » » » if i == 4 {
533 » » » » » » » expect = 200
534 » » » » » » }
535 » » » » » » So(cs.ID, ShouldEqual, expect)
536 » » » » » }
537 » » » » })
538
539 » » » » Convey("[]*S", func() {
540 » » » » » css := make([]*CommonStruct, 7)
541 » » » » » for i := range css {
542 » » » » » » css[i] = &CommonStruct{Value: in t64(i)}
543 » » » » » » if i == 4 {
544 » » » » » » » css[i].ID = 200
545 » » » » » » }
546 » » » » » }
547 » » » » » So(ds.Put(css), ShouldBeNil)
548 » » » » » for i, cs := range css {
549 » » » » » » expect := int64(i + 1)
550 » » » » » » if i == 4 {
551 » » » » » » » expect = 200
552 » » » » » » }
553 » » » » » » So(cs.ID, ShouldEqual, expect)
554 » » » » » }
555
556 » » » » » s := &CommonStruct{}
557 » » » » » So(ds.Put(s), ShouldBeNil)
558 » » » » » So(s.ID, ShouldEqual, 1)
559 » » » » })
560
561 » » » » Convey("[]P", func() {
562 » » » » » fplss := make([]FakePLS, 7)
563 » » » » » for i := range fplss {
564 » » » » » » fplss[i].Value = int64(i)
565 » » » » » » if i == 4 {
566 » » » » » » » fplss[i].IntID = int64(2 00)
567 » » » » » » }
568 » » » » » }
569 » » » » » So(ds.Put(fplss), ShouldBeNil)
570 » » » » » for i, fpls := range fplss {
571 » » » » » » expect := int64(i + 1)
572 » » » » » » if i == 4 {
573 » » » » » » » expect = 200
574 » » » » » » }
575 » » » » » » So(fpls.IntID, ShouldEqual, expe ct)
576 » » » » » }
577
578 » » » » » pm := PropertyMap{"Value": {MkProperty(0 )}, "$kind": {MkPropertyNI("Pmap")}}
579 » » » » » So(ds.Put(pm), ShouldBeNil)
580 » » » » » So(ds.KeyForObj(pm).IntID(), ShouldEqual , 1)
581 » » » » })
582
583 » » » » Convey("[]P (map)", func() {
584 » » » » » pms := make([]PropertyMap, 7)
585 » » » » » for i := range pms {
586 » » » » » » pms[i] = PropertyMap{
587 » » » » » » » "$kind": {MkProperty("Pm ap")},
588 » » » » » » » "Value": {MkProperty(i)} ,
589 » » » » » » }
590 » » » » » » if i == 4 {
591 » » » » » » » So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
592 » » » » » » }
593 » » » » » }
594 » » » » » So(ds.Put(pms), ShouldBeNil)
595 » » » » » for i, pm := range pms {
596 » » » » » » expect := int64(i + 1)
597 » » » » » » if i == 4 {
598 » » » » » » » expect = 200
599 » » » » » » }
600 » » » » » » So(ds.KeyForObj(pm).String(), Sh ouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
601 » » » » » }
602 » » » » })
603
604 » » » » Convey("[]*P", func() {
605 » » » » » fplss := make([]*FakePLS, 7)
606 » » » » » for i := range fplss {
607 » » » » » » fplss[i] = &FakePLS{Value: int64 (i)}
608 » » » » » » if i == 4 {
609 » » » » » » » fplss[i].IntID = int64(2 00)
610 » » » » » » }
611 » » » » » }
612 » » » » » So(ds.Put(fplss), ShouldBeNil)
613 » » » » » for i, fpls := range fplss {
614 » » » » » » expect := int64(i + 1)
615 » » » » » » if i == 4 {
616 » » » » » » » expect = 200
617 » » » » » » }
618 » » » » » » So(fpls.IntID, ShouldEqual, expe ct)
619 » » » » » }
620 » » » » })
621
622 » » » » Convey("[]*P (map)", func() {
623 » » » » » pms := make([]*PropertyMap, 7)
624 » » » » » for i := range pms {
625 » » » » » » pms[i] = &PropertyMap{
626 » » » » » » » "$kind": {MkProperty("Pm ap")},
627 » » » » » » » "Value": {MkProperty(i)} ,
628 » » » » » » }
629 » » » » » » if i == 4 {
630 » » » » » » » So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
631 » » » » » » }
632 » » » » » }
633 » » » » » So(ds.Put(pms), ShouldBeNil)
634 » » » » » for i, pm := range pms {
635 » » » » » » expect := int64(i + 1)
636 » » » » » » if i == 4 {
637 » » » » » » » expect = 200
638 » » » » » » }
639 » » » » » » So(ds.KeyForObj(*pm).String(), S houldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
640 » » » » » }
641 » » » » })
642
643 » » » » Convey("[]I", func() {
644 » » » » » ifs := []interface{}{
645 » » » » » » &CommonStruct{Value: 0},
646 » » » » » » &FakePLS{Value: 1},
647 » » » » » » PropertyMap{"Value": {MkProperty (2)}, "$kind": {MkPropertyNI("Pmap")}},
648 » » » » » » &PropertyMap{"Value": {MkPropert y(3)}, "$kind": {MkPropertyNI("Pmap")}},
649 » » » » » }
650 » » » » » So(ds.Put(ifs), ShouldBeNil)
651 » » » » » for i := range ifs {
652 » » » » » » switch i {
653 » » » » » » case 0:
654 » » » » » » » So(ifs[i].(*CommonStruct ).ID, ShouldEqual, 1)
655 » » » » » » case 1:
656 » » » » » » » fpls := ifs[i].(*FakePLS )
657 » » » » » » » So(fpls.IntID, ShouldEqu al, 2)
658 » » » » » » case 2:
659 » » » » » » » So(ds.KeyForObj(ifs[i].( PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
660 » » » » » » case 3:
661 » » » » » » » So(ds.KeyForObj(*ifs[i]. (*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
662 » » » » » » }
663 » » » » » }
664 » » » » })
665 » » » })
666 » » })
667
668 » » Convey("Testing PutMulti", func() {
669 » » » Convey("Fails for something other than a slice.", func() {
471 cs := CommonStruct{} 670 cs := CommonStruct{}
472 » » » » So(func() { ds.Put(cs) }, ShouldPanicLike, 671 » » » » So(func() { ds.PutMulti(&cs) }, ShouldPanicLike,
473 » » » » » "invalid Put input type (datastore.Commo nStruct): not a pointer") 672 » » » » » "argument must be a slice, not *datastor e.CommonStruct")
474 » » » }) 673 » » » })
475 674
476 » » » Convey("get with *Key is an error", func() { 675 » » » Convey("Succeeds for a slice.", func() {
477 » » » » So(func() { ds.Get(&Key{}) }, ShouldPanicLike, 676 » » » » cs := []CommonStruct{{Value: 0}, {Value: 1}}
478 » » » » » "invalid Get input type (*datastore.Key) : not user datatype") 677 » » » » So(ds.PutMulti(cs), ShouldBeNil)
479 » » » }) 678 » » » » So(cs[0].ID, ShouldEqual, 1)
480 679 » » » » So(cs[1].ID, ShouldEqual, 2)
481 » » » Convey("struct with no $kind is an error", func() { 680 » » » })
482 » » » » s := MGSWithNoKind{} 681
483 » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind") 682 » » » Convey("Returns an item error in a MultiError.", func() {
484 » » » }) 683 » » » » cs := []FakePLS{{Value: 0}, {Kind: "Fail"}}
485 684 » » » » err := ds.PutMulti(cs)
486 » » » Convey("struct with invalid but non-nil key is an error" , func() { 685 » » » » So(err, ShouldResemble, errors.MultiError{nil, e rrPutMultiFail})
487 » » » » type BadParent struct { 686 » » » » So(cs[0].IntID, ShouldEqual, 1)
488 » » » » » ID int64 `gae:"$id"`
489 » » » » » Parent *Key `gae:"$parent"`
490 » » » » }
491 » » » » // having an Incomplete parent makes an invalid key
492 » » » » bp := &BadParent{ID: 1, Parent: ds.MakeKey("Some thing", 0)}
493 » » » » So(ds.Put(bp), ShouldErrLike, ErrInvalidKey)
494 }) 687 })
495 }) 688 })
496
497 Convey("ok", func() {
498 Convey("[]S", func() {
499 css := make([]CommonStruct, 7)
500 for i := range css {
501 if i == 4 {
502 css[i].ID = 200
503 }
504 css[i].Value = int64(i)
505 }
506 So(ds.PutMulti(css), ShouldBeNil)
507 for i, cs := range css {
508 expect := int64(i + 1)
509 if i == 4 {
510 expect = 200
511 }
512 So(cs.ID, ShouldEqual, expect)
513 }
514 })
515
516 Convey("[]*S", func() {
517 css := make([]*CommonStruct, 7)
518 for i := range css {
519 css[i] = &CommonStruct{Value: int64(i)}
520 if i == 4 {
521 css[i].ID = 200
522 }
523 }
524 So(ds.PutMulti(css), ShouldBeNil)
525 for i, cs := range css {
526 expect := int64(i + 1)
527 if i == 4 {
528 expect = 200
529 }
530 So(cs.ID, ShouldEqual, expect)
531 }
532
533 s := &CommonStruct{}
534 So(ds.Put(s), ShouldBeNil)
535 So(s.ID, ShouldEqual, 1)
536 })
537
538 Convey("[]P", func() {
539 fplss := make([]FakePLS, 7)
540 for i := range fplss {
541 fplss[i].Value = int64(i)
542 if i == 4 {
543 fplss[i].IntID = int64(200)
544 }
545 }
546 So(ds.PutMulti(fplss), ShouldBeNil)
547 for i, fpls := range fplss {
548 expect := int64(i + 1)
549 if i == 4 {
550 expect = 200
551 }
552 So(fpls.IntID, ShouldEqual, expect)
553 }
554
555 pm := PropertyMap{"Value": {MkProperty(0)}, "$ki nd": {MkPropertyNI("Pmap")}}
556 So(ds.Put(pm), ShouldBeNil)
557 So(ds.KeyForObj(pm).IntID(), ShouldEqual, 1)
558 })
559
560 Convey("[]P (map)", func() {
561 pms := make([]PropertyMap, 7)
562 for i := range pms {
563 pms[i] = PropertyMap{
564 "$kind": {MkProperty("Pmap")},
565 "Value": {MkProperty(i)},
566 }
567 if i == 4 {
568 So(pms[i].SetMeta("id", int64(20 0)), ShouldBeTrue)
569 }
570 }
571 So(ds.PutMulti(pms), ShouldBeNil)
572 for i, pm := range pms {
573 expect := int64(i + 1)
574 if i == 4 {
575 expect = 200
576 }
577 So(ds.KeyForObj(pm).String(), ShouldEqua l, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
578 }
579 })
580
581 Convey("[]*P", func() {
582 fplss := make([]*FakePLS, 7)
583 for i := range fplss {
584 fplss[i] = &FakePLS{Value: int64(i)}
585 if i == 4 {
586 fplss[i].IntID = int64(200)
587 }
588 }
589 So(ds.PutMulti(fplss), ShouldBeNil)
590 for i, fpls := range fplss {
591 expect := int64(i + 1)
592 if i == 4 {
593 expect = 200
594 }
595 So(fpls.IntID, ShouldEqual, expect)
596 }
597 })
598
599 Convey("[]*P (map)", func() {
600 pms := make([]*PropertyMap, 7)
601 for i := range pms {
602 pms[i] = &PropertyMap{
603 "$kind": {MkProperty("Pmap")},
604 "Value": {MkProperty(i)},
605 }
606 if i == 4 {
607 So(pms[i].SetMeta("id", int64(20 0)), ShouldBeTrue)
608 }
609 }
610 So(ds.PutMulti(pms), ShouldBeNil)
611 for i, pm := range pms {
612 expect := int64(i + 1)
613 if i == 4 {
614 expect = 200
615 }
616 So(ds.KeyForObj(*pm).String(), ShouldEqu al, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
617 }
618 })
619
620 Convey("[]I", func() {
621 ifs := []interface{}{
622 &CommonStruct{Value: 0},
623 &FakePLS{Value: 1},
624 PropertyMap{"Value": {MkProperty(2)}, "$ kind": {MkPropertyNI("Pmap")}},
625 &PropertyMap{"Value": {MkProperty(3)}, " $kind": {MkPropertyNI("Pmap")}},
626 }
627 So(ds.PutMulti(ifs), ShouldBeNil)
628 for i := range ifs {
629 switch i {
630 case 0:
631 So(ifs[i].(*CommonStruct).ID, Sh ouldEqual, 1)
632 case 1:
633 fpls := ifs[i].(*FakePLS)
634 So(fpls.IntID, ShouldEqual, 2)
635 case 2:
636 So(ds.KeyForObj(ifs[i].(Property Map)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
637 case 3:
638 So(ds.KeyForObj(*ifs[i].(*Proper tyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
639 }
640 }
641 })
642
643 })
644
645 }) 689 })
646 } 690 }
647 691
648 func TestDelete(t *testing.T) { 692 func TestDelete(t *testing.T) {
649 t.Parallel() 693 t.Parallel()
650 694
651 Convey("Test Delete/DeleteMulti", t, func() { 695 Convey("Test Delete/DeleteMulti", t, func() {
652 c := info.Set(context.Background(), fakeInfo{}) 696 c := info.Set(context.Background(), fakeInfo{})
653 c = SetRawFactory(c, fakeDatastoreFactory) 697 c = SetRawFactory(c, fakeDatastoreFactory)
654 ds := Get(c) 698 ds := Get(c)
655 So(ds, ShouldNotBeNil) 699 So(ds, ShouldNotBeNil)
656 700
657 Convey("bad", func() { 701 Convey("bad", func() {
658 Convey("get single error for RPC failure", func() { 702 Convey("get single error for RPC failure", func() {
659 keys := []*Key{ 703 keys := []*Key{
660 MakeKey("s~aid", "ns", "FailAll", 1), 704 MakeKey("s~aid", "ns", "FailAll", 1),
661 MakeKey("s~aid", "ns", "Ok", 1), 705 MakeKey("s~aid", "ns", "Ok", 1),
662 } 706 }
663 » » » » So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D eleteMulti fail all") 707 » » » » So(ds.DeleteMulti(keys...).Error(), ShouldEqual, "DeleteMulti fail all")
664 }) 708 })
665 709
666 Convey("get multi error for individual failure", func() { 710 Convey("get multi error for individual failure", func() {
667 keys := []*Key{ 711 keys := []*Key{
668 ds.MakeKey("Ok", 1), 712 ds.MakeKey("Ok", 1),
669 ds.MakeKey("Fail", 2), 713 ds.MakeKey("Fail", 2),
670 } 714 }
671 » » » » So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D eleteMulti fail") 715 » » » » So(ds.DeleteMulti(keys...).Error(), ShouldEqual, "DeleteMulti fail")
672 }) 716 })
673 717
674 Convey("get single error when deleting a single", func() { 718 Convey("get single error when deleting a single", func() {
675 k := ds.MakeKey("Fail", 1) 719 k := ds.MakeKey("Fail", 1)
676 So(ds.Delete(k).Error(), ShouldEqual, "DeleteMul ti fail") 720 So(ds.Delete(k).Error(), ShouldEqual, "DeleteMul ti fail")
677 }) 721 })
678 }) 722 })
679 723
680 }) 724 })
681 } 725 }
682 726
683 func TestGet(t *testing.T) { 727 func TestGet(t *testing.T) {
684 t.Parallel() 728 t.Parallel()
685 729
686 » Convey("Test Get/GetMulti", t, func() { 730 » Convey("A testing environment", t, func() {
687 c := info.Set(context.Background(), fakeInfo{}) 731 c := info.Set(context.Background(), fakeInfo{})
688 c = SetRawFactory(c, fakeDatastoreFactory) 732 c = SetRawFactory(c, fakeDatastoreFactory)
689 ds := Get(c) 733 ds := Get(c)
690 So(ds, ShouldNotBeNil) 734 So(ds, ShouldNotBeNil)
691 735
692 » » Convey("bad", func() { 736 » » Convey("Testing Get", func() {
693 » » » Convey("static can't serialize", func() { 737 » » » Convey("bad", func() {
694 » » » » toGet := []badStruct{{}, {}} 738 » » » » Convey("static can't serialize", func() {
695 » » » » So(func() { ds.GetMulti(toGet) }, ShouldPanicLik e, 739 » » » » » toGet := []badStruct{{}, {}}
696 » » » » » `field "Compy" has invalid type: complex 64`) 740 » » » » » So(func() { ds.Get(toGet) }, ShouldPanic Like,
741 » » » » » » `field "Compy" has invalid type: complex64`)
742 » » » » })
743
744 » » » » Convey("can't get keys", func() {
745 » » » » » fplss := []FakePLS{{failGetMeta: true}, {}}
746 » » » » » So(ds.Get(fplss), ShouldErrLike, "unable to extract $kind")
747 » » » » })
748
749 » » » » Convey("get single error for RPC failure", func( ) {
750 » » » » » fplss := []FakePLS{
751 » » » » » » {IntID: 1, Kind: "FailAll"},
752 » » » » » » {IntID: 2},
753 » » » » » }
754 » » » » » So(ds.Get(fplss).Error(), ShouldEqual, " GetMulti fail all")
755 » » » » })
756
757 » » » » Convey("get multi error for individual failures" , func() {
758 » » » » » fplss := []FakePLS{{IntID: 1}, {IntID: 2 , Kind: "Fail"}}
759 » » » » » So(ds.Get(fplss), ShouldResemble, errors .MultiError{nil, errors.New("GetMulti fail")})
760 » » » » })
761
762 » » » » Convey("get with non-modifiable type is an error ", func() {
763 » » » » » cs := CommonStruct{}
764 » » » » » So(func() { ds.Get(cs) }, ShouldPanicLik e,
765 » » » » » » "invalid input type (datastore.C ommonStruct): not a pointer")
766 » » » » })
767
768 » » » » Convey("get with nil is an error", func() {
769 » » » » » So(func() { ds.Get(nil) }, ShouldPanicLi ke,
770 » » » » » » "cannot use nil as single argume nt")
771 » » » » })
772
773 » » » » Convey("get with ptr-to-nonstruct is an error", func() {
774 » » » » » val := 100
775 » » » » » So(func() { ds.Get(&val) }, ShouldPanicL ike,
776 » » » » » » "invalid input type (*int): not a PLS or pointer-to-struct")
777 » » » » })
778
779 » » » » Convey("failure to save metadata is no problem t hough", func() {
780 » » » » » // It just won't save the key
781 » » » » » cs := &FakePLS{IntID: 10, failSetMeta: t rue}
782 » » » » » So(ds.Get(cs), ShouldBeNil)
783 » » » » })
784
785 » » » » Convey("vararg with errors", func() {
786 » » » » » successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
787 » » » » » failSlice := []CommonStruct{{ID: noSuchE ntityID}, {ID: 3}}
788 » » » » » cs0 := CommonStruct{ID: 4}
789 » » » » » cs1 := CommonStruct{ID: noSuchEntityID}
790 » » » » » fpls := FakePLS{StringID: "ohai"}
791
792 » » » » » err := ds.Get(successSlice, failSlice, & cs0, &cs1, &fpls)
793 » » » » » So(err, ShouldResemble, errors.MultiErro r{
794 » » » » » » nil, errors.MultiError{ErrNoSuch Entity, nil}, nil, ErrNoSuchEntity, nil})
795 » » » » » So(successSlice[0].Value, ShouldEqual, 1 )
796 » » » » » So(successSlice[1].Value, ShouldEqual, 2 )
797 » » » » » So(cs0.Value, ShouldEqual, 5)
798 » » » » » So(fpls.Value, ShouldEqual, 7)
799 » » » » })
697 }) 800 })
698 801
699 » » » Convey("can't get keys", func() { 802 » » » Convey("ok", func() {
700 » » » » fplss := []FakePLS{{failGetMeta: true}, {}} 803 » » » » Convey("Get", func() {
701 » » » » So(ds.GetMulti(fplss), ShouldErrLike, "unable to extract $kind") 804 » » » » » cs := &CommonStruct{ID: 1}
702 » » » }) 805 » » » » » So(ds.Get(cs), ShouldBeNil)
806 » » » » » So(cs.Value, ShouldEqual, 1)
807 » » » » })
703 808
704 » » » Convey("get single error for RPC failure", func() { 809 » » » » Convey("Raw access too", func() {
705 » » » » fplss := []FakePLS{ 810 » » » » » rds := ds.Raw()
706 » » » » » {IntID: 1, Kind: "FailAll"}, 811 » » » » » keys := []*Key{ds.MakeKey("Kind", 1)}
707 » » » » » {IntID: 2}, 812 » » » » » So(rds.GetMulti(keys, nil, func(pm Prope rtyMap, err error) error {
708 » » » » } 813 » » » » » » So(err, ShouldBeNil)
709 » » » » So(ds.GetMulti(fplss).Error(), ShouldEqual, "Get Multi fail all") 814 » » » » » » So(pm["Value"][0].Value(), Shoul dEqual, 1)
710 » » » }) 815 » » » » » » return nil
816 » » » » » }), ShouldBeNil)
817 » » » » })
711 818
712 » » » Convey("get multi error for individual failures", func() { 819 » » » » Convey("but general failure to save is fine on a Get", func() {
713 » » » » fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}} 820 » » » » » cs := &FakePLS{failSave: true, IntID: 7}
714 » » » » So(ds.GetMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("GetMulti fail")}) 821 » » » » » So(ds.Get(cs), ShouldBeNil)
715 » » » }) 822 » » » » })
716 823
717 » » » Convey("get with non-modifiable type is an error", func( ) { 824 » » » » Convey("vararg", func() {
718 » » » » cs := CommonStruct{} 825 » » » » » successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
719 » » » » So(func() { ds.Get(cs) }, ShouldPanicLike, 826 » » » » » cs := CommonStruct{ID: 3}
720 » » » » » "invalid Get input type (datastore.Commo nStruct): not a pointer")
721 » » » })
722 827
723 » » » Convey("get with nil is an error", func() { 828 » » » » » err := ds.Get(successSlice, &cs)
724 » » » » So(func() { ds.Get(nil) }, ShouldPanicLike, 829 » » » » » So(err, ShouldBeNil)
725 » » » » » "invalid Get input type (<nil>): no type information") 830 » » » » » So(successSlice[0].Value, ShouldEqual, 1 )
726 » » » }) 831 » » » » » So(successSlice[1].Value, ShouldEqual, 2 )
727 832 » » » » » So(cs.Value, ShouldEqual, 3)
728 » » » Convey("get with ptr-to-nonstruct is an error", func() { 833 » » » » })
729 » » » » val := 100
730 » » » » So(func() { ds.Get(&val) }, ShouldPanicLike,
731 » » » » » "invalid Get input type (*int): does not point to a struct")
732 » » » })
733
734 » » » Convey("failure to save metadata is no problem though", func() {
735 » » » » // It just won't save the key
736 » » » » cs := &FakePLS{IntID: 10, failSetMeta: true}
737 » » » » So(ds.Get(cs), ShouldBeNil)
738 }) 834 })
739 }) 835 })
740 836
741 » » Convey("ok", func() { 837 » » Convey("Testing GetMulti", func() {
742 » » » Convey("Get", func() { 838 » » » Convey("Fails for something other than a slice.", func() {
743 » » » » cs := &CommonStruct{ID: 1} 839 » » » » cs := CommonStruct{}
744 » » » » So(ds.Get(cs), ShouldBeNil) 840 » » » » So(func() { ds.GetMulti(&cs) }, ShouldPanicLike,
745 » » » » So(cs.Value, ShouldEqual, 1) 841 » » » » » "argument must be a slice, not *datastor e.CommonStruct")
746 }) 842 })
747 843
748 » » » Convey("Raw access too", func() { 844 » » » Convey("Succeeds for a slice.", func() {
749 » » » » rds := ds.Raw() 845 » » » » cs := []CommonStruct{{ID: 1}}
750 » » » » keys := []*Key{ds.MakeKey("Kind", 1)} 846 » » » » So(ds.GetMulti(cs), ShouldBeNil)
751 » » » » So(rds.GetMulti(keys, nil, func(pm PropertyMap, err error) error { 847 » » » » So(cs[0].Value, ShouldEqual, 1)
752 » » » » » So(err, ShouldBeNil)
753 » » » » » So(pm["Value"][0].Value(), ShouldEqual, 1)
754 » » » » » return nil
755 » » » » }), ShouldBeNil)
756 }) 848 })
757 849
758 » » » Convey("but general failure to save is fine on a Get", f unc() { 850 » » » Convey("Returns an item error in a MultiError.", func() {
759 » » » » cs := &FakePLS{failSave: true, IntID: 7} 851 » » » » cs := []CommonStruct{{ID: 1}, {ID: noSuchEntityI D}}
760 » » » » So(ds.Get(cs), ShouldBeNil) 852 » » » » err := ds.GetMulti(cs)
853 » » » » So(err, ShouldResemble, errors.MultiError{nil, E rrNoSuchEntity})
854 » » » » So(cs[0].Value, ShouldEqual, 1)
761 }) 855 })
762 }) 856 })
763
764 }) 857 })
765 } 858 }
766 859
767 func TestGetAll(t *testing.T) { 860 func TestGetAll(t *testing.T) {
768 t.Parallel() 861 t.Parallel()
769 862
770 Convey("Test GetAll", t, func() { 863 Convey("Test GetAll", t, func() {
771 c := info.Set(context.Background(), fakeInfo{}) 864 c := info.Set(context.Background(), fakeInfo{})
772 c = SetRawFactory(c, fakeDatastoreFactory) 865 c = SetRawFactory(c, fakeDatastoreFactory)
773 ds := Get(c) 866 ds := Get(c)
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 1000
908 Convey("interface", func() { 1001 Convey("interface", func() {
909 assertBadTypePanics(func(pls PropertyLoadSaver) {}) 1002 assertBadTypePanics(func(pls PropertyLoadSaver) {})
910 }) 1003 })
911 1004
912 Convey("bad proto type", func() { 1005 Convey("bad proto type", func() {
913 cb := func(v int) { 1006 cb := func(v int) {
914 panic("never here!") 1007 panic("never here!")
915 } 1008 }
916 So(func() { ds.Run(q, cb) }, ShouldPanicLike, 1009 So(func() { ds.Run(q, cb) }, ShouldPanicLike,
917 » » » » » "invalid argument type: int") 1010 » » » » » "invalid argument type: int is not a PLS or pointer-to-struct")
918 }) 1011 })
919 1012
920 Convey("wrong # args", func() { 1013 Convey("wrong # args", func() {
921 assertBadTypePanics(func(v CommonStruct, _ Curso rCB, _ int) { 1014 assertBadTypePanics(func(v CommonStruct, _ Curso rCB, _ int) {
922 panic("never here!") 1015 panic("never here!")
923 }) 1016 })
924 }) 1017 })
925 1018
926 Convey("wrong ret type", func() { 1019 Convey("wrong ret type", func() {
927 assertBadTypePanics(func(v CommonStruct) bool { 1020 assertBadTypePanics(func(v CommonStruct) bool {
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 if err != nil { 1671 if err != nil {
1579 panic(fmt.Errorf("failed to find absolute path f or `%s`", sameLevelDir)) 1672 panic(fmt.Errorf("failed to find absolute path f or `%s`", sameLevelDir))
1580 } 1673 }
1581 1674
1582 ids, err := FindAndParseIndexYAML(abs) 1675 ids, err := FindAndParseIndexYAML(abs)
1583 So(err, ShouldBeNil) 1676 So(err, ShouldBeNil)
1584 So(ids[1].Kind, ShouldEqual, "Test Foo") 1677 So(ids[1].Kind, ShouldEqual, "Test Foo")
1585 }) 1678 })
1586 }) 1679 })
1587 } 1680 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698