OLD | NEW |
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 // +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 » dstore "github.com/luci/gae/service/datastore" | 14 » "github.com/luci/gae/service/datastore" |
| 15 » "github.com/luci/gae/service/info" |
15 . "github.com/smartystreets/goconvey/convey" | 16 . "github.com/smartystreets/goconvey/convey" |
| 17 "golang.org/x/net/context" |
16 "google.golang.org/appengine/aetest" | 18 "google.golang.org/appengine/aetest" |
17 ) | 19 ) |
18 | 20 |
19 var ( | 21 var ( |
20 » mp = dstore.MkProperty | 22 » mp = datastore.MkProperty |
21 » mpNI = dstore.MkPropertyNI | 23 » mpNI = datastore.MkPropertyNI |
22 ) | 24 ) |
23 | 25 |
24 type TestStruct struct { | 26 type TestStruct struct { |
25 ID int64 `gae:"$id"` | 27 ID int64 `gae:"$id"` |
26 | 28 |
27 ValueI []int64 | 29 ValueI []int64 |
28 ValueB []bool | 30 ValueB []bool |
29 ValueS []string | 31 ValueS []string |
30 ValueF []float64 | 32 ValueF []float64 |
31 ValueBS [][]byte // "ByteString" | 33 ValueBS [][]byte // "ByteString" |
32 » ValueK []*dstore.Key | 34 » ValueK []*datastore.Key |
33 ValueBK []blobstore.Key | 35 ValueBK []blobstore.Key |
34 » ValueGP []dstore.GeoPoint | 36 » ValueGP []datastore.GeoPoint |
35 } | 37 } |
36 | 38 |
37 func TestBasicDatastore(t *testing.T) { | 39 func TestBasicDatastore(t *testing.T) { |
38 t.Parallel() | 40 t.Parallel() |
39 | 41 |
40 Convey("basic", t, func() { | 42 Convey("basic", t, func() { |
41 » » ctx, closer, err := aetest.NewContext() | 43 » » inst, err := aetest.NewInstance(&aetest.Options{ |
| 44 » » » StronglyConsistentDatastore: true, |
| 45 » » }) |
42 So(err, ShouldBeNil) | 46 So(err, ShouldBeNil) |
43 » » defer closer() | 47 » » defer inst.Close() |
44 | 48 |
45 » » ctx = Use(ctx) | 49 » » req, err := inst.NewRequest("GET", "/", nil) |
46 » » ds := dstore.Get(ctx) | 50 » » So(err, ShouldBeNil) |
| 51 |
| 52 » » ctx := Use(context.Background(), req) |
| 53 » » ds := datastore.Get(ctx) |
| 54 » » inf := info.Get(ctx) |
| 55 |
| 56 » » Convey("Can probe/change Namespace", func() { |
| 57 » » » So(inf.GetNamespace(), ShouldEqual, "") |
| 58 » » » ctx, err = inf.Namespace("wat") |
| 59 » » » So(err, ShouldBeNil) |
| 60 » » » inf = info.Get(ctx) |
| 61 » » » So(inf.GetNamespace(), ShouldEqual, "wat") |
| 62 » » » ds = datastore.Get(ctx) |
| 63 » » » So(ds.MakeKey("Hello", "world").Namespace(), ShouldEqual
, "wat") |
| 64 » » }) |
47 | 65 |
48 Convey("Can Put/Get", func() { | 66 Convey("Can Put/Get", func() { |
49 orig := TestStruct{ | 67 orig := TestStruct{ |
50 ValueI: []int64{1, 7, 946688461000000, 996688461
000000}, | 68 ValueI: []int64{1, 7, 946688461000000, 996688461
000000}, |
51 ValueB: []bool{true, false}, | 69 ValueB: []bool{true, false}, |
52 ValueS: []string{"hello", "world"}, | 70 ValueS: []string{"hello", "world"}, |
53 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9
96688461000000.0}, | 71 ValueF: []float64{1.0, 7.0, 946688461000000.0, 9
96688461000000.0}, |
54 ValueBS: [][]byte{ | 72 ValueBS: [][]byte{ |
55 []byte("allo"), | 73 []byte("allo"), |
56 []byte("hello"), | 74 []byte("hello"), |
57 []byte("world"), | 75 []byte("world"), |
58 []byte("zurple"), | 76 []byte("zurple"), |
59 }, | 77 }, |
60 » » » » ValueK: []*dstore.Key{ | 78 » » » » ValueK: []*datastore.Key{ |
61 ds.NewKey("Something", "Cool", 0, nil), | 79 ds.NewKey("Something", "Cool", 0, nil), |
62 ds.NewKey("Something", "", 1, nil), | 80 ds.NewKey("Something", "", 1, nil), |
63 ds.NewKey("Something", "Recursive", 0, | 81 ds.NewKey("Something", "Recursive", 0, |
64 ds.NewKey("Parent", "", 2, nil))
, | 82 ds.NewKey("Parent", "", 2, nil))
, |
65 }, | 83 }, |
66 ValueBK: []blobstore.Key{"bellow", "hello"}, | 84 ValueBK: []blobstore.Key{"bellow", "hello"}, |
67 » » » » ValueGP: []dstore.GeoPoint{ | 85 » » » » ValueGP: []datastore.GeoPoint{ |
68 {Lat: 120.7, Lng: 95.5}, | 86 {Lat: 120.7, Lng: 95.5}, |
69 }, | 87 }, |
70 } | 88 } |
71 So(ds.Put(&orig), ShouldBeNil) | 89 So(ds.Put(&orig), ShouldBeNil) |
72 | 90 |
73 ret := TestStruct{ID: orig.ID} | 91 ret := TestStruct{ID: orig.ID} |
74 So(ds.Get(&ret), ShouldBeNil) | 92 So(ds.Get(&ret), ShouldBeNil) |
75 So(ret, ShouldResemble, orig) | 93 So(ret, ShouldResemble, orig) |
76 | 94 |
77 // can't be sure the indexes have caught up... so sleep | 95 // can't be sure the indexes have caught up... so sleep |
78 time.Sleep(time.Second) | 96 time.Sleep(time.Second) |
79 | 97 |
80 Convey("Can query", func() { | 98 Convey("Can query", func() { |
81 » » » » q := dstore.NewQuery("TestStruct") | 99 » » » » q := datastore.NewQuery("TestStruct") |
82 » » » » ds.Run(q, func(ts *TestStruct, _ dstore.CursorCB
) bool { | 100 » » » » ds.Run(q, func(ts *TestStruct, _ datastore.Curso
rCB) bool { |
83 So(*ts, ShouldResemble, orig) | 101 So(*ts, ShouldResemble, orig) |
84 return true | 102 return true |
85 }) | 103 }) |
86 count, err := ds.Count(q) | 104 count, err := ds.Count(q) |
87 So(err, ShouldBeNil) | 105 So(err, ShouldBeNil) |
88 So(count, ShouldEqual, 1) | 106 So(count, ShouldEqual, 1) |
89 }) | 107 }) |
90 | 108 |
91 Convey("Can project", func() { | 109 Convey("Can project", func() { |
92 » » » » q := dstore.NewQuery("TestStruct").Project("Valu
eS") | 110 » » » » q := datastore.NewQuery("TestStruct").Project("V
alueS") |
93 » » » » rslts := []dstore.PropertyMap{} | 111 » » » » rslts := []datastore.PropertyMap{} |
94 So(ds.GetAll(q, &rslts), ShouldBeNil) | 112 So(ds.GetAll(q, &rslts), ShouldBeNil) |
95 » » » » So(rslts, ShouldResemble, []dstore.PropertyMap{ | 113 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa
p{ |
96 { | 114 { |
97 "$key": {mpNI(ds.KeyForObj(&or
ig))}, | 115 "$key": {mpNI(ds.KeyForObj(&or
ig))}, |
98 "ValueS": {mp("hello")}, | 116 "ValueS": {mp("hello")}, |
99 }, | 117 }, |
100 { | 118 { |
101 "$key": {mpNI(ds.KeyForObj(&or
ig))}, | 119 "$key": {mpNI(ds.KeyForObj(&or
ig))}, |
102 "ValueS": {mp("world")}, | 120 "ValueS": {mp("world")}, |
103 }, | 121 }, |
104 }) | 122 }) |
105 | 123 |
106 » » » » q = dstore.NewQuery("TestStruct").Project("Value
BS") | 124 » » » » q = datastore.NewQuery("TestStruct").Project("Va
lueBS") |
107 » » » » rslts = []dstore.PropertyMap{} | 125 » » » » rslts = []datastore.PropertyMap{} |
108 So(ds.GetAll(q, &rslts), ShouldBeNil) | 126 So(ds.GetAll(q, &rslts), ShouldBeNil) |
109 » » » » So(rslts, ShouldResemble, []dstore.PropertyMap{ | 127 » » » » So(rslts, ShouldResemble, []datastore.PropertyMa
p{ |
110 { | 128 { |
111 "$key": {mpNI(ds.KeyForObj(&o
rig))}, | 129 "$key": {mpNI(ds.KeyForObj(&o
rig))}, |
112 "ValueBS": {mp("allo")}, | 130 "ValueBS": {mp("allo")}, |
113 }, | 131 }, |
114 { | 132 { |
115 "$key": {mpNI(ds.KeyForObj(&o
rig))}, | 133 "$key": {mpNI(ds.KeyForObj(&o
rig))}, |
116 "ValueBS": {mp("hello")}, | 134 "ValueBS": {mp("hello")}, |
117 }, | 135 }, |
118 { | 136 { |
119 "$key": {mpNI(ds.KeyForObj(&o
rig))}, | 137 "$key": {mpNI(ds.KeyForObj(&o
rig))}, |
120 "ValueBS": {mp("world")}, | 138 "ValueBS": {mp("world")}, |
121 }, | 139 }, |
122 { | 140 { |
123 "$key": {mpNI(ds.KeyForObj(&o
rig))}, | 141 "$key": {mpNI(ds.KeyForObj(&o
rig))}, |
124 "ValueBS": {mp("zurple")}, | 142 "ValueBS": {mp("zurple")}, |
125 }, | 143 }, |
126 }) | 144 }) |
127 | 145 |
128 count, err := ds.Count(q) | 146 count, err := ds.Count(q) |
129 So(err, ShouldBeNil) | 147 So(err, ShouldBeNil) |
130 So(count, ShouldEqual, 4) | 148 So(count, ShouldEqual, 4) |
131 }) | 149 }) |
132 }) | 150 }) |
133 | 151 |
134 Convey("Can Put/Get (time)", func() { | 152 Convey("Can Put/Get (time)", func() { |
135 // time comparisons in Go are wonky, so this is pulled o
ut | 153 // time comparisons in Go are wonky, so this is pulled o
ut |
136 » » » pm := dstore.PropertyMap{ | 154 » » » pm := datastore.PropertyMap{ |
137 "$key": {mpNI(ds.NewKey("Something", "value", 0,
nil))}, | 155 "$key": {mpNI(ds.NewKey("Something", "value", 0,
nil))}, |
138 "Time": { | 156 "Time": { |
139 mp(time.Date(1938, time.January, 1, 1, 1
, 1, 1, time.UTC)), | 157 mp(time.Date(1938, time.January, 1, 1, 1
, 1, 1, time.UTC)), |
140 mp(time.Time{}), | 158 mp(time.Time{}), |
141 }, | 159 }, |
142 } | 160 } |
143 So(ds.Put(&pm), ShouldBeNil) | 161 So(ds.Put(&pm), ShouldBeNil) |
144 | 162 |
145 » » » rslt := dstore.PropertyMap{} | 163 » » » rslt := datastore.PropertyMap{} |
146 rslt.SetMeta("key", ds.KeyForObj(pm)) | 164 rslt.SetMeta("key", ds.KeyForObj(pm)) |
147 So(ds.Get(&rslt), ShouldBeNil) | 165 So(ds.Get(&rslt), ShouldBeNil) |
148 | 166 |
149 So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0
].Value()) | 167 So(pm["Time"][0].Value(), ShouldResemble, rslt["Time"][0
].Value()) |
150 | 168 |
151 » » » q := dstore.NewQuery("Something").Project("Time") | 169 » » » q := datastore.NewQuery("Something").Project("Time") |
152 » » » all := []dstore.PropertyMap{} | 170 » » » all := []datastore.PropertyMap{} |
153 So(ds.GetAll(q, &all), ShouldBeNil) | 171 So(ds.GetAll(q, &all), ShouldBeNil) |
154 So(len(all), ShouldEqual, 2) | 172 So(len(all), ShouldEqual, 2) |
155 prop := all[0]["Time"][0] | 173 prop := all[0]["Time"][0] |
156 » » » So(prop.Type(), ShouldEqual, dstore.PTInt) | 174 » » » So(prop.Type(), ShouldEqual, datastore.PTInt) |
157 | 175 |
158 » » » tval, err := prop.Project(dstore.PTTime) | 176 » » » tval, err := prop.Project(datastore.PTTime) |
159 So(err, ShouldBeNil) | 177 So(err, ShouldBeNil) |
160 So(tval, ShouldResemble, time.Time{}) | 178 So(tval, ShouldResemble, time.Time{}) |
161 | 179 |
162 » » » tval, err = all[1]["Time"][0].Project(dstore.PTTime) | 180 » » » tval, err = all[1]["Time"][0].Project(datastore.PTTime) |
163 So(err, ShouldBeNil) | 181 So(err, ShouldBeNil) |
164 So(tval, ShouldResemble, pm["Time"][0].Value()) | 182 So(tval, ShouldResemble, pm["Time"][0].Value()) |
165 | 183 |
166 » » » ent := dstore.PropertyMap{ | 184 » » » ent := datastore.PropertyMap{ |
167 "$key": {mpNI(ds.MakeKey("Something", "value"))}
, | 185 "$key": {mpNI(ds.MakeKey("Something", "value"))}
, |
168 } | 186 } |
169 So(ds.Get(&ent), ShouldBeNil) | 187 So(ds.Get(&ent), ShouldBeNil) |
170 So(ent["Time"], ShouldResemble, pm["Time"]) | 188 So(ent["Time"], ShouldResemble, pm["Time"]) |
171 }) | 189 }) |
172 }) | 190 }) |
173 } | 191 } |
OLD | NEW |