tests/migration: Add test for QTAILQ migration

Add a test for QTAILQ migration to tests/test-vmstate.c.

Signed-off-by: Jianjun Duan <duanj@linux.vnet.ibm.com>
Message-Id: <1484852453-12728-4-git-send-email-duanj@linux.vnet.ibm.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
Jianjun Duan 2017-01-19 11:00:52 -08:00 committed by Dr. David Alan Gilbert
parent 94869d5c52
commit 7e99f22cbe

View File

@ -544,6 +544,150 @@ static void test_arr_ptr_str_no0_load(void)
}
}
/* test QTAILQ migration */
typedef struct TestQtailqElement TestQtailqElement;
struct TestQtailqElement {
bool b;
uint8_t u8;
QTAILQ_ENTRY(TestQtailqElement) next;
};
typedef struct TestQtailq {
int16_t i16;
QTAILQ_HEAD(TestQtailqHead, TestQtailqElement) q;
int32_t i32;
} TestQtailq;
static const VMStateDescription vmstate_q_element = {
.name = "test/queue-element",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_BOOL(b, TestQtailqElement),
VMSTATE_UINT8(u8, TestQtailqElement),
VMSTATE_END_OF_LIST()
},
};
static const VMStateDescription vmstate_q = {
.name = "test/queue",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_INT16(i16, TestQtailq),
VMSTATE_QTAILQ_V(q, TestQtailq, 1, vmstate_q_element, TestQtailqElement,
next),
VMSTATE_INT32(i32, TestQtailq),
VMSTATE_END_OF_LIST()
}
};
uint8_t wire_q[] = {
/* i16 */ 0xfe, 0x0,
/* start of element 0 of q */ 0x01,
/* .b */ 0x01,
/* .u8 */ 0x82,
/* start of element 1 of q */ 0x01,
/* b */ 0x00,
/* u8 */ 0x41,
/* end of q */ 0x00,
/* i32 */ 0x00, 0x01, 0x11, 0x70,
QEMU_VM_EOF, /* just to ensure we won't get EOF reported prematurely */
};
static void test_save_q(void)
{
TestQtailq obj_q = {
.i16 = -512,
.i32 = 70000,
};
TestQtailqElement obj_qe1 = {
.b = true,
.u8 = 130,
};
TestQtailqElement obj_qe2 = {
.b = false,
.u8 = 65,
};
QTAILQ_INIT(&obj_q.q);
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe1, next);
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe2, next);
save_vmstate(&vmstate_q, &obj_q);
compare_vmstate(wire_q, sizeof(wire_q));
}
static void test_load_q(void)
{
TestQtailq obj_q = {
.i16 = -512,
.i32 = 70000,
};
TestQtailqElement obj_qe1 = {
.b = true,
.u8 = 130,
};
TestQtailqElement obj_qe2 = {
.b = false,
.u8 = 65,
};
QTAILQ_INIT(&obj_q.q);
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe1, next);
QTAILQ_INSERT_TAIL(&obj_q.q, &obj_qe2, next);
QEMUFile *fsave = open_test_file(true);
qemu_put_buffer(fsave, wire_q, sizeof(wire_q));
g_assert(!qemu_file_get_error(fsave));
qemu_fclose(fsave);
QEMUFile *fload = open_test_file(false);
TestQtailq tgt;
QTAILQ_INIT(&tgt.q);
vmstate_load_state(fload, &vmstate_q, &tgt, 1);
char eof = qemu_get_byte(fload);
g_assert(!qemu_file_get_error(fload));
g_assert_cmpint(tgt.i16, ==, obj_q.i16);
g_assert_cmpint(tgt.i32, ==, obj_q.i32);
g_assert_cmpint(eof, ==, QEMU_VM_EOF);
TestQtailqElement *qele_from = QTAILQ_FIRST(&obj_q.q);
TestQtailqElement *qlast_from = QTAILQ_LAST(&obj_q.q, TestQtailqHead);
TestQtailqElement *qele_to = QTAILQ_FIRST(&tgt.q);
TestQtailqElement *qlast_to = QTAILQ_LAST(&tgt.q, TestQtailqHead);
while (1) {
g_assert_cmpint(qele_to->b, ==, qele_from->b);
g_assert_cmpint(qele_to->u8, ==, qele_from->u8);
if ((qele_from == qlast_from) || (qele_to == qlast_to)) {
break;
}
qele_from = QTAILQ_NEXT(qele_from, next);
qele_to = QTAILQ_NEXT(qele_to, next);
}
g_assert_cmpint((uintptr_t) qele_from, ==, (uintptr_t) qlast_from);
g_assert_cmpint((uintptr_t) qele_to, ==, (uintptr_t) qlast_to);
/* clean up */
TestQtailqElement *qele;
while (!QTAILQ_EMPTY(&tgt.q)) {
qele = QTAILQ_LAST(&tgt.q, TestQtailqHead);
QTAILQ_REMOVE(&tgt.q, qele, next);
free(qele);
qele = NULL;
}
qemu_fclose(fload);
}
int main(int argc, char **argv)
{
temp_fd = mkstemp(temp_file);
@ -562,6 +706,9 @@ int main(int argc, char **argv)
test_arr_ptr_str_no0_save);
g_test_add_func("/vmstate/array/ptr/str/no0/load",
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_run();
close(temp_fd);