Commit 5c379d90 authored by Dr. David Alan Gilbert's avatar Dr. David Alan Gilbert
Browse files

tests/migration: Add test for VMSTATE_WITH_TMP



Add a test for VMSTATE_WITH_TMP to tests/test-vmstate.c

Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: default avatarJuan Quintela <quintela@redhat.com>
Message-Id: <20170203160651.19917-4-dgilbert@redhat.com>
Signed-off-by: default avatarDr. David Alan Gilbert <dgilbert@redhat.com>
parent bcf45131
Loading
Loading
Loading
Loading
+92 −6
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ static void save_buffer(const uint8_t *buf, size_t buf_size)
    qemu_fclose(fsave);
}

static void compare_vmstate(uint8_t *wire, size_t size)
static void compare_vmstate(const uint8_t *wire, size_t size)
{
    QEMUFile *f = open_test_file(false);
    uint8_t result[size];
@@ -113,7 +113,7 @@ static void compare_vmstate(uint8_t *wire, size_t size)
}

static int load_vmstate_one(const VMStateDescription *desc, void *obj,
                            int version, uint8_t *wire, size_t size)
                            int version, const uint8_t *wire, size_t size)
{
    QEMUFile *f;
    int ret;
@@ -137,7 +137,7 @@ static int load_vmstate_one(const VMStateDescription *desc, void *obj,
static int load_vmstate(const VMStateDescription *desc,
                        void *obj, void *obj_clone,
                        void (*obj_copy)(void *, void*),
                        int version, uint8_t *wire, size_t size)
                        int version, const uint8_t *wire, size_t size)
{
    /* We test with zero size */
    obj_copy(obj_clone, obj);
@@ -289,7 +289,6 @@ static void test_simple_primitive(void)
    FIELD_EQUAL(i64_1);
    FIELD_EQUAL(i64_2);
}
#undef FIELD_EQUAL

typedef struct TestStruct {
    uint32_t a, b, c, e;
@@ -474,7 +473,6 @@ static void test_load_skip(void)
    qemu_fclose(loading);
}


typedef struct {
    int32_t i;
} TestStructTriv;
@@ -688,6 +686,94 @@ static void test_load_q(void)
    qemu_fclose(fload);
}

typedef struct TmpTestStruct {
    TestStruct *parent;
    int64_t diff;
} TmpTestStruct;

static void tmp_child_pre_save(void *opaque)
{
    struct TmpTestStruct *tts = opaque;

    tts->diff = tts->parent->b - tts->parent->a;
}

static int tmp_child_post_load(void *opaque, int version_id)
{
    struct TmpTestStruct *tts = opaque;

    tts->parent->b = tts->parent->a + tts->diff;

    return 0;
}

static const VMStateDescription vmstate_tmp_back_to_parent = {
    .name = "test/tmp_child_parent",
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(f, TestStruct),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_tmp_child = {
    .name = "test/tmp_child",
    .pre_save = tmp_child_pre_save,
    .post_load = tmp_child_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_INT64(diff, TmpTestStruct),
        VMSTATE_STRUCT_POINTER(parent, TmpTestStruct,
                               vmstate_tmp_back_to_parent, TestStruct),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_with_tmp = {
    .name = "test/with_tmp",
    .version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(a, TestStruct),
        VMSTATE_UINT64(d, TestStruct),
        VMSTATE_WITH_TMP(TestStruct, TmpTestStruct, vmstate_tmp_child),
        VMSTATE_END_OF_LIST()
    }
};

static void obj_tmp_copy(void *target, void *source)
{
    memcpy(target, source, sizeof(TestStruct));
}

static void test_tmp_struct(void)
{
    TestStruct obj, obj_clone;

    uint8_t const wire_with_tmp[] = {
        /* u32 a */ 0x00, 0x00, 0x00, 0x02,
        /* u64 d */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
        /* diff  */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
        /* u64 f */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
        QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */
    };

    memset(&obj, 0, sizeof(obj));
    obj.a = 2;
    obj.b = 4;
    obj.d = 1;
    obj.f = 8;
    save_vmstate(&vmstate_with_tmp, &obj);

    compare_vmstate(wire_with_tmp, sizeof(wire_with_tmp));

    memset(&obj, 0, sizeof(obj));
    SUCCESS(load_vmstate(&vmstate_with_tmp, &obj, &obj_clone,
                         obj_tmp_copy, 1, wire_with_tmp,
                         sizeof(wire_with_tmp)));
    g_assert_cmpint(obj.a, ==, 2); /* From top level vmsd */
    g_assert_cmpint(obj.b, ==, 4); /* from the post_load */
    g_assert_cmpint(obj.d, ==, 1); /* From top level vmsd */
    g_assert_cmpint(obj.f, ==, 8); /* From the child->parent */
}

int main(int argc, char **argv)
{
    temp_fd = mkstemp(temp_file);
@@ -708,7 +794,7 @@ int main(int argc, char **argv)
                    test_arr_ptr_str_no0_load);
    g_test_add_func("/vmstate/qtailq/save/saveq", test_save_q);
    g_test_add_func("/vmstate/qtailq/load/loadq", test_load_q);

    g_test_add_func("/vmstate/tmp_struct", test_tmp_struct);
    g_test_run();

    close(temp_fd);