Testing
This commit is contained in:
+13
-13
@@ -218,19 +218,19 @@ func DecodeTimeValue(dbrType uint16, count uint32, payload []byte) (TimeValue, b
|
||||
|
||||
// CtrlDouble is the decoded form of a DBR_CTRL_DOUBLE payload.
|
||||
type CtrlDouble struct {
|
||||
Status int16
|
||||
Severity AlarmSeverity
|
||||
Precision int16
|
||||
Units string
|
||||
UpperDispLimit float64
|
||||
LowerDispLimit float64
|
||||
UpperAlarmLimit float64
|
||||
UpperWarnLimit float64
|
||||
LowerWarnLimit float64
|
||||
LowerAlarmLimit float64
|
||||
UpperCtrlLimit float64
|
||||
LowerCtrlLimit float64
|
||||
Value float64
|
||||
Status int16
|
||||
Severity AlarmSeverity
|
||||
Precision int16
|
||||
Units string
|
||||
UpperDispLimit float64
|
||||
LowerDispLimit float64
|
||||
UpperAlarmLimit float64
|
||||
UpperWarnLimit float64
|
||||
LowerWarnLimit float64
|
||||
LowerAlarmLimit float64
|
||||
UpperCtrlLimit float64
|
||||
LowerCtrlLimit float64
|
||||
Value float64
|
||||
}
|
||||
|
||||
// DecodeCtrlDouble decodes a DBR_CTRL_DOUBLE payload (minimum 88 bytes).
|
||||
|
||||
@@ -31,8 +31,8 @@ const DefaultPort = 5064
|
||||
|
||||
// Search reply data_type values.
|
||||
const (
|
||||
SearchReply = 10 // DO_REPLY: ask server to respond
|
||||
SearchNoReply = 5 // DONT_REPLY: suppress response (used by repeater)
|
||||
SearchReply = 10 // DO_REPLY: ask server to respond
|
||||
SearchNoReply = 5 // DONT_REPLY: suppress response (used by repeater)
|
||||
)
|
||||
|
||||
// AccessRights bitmask values (parameter2 of CmdAccessRights message).
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
package proto_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/uopi/goca/proto"
|
||||
)
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
// DBR_TIME_* variants not covered by proto_test.go //
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
func TestDecodeTimeFloat(t *testing.T) {
|
||||
hdr := buildTimeHeader(0, 0, 0, 0)
|
||||
val := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(val, math.Float32bits(2.5))
|
||||
tv, ok := proto.DecodeTimeValue(proto.DBRTimeFloat, 1, append(hdr, val...))
|
||||
if !ok || math.Abs(float64(tv.Float)-2.5) > 1e-6 {
|
||||
t.Errorf("float: ok=%v Float=%g", ok, tv.Float)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeTimeShort(t *testing.T) {
|
||||
hdr := buildTimeHeader(0, 0, 0, 0)
|
||||
val := []byte{0x00, 0x00, 0xFF, 0xD6} // 2-byte pad + int16(-42)
|
||||
tv, ok := proto.DecodeTimeValue(proto.DBRTimeShort, 1, append(hdr, val...))
|
||||
if !ok || tv.Short != -42 {
|
||||
t.Errorf("short: ok=%v Short=%d", ok, tv.Short)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeTimeChar(t *testing.T) {
|
||||
hdr := buildTimeHeader(0, 0, 0, 0)
|
||||
val := []byte{0x00, 0x00, 0x00, 0x41} // pad0 + pad1 + value 'A'
|
||||
tv, ok := proto.DecodeTimeValue(proto.DBRTimeChar, 1, append(hdr, val...))
|
||||
if !ok || tv.Char != 0x41 {
|
||||
t.Errorf("char: ok=%v Char=%d", ok, tv.Char)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeTimeUnknownType(t *testing.T) {
|
||||
hdr := buildTimeHeader(0, 0, 0, 0)
|
||||
if _, ok := proto.DecodeTimeValue(9999, 1, append(hdr, make([]byte, 16)...)); ok {
|
||||
t.Error("unknown DBR type should return false")
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
// DBR_CTRL_LONG / DBR_CTRL_STRING //
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
func TestDecodeCtrlLong(t *testing.T) {
|
||||
p := make([]byte, 48)
|
||||
binary.BigEndian.PutUint16(p[2:], 2) // severity = Major
|
||||
copy(p[4:], "counts")
|
||||
i32 := func(off int, v int32) { binary.BigEndian.PutUint32(p[off:], uint32(v)) }
|
||||
i32(12, 1000) // upper_disp
|
||||
i32(16, -10) // lower_disp
|
||||
i32(44, 777) // value
|
||||
|
||||
cl, ok := proto.DecodeCtrlLong(p)
|
||||
if !ok {
|
||||
t.Fatal("DecodeCtrlLong returned false")
|
||||
}
|
||||
if cl.Units != "counts" || cl.Value != 777 || cl.UpperDispLimit != 1000 || cl.LowerDispLimit != -10 {
|
||||
t.Errorf("got %+v", cl)
|
||||
}
|
||||
if cl.Severity != proto.SeverityMajor {
|
||||
t.Errorf("severity = %v, want Major", cl.Severity)
|
||||
}
|
||||
if _, ok := proto.DecodeCtrlLong(make([]byte, 10)); ok {
|
||||
t.Error("short CtrlLong payload should return false")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeCtrlString(t *testing.T) {
|
||||
p := make([]byte, 44)
|
||||
binary.BigEndian.PutUint16(p[2:], 1) // severity = Minor
|
||||
copy(p[4:], "READY")
|
||||
|
||||
cs, ok := proto.DecodeCtrlString(p)
|
||||
if !ok {
|
||||
t.Fatal("DecodeCtrlString returned false")
|
||||
}
|
||||
if cs.Value != "READY" || cs.Severity != proto.SeverityMinor {
|
||||
t.Errorf("got %+v", cs)
|
||||
}
|
||||
if _, ok := proto.DecodeCtrlString(make([]byte, 10)); ok {
|
||||
t.Error("short CtrlString payload should return false")
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
// EncodeShort //
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
func TestEncodeShort(t *testing.T) {
|
||||
b := proto.EncodeShort(-7)
|
||||
if len(b) != 8 {
|
||||
t.Fatalf("len = %d, want 8", len(b))
|
||||
}
|
||||
if got := int16(binary.BigEndian.Uint16(b)); got != -7 {
|
||||
t.Errorf("decoded = %d, want -7", got)
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
// NativeCtrlType //
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
func TestNativeCtrlType(t *testing.T) {
|
||||
cases := []struct {
|
||||
dbf int
|
||||
want uint16
|
||||
}{
|
||||
{proto.DBFDouble, proto.DBRCtrlDouble},
|
||||
{proto.DBFFloat, proto.DBRCtrlDouble},
|
||||
{proto.DBFLong, proto.DBRCtrlLong},
|
||||
{proto.DBFShort, proto.DBRCtrlLong},
|
||||
{proto.DBFChar, proto.DBRCtrlLong},
|
||||
{proto.DBFEnum, proto.DBRCtrlEnum},
|
||||
{proto.DBFString, proto.DBRCtrlString},
|
||||
{9999, proto.DBRCtrlDouble}, // default
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := proto.NativeCtrlType(c.dbf); got != c.want {
|
||||
t.Errorf("NativeCtrlType(%d) = %d, want %d", c.dbf, got, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
// DecodeHeader: extended encoding + error path //
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
||||
func TestDecodeHeaderExtended(t *testing.T) {
|
||||
raw := make([]byte, 24)
|
||||
binary.BigEndian.PutUint16(raw[0:], proto.CmdReadNotify)
|
||||
binary.BigEndian.PutUint16(raw[2:], 0xFFFF) // extended marker
|
||||
binary.BigEndian.PutUint16(raw[6:], 0x0000)
|
||||
binary.BigEndian.PutUint32(raw[16:], 70000) // real payload size
|
||||
binary.BigEndian.PutUint32(raw[20:], 5) // real count
|
||||
|
||||
h, n, err := proto.DecodeHeader(bytes.NewReader(raw))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if n != 24 {
|
||||
t.Errorf("bytes read = %d, want 24", n)
|
||||
}
|
||||
if h.PayloadSize != 70000 || h.DataCount != 5 {
|
||||
t.Errorf("extended header = %+v", h)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeHeaderTruncated(t *testing.T) {
|
||||
if _, _, err := proto.DecodeHeader(bytes.NewReader([]byte{0x00, 0x01})); err == nil {
|
||||
t.Error("truncated header: want error")
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ func TestDecodeTimeDouble(t *testing.T) {
|
||||
const want = 3.14159
|
||||
|
||||
hdr := buildTimeHeader(0, 0, sec, nsec)
|
||||
pad := make([]byte, 4) // RISC pad
|
||||
pad := make([]byte, 4) // RISC pad
|
||||
val := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(val, math.Float64bits(want))
|
||||
payload := append(append(hdr, pad...), val...)
|
||||
|
||||
Reference in New Issue
Block a user