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

Side by Side Diff: service/datastore/serialize/serialize_test.go

Issue 2302743002: Interface update, per-method Contexts. (Closed)
Patch Set: WithoutTransaction, comments, fixes, cleanup. Created 4 years, 3 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 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 package serialize 5 package serialize
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "io" 10 "io"
11 "testing" 11 "testing"
12 "time" 12 "time"
13 13
14 "github.com/luci/gae/service/blobstore" 14 "github.com/luci/gae/service/blobstore"
15 ds "github.com/luci/gae/service/datastore" 15 ds "github.com/luci/gae/service/datastore"
16 "github.com/luci/luci-go/common/data/cmpbin" 16 "github.com/luci/luci-go/common/data/cmpbin"
17
17 . "github.com/luci/luci-go/common/testing/assertions" 18 . "github.com/luci/luci-go/common/testing/assertions"
18 . "github.com/smartystreets/goconvey/convey" 19 . "github.com/smartystreets/goconvey/convey"
19 ) 20 )
20 21
21 func init() { 22 func init() {
22 WritePropertyMapDeterministic = true 23 WritePropertyMapDeterministic = true
23 } 24 }
24 25
25 var ( 26 var (
26 mp = ds.MkProperty 27 mp = ds.MkProperty
27 mpNI = ds.MkPropertyNI 28 mpNI = ds.MkPropertyNI
28 ) 29 )
29 30
30 type dspmapTC struct { 31 type dspmapTC struct {
31 name string 32 name string
32 props ds.PropertyMap 33 props ds.PropertyMap
33 } 34 }
34 35
35 var mkKey = ds.MakeKey 36 func mkKey(appID, namespace string, elems ...interface{}) *ds.Key {
37 » return ds.KeyContext{appID, namespace}.MakeKey(elems...)
38 }
36 39
37 func mkBuf(data []byte) Buffer { 40 func mkBuf(data []byte) Buffer {
38 return Invertible(bytes.NewBuffer(data)) 41 return Invertible(bytes.NewBuffer(data))
39 } 42 }
40 43
41 // TODO(riannucci): dedup with datastore/key testing file 44 // TODO(riannucci): dedup with datastore/key testing file
42 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { 45 func ShouldEqualKey(actual interface{}, expected ...interface{}) string {
43 if len(expected) != 1 { 46 if len(expected) != 1 {
44 return fmt.Sprintf("Assertion requires 1 expected value, got %d" , len(expected)) 47 return fmt.Sprintf("Assertion requires 1 expected value, got %d" , len(expected))
45 } 48 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 }, 107 },
105 }, 108 },
106 } 109 }
107 110
108 Convey("PropertyMap serialization", t, func() { 111 Convey("PropertyMap serialization", t, func() {
109 Convey("round trip", func() { 112 Convey("round trip", func() {
110 for _, tc := range tests { 113 for _, tc := range tests {
111 tc := tc 114 tc := tc
112 Convey(tc.name, func() { 115 Convey(tc.name, func() {
113 data := ToBytesWithContext(tc.props) 116 data := ToBytesWithContext(tc.props)
114 » » » » » dec, err := ReadPropertyMap(mkBuf(data), WithContext, "", "") 117 » » » » » dec, err := ReadPropertyMap(mkBuf(data), WithContext, ds.KeyContext{})
115 So(err, ShouldBeNil) 118 So(err, ShouldBeNil)
116 So(dec, ShouldResemble, tc.props) 119 So(dec, ShouldResemble, tc.props)
117 }) 120 })
118 } 121 }
119 }) 122 })
120 }) 123 })
121 } 124 }
122 125
123 func die(err error) { 126 func die(err error) {
124 if err != nil { 127 if err != nil {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 t, err := ReadTime(mkBuf(buf.Bytes())) 200 t, err := ReadTime(mkBuf(buf.Bytes()))
198 So(err, ShouldBeNil) 201 So(err, ShouldBeNil)
199 So(t.Equal(time.Time{}), ShouldBeTrue) 202 So(t.Equal(time.Time{}), ShouldBeTrue)
200 }) 203 })
201 204
202 Convey("ReadKey", func() { 205 Convey("ReadKey", func() {
203 Convey("good cases", func() { 206 Convey("good cases", func() {
204 Convey("w/ ctx decodes normally w/ ctx", func() { 207 Convey("w/ ctx decodes normally w/ ctx", func() {
205 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 208 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
206 data := ToBytesWithContext(k) 209 data := ToBytesWithContext(k)
207 » » » » » dk, err := ReadKey(mkBuf(data), WithCont ext, "", "") 210 » » » » » dk, err := ReadKey(mkBuf(data), WithCont ext, ds.KeyContext{})
208 So(err, ShouldBeNil) 211 So(err, ShouldBeNil)
209 So(dk, ShouldEqualKey, k) 212 So(dk, ShouldEqualKey, k)
210 }) 213 })
211 Convey("w/ ctx decodes normally w/o ctx", func() { 214 Convey("w/ ctx decodes normally w/o ctx", func() {
212 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 215 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
213 data := ToBytesWithContext(k) 216 data := ToBytesWithContext(k)
214 » » » » » dk, err := ReadKey(mkBuf(data), WithoutC ontext, "spam", "nerd") 217 » » » » » dk, err := ReadKey(mkBuf(data), WithoutC ontext, ds.KeyContext{"spam", "nerd"})
215 So(err, ShouldBeNil) 218 So(err, ShouldBeNil)
216 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10)) 219 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10))
217 }) 220 })
218 Convey("w/o ctx decodes normally w/ ctx", func() { 221 Convey("w/o ctx decodes normally w/ ctx", func() {
219 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 222 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
220 data := ToBytes(k) 223 data := ToBytes(k)
221 » » » » » dk, err := ReadKey(mkBuf(data), WithCont ext, "spam", "nerd") 224 » » » » » dk, err := ReadKey(mkBuf(data), WithCont ext, ds.KeyContext{"spam", "nerd"})
222 So(err, ShouldBeNil) 225 So(err, ShouldBeNil)
223 So(dk, ShouldEqualKey, mkKey("", "", "kn d", "yo", "other", 10)) 226 So(dk, ShouldEqualKey, mkKey("", "", "kn d", "yo", "other", 10))
224 }) 227 })
225 Convey("w/o ctx decodes normally w/o ctx", func( ) { 228 Convey("w/o ctx decodes normally w/o ctx", func( ) {
226 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 229 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
227 data := ToBytes(k) 230 data := ToBytes(k)
228 » » » » » dk, err := ReadKey(mkBuf(data), WithoutC ontext, "spam", "nerd") 231 » » » » » dk, err := ReadKey(mkBuf(data), WithoutC ontext, ds.KeyContext{"spam", "nerd"})
229 So(err, ShouldBeNil) 232 So(err, ShouldBeNil)
230 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10)) 233 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10))
231 }) 234 })
232 Convey("IntIDs always sort before StringIDs", fu nc() { 235 Convey("IntIDs always sort before StringIDs", fu nc() {
233 // -1 writes as almost all 1's in the fi rst byte under cmpbin, even 236 // -1 writes as almost all 1's in the fi rst byte under cmpbin, even
234 // though it's technically not a valid k ey. 237 // though it's technically not a valid k ey.
235 k := mkKey("aid", "ns", "knd", -1) 238 k := mkKey("aid", "ns", "knd", -1)
236 data := ToBytes(k) 239 data := ToBytes(k)
237 240
238 k = mkKey("aid", "ns", "knd", "hat") 241 k = mkKey("aid", "ns", "knd", "hat")
239 data2 := ToBytes(k) 242 data2 := ToBytes(k)
240 243
241 So(string(data), ShouldBeLessThan, strin g(data2)) 244 So(string(data), ShouldBeLessThan, strin g(data2))
242 }) 245 })
243 }) 246 })
244 247
245 Convey("err cases", func() { 248 Convey("err cases", func() {
246 buf := mkBuf(nil) 249 buf := mkBuf(nil)
247 Convey("nil", func() { 250 Convey("nil", func() {
248 » » » » » _, err := ReadKey(buf, WithContext, "", "") 251 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
249 So(err, ShouldEqual, io.EOF) 252 So(err, ShouldEqual, io.EOF)
250 }) 253 })
251 Convey("str", func() { 254 Convey("str", func() {
252 _, err := buf.WriteString("sup") 255 _, err := buf.WriteString("sup")
253 die(err) 256 die(err)
254 » » » » » _, err = ReadKey(buf, WithContext, "", " ") 257 » » » » » _, err = ReadKey(buf, WithContext, ds.Ke yContext{})
255 So(err, ShouldErrLike, "expected actualC tx") 258 So(err, ShouldErrLike, "expected actualC tx")
256 }) 259 })
257 Convey("truncated 1", func() { 260 Convey("truncated 1", func() {
258 die(buf.WriteByte(1)) // actualCtx == 1 261 die(buf.WriteByte(1)) // actualCtx == 1
259 » » » » » _, err := ReadKey(buf, WithContext, "", "") 262 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
260 So(err, ShouldEqual, io.EOF) 263 So(err, ShouldEqual, io.EOF)
261 }) 264 })
262 Convey("truncated 2", func() { 265 Convey("truncated 2", func() {
263 die(buf.WriteByte(1)) // actualCtx == 1 266 die(buf.WriteByte(1)) // actualCtx == 1
264 ws(buf, "aid") 267 ws(buf, "aid")
265 » » » » » _, err := ReadKey(buf, WithContext, "", "") 268 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
266 So(err, ShouldEqual, io.EOF) 269 So(err, ShouldEqual, io.EOF)
267 }) 270 })
268 Convey("truncated 3", func() { 271 Convey("truncated 3", func() {
269 die(buf.WriteByte(1)) // actualCtx == 1 272 die(buf.WriteByte(1)) // actualCtx == 1
270 ws(buf, "aid") 273 ws(buf, "aid")
271 ws(buf, "ns") 274 ws(buf, "ns")
272 » » » » » _, err := ReadKey(buf, WithContext, "", "") 275 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
273 So(err, ShouldEqual, io.EOF) 276 So(err, ShouldEqual, io.EOF)
274 }) 277 })
275 Convey("huge key", func() { 278 Convey("huge key", func() {
276 die(buf.WriteByte(1)) // actualCtx == 1 279 die(buf.WriteByte(1)) // actualCtx == 1
277 ws(buf, "aid") 280 ws(buf, "aid")
278 ws(buf, "ns") 281 ws(buf, "ns")
279 for i := 1; i < 60; i++ { 282 for i := 1; i < 60; i++ {
280 die(buf.WriteByte(1)) 283 die(buf.WriteByte(1))
281 die(WriteKeyTok(buf, ds.KeyTok{K ind: "sup", IntID: int64(i)})) 284 die(WriteKeyTok(buf, ds.KeyTok{K ind: "sup", IntID: int64(i)}))
282 } 285 }
283 die(buf.WriteByte(0)) 286 die(buf.WriteByte(0))
284 » » » » » _, err := ReadKey(buf, WithContext, "", "") 287 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
285 So(err, ShouldErrLike, "huge key") 288 So(err, ShouldErrLike, "huge key")
286 }) 289 })
287 Convey("insufficient tokens", func() { 290 Convey("insufficient tokens", func() {
288 die(buf.WriteByte(1)) // actualCtx == 1 291 die(buf.WriteByte(1)) // actualCtx == 1
289 ws(buf, "aid") 292 ws(buf, "aid")
290 ws(buf, "ns") 293 ws(buf, "ns")
291 wui(buf, 2) 294 wui(buf, 2)
292 » » » » » _, err := ReadKey(buf, WithContext, "", "") 295 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
293 So(err, ShouldEqual, io.EOF) 296 So(err, ShouldEqual, io.EOF)
294 }) 297 })
295 Convey("partial token 1", func() { 298 Convey("partial token 1", func() {
296 die(buf.WriteByte(1)) // actualCtx == 1 299 die(buf.WriteByte(1)) // actualCtx == 1
297 ws(buf, "aid") 300 ws(buf, "aid")
298 ws(buf, "ns") 301 ws(buf, "ns")
299 die(buf.WriteByte(1)) 302 die(buf.WriteByte(1))
300 ws(buf, "hi") 303 ws(buf, "hi")
301 » » » » » _, err := ReadKey(buf, WithContext, "", "") 304 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
302 So(err, ShouldEqual, io.EOF) 305 So(err, ShouldEqual, io.EOF)
303 }) 306 })
304 Convey("partial token 2", func() { 307 Convey("partial token 2", func() {
305 die(buf.WriteByte(1)) // actualCtx == 1 308 die(buf.WriteByte(1)) // actualCtx == 1
306 ws(buf, "aid") 309 ws(buf, "aid")
307 ws(buf, "ns") 310 ws(buf, "ns")
308 die(buf.WriteByte(1)) 311 die(buf.WriteByte(1))
309 ws(buf, "hi") 312 ws(buf, "hi")
310 die(buf.WriteByte(byte(ds.PTString))) 313 die(buf.WriteByte(byte(ds.PTString)))
311 » » » » » _, err := ReadKey(buf, WithContext, "", "") 314 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
312 So(err, ShouldEqual, io.EOF) 315 So(err, ShouldEqual, io.EOF)
313 }) 316 })
314 Convey("bad token (invalid type)", func() { 317 Convey("bad token (invalid type)", func() {
315 die(buf.WriteByte(1)) // actualCtx == 1 318 die(buf.WriteByte(1)) // actualCtx == 1
316 ws(buf, "aid") 319 ws(buf, "aid")
317 ws(buf, "ns") 320 ws(buf, "ns")
318 die(buf.WriteByte(1)) 321 die(buf.WriteByte(1))
319 ws(buf, "hi") 322 ws(buf, "hi")
320 die(buf.WriteByte(byte(ds.PTBlobKey))) 323 die(buf.WriteByte(byte(ds.PTBlobKey)))
321 » » » » » _, err := ReadKey(buf, WithContext, "", "") 324 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
322 So(err, ShouldErrLike, "invalid type PTB lobKey") 325 So(err, ShouldErrLike, "invalid type PTB lobKey")
323 }) 326 })
324 Convey("bad token (invalid IntID)", func() { 327 Convey("bad token (invalid IntID)", func() {
325 die(buf.WriteByte(1)) // actualCtx == 1 328 die(buf.WriteByte(1)) // actualCtx == 1
326 ws(buf, "aid") 329 ws(buf, "aid")
327 ws(buf, "ns") 330 ws(buf, "ns")
328 die(buf.WriteByte(1)) 331 die(buf.WriteByte(1))
329 ws(buf, "hi") 332 ws(buf, "hi")
330 die(buf.WriteByte(byte(ds.PTInt))) 333 die(buf.WriteByte(byte(ds.PTInt)))
331 wi(buf, -2) 334 wi(buf, -2)
332 » » » » » _, err := ReadKey(buf, WithContext, "", "") 335 » » » » » _, err := ReadKey(buf, WithContext, ds.K eyContext{})
333 So(err, ShouldErrLike, "zero/negative") 336 So(err, ShouldErrLike, "zero/negative")
334 }) 337 })
335 }) 338 })
336 }) 339 })
337 340
338 Convey("ReadGeoPoint", func() { 341 Convey("ReadGeoPoint", func() {
339 buf := mkBuf(nil) 342 buf := mkBuf(nil)
340 Convey("trunc 1", func() { 343 Convey("trunc 1", func() {
341 _, err := ReadGeoPoint(buf) 344 _, err := ReadGeoPoint(buf)
342 So(err, ShouldEqual, io.EOF) 345 So(err, ShouldEqual, io.EOF)
(...skipping 24 matching lines...) Expand all
367 Convey("ReadTime", func() { 370 Convey("ReadTime", func() {
368 Convey("trunc 1", func() { 371 Convey("trunc 1", func() {
369 _, err := ReadTime(mkBuf(nil)) 372 _, err := ReadTime(mkBuf(nil))
370 So(err, ShouldEqual, io.EOF) 373 So(err, ShouldEqual, io.EOF)
371 }) 374 })
372 }) 375 })
373 376
374 Convey("ReadProperty", func() { 377 Convey("ReadProperty", func() {
375 buf := mkBuf(nil) 378 buf := mkBuf(nil)
376 Convey("trunc 1", func() { 379 Convey("trunc 1", func() {
377 » » » » p, err := ReadProperty(buf, WithContext, "", "") 380 » » » » p, err := ReadProperty(buf, WithContext, ds.KeyC ontext{})
378 So(err, ShouldEqual, io.EOF) 381 So(err, ShouldEqual, io.EOF)
379 So(p.Type(), ShouldEqual, ds.PTNull) 382 So(p.Type(), ShouldEqual, ds.PTNull)
380 So(p.Value(), ShouldBeNil) 383 So(p.Value(), ShouldBeNil)
381 }) 384 })
382 Convey("trunc (PTBytes)", func() { 385 Convey("trunc (PTBytes)", func() {
383 die(buf.WriteByte(byte(ds.PTBytes))) 386 die(buf.WriteByte(byte(ds.PTBytes)))
384 » » » » _, err := ReadProperty(buf, WithContext, "", "") 387 » » » » _, err := ReadProperty(buf, WithContext, ds.KeyC ontext{})
385 So(err, ShouldEqual, io.EOF) 388 So(err, ShouldEqual, io.EOF)
386 }) 389 })
387 Convey("trunc (PTBlobKey)", func() { 390 Convey("trunc (PTBlobKey)", func() {
388 die(buf.WriteByte(byte(ds.PTBlobKey))) 391 die(buf.WriteByte(byte(ds.PTBlobKey)))
389 » » » » _, err := ReadProperty(buf, WithContext, "", "") 392 » » » » _, err := ReadProperty(buf, WithContext, ds.KeyC ontext{})
390 So(err, ShouldEqual, io.EOF) 393 So(err, ShouldEqual, io.EOF)
391 }) 394 })
392 Convey("invalid type", func() { 395 Convey("invalid type", func() {
393 die(buf.WriteByte(byte(ds.PTUnknown + 1))) 396 die(buf.WriteByte(byte(ds.PTUnknown + 1)))
394 » » » » _, err := ReadProperty(buf, WithContext, "", "") 397 » » » » _, err := ReadProperty(buf, WithContext, ds.KeyC ontext{})
395 So(err, ShouldErrLike, "unknown type!") 398 So(err, ShouldErrLike, "unknown type!")
396 }) 399 })
397 }) 400 })
398 401
399 Convey("ReadPropertyMap", func() { 402 Convey("ReadPropertyMap", func() {
400 buf := mkBuf(nil) 403 buf := mkBuf(nil)
401 Convey("trunc 1", func() { 404 Convey("trunc 1", func() {
402 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "") 405 » » » » _, err := ReadPropertyMap(buf, WithContext, ds.K eyContext{})
403 So(err, ShouldEqual, io.EOF) 406 So(err, ShouldEqual, io.EOF)
404 }) 407 })
405 Convey("too many rows", func() { 408 Convey("too many rows", func() {
406 wui(buf, 1000000) 409 wui(buf, 1000000)
407 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "") 410 » » » » _, err := ReadPropertyMap(buf, WithContext, ds.K eyContext{})
408 So(err, ShouldErrLike, "huge number of rows") 411 So(err, ShouldErrLike, "huge number of rows")
409 }) 412 })
410 Convey("trunc 2", func() { 413 Convey("trunc 2", func() {
411 wui(buf, 10) 414 wui(buf, 10)
412 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "") 415 » » » » _, err := ReadPropertyMap(buf, WithContext, ds.K eyContext{})
413 So(err, ShouldEqual, io.EOF) 416 So(err, ShouldEqual, io.EOF)
414 }) 417 })
415 Convey("trunc 3", func() { 418 Convey("trunc 3", func() {
416 wui(buf, 10) 419 wui(buf, 10)
417 ws(buf, "ohai") 420 ws(buf, "ohai")
418 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "") 421 » » » » _, err := ReadPropertyMap(buf, WithContext, ds.K eyContext{})
419 So(err, ShouldEqual, io.EOF) 422 So(err, ShouldEqual, io.EOF)
420 }) 423 })
421 Convey("too many values", func() { 424 Convey("too many values", func() {
422 wui(buf, 10) 425 wui(buf, 10)
423 ws(buf, "ohai") 426 ws(buf, "ohai")
424 wui(buf, 100000) 427 wui(buf, 100000)
425 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "") 428 » » » » _, err := ReadPropertyMap(buf, WithContext, ds.K eyContext{})
426 So(err, ShouldErrLike, "huge number of propertie s") 429 So(err, ShouldErrLike, "huge number of propertie s")
427 }) 430 })
428 Convey("trunc 4", func() { 431 Convey("trunc 4", func() {
429 wui(buf, 10) 432 wui(buf, 10)
430 ws(buf, "ohai") 433 ws(buf, "ohai")
431 wui(buf, 10) 434 wui(buf, 10)
432 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "") 435 » » » » _, err := ReadPropertyMap(buf, WithContext, ds.K eyContext{})
433 So(err, ShouldEqual, io.EOF) 436 So(err, ShouldEqual, io.EOF)
434 }) 437 })
435 }) 438 })
436 439
437 Convey("IndexDefinition", func() { 440 Convey("IndexDefinition", func() {
438 id := ds.IndexDefinition{Kind: "kind"} 441 id := ds.IndexDefinition{Kind: "kind"}
439 data := ToBytes(*id.PrepForIdxTable()) 442 data := ToBytes(*id.PrepForIdxTable())
440 newID, err := ReadIndexDefinition(mkBuf(data)) 443 newID, err := ReadIndexDefinition(mkBuf(data))
441 So(err, ShouldBeNil) 444 So(err, ShouldBeNil)
442 So(newID.Flip(), ShouldResemble, id.Normalize()) 445 So(newID.Flip(), ShouldResemble, id.Normalize())
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 "__ancestor__": { 509 "__ancestor__": {
507 ToBytes(mp(fakeKey)), 510 ToBytes(mp(fakeKey)),
508 ToBytes(mp(fakeKey.Paren t())), 511 ToBytes(mp(fakeKey.Paren t())),
509 }, 512 },
510 }) 513 })
511 }) 514 })
512 }) 515 })
513 }) 516 })
514 }) 517 })
515 } 518 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698