OLD | NEW |
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 // 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 139 |
140 type CommonStruct struct { | 140 type CommonStruct struct { |
141 ID int64 `gae:"$id"` | 141 ID int64 `gae:"$id"` |
142 Parent *Key `gae:"$parent"` | 142 Parent *Key `gae:"$parent"` |
143 | 143 |
144 Value int64 | 144 Value int64 |
145 } | 145 } |
146 | 146 |
147 type permaBad struct { | 147 type permaBad struct { |
148 PropertyLoadSaver | 148 PropertyLoadSaver |
| 149 MetaGetterSetter |
149 } | 150 } |
150 | 151 |
151 func (f *permaBad) Load(pm PropertyMap) error { | 152 func (f *permaBad) Load(pm PropertyMap) error { |
152 return errors.New("permaBad") | 153 return errors.New("permaBad") |
153 } | 154 } |
154 | 155 |
155 type SingletonStruct struct { | 156 type SingletonStruct struct { |
156 id int64 `gae:"$id,1"` | 157 id int64 `gae:"$id,1"` |
157 } | 158 } |
158 | 159 |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 Convey("get single error for RPC failure", func(
) { | 466 Convey("get single error for RPC failure", func(
) { |
466 fplss := []FakePLS{{Kind: "FailAll"}, {}
} | 467 fplss := []FakePLS{{Kind: "FailAll"}, {}
} |
467 So(ds.Put(fplss), ShouldEqual, errFailAl
l) | 468 So(ds.Put(fplss), ShouldEqual, errFailAl
l) |
468 }) | 469 }) |
469 | 470 |
470 Convey("get multi error for individual failures"
, func() { | 471 Convey("get multi error for individual failures"
, func() { |
471 fplss := []FakePLS{{}, {Kind: "Fail"}} | 472 fplss := []FakePLS{{}, {Kind: "Fail"}} |
472 So(ds.Put(fplss), ShouldResemble, errors
.MultiError{nil, errFail}) | 473 So(ds.Put(fplss), ShouldResemble, errors
.MultiError{nil, errFail}) |
473 }) | 474 }) |
474 | 475 |
475 Convey("put with non-modifyable type is an error
", func() { | |
476 cs := CommonStruct{} | |
477 So(func() { ds.Put(cs) }, ShouldPanicLik
e, | |
478 "invalid input type (datastore.C
ommonStruct): not a pointer") | |
479 }) | |
480 | |
481 Convey("get with *Key is an error", func() { | 476 Convey("get with *Key is an error", func() { |
482 So(func() { ds.Get(&Key{}) }, ShouldPani
cLike, | 477 So(func() { ds.Get(&Key{}) }, ShouldPani
cLike, |
483 "invalid input type (*datastore.
Key): not user datatype") | 478 "invalid input type (*datastore.
Key): not user datatype") |
484 }) | 479 }) |
485 | 480 |
486 Convey("struct with no $kind is an error", func(
) { | 481 Convey("struct with no $kind is an error", func(
) { |
487 s := MGSWithNoKind{} | 482 s := MGSWithNoKind{} |
488 So(ds.Put(&s), ShouldErrLike, "unable to
extract $kind") | 483 So(ds.Put(&s), ShouldErrLike, "unable to
extract $kind") |
489 }) | 484 }) |
490 | 485 |
491 Convey("struct with invalid but non-nil key is a
n error", func() { | 486 Convey("struct with invalid but non-nil key is a
n error", func() { |
492 type BadParent struct { | 487 type BadParent struct { |
493 ID int64 `gae:"$id"` | 488 ID int64 `gae:"$id"` |
494 Parent *Key `gae:"$parent"` | 489 Parent *Key `gae:"$parent"` |
495 } | 490 } |
496 // having an Incomplete parent makes an
invalid key | 491 // having an Incomplete parent makes an
invalid key |
497 bp := &BadParent{ID: 1, Parent: ds.MakeK
ey("Something", 0)} | 492 bp := &BadParent{ID: 1, Parent: ds.MakeK
ey("Something", 0)} |
498 So(ds.Put(bp), ShouldErrLike, ErrInvalid
Key) | 493 So(ds.Put(bp), ShouldErrLike, ErrInvalid
Key) |
499 }) | 494 }) |
500 | 495 |
501 Convey("vararg with errors", func() { | 496 Convey("vararg with errors", func() { |
502 successSlice := []CommonStruct{{Value: 0
}, {Value: 1}} | 497 successSlice := []CommonStruct{{Value: 0
}, {Value: 1}} |
503 failSlice := []FakePLS{{Kind: "Fail"}, {
Value: 3}} | 498 failSlice := []FakePLS{{Kind: "Fail"}, {
Value: 3}} |
504 emptySlice := []CommonStruct(nil) | 499 emptySlice := []CommonStruct(nil) |
505 cs0 := CommonStruct{Value: 4} | 500 cs0 := CommonStruct{Value: 4} |
506 » » » » » cs1 := FakePLS{Kind: "Fail", Value: 5} | 501 » » » » » failPLS := FakePLS{Kind: "Fail", Value:
5} |
507 fpls := FakePLS{StringID: "ohai", Value:
6} | 502 fpls := FakePLS{StringID: "ohai", Value:
6} |
508 | 503 |
509 » » » » » err := ds.Put(successSlice, failSlice, e
mptySlice, &cs0, &cs1, &fpls) | 504 » » » » » err := ds.Put(successSlice, failSlice, e
mptySlice, &cs0, &failPLS, &fpls) |
510 So(err, ShouldResemble, errors.MultiErro
r{ | 505 So(err, ShouldResemble, errors.MultiErro
r{ |
511 nil, errors.MultiError{errFail,
nil}, nil, nil, errFail, nil}) | 506 nil, errors.MultiError{errFail,
nil}, nil, nil, errFail, nil}) |
512 So(successSlice[0].ID, ShouldEqual, 1) | 507 So(successSlice[0].ID, ShouldEqual, 1) |
513 So(successSlice[1].ID, ShouldEqual, 2) | 508 So(successSlice[1].ID, ShouldEqual, 2) |
514 So(cs0.ID, ShouldEqual, 5) | 509 So(cs0.ID, ShouldEqual, 5) |
515 }) | 510 }) |
516 }) | 511 }) |
517 | 512 |
518 Convey("ok", func() { | 513 Convey("ok", func() { |
519 Convey("[]S", func() { | 514 Convey("[]S", func() { |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 er, err = ds.Exists(k, ds.MakeKey("DNE", "other")) | 721 er, err = ds.Exists(k, ds.MakeKey("DNE", "other")) |
727 So(err, ShouldBeNil) | 722 So(err, ShouldBeNil) |
728 So(er.Get(0), ShouldBeTrue) | 723 So(er.Get(0), ShouldBeTrue) |
729 So(er.Get(1), ShouldBeFalse) | 724 So(er.Get(1), ShouldBeFalse) |
730 | 725 |
731 // Multi-arg keys with two missing. | 726 // Multi-arg keys with two missing. |
732 er, err = ds.Exists(ds.MakeKey("DNE", "nope"), ds.MakeKe
y("DNE", "other")) | 727 er, err = ds.Exists(ds.MakeKey("DNE", "nope"), ds.MakeKe
y("DNE", "other")) |
733 So(err, ShouldBeNil) | 728 So(err, ShouldBeNil) |
734 So(er.Any(), ShouldBeFalse) | 729 So(er.Any(), ShouldBeFalse) |
735 | 730 |
| 731 // Single struct pointer. |
| 732 er, err = ds.Exists(&CommonStruct{ID: 1}) |
| 733 So(err, ShouldBeNil) |
| 734 So(er.All(), ShouldBeTrue) |
| 735 |
736 // Multi-arg mixed key/struct/slices. | 736 // Multi-arg mixed key/struct/slices. |
737 » » » er, err = ds.Exists(&CommonStruct{ID: 1}, []*CommonStruc
t(nil), []*Key{ds.MakeKey("DNE", "nope"), ds.MakeKey("hello", "ohai")}) | 737 » » » er, err = ds.Exists( |
| 738 » » » » &CommonStruct{ID: 1}, |
| 739 » » » » []*CommonStruct(nil), |
| 740 » » » » []*Key{ds.MakeKey("DNE", "nope"), ds.MakeKey("he
llo", "ohai")}, |
| 741 » » » ) |
738 So(err, ShouldBeNil) | 742 So(err, ShouldBeNil) |
739 So(er.Get(0), ShouldBeTrue) | 743 So(er.Get(0), ShouldBeTrue) |
740 So(er.Get(1), ShouldBeTrue) | 744 So(er.Get(1), ShouldBeTrue) |
741 So(er.Get(2), ShouldBeFalse) | 745 So(er.Get(2), ShouldBeFalse) |
742 So(er.Get(2, 0), ShouldBeFalse) | 746 So(er.Get(2, 0), ShouldBeFalse) |
743 So(er.Get(2, 1), ShouldBeTrue) | 747 So(er.Get(2, 1), ShouldBeTrue) |
744 }) | 748 }) |
745 | 749 |
746 Convey("ExistsMulti", func() { | 750 Convey("ExistsMulti", func() { |
747 Convey("Returns no error if there are no failures.", fun
c() { | 751 Convey("Returns no error if there are no failures.", fun
c() { |
(...skipping 30 matching lines...) Expand all Loading... |
778 }) | 782 }) |
779 | 783 |
780 Convey("get multi error for individual failure",
func() { | 784 Convey("get multi error for individual failure",
func() { |
781 keys := []*Key{ | 785 keys := []*Key{ |
782 ds.MakeKey("Ok", 1), | 786 ds.MakeKey("Ok", 1), |
783 ds.MakeKey("Fail", 2), | 787 ds.MakeKey("Fail", 2), |
784 } | 788 } |
785 So(ds.Delete(keys), ShouldResemble, erro
rs.MultiError{nil, errFail}) | 789 So(ds.Delete(keys), ShouldResemble, erro
rs.MultiError{nil, errFail}) |
786 }) | 790 }) |
787 | 791 |
| 792 Convey("put with non-modifyable type is an error
", func() { |
| 793 cs := CommonStruct{} |
| 794 So(func() { ds.Put(cs) }, ShouldPanicLik
e, |
| 795 "invalid input type (datastore.C
ommonStruct): not a pointer") |
| 796 }) |
| 797 |
788 Convey("get single error when deleting a single"
, func() { | 798 Convey("get single error when deleting a single"
, func() { |
789 k := ds.MakeKey("Fail", 1) | 799 k := ds.MakeKey("Fail", 1) |
790 So(ds.Delete(k), ShouldEqual, errFail) | 800 So(ds.Delete(k), ShouldEqual, errFail) |
791 }) | 801 }) |
792 }) | 802 }) |
793 | 803 |
794 Convey("good", func() { | 804 Convey("good", func() { |
795 » » » » // Single struct. | 805 » » » » // Single struct pointer. |
796 So(ds.Delete(&CommonStruct{ID: 1}), ShouldBeNil) | 806 So(ds.Delete(&CommonStruct{ID: 1}), ShouldBeNil) |
797 | 807 |
798 // Single key. | 808 // Single key. |
799 So(ds.Delete(ds.MakeKey("hello", "ohai")), Shoul
dBeNil) | 809 So(ds.Delete(ds.MakeKey("hello", "ohai")), Shoul
dBeNil) |
800 | 810 |
801 // Single struct DNE. | 811 // Single struct DNE. |
802 So(ds.Delete(&CommonStruct{ID: noSuchEntityID}),
ShouldEqual, ErrNoSuchEntity) | 812 So(ds.Delete(&CommonStruct{ID: noSuchEntityID}),
ShouldEqual, ErrNoSuchEntity) |
803 | 813 |
804 // Single key DNE. | 814 // Single key DNE. |
805 So(ds.Delete(ds.MakeKey("DNE", "nope")), ShouldE
qual, ErrNoSuchEntity) | 815 So(ds.Delete(ds.MakeKey("DNE", "nope")), ShouldE
qual, ErrNoSuchEntity) |
806 | 816 |
807 // Mixed key/struct/slices. | 817 // Mixed key/struct/slices. |
808 » » » » err := ds.Delete(&CommonStruct{ID: 1}, []*Key{ds
.MakeKey("hello", "ohai"), ds.MakeKey("DNE", "nope")}) | 818 » » » » err := ds.Delete( |
| 819 » » » » » &CommonStruct{ID: 1}, |
| 820 » » » » » []*Key{ds.MakeKey("hello", "ohai"), ds.M
akeKey("DNE", "nope")}, |
| 821 » » » » ) |
809 So(err, ShouldResemble, errors.MultiError{nil, e
rrors.MultiError{nil, ErrNoSuchEntity}}) | 822 So(err, ShouldResemble, errors.MultiError{nil, e
rrors.MultiError{nil, ErrNoSuchEntity}}) |
810 }) | 823 }) |
811 }) | 824 }) |
812 | 825 |
813 Convey("Testing DeleteMulti", func() { | 826 Convey("Testing DeleteMulti", func() { |
814 Convey("Succeeds for valid keys.", func() { | 827 Convey("Succeeds for valid keys.", func() { |
815 So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh
ai")}), ShouldBeNil) | 828 So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh
ai")}), ShouldBeNil) |
816 So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh
ai"), ds.MakeKey("hello", "sup")}), ShouldBeNil) | 829 So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh
ai"), ds.MakeKey("hello", "sup")}), ShouldBeNil) |
817 }) | 830 }) |
818 | 831 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
879 // It just won't save the key | 892 // It just won't save the key |
880 cs := &FakePLS{IntID: 10, failSetMeta: t
rue} | 893 cs := &FakePLS{IntID: 10, failSetMeta: t
rue} |
881 So(ds.Get(cs), ShouldBeNil) | 894 So(ds.Get(cs), ShouldBeNil) |
882 }) | 895 }) |
883 | 896 |
884 Convey("vararg with errors", func() { | 897 Convey("vararg with errors", func() { |
885 successSlice := []CommonStruct{{ID: 1},
{ID: 2}} | 898 successSlice := []CommonStruct{{ID: 1},
{ID: 2}} |
886 failSlice := []CommonStruct{{ID: noSuchE
ntityID}, {ID: 3}} | 899 failSlice := []CommonStruct{{ID: noSuchE
ntityID}, {ID: 3}} |
887 emptySlice := []CommonStruct(nil) | 900 emptySlice := []CommonStruct(nil) |
888 cs0 := CommonStruct{ID: 4} | 901 cs0 := CommonStruct{ID: 4} |
889 » » » » » cs1 := CommonStruct{ID: noSuchEntityID} | 902 » » » » » failPLS := CommonStruct{ID: noSuchEntity
ID} |
890 fpls := FakePLS{StringID: "ohai"} | 903 fpls := FakePLS{StringID: "ohai"} |
891 | 904 |
892 » » » » » err := ds.Get(successSlice, failSlice, e
mptySlice, &cs0, &cs1, &fpls) | 905 » » » » » err := ds.Get(successSlice, failSlice, e
mptySlice, &cs0, &failPLS, &fpls) |
893 So(err, ShouldResemble, errors.MultiErro
r{ | 906 So(err, ShouldResemble, errors.MultiErro
r{ |
894 nil, errors.MultiError{ErrNoSuch
Entity, nil}, nil, nil, ErrNoSuchEntity, nil}) | 907 nil, errors.MultiError{ErrNoSuch
Entity, nil}, nil, nil, ErrNoSuchEntity, nil}) |
895 So(successSlice[0].Value, ShouldEqual, 1
) | 908 So(successSlice[0].Value, ShouldEqual, 1
) |
896 So(successSlice[1].Value, ShouldEqual, 2
) | 909 So(successSlice[1].Value, ShouldEqual, 2
) |
897 So(cs0.Value, ShouldEqual, 5) | 910 So(cs0.Value, ShouldEqual, 5) |
898 So(fpls.Value, ShouldEqual, 7) | 911 So(fpls.Value, ShouldEqual, 7) |
899 }) | 912 }) |
900 }) | 913 }) |
901 | 914 |
902 Convey("ok", func() { | 915 Convey("ok", func() { |
(...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1801 if err != nil { | 1814 if err != nil { |
1802 panic(fmt.Errorf("failed to find absolute path f
or `%s`", sameLevelDir)) | 1815 panic(fmt.Errorf("failed to find absolute path f
or `%s`", sameLevelDir)) |
1803 } | 1816 } |
1804 | 1817 |
1805 ids, err := FindAndParseIndexYAML(abs) | 1818 ids, err := FindAndParseIndexYAML(abs) |
1806 So(err, ShouldBeNil) | 1819 So(err, ShouldBeNil) |
1807 So(ids[1].Kind, ShouldEqual, "Test Foo") | 1820 So(ids[1].Kind, ShouldEqual, "Test Foo") |
1808 }) | 1821 }) |
1809 }) | 1822 }) |
1810 } | 1823 } |
OLD | NEW |