|
4 | 4 | "bytes"
|
5 | 5 | "context"
|
6 | 6 | "crypto/rand"
|
| 7 | + "errors" |
7 | 8 | "fmt"
|
8 | 9 | "reflect"
|
9 | 10 | "strings"
|
@@ -403,7 +404,8 @@ func randValue() []byte {
|
403 | 404 | }
|
404 | 405 |
|
405 | 406 | func subtestQuery(t *testing.T, ds dstore.Datastore, q dsq.Query, count int) {
|
406 |
| - ctx := context.Background() |
| 407 | + ctx, cancel := context.WithCancel(context.Background()) |
| 408 | + defer cancel() |
407 | 409 |
|
408 | 410 | var input []dsq.Entry
|
409 | 411 | for i := 0; i < count; i++ {
|
@@ -511,6 +513,58 @@ func subtestQuery(t *testing.T, ds dstore.Datastore, q dsq.Query, count int) {
|
511 | 513 | }
|
512 | 514 | }
|
513 | 515 |
|
| 516 | + // Test QueryIter for same results. |
| 517 | + actual = actual[:0] |
| 518 | + for ent, err := range dstore.QueryIter(ctx, ds, q) { |
| 519 | + if err != nil { |
| 520 | + t.Fatal("query result error: ", err) |
| 521 | + } |
| 522 | + actual = append(actual, ent) |
| 523 | + } |
| 524 | + if len(actual) != len(expected) { |
| 525 | + t.Fatalf("expected %d results from QueryIter, got %d", len(expected), len(actual)) |
| 526 | + } |
| 527 | + if len(q.Orders) == 0 { |
| 528 | + dsq.Sort([]dsq.Order{dsq.OrderByKey{}}, actual) |
| 529 | + } |
| 530 | + for i := range actual { |
| 531 | + if actual[i].Key != expected[i].Key { |
| 532 | + t.Errorf("for result %d, expected key %q, got %q", i, expected[i].Key, actual[i].Key) |
| 533 | + continue |
| 534 | + } |
| 535 | + if !q.KeysOnly && !bytes.Equal(actual[i].Value, expected[i].Value) { |
| 536 | + t.Errorf("value mismatch for result %d (key=%q)", i, expected[i].Key) |
| 537 | + } |
| 538 | + if q.ReturnsSizes && actual[i].Size <= 0 { |
| 539 | + t.Errorf("for result %d, expected size > 0 with ReturnsSizes", i) |
| 540 | + } |
| 541 | + } |
| 542 | + |
| 543 | + const cancelAt = 1 |
| 544 | + if len(actual) > cancelAt { |
| 545 | + // Test that query iterator stops when context is canceled. |
| 546 | + var i int |
| 547 | + for ent, err := range dstore.QueryIter(ctx, ds, q) { |
| 548 | + if err != nil { |
| 549 | + if !errors.Is(err, context.Canceled) { |
| 550 | + t.Fatal("query result error: ", err) |
| 551 | + } |
| 552 | + t.Log("err at:", i, err) |
| 553 | + continue |
| 554 | + } |
| 555 | + if ent.Key == "" { |
| 556 | + t.Fatal("entry has empty key") |
| 557 | + } |
| 558 | + i++ |
| 559 | + if i == cancelAt { |
| 560 | + cancel() |
| 561 | + } |
| 562 | + } |
| 563 | + if i != cancelAt { |
| 564 | + t.Fatal("expected iteration to be canceled at", cancelAt, "canceled at", i) |
| 565 | + } |
| 566 | + } |
| 567 | + |
514 | 568 | t.Log("deleting all keys")
|
515 | 569 | for _, e := range input {
|
516 | 570 | if err := ds.Delete(ctx, dstore.RawKey(e.Key)); err != nil {
|
|
0 commit comments