Signed-off-by: Juan Quintela <quint...@redhat.com> --- tests/test-vmstate.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+)
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c index fa69209..ca1f6e2 100644 --- a/tests/test-vmstate.c +++ b/tests/test-vmstate.c @@ -1916,6 +1916,110 @@ static void test_struct_varray(void) } } } + +typedef struct TestStruct3 { + SubStruct *p_1[3]; +} TestStruct3; + +/* + * size: needs to be the 1st field + * a: needs to be the last field + * We use that fact to load with different sizes + */ + +static const VMStateDescription vmstate_struct_pointer = { + .name = "struct/pointer", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(p_1, TestStruct3, 3, + vmstate_sub_struct, SubStruct), + VMSTATE_END_OF_LIST() + } +}; + +/* This is the binary representation on the wire of that struct */ +/* We need to change the first byte for load to work */ +uint8_t wire_struct_pointer[] = { + /* p_1[0] */ + /* i32 */ 0x00, 0x00, 0x00, 0x15, + /* i64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, + /* buffer */ 0x62, 0x79, 0x65, 0x30, 0x20, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x21, 0x00, + /* p_1[1] */ + /* i32 */ 0x00, 0x00, 0x00, 0x16, + /* i64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + /* buffer */ 0x62, 0x79, 0x65, 0x31, 0x20, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x21, 0x00, + /* p_1[2] */ + /* i32 */ 0x00, 0x00, 0x00, 0x17, + /* i64 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, + /* buffer */ 0x62, 0x79, 0x65, 0x32, 0x20, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x21, 0x00, + QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */ +}; + +static void obj_struct3_copy(void *arg1, void *arg2) +{ + TestStruct3 *target = arg1; + TestStruct3 *source = arg2; + int i; + + for (i = 0; i < 3; i++) { + target->p_1[i]->i32 = source->p_1[i]->i32; + target->p_1[i]->i64 = source->p_1[i]->i64; + memcpy(target->p_1[i]->buffer, source->p_1[i]->buffer, 13); + } +} + +static TestStruct3 *create_struct3(void) +{ + TestStruct3 *obj = g_malloc0(sizeof(*obj)); + int i; + + for (i = 0; i < 3; i++) { + obj->p_1[i] = g_malloc0(sizeof(SubStruct)); + } + + return obj; +} + +static TestStruct3 *create_struct3_init(void) +{ + TestStruct3 *obj = create_struct3(); + int i; + + for (i = 0; i < 3; i++) { + obj->p_1[i]->i32 = i + 21; + obj->p_1[i]->i64 = i + 31; + snprintf((char *)obj->p_1[i]->buffer, 13, "bye%d world!", i); + } + + return obj; +} + +static void test_struct_pointer(void) +{ + TestStruct3 *obj, *obj_clone, *obj_struct3; + int i; + + obj_struct3 = create_struct3_init(); + obj = create_struct3(); + obj_clone = create_struct3(); + + save_vmstate(&vmstate_struct_pointer, obj_struct3); + + compare_vmstate(wire_struct_pointer, sizeof(wire_struct_pointer)); + + SUCCESS(load_vmstate(&vmstate_struct_pointer, obj, obj_clone, + obj_struct3_copy, 1, wire_struct_pointer, + sizeof(wire_struct_pointer))); + + for (i = 0; i < 3; i++) { + STRUCT_EQUAL(obj->p_1[i], obj_struct3->p_1[i]); + } +} #undef STRUCT_EQUAL #undef STRUCT_NOT_EQUAL @@ -2164,6 +2268,7 @@ int main(int argc, char **argv) g_test_add_func("/vmstate/struct/simple", test_struct_simple); g_test_add_func("/vmstate/struct/test", test_struct_test); g_test_add_func("/vmstate/struct/varray", test_struct_varray); + g_test_add_func("/vmstate/struct/pointer", test_struct_pointer); g_test_run(); close(temp_fd); -- 1.9.0