mirror of
https://github.com/documize/community.git
synced 2025-07-22 14:49:42 +02:00
284 lines
7.5 KiB
Go
284 lines
7.5 KiB
Go
package mssql
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
type closableBuffer struct {
|
|
*bytes.Buffer
|
|
}
|
|
|
|
func (closableBuffer) Close() error {
|
|
return nil
|
|
}
|
|
|
|
type failBuffer struct {
|
|
}
|
|
|
|
func (failBuffer) Read([]byte) (int, error) {
|
|
return 0, errors.New("read failed")
|
|
}
|
|
|
|
func (failBuffer) Write([]byte) (int, error) {
|
|
return 0, errors.New("write failed")
|
|
}
|
|
|
|
func (failBuffer) Close() error {
|
|
return nil
|
|
}
|
|
|
|
func makeBuf(bufSize uint16, testData []byte) *tdsBuffer {
|
|
buffer := closableBuffer{bytes.NewBuffer(testData)}
|
|
return newTdsBuffer(bufSize, &buffer)
|
|
}
|
|
|
|
func TestStreamShorterThanHeader(t *testing.T) {
|
|
//buffer := closableBuffer{*bytes.NewBuffer([]byte{0xFF, 0xFF})}
|
|
//buffer := closableBuffer{*bytes.NewBuffer([]byte{0x6F, 0x96, 0x19, 0xFF, 0x8B, 0x86, 0xD0, 0x11, 0xB4, 0x2D, 0x00, 0xC0, 0x4F, 0xC9, 0x64, 0xFF})}
|
|
//tdsBuffer := newTdsBuffer(100, &buffer)
|
|
buffer := makeBuf(100, []byte{0xFF, 0xFF})
|
|
_, err := buffer.BeginRead()
|
|
if err == nil {
|
|
t.Fatal("BeginRead was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("BeginRead failed as expected with error:", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestInvalidLengthInHeaderTooLong(t *testing.T) {
|
|
buffer := makeBuf(8, []byte{0xFF, 0xFF, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff})
|
|
_, err := buffer.BeginRead()
|
|
if err == nil {
|
|
t.Fatal("BeginRead was expected to return error but it didn't")
|
|
} else {
|
|
if err.Error() != "Invalid packet size, it is longer than buffer size" {
|
|
t.Fatal("BeginRead failed with incorrect error", err)
|
|
} else {
|
|
t.Log("BeginRead failed as expected with error:", err.Error())
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestInvalidLengthInHeaderTooShort(t *testing.T) {
|
|
buffer := makeBuf(100, []byte{0xFF, 0xFF, 0x0, 0x1, 0xff, 0xff, 0xff, 0xff})
|
|
_, err := buffer.BeginRead()
|
|
if err == nil {
|
|
t.Fatal("BeginRead was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("BeginRead failed as expected with error:", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestInvalidLengthInHeaderLongerThanIncomingBuffer(t *testing.T) {
|
|
buffer := makeBuf(9, []byte{0xFF, 0xFF, 0x0, 0x9, 0xff, 0xff, 0xff, 0xff})
|
|
_, err := buffer.BeginRead()
|
|
if err == nil {
|
|
t.Fatal("BeginRead was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("BeginRead failed as expected with error:", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestBeginReadSucceeds(t *testing.T) {
|
|
buffer := makeBuf(9, []byte{0x01 /*id*/, 0xFF /*status*/, 0x0, 0x9 /*size*/, 0xff, 0xff, 0xff, 0xff, 0x02 /*test byte*/})
|
|
|
|
id, err := buffer.BeginRead()
|
|
if err != nil {
|
|
t.Fatal("BeginRead failed:", err.Error())
|
|
}
|
|
if id != 1 {
|
|
t.Fatalf("Expected id to be 1 but it is %d", id)
|
|
}
|
|
|
|
b, err := buffer.ReadByte()
|
|
if err != nil {
|
|
t.Fatal("ReadByte failed:", err.Error())
|
|
}
|
|
if b != 2 {
|
|
t.Fatalf("Expected read byte to be 2 but it is %d", b)
|
|
}
|
|
|
|
// should fail because no more bytes left
|
|
_, err = buffer.ReadByte()
|
|
if err == nil {
|
|
t.Fatal("ReadByte was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("ReadByte failed as expected with error:", err.Error())
|
|
}
|
|
|
|
testBuf := []byte{0, 1, 2}
|
|
// should fail because no more bytes left
|
|
_, err = buffer.Read(testBuf)
|
|
if err == nil {
|
|
t.Fatal("Read was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("Read failed as expected with error:", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestReadByteFailsOnSecondPacket(t *testing.T) {
|
|
buffer := makeBuf(9, []byte{
|
|
0x01 /*id*/, 0x0 /*not final*/, 0x0, 0x9 /*size*/, 0xff, 0xff, 0xff, 0xff, 0x02, /*test byte*/
|
|
0x01 /*next id, this packet is invalid, it is too short*/})
|
|
|
|
_, err := buffer.BeginRead()
|
|
if err != nil {
|
|
t.Fatal("BeginRead failed:", err.Error())
|
|
}
|
|
|
|
_, err = buffer.ReadByte()
|
|
if err != nil {
|
|
t.Fatal("ReadByte failed:", err.Error())
|
|
}
|
|
|
|
_, err = buffer.ReadByte()
|
|
if err == nil {
|
|
t.Fatal("ReadByte was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("ReadByte failed as expected with error:", err.Error())
|
|
}
|
|
|
|
t.Run("test byte() panic", func(t *testing.T) {
|
|
defer func() {
|
|
recover()
|
|
}()
|
|
buffer.byte()
|
|
t.Fatal("byte() should panic, but it didn't")
|
|
})
|
|
|
|
t.Run("test ReadFull() panic", func(t *testing.T) {
|
|
defer func() {
|
|
recover()
|
|
}()
|
|
buf := make([]byte, 10)
|
|
buffer.ReadFull(buf)
|
|
t.Fatal("ReadFull() should panic, but it didn't")
|
|
})
|
|
}
|
|
|
|
func TestReadFailsOnSecondPacket(t *testing.T) {
|
|
buffer := makeBuf(9, []byte{
|
|
0x01 /*id*/, 0x0 /*not final*/, 0x0, 0x9 /*size*/, 0xff, 0xff, 0xff, 0xff, 0x02, /*test byte*/
|
|
0x01 /*next id, this packet is invalid, it is too short*/})
|
|
|
|
_, err := buffer.BeginRead()
|
|
if err != nil {
|
|
t.Fatal("BeginRead failed:", err.Error())
|
|
}
|
|
|
|
testBuf := []byte{0}
|
|
_, err = buffer.Read(testBuf)
|
|
if err != nil {
|
|
t.Fatal("Read failed:", err.Error())
|
|
}
|
|
if testBuf[0] != 2 {
|
|
t.Fatal("Read returned invalid value")
|
|
}
|
|
|
|
_, err = buffer.Read(testBuf)
|
|
if err == nil {
|
|
t.Fatal("ReadByte was expected to return error but it didn't")
|
|
} else {
|
|
t.Log("ReadByte failed as expected with error:", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestWrite(t *testing.T) {
|
|
memBuf := bytes.NewBuffer([]byte{})
|
|
buf := newTdsBuffer(11, closableBuffer{memBuf})
|
|
buf.BeginPacket(1, false)
|
|
err := buf.WriteByte(2)
|
|
if err != nil {
|
|
t.Fatal("WriteByte failed:", err.Error())
|
|
}
|
|
wrote, err := buf.Write([]byte{3, 4})
|
|
if err != nil {
|
|
t.Fatal("Write failed:", err.Error())
|
|
}
|
|
if wrote != 2 {
|
|
t.Fatalf("Write returned invalid value of written bytes %d", wrote)
|
|
}
|
|
|
|
err = buf.FinishPacket()
|
|
if err != nil {
|
|
t.Fatal("FinishPacket failed:", err.Error())
|
|
}
|
|
if bytes.Compare(memBuf.Bytes(), []byte{1, 1, 0, 11, 0, 0, 1, 0, 2, 3, 4}) != 0 {
|
|
t.Fatalf("Written buffer has invalid content: %v", memBuf.Bytes())
|
|
}
|
|
|
|
buf.BeginPacket(2, false)
|
|
wrote, err = buf.Write([]byte{3, 4, 5, 6})
|
|
if err != nil {
|
|
t.Fatal("Write failed:", err.Error())
|
|
}
|
|
if wrote != 4 {
|
|
t.Fatalf("Write returned invalid value of written bytes %d", wrote)
|
|
}
|
|
err = buf.FinishPacket()
|
|
if err != nil {
|
|
t.Fatal("FinishPacket failed:", err.Error())
|
|
}
|
|
expectedBuf := []byte{
|
|
1, 1, 0, 11, 0, 0, 1, 0, 2, 3, 4, // packet 1
|
|
2, 0, 0, 11, 0, 0, 1, 0, 3, 4, 5, // packet 2
|
|
2, 1, 0, 9, 0, 0, 2, 0, 6, // packet 3
|
|
}
|
|
if bytes.Compare(memBuf.Bytes(), expectedBuf) != 0 {
|
|
t.Fatalf("Written buffer has invalid content:\n got: %v\nwant: %v", memBuf.Bytes(), expectedBuf)
|
|
}
|
|
}
|
|
|
|
func TestWriteErrors(t *testing.T) {
|
|
// write should fail if underlying transport fails
|
|
buf := newTdsBuffer(uint16(headerSize)+1, failBuffer{})
|
|
buf.BeginPacket(1, false)
|
|
wrote, err := buf.Write([]byte{0, 0})
|
|
// may change from error to panic in future
|
|
if err == nil {
|
|
t.Fatal("Write should fail but it didn't")
|
|
}
|
|
if wrote != 1 {
|
|
t.Fatal("Should write 1 byte but it wrote ", wrote)
|
|
}
|
|
|
|
// writebyte should fail if underlying transport fails
|
|
buf = newTdsBuffer(uint16(headerSize)+1, failBuffer{})
|
|
buf.BeginPacket(1, false)
|
|
// first write should not fail because if fits in the buffer
|
|
err = buf.WriteByte(0)
|
|
if err != nil {
|
|
t.Fatal("First WriteByte should not fail because it should fit in the buffer, but it failed", err)
|
|
}
|
|
err = buf.WriteByte(0)
|
|
// may change from error to panic in future
|
|
if err == nil {
|
|
t.Fatal("Second WriteByte should fail but it didn't")
|
|
}
|
|
}
|
|
|
|
func TestWrite_BufferBounds(t *testing.T) {
|
|
memBuf := bytes.NewBuffer([]byte{})
|
|
buf := newTdsBuffer(11, closableBuffer{memBuf})
|
|
|
|
buf.BeginPacket(1, false)
|
|
// write bytes enough to complete a package
|
|
_, err := buf.Write([]byte{1, 1, 1})
|
|
if err != nil {
|
|
t.Fatal("Write failed:", err.Error())
|
|
}
|
|
err = buf.WriteByte(1)
|
|
if err != nil {
|
|
t.Fatal("WriteByte failed:", err.Error())
|
|
}
|
|
_, err = buf.Write([]byte{1, 1, 1})
|
|
if err != nil {
|
|
t.Fatal("Write failed:", err.Error())
|
|
}
|
|
err = buf.FinishPacket()
|
|
if err != nil {
|
|
t.Fatal("FinishPacket failed:", err.Error())
|
|
}
|
|
}
|