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

Side by Side Diff: impl/memory/datastore_index_test.go

Issue 1365743002: Refactor serialization helpers from impl/memory -> service/datastore/serialize (Closed) Base URL: https://github.com/luci/gae.git@estimate_size
Patch Set: fix comments Created 5 years, 2 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
« no previous file with comments | « impl/memory/datastore_index_selection.go ('k') | impl/memory/datastore_query.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 package memory 5 package memory
6 6
7 import ( 7 import (
8 "sort" 8 "sort"
9 "testing" 9 "testing"
10 "time" 10 "time"
11 11
12 ds "github.com/luci/gae/service/datastore" 12 ds "github.com/luci/gae/service/datastore"
13 "github.com/luci/gae/service/datastore/serialize"
13 "github.com/luci/gkvlite" 14 "github.com/luci/gkvlite"
14 . "github.com/smartystreets/goconvey/convey" 15 . "github.com/smartystreets/goconvey/convey"
15 ) 16 )
16 17
17 var fakeKey = key("parentKind", "sid", "knd", 10) 18 var fakeKey = key("parentKind", "sid", "knd", 10)
18 19
19 func TestCollated(t *testing.T) {
20 t.Parallel()
21
22 Convey("TestCollated", t, func() {
23 Convey("nil list", func() {
24 pm := ds.PropertyMap(nil)
25 sip := partiallySerialize(fakeKey, pm)
26
27 Convey("nil collated", func() {
28 Convey("defaultIndexes", func() {
29 idxs := defaultIndexes("knd", pm)
30 So(len(idxs), ShouldEqual, 1)
31 So(idxs[0].String(), ShouldEqual, "B:knd ")
32 })
33 Convey("indexEntries", func() {
34 s := sip.indexEntries("ns", defaultIndex es("knd", pm))
35 numItems, _ := s.GetCollection("idx").Ge tTotals()
36 So(numItems, ShouldEqual, 1)
37 itm := s.GetCollection("idx").MinItem(fa lse)
38 So(itm.Key, ShouldResemble, cat(indx("kn d").PrepForIdxTable()))
39 numItems, _ = s.GetCollection("idx:ns:" + string(itm.Key)).GetTotals()
40 So(numItems, ShouldEqual, 1)
41 })
42 })
43 })
44
45 Convey("list", func() {
46 pm := ds.PropertyMap{
47 "wat": {propNI("thing"), prop("hat"), prop(100) },
48 "nerd": {prop(103.7)},
49 "spaz": {propNI(false)},
50 }
51 sip := partiallySerialize(fakeKey, pm)
52 So(len(sip), ShouldEqual, 4)
53
54 Convey("single collated", func() {
55 Convey("indexableMap", func() {
56 So(sip, ShouldResemble, serializedIndexa blePmap{
57 "wat": {
58 cat(prop("hat")),
59 cat(prop(100)),
60 // 'thing' is skipped, b ecause it's not NoIndex
61 },
62 "nerd": {
63 cat(prop(103.7)),
64 },
65 "__key__": {
66 cat(prop(fakeKey)),
67 },
68 "__ancestor__": {
69 cat(prop(fakeKey)),
70 cat(prop(fakeKey.Parent( ))),
71 },
72 })
73 })
74 Convey("defaultIndexes", func() {
75 idxs := defaultIndexes("knd", pm)
76 So(len(idxs), ShouldEqual, 5)
77 So(idxs[0].String(), ShouldEqual, "B:knd ")
78 So(idxs[1].String(), ShouldEqual, "B:knd /nerd")
79 So(idxs[2].String(), ShouldEqual, "B:knd /wat")
80 So(idxs[3].String(), ShouldEqual, "B:knd /-nerd")
81 So(idxs[4].String(), ShouldEqual, "B:knd /-wat")
82 })
83 })
84 })
85 })
86 }
87
88 var rgenComplexTime = time.Date( 20 var rgenComplexTime = time.Date(
89 1986, time.October, 26, 1, 20, 00, 00, time.UTC) 21 1986, time.October, 26, 1, 20, 00, 00, time.UTC)
90 var rgenComplexKey = key("kind", "id") 22 var rgenComplexKey = key("kind", "id")
91 var rgenComplexTimeIdx = prop(rgenComplexTime).ForIndex() 23 var rgenComplexTimeIdx = prop(rgenComplexTime).ForIndex()
92 24
93 var rowGenTestCases = []struct { 25 var rowGenTestCases = []struct {
94 name string 26 name string
95 pmap ds.PropertyMap 27 pmap ds.PropertyMap
96 withBuiltin bool 28 withBuiltin bool
97 idxs []*ds.IndexDefinition 29 idxs []*ds.IndexDefinition
98 30
99 // These are checked in TestIndexRowGen. nil to skip test case. 31 // These are checked in TestIndexRowGen. nil to skip test case.
100 » expected []serializedPvals 32 » expected []serialize.SerializedPslice
101 33
102 // just the collections you want to assert. These are checked in 34 // just the collections you want to assert. These are checked in
103 // TestIndexEntries. nil to skip test case. 35 // TestIndexEntries. nil to skip test case.
104 collections map[string][][]byte 36 collections map[string][][]byte
105 }{ 37 }{
106 38
107 { 39 {
108 name: "simple including builtins", 40 name: "simple including builtins",
109 pmap: ds.PropertyMap{ 41 pmap: ds.PropertyMap{
110 "wat": {propNI("thing"), prop("hat"), prop(100)}, 42 "wat": {propNI("thing"), prop("hat"), prop(100)},
111 "nerd": {prop(103.7)}, 43 "nerd": {prop(103.7)},
112 "spaz": {propNI(false)}, 44 "spaz": {propNI(false)},
113 }, 45 },
114 withBuiltin: true, 46 withBuiltin: true,
115 idxs: []*ds.IndexDefinition{ 47 idxs: []*ds.IndexDefinition{
116 indx("knd", "-wat", "nerd"), 48 indx("knd", "-wat", "nerd"),
117 }, 49 },
118 » » expected: []serializedPvals{ 50 » » expected: []serialize.SerializedPslice{
119 {cat(prop(fakeKey))}, // B:knd 51 {cat(prop(fakeKey))}, // B:knd
120 {cat(prop(103.7), prop(fakeKey))}, // B:knd/nerd 52 {cat(prop(103.7), prop(fakeKey))}, // B:knd/nerd
121 { // B:knd/wat 53 { // B:knd/wat
122 cat(prop(100), prop(fakeKey)), 54 cat(prop(100), prop(fakeKey)),
123 cat(prop("hat"), prop(fakeKey)), 55 cat(prop("hat"), prop(fakeKey)),
124 }, 56 },
125 { // B:knd/-nerd 57 { // B:knd/-nerd
126 cat(icat(prop(103.7)), prop(fakeKey)), 58 cat(icat(prop(103.7)), prop(fakeKey)),
127 }, 59 },
128 { // B:knd/-wat 60 { // B:knd/-wat
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 "wat": { 97 "wat": {
166 prop(rgenComplexTime), 98 prop(rgenComplexTime),
167 prop([]byte("value")), 99 prop([]byte("value")),
168 prop(rgenComplexKey)}, 100 prop(rgenComplexKey)},
169 "spaz": {prop(nil), prop(false), prop(true)}, 101 "spaz": {prop(nil), prop(false), prop(true)},
170 }, 102 },
171 idxs: []*ds.IndexDefinition{ 103 idxs: []*ds.IndexDefinition{
172 indx("knd", "-wat", "nerd", "spaz"), // doesn't match, s o empty 104 indx("knd", "-wat", "nerd", "spaz"), // doesn't match, s o empty
173 indx("knd", "yerp", "-wat", "spaz"), 105 indx("knd", "yerp", "-wat", "spaz"),
174 }, 106 },
175 » » expected: []serializedPvals{ 107 » » expected: []serialize.SerializedPslice{
176 {}, // C:knd/-wat/nerd/spaz, no match 108 {}, // C:knd/-wat/nerd/spaz, no match
177 { // C:knd/yerp/-wat/spaz 109 { // C:knd/yerp/-wat/spaz
178 // thank goodness the binary serialization only happens 1/val in the 110 // thank goodness the binary serialization only happens 1/val in the
179 // real code :). 111 // real code :).
180 cat(prop("hat"), icat(prop(rgenComplexKey)), pro p(nil), prop(fakeKey)), 112 cat(prop("hat"), icat(prop(rgenComplexKey)), pro p(nil), prop(fakeKey)),
181 cat(prop("hat"), icat(prop(rgenComplexKey)), pro p(false), prop(fakeKey)), 113 cat(prop("hat"), icat(prop(rgenComplexKey)), pro p(false), prop(fakeKey)),
182 cat(prop("hat"), icat(prop(rgenComplexKey)), pro p(true), prop(fakeKey)), 114 cat(prop("hat"), icat(prop(rgenComplexKey)), pro p(true), prop(fakeKey)),
183 cat(prop("hat"), icat(prop("value")), prop(nil), prop(fakeKey)), 115 cat(prop("hat"), icat(prop("value")), prop(nil), prop(fakeKey)),
184 cat(prop("hat"), icat(prop("value")), prop(false ), prop(fakeKey)), 116 cat(prop("hat"), icat(prop("value")), prop(false ), prop(fakeKey)),
185 cat(prop("hat"), icat(prop("value")), prop(true) , prop(fakeKey)), 117 cat(prop("hat"), icat(prop("value")), prop(true) , prop(fakeKey)),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 t.Parallel() 153 t.Parallel()
222 154
223 Convey("Test Index Row Generation", t, func() { 155 Convey("Test Index Row Generation", t, func() {
224 for _, tc := range rowGenTestCases { 156 for _, tc := range rowGenTestCases {
225 if tc.expected == nil { 157 if tc.expected == nil {
226 Convey(tc.name, nil) // shows up as 'skipped' 158 Convey(tc.name, nil) // shows up as 'skipped'
227 continue 159 continue
228 } 160 }
229 161
230 Convey(tc.name, func() { 162 Convey(tc.name, func() {
231 » » » » mvals := partiallySerialize(fakeKey, tc.pmap) 163 » » » » mvals := serialize.PropertyMapPartially(fakeKey, tc.pmap)
232 idxs := []*ds.IndexDefinition(nil) 164 idxs := []*ds.IndexDefinition(nil)
233 if tc.withBuiltin { 165 if tc.withBuiltin {
234 idxs = append(defaultIndexes("coolKind", tc.pmap), tc.idxs...) 166 idxs = append(defaultIndexes("coolKind", tc.pmap), tc.idxs...)
235 } else { 167 } else {
236 idxs = tc.idxs 168 idxs = tc.idxs
237 } 169 }
238 170
239 m := matcher{} 171 m := matcher{}
240 for i, idx := range idxs { 172 for i, idx := range idxs {
241 Convey(idx.String(), func() { 173 Convey(idx.String(), func() {
242 iGen, ok := m.match(idx.GetFullS ortOrder(), mvals) 174 iGen, ok := m.match(idx.GetFullS ortOrder(), mvals)
243 if len(tc.expected[i]) > 0 { 175 if len(tc.expected[i]) > 0 {
244 So(ok, ShouldBeTrue) 176 So(ok, ShouldBeTrue)
245 » » » » » » » actual := make(serialize dPvals, 0, len(tc.expected[i])) 177 » » » » » » » actual := make(serialize .SerializedPslice, 0, len(tc.expected[i]))
246 iGen.permute(func(row, _ []byte) { 178 iGen.permute(func(row, _ []byte) {
247 actual = append( actual, row) 179 actual = append( actual, row)
248 }) 180 })
249 So(len(actual), ShouldEq ual, len(tc.expected[i])) 181 So(len(actual), ShouldEq ual, len(tc.expected[i]))
250 sort.Sort(actual) 182 sort.Sort(actual)
251 for j, act := range actu al { 183 for j, act := range actu al {
252 So(act, ShouldRe semble, tc.expected[i][j]) 184 So(act, ShouldRe semble, tc.expected[i][j])
253 } 185 }
254 } else { 186 } else {
255 So(ok, ShouldBeFalse) 187 So(ok, ShouldBeFalse)
256 } 188 }
257 }) 189 })
258 } 190 }
259 }) 191 })
260 } 192 }
261 }) 193 })
194
195 Convey("default indexes", t, func() {
196 Convey("nil collated", func() {
197 Convey("defaultIndexes (nil)", func() {
198 idxs := defaultIndexes("knd", ds.PropertyMap(nil ))
199 So(len(idxs), ShouldEqual, 1)
200 So(idxs[0].String(), ShouldEqual, "B:knd")
201 })
202
203 Convey("indexEntries", func() {
204 sip := serialize.PropertyMapPartially(fakeKey, n il)
205 s := indexEntries(sip, "ns", defaultIndexes("knd ", ds.PropertyMap(nil)))
206 numItems, _ := s.GetCollection("idx").GetTotals( )
207 So(numItems, ShouldEqual, 1)
208 itm := s.GetCollection("idx").MinItem(false)
209 So(itm.Key, ShouldResemble, cat(indx("knd").Prep ForIdxTable()))
210 numItems, _ = s.GetCollection("idx:ns:" + string (itm.Key)).GetTotals()
211 So(numItems, ShouldEqual, 1)
212 })
213
214 Convey("defaultIndexes", func() {
215 pm := ds.PropertyMap{
216 "wat": {propNI("thing"), prop("hat"), p rop(100)},
217 "nerd": {prop(103.7)},
218 "spaz": {propNI(false)},
219 }
220 idxs := defaultIndexes("knd", pm)
221 So(len(idxs), ShouldEqual, 5)
222 So(idxs[0].String(), ShouldEqual, "B:knd")
223 So(idxs[1].String(), ShouldEqual, "B:knd/nerd")
224 So(idxs[2].String(), ShouldEqual, "B:knd/wat")
225 So(idxs[3].String(), ShouldEqual, "B:knd/-nerd")
226 So(idxs[4].String(), ShouldEqual, "B:knd/-wat")
227 })
228
229 })
230 })
262 } 231 }
263 232
264 func TestIndexEntries(t *testing.T) { 233 func TestIndexEntries(t *testing.T) {
265 t.Parallel() 234 t.Parallel()
266 235
267 Convey("Test indexEntriesWithBuiltins", t, func() { 236 Convey("Test indexEntriesWithBuiltins", t, func() {
268 for _, tc := range rowGenTestCases { 237 for _, tc := range rowGenTestCases {
269 if tc.collections == nil { 238 if tc.collections == nil {
270 Convey(tc.name, nil) // shows up as 'skipped' 239 Convey(tc.name, nil) // shows up as 'skipped'
271 continue 240 continue
272 } 241 }
273 242
274 Convey(tc.name, func() { 243 Convey(tc.name, func() {
275 store := (*memStore)(nil) 244 store := (*memStore)(nil)
276 if tc.withBuiltin { 245 if tc.withBuiltin {
277 store = indexEntriesWithBuiltins(fakeKey , tc.pmap, tc.idxs) 246 store = indexEntriesWithBuiltins(fakeKey , tc.pmap, tc.idxs)
278 } else { 247 } else {
279 » » » » » store = partiallySerialize(fakeKey, tc.p map).indexEntries(fakeKey.Namespace(), tc.idxs) 248 » » » » » sip := serialize.PropertyMapPartially(fa keKey, tc.pmap)
249 » » » » » store = indexEntries(sip, fakeKey.Namesp ace(), tc.idxs)
280 } 250 }
281 for colName, vals := range tc.collections { 251 for colName, vals := range tc.collections {
282 i := 0 252 i := 0
283 coll := store.GetCollection(colName) 253 coll := store.GetCollection(colName)
284 numItems, _ := coll.GetTotals() 254 numItems, _ := coll.GetTotals()
285 So(numItems, ShouldEqual, len(tc.collect ions[colName])) 255 So(numItems, ShouldEqual, len(tc.collect ions[colName]))
286 coll.VisitItemsAscend(nil, true, func(it m *gkvlite.Item) bool { 256 coll.VisitItemsAscend(nil, true, func(it m *gkvlite.Item) bool {
287 So(itm.Key, ShouldResemble, vals [i]) 257 So(itm.Key, ShouldResemble, vals [i])
288 i++ 258 i++
289 return true 259 return true
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 So(data[i], ShouldResemble, itm. Key) 374 So(data[i], ShouldResemble, itm. Key)
405 i++ 375 i++
406 return true 376 return true
407 }) 377 })
408 So(i, ShouldEqual, len(data)) 378 So(i, ShouldEqual, len(data))
409 } 379 }
410 }) 380 })
411 } 381 }
412 }) 382 })
413 } 383 }
OLDNEW
« no previous file with comments | « impl/memory/datastore_index_selection.go ('k') | impl/memory/datastore_query.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698