Skip to content

Commit

Permalink
test: add ordering tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Stebalien committed Apr 18, 2019
1 parent ce3a022 commit 05e6f03
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 46 deletions.
8 changes: 8 additions & 0 deletions query/order.go
Expand Up @@ -2,6 +2,7 @@ package query

import (
"bytes"
"sort"
"strings"
)

Expand Down Expand Up @@ -64,3 +65,10 @@ func Less(orders []Order, a, b Entry) bool {
// because it's undefined.
return a.Key < b.Key
}

// Sort sorts the given entries using the given orders.
func Sort(orders []Order, entries []Entry) {
sort.Slice(entries, func(i int, j int) bool {
return Less(orders, entries[i], entries[j])
})
}
6 changes: 1 addition & 5 deletions query/query_impl.go
@@ -1,7 +1,5 @@
package query

import "sort"

func DerivedResults(qr Results, ch <-chan Result) Results {
return &results{
query: qr.Query(),
Expand Down Expand Up @@ -96,9 +94,7 @@ func NaiveOrder(qr Results, orders ...Order) Results {

entries = append(entries, e.Entry)
}
sort.Slice(entries, func(i int, j int) bool {
return Less(orders, entries[i], entries[j])
})
Sort(orders, entries)

for _, e := range entries {
ch <- Result{Entry: e}
Expand Down
114 changes: 73 additions & 41 deletions test/basic_tests.go
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"fmt"
"math/rand"
"sort"
"strings"
"testing"

dstore "github.com/ipfs/go-datastore"
Expand Down Expand Up @@ -123,79 +123,111 @@ func SubtestNotFounds(t *testing.T, ds dstore.Datastore) {
}
}

func SubtestOrder(t *testing.T, ds dstore.Datastore) {
test := func(orders ...dsq.Order) {
var types []string
for _, o := range orders {
types = append(types, fmt.Sprintf("%T", o))
}
name := strings.Join(types, ":")
t.Run(name, func(t *testing.T) {
subtestQuery(t, ds, dsq.Query{
Orders: orders,
}, func(t *testing.T, input, output []dsq.Entry) {
if len(input) != len(output) {
t.Fatal("got wrong number of keys back")
}

dsq.Sort(orders, input)

for i, e := range output {
if input[i].Key != e.Key {
t.Fatalf("in key output, got %s but expected %s", e.Key, input[i].Key)
}
}
})
})
}
test(dsq.OrderByKey{})
test(new(dsq.OrderByKey))
test(dsq.OrderByKeyDescending{})
test(new(dsq.OrderByKeyDescending))
test(dsq.OrderByValue{})
test(dsq.OrderByValue{}, dsq.OrderByKey{})
test(dsq.OrderByFunction(func(a, b dsq.Entry) int {
return bytes.Compare(a.Value, b.Value)
}))
}

func SubtestManyKeysAndQuery(t *testing.T, ds dstore.Datastore) {
var keys []dstore.Key
var keystrs []string
var values [][]byte
subtestQuery(t, ds, dsq.Query{KeysOnly: true}, func(t *testing.T, input, output []dsq.Entry) {
if len(input) != len(output) {
t.Fatal("got wrong number of keys back")
}

dsq.Sort([]dsq.Order{dsq.OrderByKey{}}, input)
dsq.Sort([]dsq.Order{dsq.OrderByKey{}}, output)

for i, e := range output {
if input[i].Key != e.Key {
t.Fatalf("in key output, got %s but expected %s", e.Key, input[i].Key)
}
}
})
}

func subtestQuery(t *testing.T, ds dstore.Datastore, q dsq.Query, check func(t *testing.T, input, output []dsq.Entry)) {
var input []dsq.Entry
count := 100
for i := 0; i < count; i++ {
s := fmt.Sprintf("%dkey%d", i, i)
dsk := dstore.NewKey(s)
keystrs = append(keystrs, dsk.String())
keys = append(keys, dsk)
buf := make([]byte, 64)
rand.Read(buf)
values = append(values, buf)
key := dstore.NewKey(s).String()
value := make([]byte, 64)
rand.Read(value)
input = append(input, dsq.Entry{
Key: key,
Value: value,
})
}

t.Logf("putting %d values", count)
for i, k := range keys {
err := ds.Put(k, values[i])
for i, e := range input {
err := ds.Put(dstore.RawKey(e.Key), e.Value)
if err != nil {
t.Fatalf("error on put[%d]: %s", i, err)
}
}

t.Log("getting values back")
for i, k := range keys {
val, err := ds.Get(k)
for i, e := range input {
val, err := ds.Get(dstore.RawKey(e.Key))
if err != nil {
t.Fatalf("error on get[%d]: %s", i, err)
}

if !bytes.Equal(val, values[i]) {
if !bytes.Equal(val, e.Value) {
t.Fatal("input value didnt match the one returned from Get")
}
}

t.Log("querying values")
q := dsq.Query{KeysOnly: true}
resp, err := ds.Query(q)
if err != nil {
t.Fatal("calling query: ", err)
}

t.Log("aggregating query results")
var outkeys []string
for {
res, ok := resp.NextSync()
if res.Error != nil {
t.Fatal("query result error: ", res.Error)
}
if !ok {
break
}

outkeys = append(outkeys, res.Key)
output, err := resp.Rest()
if err != nil {
t.Fatal("query result error: ", err)
}

t.Log("verifying query output")
sort.Strings(keystrs)
sort.Strings(outkeys)

if len(keystrs) != len(outkeys) {
t.Fatal("got wrong number of keys back")
}

for i, s := range keystrs {
if outkeys[i] != s {
t.Fatalf("in key output, got %s but expected %s", outkeys[i], s)
}
}
check(t, input, output)

t.Log("deleting all keys")
for _, k := range keys {
if err := ds.Delete(k); err != nil {
for _, e := range input {
if err := ds.Delete(dstore.RawKey(e.Key)); err != nil {
t.Fatal(err)
}
}
Expand Down

0 comments on commit 05e6f03

Please sign in to comment.