On 12/08/2016 01:03 AM, Dr. David Alan Gilbert wrote: > * Jianjun Duan (du...@linux.vnet.ibm.com) wrote: >> >> >> On 12/07/2016 11:49 AM, Dr. David Alan Gilbert wrote: >>> * Jianjun Duan (du...@linux.vnet.ibm.com) wrote: >>>> Add a test for QTAILQ migration to tests/test-vmstate.c. >>> >>> Yes, but see comment below if you have to respin: >>> >>>> Signed-off-by: Jianjun Duan <du...@linux.vnet.ibm.com> >>>> --- >>>> tests/test-vmstate.c | 160 >>>> +++++++++++++++++++++++++++++++++++++++++++++++++++ >>>> 1 file changed, 160 insertions(+) >>>> >>>> diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c >>>> index d2f529b..88aab8c 100644 >>>> --- a/tests/test-vmstate.c >>>> +++ b/tests/test-vmstate.c >>>> @@ -544,6 +544,163 @@ 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() >>>> + } >>>> +}; >>>> + >>>> +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, >>>> + }; >>>> + >>>> + 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 */ >>>> + }; >>> >>> If possible it would be great to share these structures with the ones in >>> test_load_q. >>> >> The issue is that obj_q need be initialized and elements need be >> inserted in both testing cases. It is not straightforward or a good idea >> to construct the q in a static way. Sharing the structures would make >> one test depending on another, since the q needs be torn down and >> restored to the uninitialized states after one test, which has to be >> manually done. Or we need to add a test to just init the q before these >> two tests. That will still create dependence issue. > > OK, what about sharing wire_q ?
That is doable. Thanks, Jianjun > > Dave > >> So I would leave it as it is. >> >> Thanks, >> Jianjun >> >>> Dave >>> >>>> + 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, >>>> + }; >>>> + >>>> + 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, >>>> + }; >>>> + >>>> + 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)); >>>> + qemu_put_byte(fsave, QEMU_VM_EOF); >>>> + 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((uint64_t) qele_from, ==, (uint64_t) qlast_from); >>>> + g_assert_cmpint((uint64_t) qele_to, ==, (uint64_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 +719,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); >>>> -- >>>> 1.9.1 >>>> >>> -- >>> Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK >>> >> > -- > Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK >