305 lines
8.3 KiB
Go
305 lines
8.3 KiB
Go
package binary
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/influxdata/telegraf/internal"
|
|
)
|
|
|
|
func TestSerialization(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
entry *Entry
|
|
input interface{}
|
|
expected map[binary.ByteOrder][]byte
|
|
overflow bool
|
|
}{
|
|
{
|
|
name: "positive int serialization",
|
|
entry: &Entry{Name: "test", DataFormat: "int32"},
|
|
input: 1,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x00, 0x00, 0x00, 0x01},
|
|
binary.LittleEndian: {0x01, 0x00, 0x00, 0x00},
|
|
},
|
|
},
|
|
{
|
|
name: "negative int serialization",
|
|
entry: &Entry{Name: "test", DataFormat: "int32"},
|
|
input: -1,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0xff, 0xff, 0xff, 0xff},
|
|
binary.LittleEndian: {0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
},
|
|
{
|
|
name: "negative int serialization | uint32 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "uint32"},
|
|
input: -1,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0xff, 0xff, 0xff, 0xff},
|
|
binary.LittleEndian: {0xff, 0xff, 0xff, 0xff},
|
|
},
|
|
overflow: true,
|
|
},
|
|
{
|
|
name: "uint to int serialization",
|
|
entry: &Entry{Name: "test", DataFormat: "uint8"},
|
|
input: uint(1),
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x01},
|
|
binary.LittleEndian: {0x01},
|
|
},
|
|
},
|
|
{
|
|
name: "string serialization",
|
|
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 4},
|
|
input: "test",
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x74, 0x65, 0x73, 0x00},
|
|
binary.LittleEndian: {0x74, 0x65, 0x73, 0x00},
|
|
},
|
|
},
|
|
{
|
|
name: "string serialization with terminator",
|
|
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "null"},
|
|
input: "test",
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x74, 0x65, 0x73, 0x74, 0x00},
|
|
binary.LittleEndian: {0x74, 0x65, 0x73, 0x74, 0x00},
|
|
},
|
|
},
|
|
{
|
|
name: "string serialization with hex terminator",
|
|
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "0x01"},
|
|
input: "test",
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x74, 0x65, 0x73, 0x74, 0x01},
|
|
binary.LittleEndian: {0x74, 0x65, 0x73, 0x74, 0x01},
|
|
},
|
|
},
|
|
{
|
|
name: "time serialization",
|
|
entry: &Entry{ReadFrom: "time", DataFormat: "uint64"},
|
|
input: time.Date(2024, time.January, 6, 19, 44, 10, 0, time.UTC),
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x00, 0x00, 0x00, 0x00, 0x65, 0x99, 0xad, 0x8a},
|
|
binary.LittleEndian: {0x8a, 0xad, 0x99, 0x65, 0x00, 0x00, 0x00, 0x00},
|
|
},
|
|
},
|
|
{
|
|
name: "float32 serialization",
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: float32(3.1415),
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x40, 0x49, 0x0e, 0x56},
|
|
binary.LittleEndian: {0x56, 0x0e, 0x49, 0x40},
|
|
},
|
|
},
|
|
{
|
|
name: "float32 serialization | float64 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "float64"},
|
|
input: float32(3.1415),
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x40, 0x09, 0x21, 0xCA, 0xC0, 0x00, 0x00, 0x00},
|
|
binary.LittleEndian: {0x00, 0x00, 0x00, 0xC0, 0xCA, 0x21, 0x09, 0x40},
|
|
},
|
|
},
|
|
{
|
|
name: "float64 serialization",
|
|
entry: &Entry{Name: "test", DataFormat: "float64"},
|
|
input: 3.1415,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x40, 0x09, 0x21, 0xCA, 0xC0, 0x83, 0x12, 0x6F},
|
|
binary.LittleEndian: {0x6F, 0x12, 0x83, 0xC0, 0xCA, 0x21, 0x09, 0x40},
|
|
},
|
|
},
|
|
{
|
|
name: "float64 serialization | float32 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: 3.1415,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x40, 0x49, 0x0e, 0x56},
|
|
binary.LittleEndian: {0x56, 0x0e, 0x49, 0x40},
|
|
},
|
|
},
|
|
{
|
|
name: "float64 serialization | int64 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "int64"},
|
|
input: 3.1415,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03},
|
|
binary.LittleEndian: {0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
},
|
|
},
|
|
{
|
|
name: "float64 serialization | uint8 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "uint8"},
|
|
input: 3.1415,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x03}, binary.LittleEndian: {0x03},
|
|
},
|
|
},
|
|
{
|
|
name: "uint serialization | float32 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: uint(1),
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x3f, 0x80, 0x00, 0x00},
|
|
binary.LittleEndian: {0x00, 0x00, 0x80, 0x3f},
|
|
},
|
|
},
|
|
{
|
|
name: "uint serialization | float64 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "float64"},
|
|
input: uint(1),
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
|
binary.LittleEndian: {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f},
|
|
},
|
|
},
|
|
{
|
|
name: "int serialization | float32 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: -101,
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0xc2, 0xca, 0x00, 0x00},
|
|
binary.LittleEndian: {0x00, 0x00, 0xca, 0xc2},
|
|
},
|
|
},
|
|
{
|
|
name: "string serialization | float32 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: "-101.25",
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0xc2, 0xca, 0x80, 0x00},
|
|
binary.LittleEndian: {0x00, 0x80, 0xca, 0xc2},
|
|
},
|
|
},
|
|
{
|
|
name: "string serialization | int32 representation",
|
|
entry: &Entry{Name: "test", DataFormat: "int32"},
|
|
input: "1",
|
|
expected: map[binary.ByteOrder][]byte{
|
|
binary.BigEndian: {0x00, 0x00, 0x00, 0x01},
|
|
binary.LittleEndian: {0x01, 0x00, 0x00, 0x00},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
require.NoError(t, tc.entry.fillDefaults())
|
|
|
|
for endianness, expected := range tc.expected {
|
|
value, err := tc.entry.serializeValue(tc.input, endianness)
|
|
if tc.overflow {
|
|
require.ErrorIs(t, err, internal.ErrOutOfRange)
|
|
} else {
|
|
require.NoError(t, err)
|
|
}
|
|
require.Equal(t, expected, value)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNoNameSerialization(t *testing.T) {
|
|
e := &Entry{}
|
|
require.ErrorContains(t, e.fillDefaults(), "missing name")
|
|
}
|
|
|
|
func BenchmarkSerialization(b *testing.B) {
|
|
entries := []struct {
|
|
entry *Entry
|
|
input interface{}
|
|
}{
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "int32"},
|
|
input: 1,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "int32"},
|
|
input: -1,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "uint8"},
|
|
input: uint(1),
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 4},
|
|
input: "test",
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "null"},
|
|
input: "test",
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "string", StringLength: 5, StringTerminator: "0x01"},
|
|
input: "test",
|
|
},
|
|
{
|
|
entry: &Entry{ReadFrom: "time", DataFormat: "uint64"},
|
|
input: time.Date(2024, time.January, 6, 19, 44, 10, 0, time.UTC),
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: float32(3.1415),
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float64"},
|
|
input: float32(3.1415),
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float64"},
|
|
input: 3.1415,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: 3.1415,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "int64"},
|
|
input: 3.1415,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "uint8"},
|
|
input: 3.1415,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: uint(1),
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float64"},
|
|
input: uint(1),
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: -101,
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "float32"},
|
|
input: "-101.25",
|
|
},
|
|
{
|
|
entry: &Entry{Name: "test", DataFormat: "int32"},
|
|
input: "1",
|
|
},
|
|
}
|
|
|
|
for _, tc := range entries {
|
|
require.NoError(b, tc.entry.fillDefaults())
|
|
}
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
for _, tc := range entries {
|
|
_, err := tc.entry.serializeValue(tc.input, binary.BigEndian)
|
|
require.NoError(b, err)
|
|
}
|
|
}
|
|
}
|