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

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

Issue 2498463003: Fix a bug where deletions weren't updating the raw Kind index. (Closed)
Patch Set: impl/memory: query limits/offsets count deleted Created 4 years, 1 month 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 memory 5 package memory
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "strings" 9 "strings"
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 ds "github.com/luci/gae/service/datastore" 14 ds "github.com/luci/gae/service/datastore"
15 "github.com/luci/gae/service/info" 15 "github.com/luci/gae/service/info"
16 "golang.org/x/net/context" 16 "golang.org/x/net/context"
17 17
18 . "github.com/luci/luci-go/common/testing/assertions" 18 . "github.com/luci/luci-go/common/testing/assertions"
19 . "github.com/smartystreets/goconvey/convey" 19 . "github.com/smartystreets/goconvey/convey"
20 ) 20 )
21 21
22 func mkKey(appID, namespace string, elems ...interface{}) *ds.Key { 22 func mkKey(appID, namespace string, elems ...interface{}) *ds.Key {
23 return ds.MkKeyContext(appID, namespace).MakeKey(elems...) 23 return ds.MkKeyContext(appID, namespace).MakeKey(elems...)
24 } 24 }
25 25
26 var enableOnly = false
27
28 func enable() bool {
dnj 2016/11/11 08:37:53 This is something useful for debugging specific te
29 enableOnly = true
30 return true
31 }
32
26 type qExpect struct { 33 type qExpect struct {
27 q *ds.Query 34 q *ds.Query
28 inTxn bool 35 inTxn bool
29 36
30 get []ds.PropertyMap 37 get []ds.PropertyMap
31 keys []*ds.Key 38 keys []*ds.Key
32 count int 39 count int
40
41 enable bool
33 } 42 }
34 43
35 type qExStage struct { 44 type qExStage struct {
36 addIdxs []*ds.IndexDefinition 45 addIdxs []*ds.IndexDefinition
37 putEnts []ds.PropertyMap 46 putEnts []ds.PropertyMap
38 delEnts []*ds.Key 47 delEnts []*ds.Key
39 48
40 expect []qExpect 49 expect []qExpect
41 50
42 extraFns []func(context.Context) 51 extraFns []func(context.Context)
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 254
246 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5), get: []ds.PropertyMap{ 255 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5), get: []ds.PropertyMap{
247 stage1Data[0], stage1Data[3], 256 stage1Data[0], stage1Data[3],
248 }}, 257 }},
249 258
250 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5).Order( "-Val"), get: []ds.PropertyMap{ 259 {q: nq("Kind").Gt("Val", 2).Lte("Val", 5).Order( "-Val"), get: []ds.PropertyMap{
251 stage1Data[3], stage1Data[0], 260 stage1Data[3], stage1Data[0],
252 }}, 261 }},
253 262
254 {q: nq("").Gt("__key__", key("Kind", 2)), 263 {q: nq("").Gt("__key__", key("Kind", 2)),
255 » » » » » // count counts from the index with Keys Only and so counts the deleted 264 » » » » » count: 7,
dnj 2016/11/11 08:37:53 (This is no longer true, since we don't auto-KeysO
256 » » » » » // entity Unique/1.
257 » » » » » count: 8,
258 get: []ds.PropertyMap{ 265 get: []ds.PropertyMap{
259 // TODO(riannucci): determine if the real datastore shows metadata 266 // TODO(riannucci): determine if the real datastore shows metadata
260 // during kindless queries. The documentation seems to imply so, but 267 // during kindless queries. The documentation seems to imply so, but
261 // I'd like to be sure. 268 // I'd like to be sure.
262 pmap("$key", key("Kind", 2, "__e ntity_group__", 1), Next, 269 pmap("$key", key("Kind", 2, "__e ntity_group__", 1), Next,
263 "__version__", 1), 270 "__version__", 1),
264 stage1Data[2], 271 stage1Data[2],
265 stage1Data[4], 272 stage1Data[4],
266 // this is 5 because the value i s retrieved from HEAD and not from 273 // this is 5 because the value i s retrieved from HEAD and not from
267 // the index snapshot! 274 // the index snapshot!
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 " - name: Val", 423 " - name: Val",
417 }, "\n")) 424 }, "\n"))
418 }, 425 },
419 }, 426 },
420 }, 427 },
421 428
422 { 429 {
423 expect: []qExpect{ 430 expect: []qExpect{
424 // eventual consistency; Unique/1 is deleted at HEAD. Keysonly finds it, 431 // eventual consistency; Unique/1 is deleted at HEAD. Keysonly finds it,
425 // but 'normal' doesn't. 432 // but 'normal' doesn't.
433 {q: nq("Unique").Gt("__key__", key("AKind", 5)). Lte("__key__", key("Zeta", "prime")).KeysOnly(true),
434 keys: []*ds.Key{key("Unique", 1)}},
426 {q: nq("Unique").Gt("__key__", key("AKind", 5)). Lte("__key__", key("Zeta", "prime")), 435 {q: nq("Unique").Gt("__key__", key("AKind", 5)). Lte("__key__", key("Zeta", "prime")),
427 » » » » » keys: []*ds.Key{key("Unique", 1)}, 436 » » » » » get: []ds.PropertyMap{}},
428 » » » » » get: []ds.PropertyMap{}},
429 437
430 {q: nq("Kind").Eq("Val", 1, 3), get: []ds.Proper tyMap{ 438 {q: nq("Kind").Eq("Val", 1, 3), get: []ds.Proper tyMap{
431 stage1Data[0], stage2Data[2], 439 stage1Data[0], stage2Data[2],
432 }}, 440 }},
433 }, 441 },
434 }, 442 },
435 }}, 443 }},
436 {"collapsed types", []qExStage{ 444 {"collapsed types", []qExStage{
437 { 445 {
438 putEnts: collapsedData, 446 putEnts: collapsedData,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 }, 484 },
477 { 485 {
478 q: nq("Kind").Eq("Val", []byte("uwutm8") ), 486 q: nq("Kind").Eq("Val", []byte("uwutm8") ),
479 get: []ds.PropertyMap{ 487 get: []ds.PropertyMap{
480 collapsedData[5], 488 collapsedData[5],
481 }, 489 },
482 }, 490 },
483 }, 491 },
484 }, 492 },
485 }}, 493 }},
494
495 {"regression: tombstones and limit/offset queries", []qExStage{
496 {
497 putEnts: []ds.PropertyMap{
498 pmap("$key", key("Kind", 1)),
499 pmap("$key", key("Kind", 2)),
500 pmap("$key", key("Kind", 3)),
501 },
502 delEnts: []*ds.Key{key("Kind", 2)},
503 },
504 {
505 expect: []qExpect{
506 {
507 q: nq("Kind").Limit(2),
508 get: []ds.PropertyMap{
509 pmap("$key", key("Kind", 1)),
510 pmap("$key", key("Kind", 3)),
511 },
512 },
513
514 {
515 q: nq("Kind").Offset(2),
516 get: []ds.PropertyMap{},
517 },
518 },
519 },
520 }},
486 } 521 }
487 522
488 func TestQueryExecution(t *testing.T) { 523 func TestQueryExecution(t *testing.T) {
489 t.Parallel() 524 t.Parallel()
490 525
491 Convey("Test query execution", t, func() { 526 Convey("Test query execution", t, func() {
492 c, err := info.Namespace(Use(context.Background()), "ns") 527 c, err := info.Namespace(Use(context.Background()), "ns")
493 if err != nil { 528 if err != nil {
494 panic(err) 529 panic(err)
495 } 530 }
(...skipping 23 matching lines...) Expand all
519 panic(err) 554 panic(err)
520 } 555 }
521 } 556 }
522 557
523 if err := ds.Delete(c, stage.delEnts); e rr != nil { 558 if err := ds.Delete(c, stage.delEnts); e rr != nil {
524 panic(err) 559 panic(err)
525 } 560 }
526 561
527 Convey(fmt.Sprintf("stage %d", i), func( ) { 562 Convey(fmt.Sprintf("stage %d", i), func( ) {
528 for j, expect := range stage.exp ect { 563 for j, expect := range stage.exp ect {
564 if enableOnly && !expect .enable {
565 continue
566 }
529 runner := func(c context .Context, f func(ic context.Context) error, _ *ds.TransactionOptions) error { 567 runner := func(c context .Context, f func(ic context.Context) error, _ *ds.TransactionOptions) error {
530 return f(c) 568 return f(c)
531 } 569 }
532 if expect.inTxn { 570 if expect.inTxn {
533 runner = ds.RunI nTransaction 571 runner = ds.RunI nTransaction
534 } 572 }
535 573
536 if expect.count == 0 { 574 if expect.count == 0 {
537 if len(expect.ke ys) > 0 { 575 if len(expect.ke ys) > 0 {
538 expect.c ount = len(expect.keys) 576 expect.c ount = len(expect.keys)
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 671
634 v, ok := actual.(error) 672 v, ok := actual.(error)
635 if !ok { 673 if !ok {
636 return fmt.Sprintf("type of 'actual' must be error, not %T", act ual) 674 return fmt.Sprintf("type of 'actual' must be error, not %T", act ual)
637 } 675 }
638 if v == nil || v == ds.Stop { 676 if v == nil || v == ds.Stop {
639 return "" 677 return ""
640 } 678 }
641 return fmt.Sprintf("expected success value, not %v", v) 679 return fmt.Sprintf("expected success value, not %v", v)
642 } 680 }
OLDNEW
« impl/memory/datastore_query_execution.go ('K') | « impl/memory/datastore_query_execution.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698