From: Marc-André Lureau <marcandre.lur...@redhat.com> Check subsection support, and optional handling.
Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> Reviewed-by: Juan Quintela <quint...@redhat.com> --- tests/unit/test-vmstate.c | 116 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c index 0b7d5ecd68..d60457486c 100644 --- a/tests/unit/test-vmstate.c +++ b/tests/unit/test-vmstate.c @@ -1479,6 +1479,118 @@ static void test_tmp_struct(void) g_assert_cmpint(obj.f, ==, 8); /* From the child->parent */ } +static bool sub_optional_needed = true; + +static bool sub_optional_needed_cb(void *opaque) +{ + return sub_optional_needed; +} + +static const VMStateDescription vmstate_sub_optional_a = { + .name = "sub/optional/a", + .version_id = 1, + .minimum_version_id = 1, + .needed = sub_optional_needed_cb, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_sub_optional = { + .name = "sub/optional", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &vmstate_sub_optional_a, + } +}; + +static uint8_t wire_sub_optional[] = { + QEMU_VM_SUBSECTION, + 14, + 's', 'u', 'b', '/', 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '/', 'a', + 0x0, 0x0, 0x0, 1, + QEMU_VM_EOF, +}; + +static uint8_t wire_sub_optional_missing[] = { + QEMU_VM_EOF, +}; + +static void test_sub_optional_needed(void) +{ + sub_optional_needed = true; + save_vmstate(&vmstate_sub_optional, NULL); + + compare_vmstate(wire_sub_optional, sizeof(wire_sub_optional)); + + SUCCESS(load_vmstate_one(&vmstate_sub_optional, NULL, + 1, wire_sub_optional, + sizeof(wire_sub_optional))); + + /* this will print an error, but succeed nonetheless */ + load_vmstate_one(&vmstate_sub_optional, NULL, + 1, wire_sub_optional_missing, + sizeof(wire_sub_optional_missing)); +} + +static void test_sub_optional_missing(void) +{ + sub_optional_needed = false; + save_vmstate(&vmstate_sub_optional, NULL); + + compare_vmstate(wire_sub_optional_missing, sizeof(wire_sub_optional_missing)); + + SUCCESS(load_vmstate_one(&vmstate_sub_optional, NULL, + 1, wire_sub_optional, + sizeof(wire_sub_optional))); + + SUCCESS(load_vmstate_one(&vmstate_sub_optional, NULL, + 1, wire_sub_optional_missing, + sizeof(wire_sub_optional_missing))); +} + +static uint8_t wire_sub_dup[] = { + QEMU_VM_SUBSECTION, + 14, + 's', 'u', 'b', '/', 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '/', 'a', + 0x0, 0x0, 0x0, 1, + QEMU_VM_SUBSECTION, + 14, + 's', 'u', 'b', '/', 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '/', 'a', + 0x0, 0x0, 0x0, 1, + QEMU_VM_EOF, +}; + +static void test_sub_optional_dup(void) +{ + sub_optional_needed = false; + + FAILURE(load_vmstate_one(&vmstate_sub_optional, NULL, + 1, wire_sub_dup, + sizeof(wire_sub_dup))); +} + +static uint8_t wire_sub_unknown[] = { + QEMU_VM_SUBSECTION, + 14, + 's', 'u', 'b', '/', 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l', '/', 'b', + 0x0, 0x0, 0x0, 1, + QEMU_VM_EOF, +}; + +static void test_sub_optional_unknown(void) +{ + sub_optional_needed = false; + + FAILURE(load_vmstate_one(&vmstate_sub_optional, NULL, + 1, wire_sub_unknown, + sizeof(wire_sub_unknown))); +} + int main(int argc, char **argv) { g_autofree char *temp_file = g_strdup_printf("%s/vmst.test.XXXXXX", @@ -1519,6 +1631,10 @@ int main(int argc, char **argv) g_test_add_func("/vmstate/qlist/save/saveqlist", test_save_qlist); g_test_add_func("/vmstate/qlist/load/loadqlist", test_load_qlist); g_test_add_func("/vmstate/tmp_struct", test_tmp_struct); + g_test_add_func("/vmstate/subsection/needed", test_sub_optional_needed); + g_test_add_func("/vmstate/subsection/missing", test_sub_optional_missing); + g_test_add_func("/vmstate/subsection/dup", test_sub_optional_dup); + g_test_add_func("/vmstate/subsection/unknown", test_sub_optional_unknown); g_test_run(); close(temp_fd); -- 2.41.0