Signed-off-by: Juan Quintela <quint...@redhat.com> --- tests/test-vmstate.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+)
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c index 7e69b14..93537f7 100644 --- a/tests/test-vmstate.c +++ b/tests/test-vmstate.c @@ -1393,6 +1393,152 @@ static void test_varray_test(void) #undef ELEM_EQUAL #undef ELEM_NOTEQUAL +typedef struct SubStruct { + int32_t i32; + int64_t i64; + uint8_t buffer[13]; +} SubStruct; + +static const VMStateDescription vmstate_sub_struct = { + .name = "struct/substruct", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_INT32(i32, SubStruct), + VMSTATE_INT64(i64, SubStruct), + VMSTATE_BUFFER(buffer, SubStruct), + VMSTATE_END_OF_LIST() + } +}; + +typedef struct TestStruct { + SubStruct sub; + SubStruct sub2; +} TestStruct; + +static const VMStateDescription vmstate_struct_simple = { + .name = "struct/simple", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(sub, TestStruct, vmstate_sub_struct, SubStruct), + VMSTATE_END_OF_LIST() + } +}; + +TestStruct obj_struct = { + .sub = { + .i32 = 33, + .i64 = 77, + .buffer = "hello world!", + }, + .sub2 = { + .i32 = 66, + .i64 = 99, + .buffer = "bye world!", + }, +}; + +/* This is the binary representation on the wire of that struct */ +uint8_t wire_struct_simple[] = { + /* i32 */ 0x00, 0x00, 0x00, 0x21, + /* i64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + /* buffer */ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x21, 0x00, + QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */ +}; + +static void obj_struct_copy(void *arg1, void *arg2) +{ + TestStruct *target = arg1; + TestStruct *source = arg2; + + target->sub.i32 = source->sub.i32; + target->sub.i64 = source->sub.i64; + memcpy(target->sub.buffer, source->sub.buffer, 13); + + target->sub2.i32 = source->sub2.i32; + target->sub2.i64 = source->sub2.i64; + memcpy(target->sub2.buffer, source->sub2.buffer, 13); +} + +static void test_struct_simple(void) +{ + TestStruct obj, obj_clone; + + + memset(&obj, 0, sizeof(obj)); + + save_vmstate(&vmstate_struct_simple, &obj_struct); + + compare_vmstate(wire_struct_simple, sizeof(wire_struct_simple)); + + SUCCESS(load_vmstate(&vmstate_struct_simple, &obj, &obj_clone, + obj_struct_copy, 1, wire_struct_simple, + sizeof(wire_struct_simple))); + +#define STRUCT_EQUAL(s1, s2) \ + do { \ + g_assert_cmpint(s1->i32, ==, s2->i32); \ + g_assert_cmpint(s1->i64, ==, s2->i64); \ + SUCCESS(memcmp(s1->buffer, s2->buffer, \ + sizeof(s1->buffer))); \ + } while (0) + +#define STRUCT_NOT_EQUAL(s1, s2) \ + do { \ + g_assert_cmpint(s1->i32, !=, s2->i32); \ + g_assert_cmpint(s1->i64, !=, s2->i64); \ + FAILURE(memcmp(s1->buffer, s2->buffer, \ + sizeof(s1->buffer))); \ + } while (0) + + STRUCT_EQUAL((&obj.sub), (&obj_struct.sub)); + STRUCT_NOT_EQUAL((&obj.sub2), (&obj_struct.sub2)); +} + +static const VMStateDescription vmstate_struct_test = { + .name = "struct/test", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(sub, TestStruct, vmstate_sub_struct, SubStruct), + VMSTATE_END_OF_LIST() + } +}; + +/* This is the binary representation on the wire of that struct */ +uint8_t wire_struct_test[] = { + /* i32 */ 0x00, 0x00, 0x00, 0x21, + /* i64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + /* buffer */ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x21, 0x00, + QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */ +}; + +static void test_struct_test(void) +{ + TestStruct obj, obj_clone; + + memset(&obj, 0, sizeof(obj)); + + save_vmstate(&vmstate_struct_test, &obj_struct); + + compare_vmstate(wire_struct_test, sizeof(wire_struct_test)); + + SUCCESS(load_vmstate(&vmstate_struct_test, &obj, &obj_clone, + obj_struct_copy, 1, wire_struct_test, + sizeof(wire_struct_test))); + + STRUCT_EQUAL((&obj.sub), (&obj_struct.sub)); + STRUCT_NOT_EQUAL((&obj.sub2), (&obj_struct.sub2)); +} +#undef STRUCT_EQUAL +#undef STRUCT_NOT_EQUAL + typedef struct TestVersioned { uint32_t a, b, c, e; uint64_t d, f; @@ -1635,6 +1781,8 @@ int main(int argc, char **argv) g_test_add_func("/vmstate/pointer/simple", test_pointer_simple); g_test_add_func("/vmstate/varray/simple", test_varray_simple); g_test_add_func("/vmstate/varray/test", test_varray_test); + g_test_add_func("/vmstate/struct/simple", test_struct_simple); + g_test_add_func("/vmstate/struct/test", test_struct_test); g_test_run(); close(temp_fd); -- 1.9.0