2023-09-03 17:50:12 -06:00
|
|
|
package graphvent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"reflect"
|
|
|
|
"fmt"
|
2023-10-16 10:03:51 -06:00
|
|
|
"time"
|
2023-09-03 17:50:12 -06:00
|
|
|
)
|
|
|
|
|
2023-10-15 15:14:33 -06:00
|
|
|
func TestSerializeTest(t *testing.T) {
|
2023-10-29 18:26:14 -06:00
|
|
|
ctx := logTestContext(t, []string{"test", "serialize", "deserialize_types"})
|
2023-10-15 15:14:33 -06:00
|
|
|
testSerialize(t, ctx, map[string][]NodeID{"test_group": {RandID(), RandID(), RandID()}})
|
2023-10-29 18:26:14 -06:00
|
|
|
testSerialize(t, ctx, map[NodeID]ReqInfo{
|
|
|
|
RandID(): {},
|
|
|
|
RandID(): {},
|
|
|
|
RandID(): {},
|
|
|
|
})
|
2023-10-15 15:14:33 -06:00
|
|
|
}
|
|
|
|
|
2023-09-03 17:50:12 -06:00
|
|
|
func TestSerializeBasic(t *testing.T) {
|
2023-10-29 18:26:14 -06:00
|
|
|
ctx := logTestContext(t, []string{"test", "serialize"})
|
2023-09-03 17:50:12 -06:00
|
|
|
testSerializeComparable[bool](t, ctx, true)
|
2023-10-29 18:26:14 -06:00
|
|
|
|
|
|
|
type bool_wrapped bool
|
|
|
|
err := ctx.RegisterType(reflect.TypeOf(bool_wrapped(true)), NewSerializedType("BOOL_WRAPPED"), nil, nil, nil, DeserializeBool[bool_wrapped])
|
|
|
|
fatalErr(t, err)
|
|
|
|
testSerializeComparable[bool_wrapped](t, ctx, true)
|
|
|
|
|
|
|
|
testSerializeSlice[[]bool](t, ctx, []bool{false, false, true, false})
|
|
|
|
testSerializeComparable[string](t, ctx, "test")
|
2023-09-03 17:50:12 -06:00
|
|
|
testSerializeComparable[float32](t, ctx, 0.05)
|
|
|
|
testSerializeComparable[float64](t, ctx, 0.05)
|
|
|
|
testSerializeComparable[uint](t, ctx, uint(1234))
|
|
|
|
testSerializeComparable[uint8] (t, ctx, uint8(123))
|
|
|
|
testSerializeComparable[uint16](t, ctx, uint16(1234))
|
|
|
|
testSerializeComparable[uint32](t, ctx, uint32(12345))
|
|
|
|
testSerializeComparable[uint64](t, ctx, uint64(123456))
|
|
|
|
testSerializeComparable[int](t, ctx, 1234)
|
|
|
|
testSerializeComparable[int8] (t, ctx, int8(-123))
|
|
|
|
testSerializeComparable[int16](t, ctx, int16(-1234))
|
|
|
|
testSerializeComparable[int32](t, ctx, int32(-12345))
|
|
|
|
testSerializeComparable[int64](t, ctx, int64(-123456))
|
2023-10-16 10:03:51 -06:00
|
|
|
testSerializeComparable[time.Duration](t, ctx, time.Duration(100))
|
2023-10-16 23:08:23 -06:00
|
|
|
testSerializeComparable[time.Time](t, ctx, time.Now().Truncate(0))
|
2023-09-03 17:50:12 -06:00
|
|
|
testSerializeSlice[[]int](t, ctx, []int{123, 456, 789, 101112})
|
|
|
|
testSerializeSlice[[]int](t, ctx, ([]int)(nil))
|
|
|
|
testSerializeSliceSlice[[][]int](t, ctx, [][]int{{123, 456, 789, 101112}, {3253, 2341, 735, 212}, {123, 51}, nil})
|
|
|
|
testSerializeSliceSlice[[][]string](t, ctx, [][]string{{"123", "456", "789", "101112"}, {"3253", "2341", "735", "212"}, {"123", "51"}, nil})
|
|
|
|
|
2023-09-05 01:02:41 -06:00
|
|
|
testSerialize(t, ctx, map[int8]map[*int8]string{})
|
2023-10-29 18:26:14 -06:00
|
|
|
testSerialize(t, ctx, map[int8]time.Time{
|
|
|
|
1: time.Now(),
|
|
|
|
3: time.Now().Add(time.Second),
|
|
|
|
0: time.Now().Add(time.Second*2),
|
|
|
|
4: time.Now().Add(time.Second*3),
|
|
|
|
})
|
2023-09-05 00:46:49 -06:00
|
|
|
|
2023-10-29 18:26:14 -06:00
|
|
|
testSerialize(t, ctx, Tree{
|
|
|
|
NodeTypeSerialized: nil,
|
|
|
|
SerializedTypeSerialized: Tree{
|
|
|
|
NodeTypeSerialized: Tree{},
|
|
|
|
},
|
|
|
|
})
|
2023-10-15 15:14:33 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
var i interface{} = nil
|
|
|
|
testSerialize(t, ctx, i)
|
|
|
|
|
|
|
|
testSerializeMap(t, ctx, map[int8]interface{}{
|
|
|
|
0: "abcd",
|
|
|
|
1: uint32(12345678),
|
|
|
|
2: i,
|
|
|
|
3: 123,
|
|
|
|
})
|
|
|
|
|
2023-09-05 00:46:49 -06:00
|
|
|
testSerializeMap(t, ctx, map[int8]int32{
|
|
|
|
0: 1234,
|
|
|
|
2: 5678,
|
|
|
|
4: 9101,
|
|
|
|
6: 1121,
|
|
|
|
})
|
|
|
|
|
2023-09-12 20:30:18 -06:00
|
|
|
type test_struct struct {
|
|
|
|
Int int `gv:"int"`
|
|
|
|
String string `gv:"string"`
|
|
|
|
}
|
|
|
|
|
|
|
|
test_struct_type := reflect.TypeOf(test_struct{})
|
2023-10-29 18:26:14 -06:00
|
|
|
test_struct_info, err := GetStructInfo(ctx, test_struct_type)
|
|
|
|
fatalErr(t, err)
|
|
|
|
|
|
|
|
err = ctx.RegisterType(test_struct_type, NewSerializedType("TEST_STRUCT"), nil, SerializeStruct(test_struct_info), nil, DeserializeStruct(test_struct_info))
|
2023-09-12 20:30:18 -06:00
|
|
|
fatalErr(t, err)
|
|
|
|
|
|
|
|
testSerialize(t, ctx, test_struct{
|
2023-09-03 17:50:12 -06:00
|
|
|
12345,
|
|
|
|
"test_string",
|
|
|
|
})
|
2023-09-20 19:14:28 -06:00
|
|
|
|
2023-10-15 18:34:34 -06:00
|
|
|
testSerialize(t, ctx, Tree{
|
|
|
|
MapType: nil,
|
|
|
|
StringType: nil,
|
|
|
|
})
|
|
|
|
|
2023-09-20 19:14:28 -06:00
|
|
|
testSerialize(t, ctx, Tree{
|
|
|
|
TreeType: nil,
|
|
|
|
})
|
|
|
|
|
|
|
|
testSerialize(t, ctx, Tree{
|
|
|
|
TreeType: {
|
|
|
|
ErrorType: Tree{},
|
|
|
|
MapType: nil,
|
|
|
|
},
|
|
|
|
StringType: nil,
|
|
|
|
})
|
2023-10-10 11:23:44 -06:00
|
|
|
|
|
|
|
type test_slice []string
|
|
|
|
test_slice_type := reflect.TypeOf(test_slice{})
|
2023-10-29 18:26:14 -06:00
|
|
|
err = ctx.RegisterType(test_slice_type, NewSerializedType("TEST_SLICE"), SerializeTypeStub, SerializeSlice, DeserializeTypeStub[test_slice], DeserializeSlice)
|
2023-10-10 11:23:44 -06:00
|
|
|
fatalErr(t, err)
|
|
|
|
|
2023-10-29 18:26:14 -06:00
|
|
|
testSerialize[[]string](t, ctx, []string{"test_1", "test_2", "test_3"})
|
2023-10-10 11:23:44 -06:00
|
|
|
testSerialize[test_slice](t, ctx, test_slice{"test_1", "test_2", "test_3"})
|
|
|
|
|
|
|
|
testSerialize[Changes](t, ctx, Changes{"change_1", "change_2", "change_3"})
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
type test struct {
|
|
|
|
Int int `gv:"int"`
|
|
|
|
Str string `gv:"string"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s test) String() string {
|
|
|
|
return fmt.Sprintf("%d:%s", s.Int, s.Str)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSerializeStructTags(t *testing.T) {
|
2023-09-12 20:30:18 -06:00
|
|
|
ctx := logTestContext(t, []string{"test"})
|
2023-09-11 21:47:53 -06:00
|
|
|
|
|
|
|
test_type := NewSerializedType("TEST_STRUCT")
|
2023-09-12 20:30:18 -06:00
|
|
|
test_struct_type := reflect.TypeOf(test{})
|
2023-09-11 21:47:53 -06:00
|
|
|
ctx.Log.Logf("test", "TEST_TYPE: %+v", test_type)
|
2023-10-29 18:26:14 -06:00
|
|
|
test_struct_info, err := GetStructInfo(ctx, test_struct_type)
|
|
|
|
fatalErr(t, err)
|
|
|
|
ctx.RegisterType(test_struct_type, test_type, nil, SerializeStruct(test_struct_info), nil, DeserializeStruct(test_struct_info))
|
2023-09-11 21:47:53 -06:00
|
|
|
|
|
|
|
test_int := 10
|
|
|
|
test_string := "test"
|
|
|
|
|
|
|
|
ret := testSerialize(t, ctx, test{
|
|
|
|
test_int,
|
|
|
|
test_string,
|
|
|
|
})
|
|
|
|
if ret.Int != test_int {
|
|
|
|
t.Fatalf("Deserialized int %d does not equal test %d", ret.Int, test_int)
|
|
|
|
} else if ret.Str != test_string {
|
|
|
|
t.Fatalf("Deserialized string %s does not equal test %s", ret.Str, test_string)
|
|
|
|
}
|
|
|
|
|
|
|
|
testSerialize(t, ctx, []test{
|
|
|
|
{
|
|
|
|
test_int,
|
|
|
|
test_string,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test_int * 2,
|
|
|
|
fmt.Sprintf("%s%s", test_string, test_string),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test_int * 4,
|
|
|
|
fmt.Sprintf("%s%s%s", test_string, test_string, test_string),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-09-03 17:50:12 -06:00
|
|
|
func testSerializeMap[M map[T]R, T, R comparable](t *testing.T, ctx *Context, val M) {
|
|
|
|
v := testSerialize(t, ctx, val)
|
|
|
|
for key, value := range(val) {
|
|
|
|
recreated, exists := v[key]
|
|
|
|
if exists == false {
|
2023-09-11 21:47:53 -06:00
|
|
|
t.Fatalf("DeserializeValue returned wrong value %+v != %+v", v, val)
|
2023-09-03 17:50:12 -06:00
|
|
|
} else if recreated != value {
|
2023-09-11 21:47:53 -06:00
|
|
|
t.Fatalf("DeserializeValue returned wrong value %+v != %+v", v, val)
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(v) != len(val) {
|
2023-09-11 21:47:53 -06:00
|
|
|
t.Fatalf("DeserializeValue returned wrong value %+v != %+v", v, val)
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testSerializeSliceSlice[S [][]T, T comparable](t *testing.T, ctx *Context, val S) {
|
|
|
|
v := testSerialize(t, ctx, val)
|
|
|
|
for i, original := range(val) {
|
|
|
|
if (original == nil && v[i] != nil) || (original != nil && v[i] == nil) {
|
2023-09-11 21:47:53 -06:00
|
|
|
t.Fatalf("DeserializeValue returned wrong value %+v != %+v", v, val)
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
|
|
|
for j, o := range(original) {
|
|
|
|
if v[i][j] != o {
|
2023-09-11 21:47:53 -06:00
|
|
|
t.Fatalf("DeserializeValue returned wrong value %+v != %+v", v, val)
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testSerializeSlice[S []T, T comparable](t *testing.T, ctx *Context, val S) {
|
|
|
|
v := testSerialize(t, ctx, val)
|
|
|
|
for i, original := range(val) {
|
|
|
|
if v[i] != original {
|
|
|
|
t.Fatal(fmt.Sprintf("DeserializeValue returned wrong value %+v != %+v", v, val))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testSerializeComparable[T comparable](t *testing.T, ctx *Context, val T) {
|
|
|
|
v := testSerialize(t, ctx, val)
|
|
|
|
if v != val {
|
|
|
|
t.Fatal(fmt.Sprintf("DeserializeValue returned wrong value %+v != %+v", v, val))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testSerialize[T any](t *testing.T, ctx *Context, val T) T {
|
2023-09-11 21:47:53 -06:00
|
|
|
value := reflect.ValueOf(&val).Elem()
|
2023-10-29 18:26:14 -06:00
|
|
|
type_stack, err := SerializeType(ctx, value.Type())
|
|
|
|
data, err := SerializeValue(ctx, value)
|
|
|
|
value_serialized := SerializedValue{type_stack, data}
|
2023-09-03 17:50:12 -06:00
|
|
|
fatalErr(t, err)
|
2023-09-11 21:47:53 -06:00
|
|
|
ctx.Log.Logf("test", "Serialized %+v to %+v", val, value_serialized)
|
2023-09-03 17:50:12 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
ser, err := value_serialized.MarshalBinary()
|
2023-09-03 17:50:12 -06:00
|
|
|
fatalErr(t, err)
|
|
|
|
ctx.Log.Logf("test", "Binary: %+v", ser)
|
|
|
|
|
|
|
|
val_parsed, remaining_parse, err := ParseSerializedValue(ser)
|
|
|
|
fatalErr(t, err)
|
|
|
|
ctx.Log.Logf("test", "Parsed: %+v", val_parsed)
|
|
|
|
|
|
|
|
if len(remaining_parse) != 0 {
|
|
|
|
t.Fatal("Data remaining after deserializing value")
|
|
|
|
}
|
|
|
|
|
2023-10-29 18:26:14 -06:00
|
|
|
val_type, remaining_types, err := DeserializeType(ctx, val_parsed.TypeStack)
|
|
|
|
deserialized_value, remaining_deserialize, err := DeserializeValue(ctx, val_type, val_parsed.Data)
|
2023-09-03 17:50:12 -06:00
|
|
|
fatalErr(t, err)
|
|
|
|
|
2023-10-29 18:26:14 -06:00
|
|
|
if len(remaining_deserialize) != 0 {
|
2023-09-03 17:50:12 -06:00
|
|
|
t.Fatal("Data remaining after deserializing value")
|
2023-10-29 18:26:14 -06:00
|
|
|
} else if len(remaining_types) != 0 {
|
2023-09-03 17:50:12 -06:00
|
|
|
t.Fatal("TypeStack remaining after deserializing value")
|
2023-09-11 21:47:53 -06:00
|
|
|
} else if val_type != value.Type() {
|
2023-09-03 17:50:12 -06:00
|
|
|
t.Fatal(fmt.Sprintf("DeserializeValue returned wrong reflect.Type %+v - %+v", val_type, reflect.TypeOf(val)))
|
2023-09-11 21:47:53 -06:00
|
|
|
} else if deserialized_value.CanConvert(val_type) == false {
|
2023-09-03 17:50:12 -06:00
|
|
|
t.Fatal("DeserializeValue returned value that can't convert to original value")
|
|
|
|
}
|
2023-09-11 21:47:53 -06:00
|
|
|
ctx.Log.Logf("test", "Value: %+v", deserialized_value.Interface())
|
|
|
|
if val_type.Kind() == reflect.Interface && deserialized_value.Interface() == nil {
|
|
|
|
var zero T
|
|
|
|
return zero
|
|
|
|
}
|
|
|
|
return deserialized_value.Interface().(T)
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|