@samitouri / QOSamiQemu / commits / 3260412dd7

tests/unit/test-vmstate: add tests for VMS_ARRAY_OF_POINTER_AUTO_ALLOC

Add tests for VMSTATE_VARRAY_OF_POINTER_TO_STRUCT_UINT32_ALLOC. Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@futurfusion.io> [peterx: Removed two tests due to macro not used, rebase, fix warning] Signed-off-by: Peter Xu <peterx@redhat.com> Reviewed-by: Juraj Marcin <jmarcin@redhat.com> Link: https://lore.kernel.org/qemu-devel/20260401202844.673494-12-peterx@redhat.com Signed-off-by: Fabiano Rosas <farosas@suse.de>

Alexander Mikhalitsyn committed Apr 1, 2026 at 16:28 UTC 3260412dd7d2b0c37db765051db54affb6e4ba40
1 file changed +86
tests/unit/test-vmstate.c
+86
@@ -702,6 +702,88 @@ static void test_arr_ptr_prim_0_load(void)
702 }
703 }
704
705 +static uint8_t wire_arr_ptr_with_nulls[] = {
706 + VMS_MARKER_PTR_VALID,
707 + 0x00, 0x00, 0x00, 0x00,
708 + VMS_MARKER_PTR_NULL,
709 + VMS_MARKER_PTR_VALID,
710 + 0x00, 0x00, 0x00, 0x02,
711 + VMS_MARKER_PTR_VALID,
712 + 0x00, 0x00, 0x00, 0x03,
713 + QEMU_VM_EOF
714 +};
715 +
716 +typedef struct {
717 + uint32_t ar_items_num;
718 + TestStructTriv **ar;
719 +} TestVArrayOfPtrToStuctWithNULLs;
720 +
721 +const VMStateDescription vmsd_arps_with_nulls = {
722 + .name = "test/arps_with_nulls",
723 + .version_id = 1,
724 + .minimum_version_id = 1,
725 + .fields = (const VMStateField[]) {
726 + VMSTATE_VARRAY_OF_POINTER_TO_STRUCT_UINT32_ALLOC(
727 + ar, TestVArrayOfPtrToStuctWithNULLs, ar_items_num,
728 + 0, vmsd_tst, TestStructTriv),
729 + VMSTATE_END_OF_LIST()
730 + }
731 +};
732 +
733 +static void test_arr_ptr_nulls_str_save(void)
734 +{
735 + TestStructTriv ar[AR_SIZE] = { {.i = 0}, {.i = 1}, {.i = 2}, {.i = 3} };
736 + TestVArrayOfPtrToStuctWithNULLs sample = {};
737 + int idx;
738 +
739 + sample.ar_items_num = AR_SIZE;
740 + sample.ar = g_new0(TestStructTriv*, sample.ar_items_num);
741 + sample.ar[0] = g_new0(TestStructTriv, 1);
742 + *sample.ar[0] = ar[0];
743 + /* note, sample.ar[1] remains NULL */
744 + sample.ar[2] = g_new0(TestStructTriv, 1);
745 + *sample.ar[2] = ar[2];
746 + sample.ar[3] = g_new0(TestStructTriv, 1);
747 + *sample.ar[3] = ar[3];
748 +
749 + save_vmstate(&vmsd_arps_with_nulls, &sample);
750 + compare_vmstate(wire_arr_ptr_with_nulls, sizeof(wire_arr_ptr_with_nulls));
751 +
752 + for (idx = 0; idx < AR_SIZE; ++idx) {
753 + g_free(sample.ar[idx]);
754 + }
755 + g_free(sample.ar);
756 +}
757 +
758 +static void test_arr_ptr_nulls_str_load(void)
759 +{
760 + TestStructTriv ar_gt[AR_SIZE] = {{.i = 0}, {.i = 0}, {.i = 2}, {.i = 3} };
761 + TestVArrayOfPtrToStuctWithNULLs obj = {};
762 + int idx;
763 +
764 + obj.ar_items_num = AR_SIZE;
765 + obj.ar = g_new0(TestStructTriv*, obj.ar_items_num);
766 +
767 + save_buffer(wire_arr_ptr_with_nulls, sizeof(wire_arr_ptr_with_nulls));
768 + SUCCESS(load_vmstate_one(
769 + &vmsd_arps_with_nulls, &obj, 1,
770 + wire_arr_ptr_with_nulls, sizeof(wire_arr_ptr_with_nulls)));
771 +
772 + for (idx = 0; idx < AR_SIZE; ++idx) {
773 + if (idx == 1) {
774 + g_assert_cmpint((uintptr_t)(obj.ar[idx]), ==, 0);
775 + } else {
776 + /* compare the target array ar with the ground truth array ar_gt */
777 + g_assert_cmpint(ar_gt[idx].i, ==, obj.ar[idx]->i);
778 + }
779 + }
780 +
781 + for (idx = 0; idx < AR_SIZE; ++idx) {
782 + g_free(obj.ar[idx]);
783 + }
784 + g_free(obj.ar);
785 +}
786 +
787 /* test QTAILQ migration */
788 typedef struct TestQtailqElement TestQtailqElement;
789
@@ -1568,6 +1650,10 @@ int main(int argc, char **argv)
1650 test_arr_ptr_prim_0_save);
1651 g_test_add_func("/vmstate/array/ptr/prim/0/load",
1652 test_arr_ptr_prim_0_load);
1653 + g_test_add_func("/vmstate/array/ptr-nulls/str/save",
1654 + test_arr_ptr_nulls_str_save);
1655 + g_test_add_func("/vmstate/array/ptr-nulls/str/load",
1656 + test_arr_ptr_nulls_str_load);
1657 g_test_add_func("/vmstate/qtailq/save/saveq", test_save_q);
1658 g_test_add_func("/vmstate/qtailq/load/loadq", test_load_q);
1659 g_test_add_func("/vmstate/gtree/save/savedomain", test_gtree_save_domain);