Testing
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
package pva
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// ---- Header codec -----------------------------------------------------
|
||||
|
||||
func TestHeaderRoundTrip(t *testing.T) {
|
||||
h := PVAHeader{Version: 1, Flags: flagApp, Command: CmdGet, Size: 1234}
|
||||
var buf bytes.Buffer
|
||||
if err := WriteHeader(&buf, h); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := ReadHeader(&buf)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Version != h.Version || got.Command != h.Command || got.Size != h.Size {
|
||||
t.Errorf("round-trip header: got %+v want %+v", got, h)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadHeaderBadMagic(t *testing.T) {
|
||||
raw := []byte{0xAB, 0x01, 0x00, CmdGet, 0, 0, 0, 0}
|
||||
if _, err := ReadHeader(bytes.NewReader(raw)); err == nil {
|
||||
t.Error("bad magic: want error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadHeaderTruncated(t *testing.T) {
|
||||
if _, err := ReadHeader(bytes.NewReader([]byte{0xCA, 0x01})); err == nil {
|
||||
t.Error("truncated header: want error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaderBigEndian(t *testing.T) {
|
||||
// Hand-assemble a big-endian server header with size 0x00010203.
|
||||
raw := []byte{magic, 0x01, flagBigEndian | flagFromServer, CmdMonitor, 0x00, 0x01, 0x02, 0x03}
|
||||
h, err := ReadHeader(bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if h.isLittleEndian() {
|
||||
t.Error("expected big-endian header")
|
||||
}
|
||||
if !h.isFromServer() {
|
||||
t.Error("expected from-server bit")
|
||||
}
|
||||
if h.byteOrder() != binary.BigEndian {
|
||||
t.Error("byteOrder should be big-endian")
|
||||
}
|
||||
if h.Size != 0x00010203 {
|
||||
t.Errorf("size = %#x, want 0x00010203", h.Size)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaderPredicates(t *testing.T) {
|
||||
le := PVAHeader{Flags: flagApp}
|
||||
if !le.isLittleEndian() || le.isFromServer() || le.isControl() {
|
||||
t.Errorf("app/LE header predicates wrong: %+v", le)
|
||||
}
|
||||
ctrl := PVAHeader{Flags: flagControl}
|
||||
if !ctrl.isControl() {
|
||||
t.Error("control header should report isControl")
|
||||
}
|
||||
}
|
||||
|
||||
// ---- BuildMessage -----------------------------------------------------
|
||||
|
||||
func TestBuildMessage(t *testing.T) {
|
||||
payload := []byte{1, 2, 3, 4, 5}
|
||||
// Pass the server flag too; BuildMessage must clear it (client direction).
|
||||
msg := BuildMessage(CmdCreateChannel, flagFromServer, payload)
|
||||
h, err := ReadHeader(bytes.NewReader(msg))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if h.Command != CmdCreateChannel {
|
||||
t.Errorf("command = %#x, want %#x", h.Command, CmdCreateChannel)
|
||||
}
|
||||
if h.isFromServer() {
|
||||
t.Error("BuildMessage must clear the from-server flag")
|
||||
}
|
||||
if int(h.Size) != len(payload) {
|
||||
t.Errorf("size = %d, want %d", h.Size, len(payload))
|
||||
}
|
||||
if got := msg[headerSize:]; !bytes.Equal(got, payload) {
|
||||
t.Errorf("payload = %v, want %v", got, payload)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Status decoding --------------------------------------------------
|
||||
|
||||
func TestReadStatusOKShort(t *testing.T) {
|
||||
s, err := ReadStatus(bytes.NewReader([]byte{StatusOK}), binary.LittleEndian)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !s.OK() || s.Error() != "" {
|
||||
t.Errorf("short OK status: got %+v", s)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadStatusError(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteByte(StatusError)
|
||||
buf.WriteByte(0x04) // compact size 4
|
||||
buf.WriteString("boom")
|
||||
buf.WriteByte(0x00) // empty stack
|
||||
s, err := ReadStatus(&buf, binary.LittleEndian)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if s.OK() {
|
||||
t.Error("error status should not be OK")
|
||||
}
|
||||
if s.Message != "boom" {
|
||||
t.Errorf("message = %q, want boom", s.Message)
|
||||
}
|
||||
if s.Error() == "" {
|
||||
t.Error("Error() should be non-empty for an error status")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadStatusTruncated(t *testing.T) {
|
||||
if _, err := ReadStatus(bytes.NewReader(nil), binary.LittleEndian); err == nil {
|
||||
t.Error("empty status: want error")
|
||||
}
|
||||
// type byte present but the message string is missing.
|
||||
if _, err := ReadStatus(bytes.NewReader([]byte{StatusError}), binary.LittleEndian); err == nil {
|
||||
t.Error("status missing message: want error")
|
||||
}
|
||||
}
|
||||
|
||||
// ---- readPVAString ----------------------------------------------------
|
||||
|
||||
func TestReadPVAString(t *testing.T) {
|
||||
// Short form.
|
||||
short := append([]byte{0x03}, []byte("abc")...)
|
||||
s, err := readPVAString(bytes.NewReader(short), binary.LittleEndian)
|
||||
if err != nil || s != "abc" {
|
||||
t.Errorf("short string: got %q err %v", s, err)
|
||||
}
|
||||
// Empty.
|
||||
s, err = readPVAString(bytes.NewReader([]byte{0x00}), binary.LittleEndian)
|
||||
if err != nil || s != "" {
|
||||
t.Errorf("empty string: got %q err %v", s, err)
|
||||
}
|
||||
// Extended form: 0xFF + int32 length + bytes.
|
||||
var ext bytes.Buffer
|
||||
ext.WriteByte(0xFF)
|
||||
_ = binary.Write(&ext, binary.LittleEndian, int32(5))
|
||||
ext.WriteString("hello")
|
||||
s, err = readPVAString(&ext, binary.LittleEndian)
|
||||
if err != nil || s != "hello" {
|
||||
t.Errorf("extended string: got %q err %v", s, err)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- env --------------------------------------------------------------
|
||||
|
||||
func TestAddrsFromEnv(t *testing.T) {
|
||||
t.Setenv("EPICS_PVA_ADDR_LIST", "")
|
||||
if got := addrsFromEnv(); got != nil {
|
||||
t.Errorf("empty env: got %v, want nil", got)
|
||||
}
|
||||
t.Setenv("EPICS_PVA_ADDR_LIST", " 1.2.3.4 5.6.7.8 ")
|
||||
got := addrsFromEnv()
|
||||
if len(got) != 2 || got[0] != "1.2.3.4" || got[1] != "5.6.7.8" {
|
||||
t.Errorf("addr list: got %v", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user