mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
177 lines
4.9 KiB
Go
177 lines
4.9 KiB
Go
// Copyright 2022 Molecula Corp. (DBA FeatureBase).
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
package proto
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"testing"
|
|
|
|
pilosa "github.com/featurebasedb/featurebase/v3"
|
|
"github.com/featurebasedb/featurebase/v3/ingest"
|
|
"github.com/featurebasedb/featurebase/v3/pb"
|
|
)
|
|
|
|
func testOneRoundTrip(t *testing.T, s pilosa.Serializer, obj pilosa.Message, expectedMarshalErr error, expectedUnmarshalErr error, expectedMismatchErr error) {
|
|
repr, err := s.Marshal(obj)
|
|
if err != nil {
|
|
if expectedMarshalErr == nil {
|
|
t.Fatalf("unexpected marshalling error %q", err.Error())
|
|
}
|
|
if err.Error() != expectedMarshalErr.Error() {
|
|
t.Fatalf("expecting marshalling error %q, got %q", expectedMarshalErr.Error(), err.Error())
|
|
}
|
|
} else {
|
|
if expectedMarshalErr != nil {
|
|
t.Fatalf("expected marshalling error %q, got no error", expectedMarshalErr.Error())
|
|
}
|
|
}
|
|
|
|
obj2 := reflect.New(reflect.TypeOf(obj).Elem()).Interface()
|
|
err = s.Unmarshal(repr, obj2)
|
|
if err != nil {
|
|
if expectedUnmarshalErr == nil {
|
|
t.Fatalf("unexpected unmarshalling error %q", err.Error())
|
|
}
|
|
if err.Error() != expectedUnmarshalErr.Error() {
|
|
t.Fatalf("expecting unmarshalling error %q, got %q", expectedUnmarshalErr.Error(), err.Error())
|
|
}
|
|
} else {
|
|
if expectedUnmarshalErr != nil {
|
|
t.Fatalf("expected unmarshalling error %q, got no error", expectedUnmarshalErr.Error())
|
|
}
|
|
}
|
|
switch real := obj.(type) {
|
|
case *ingest.ShardedRequest:
|
|
real2 := obj2.(*ingest.ShardedRequest)
|
|
err := real.Compare(real2)
|
|
if err != nil {
|
|
if expectedMismatchErr == nil {
|
|
t.Fatalf("unexpected compare error %q", err.Error())
|
|
}
|
|
if err.Error() != expectedMismatchErr.Error() {
|
|
t.Fatalf("expecting compare error %q, got %q", expectedMismatchErr.Error(), err.Error())
|
|
}
|
|
} else {
|
|
if expectedMismatchErr != nil {
|
|
t.Fatalf("expected compare error %q, got no error", expectedMismatchErr.Error())
|
|
}
|
|
}
|
|
default:
|
|
if !reflect.DeepEqual(obj, obj2) {
|
|
t.Fatalf("serialization round trip failed for %T:\nexpected %#v\ngot %#v", obj, obj, obj2)
|
|
}
|
|
}
|
|
}
|
|
|
|
type shardedIngestRequestTest struct {
|
|
req *ingest.ShardedRequest
|
|
err error
|
|
}
|
|
|
|
var shardedIngestRequestTestcases = []shardedIngestRequestTest{
|
|
{
|
|
req: &ingest.ShardedRequest{
|
|
Ops: map[uint64][]*ingest.Operation{
|
|
1: {
|
|
{
|
|
OpType: ingest.OpWrite,
|
|
ClearFields: []string{"clearField", "clearField2"},
|
|
ClearRecordIDs: []uint64{1, 7, 9},
|
|
FieldOps: map[string]*ingest.FieldOperation{
|
|
"writeAll": {
|
|
RecordIDs: []uint64{3, 6, 8},
|
|
Values: []uint64{0, 17, 34},
|
|
Signed: []int64{-9, 23, 17},
|
|
},
|
|
"writeValues": {
|
|
RecordIDs: []uint64{3, 6, 8},
|
|
Values: []uint64{0, 17, 34},
|
|
},
|
|
"writeSigned": {
|
|
RecordIDs: []uint64{3, 6, 8},
|
|
Signed: []int64{-9, 23, 17},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
OpType: ingest.OpSet,
|
|
FieldOps: map[string]*ingest.FieldOperation{
|
|
"foo": nil,
|
|
},
|
|
},
|
|
},
|
|
2: {},
|
|
3: nil,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
req: &ingest.ShardedRequest{
|
|
Ops: map[uint64][]*ingest.Operation{
|
|
1: {
|
|
{
|
|
OpType: ingest.OpWrite,
|
|
FieldOps: map[string]*ingest.FieldOperation{
|
|
"writeAll": {},
|
|
},
|
|
},
|
|
{
|
|
OpType: ingest.OpSet,
|
|
FieldOps: map[string]*ingest.FieldOperation{
|
|
"foo": nil,
|
|
},
|
|
},
|
|
nil,
|
|
},
|
|
},
|
|
},
|
|
err: errors.New("shard 1: expected 3 ops, got 2"),
|
|
},
|
|
}
|
|
|
|
func TestIngestRoundTrip(t *testing.T) {
|
|
for _, tc := range shardedIngestRequestTestcases {
|
|
t.Logf("next case")
|
|
testOneRoundTrip(t, DefaultSerializer, tc.req, nil, nil, tc.err)
|
|
}
|
|
}
|
|
|
|
func TestEncodeDecodeDistinctTimestamp(t *testing.T) {
|
|
s := Serializer{}
|
|
pbTime := pb.DistinctTimestamp{
|
|
Values: []string{"this", "is", "fake", "timestamp", "values"},
|
|
Name: "pbtime",
|
|
}
|
|
piloTime := pilosa.DistinctTimestamp{
|
|
Values: []string{"this", "is", "fake", "timestamp", "values"},
|
|
Name: "pbtime",
|
|
}
|
|
decoded := s.decodeDistinctTimestamp(&pbTime)
|
|
if !reflect.DeepEqual(decoded, piloTime) {
|
|
t.Errorf("failed to decode DistinctTimestamp. expected %v got %v", piloTime, decoded)
|
|
}
|
|
encoded := s.encodeDistinctTimestamp(piloTime)
|
|
if !reflect.DeepEqual(encoded, &pbTime) {
|
|
t.Errorf("failed to encode DistinctTimestamp. expected %v got %v", &pbTime, encoded)
|
|
}
|
|
}
|
|
|
|
func TestDecodeQueryResult(t *testing.T) {
|
|
t.Run("DistinctTimestamp", func(t *testing.T) {
|
|
pbTime := pb.DistinctTimestamp{
|
|
Values: []string{"this", "is", "fake", "timestamp", "values"},
|
|
Name: "pbtime",
|
|
}
|
|
piloTime := pilosa.DistinctTimestamp{
|
|
Values: []string{"this", "is", "fake", "timestamp", "values"},
|
|
Name: "pbtime",
|
|
}
|
|
q := &pb.QueryResult{Type: queryResultTypeDistinctTimestamp, DistinctTimestamp: &pbTime}
|
|
s := Serializer{}
|
|
decoded := s.decodeQueryResult(q)
|
|
if !reflect.DeepEqual(decoded, piloTime) {
|
|
t.Errorf("failed to decode DistinctTimestamp. expected %v got %v", piloTime, decoded)
|
|
}
|
|
})
|
|
}
|