SQL3 tests newMessageError and all the constructors (#2320)

* sql3 wire protocol message constructor tests

* convert to testify assertion, clarify comment
This commit is contained in:
tgruben 2023-03-15 12:41:35 -05:00 committed by GitHub
parent aa17b8d725
commit e02ea2c2e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 162 additions and 0 deletions

View file

@ -0,0 +1,158 @@
package planner
import (
"bytes"
"encoding/binary"
"errors"
"io"
"testing"
"github.com/featurebasedb/featurebase/v3/sql3/parser"
"github.com/featurebasedb/featurebase/v3/sql3/planner/types"
"github.com/featurebasedb/featurebase/v3/wireprotocol"
"github.com/stretchr/testify/assert"
)
func Test_newMessageError(t *testing.T) {
type args struct {
p *ExecutionPlanner
reader io.Reader
}
tests := []struct {
name string
args args
want *messageError
wantErr bool
}{
{
name: "err read len",
args: args{p: nil, reader: bytes.NewReader([]byte{})},
want: nil,
wantErr: true,
},
{
name: "err read name",
args: args{p: nil, reader: bytes.NewReader([]byte{0x0, 0x0, 0x0, 0x1})},
want: nil,
wantErr: true,
},
{
name: "happy path",
args: args{p: nil, reader: bytes.NewReader([]byte{0x0, 0x0, 0x0, 0x3, 0x41, 0x42, 0x43})},
want: &messageError{
token: wireprotocol.TOKEN_ERROR_MESSAGE,
err: errors.New("ABC"),
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := newMessageError(tt.args.p, tt.args.reader)
if tt.wantErr {
assert.NotNil(t, err)
} else {
assert.Nil(t, err)
}
assert.EqualValues(t, tt.want, got)
})
}
}
func Test_Token(t *testing.T) {
makeError := func() io.Reader {
// errorMessage "ABC"
return bytes.NewReader([]byte{0x0, 0x0, 0x0, 0x3, 0x41, 0x42, 0x43})
}
makePlanOp := func() io.Reader {
var buf bytes.Buffer
name := fbClusterInfo
binary.Write(&buf, binary.BigEndian, (int32)(len(name)))
buf.WriteString(name)
return bytes.NewReader(buf.Bytes())
}
tests := []struct {
name string
message func() wireProtocolMessage
want int16
}{
{
name: "token error",
message: func() wireProtocolMessage {
m, err := newMessageError(nil, makeError())
assert.Nil(t, err)
return m
},
want: wireprotocol.TOKEN_ERROR_MESSAGE,
},
{
name: "token planOp",
message: func() wireProtocolMessage {
m, err := newMessagePlanOp(nil, makePlanOp())
assert.Nil(t, err)
return m
},
want: wireprotocol.TOKEN_PLAN_OP,
},
{
name: "token schemaInfo",
message: func() wireProtocolMessage {
s := types.Schema{
&types.PlannerColumn{
ColumnName: "col1",
Type: parser.NewDataTypeID(),
},
}
b, err := wireprotocol.WriteSchema(s)
assert.Nil(t, err)
rdr := bytes.NewReader(b)
_, err = wireprotocol.ExpectToken(rdr, wireprotocol.TOKEN_SCHEMA_INFO)
assert.Nil(t, err)
m, err := newMessageSchemaInfo(nil, rdr)
assert.Nil(t, err)
return m
},
want: wireprotocol.TOKEN_SCHEMA_INFO,
},
{
name: "token Row",
message: func() wireProtocolMessage {
schema := types.Schema{
&types.PlannerColumn{
ColumnName: "col1",
Type: parser.NewDataTypeID(),
},
}
row := types.Row{
int64(1),
}
b, err := wireprotocol.WriteRow(row, schema)
assert.Nil(t, err)
m, err := newMessageRow(nil, bytes.NewReader(b), schema)
assert.Nil(t, err)
return m
},
want: wireprotocol.TOKEN_ROW,
},
{
name: "token Done",
message: func() wireProtocolMessage {
m, _ := newMessageDone(nil, nil)
return m
},
want: wireprotocol.TOKEN_DONE,
},
}
for _, tt := range tests {
message := tt.message()
t.Run(tt.name, func(t *testing.T) {
got := message.Token()
assert.Equal(t, tt.want, got)
})
}
}

View file

@ -117,6 +117,10 @@ func WriteSchema(schema types.Schema) ([]byte, error) {
return buf.Bytes(), nil
}
// ReadSchema consumes a schema object from a reader
// Note you cannot do WriteSchema to a buffer then Read that schame
// back without consuming or skipping the token.
// so you can't just to WriteSchema -> ReadSchema it must be WriteSchema->ConsumeToken->ReadSchema
func ReadSchema(reader io.Reader) (types.Schema, error) {
var columnCount int16
err := binary.Read(reader, binary.BigEndian, &columnCount)