qemu/tests/unit/test-clone-visitor.c
<<
>>
Prefs
   1/*
   2 * QAPI Clone Visitor unit-tests.
   3 *
   4 * Copyright (C) 2016 Red Hat Inc.
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   7 * See the COPYING file in the top-level directory.
   8 */
   9
  10#include "qemu/osdep.h"
  11
  12#include "qapi/clone-visitor.h"
  13#include "test-qapi-visit.h"
  14
  15static void test_clone_struct(void)
  16{
  17    UserDefOne *src, *dst;
  18
  19    src = g_new0(UserDefOne, 1);
  20    src->integer = 42;
  21    src->string = g_strdup("Hello");
  22    src->has_enum1 = false;
  23    src->enum1 = ENUM_ONE_VALUE2;
  24
  25    dst = QAPI_CLONE(UserDefOne, src);
  26    g_assert(dst);
  27    g_assert_cmpint(dst->integer, ==, 42);
  28    g_assert(dst->string != src->string);
  29    g_assert_cmpstr(dst->string, ==, "Hello");
  30    g_assert_cmpint(dst->has_enum1, ==, false);
  31    /* Our implementation does this, but it is not required:
  32    g_assert_cmpint(dst->enum1, ==, ENUM_ONE_VALUE2);
  33    */
  34
  35    qapi_free_UserDefOne(src);
  36    qapi_free_UserDefOne(dst);
  37}
  38
  39static void test_clone_alternate(void)
  40{
  41    AltEnumBool *b_src, *s_src, *b_dst, *s_dst;
  42
  43    b_src = g_new0(AltEnumBool, 1);
  44    b_src->type = QTYPE_QBOOL;
  45    b_src->u.b = true;
  46    s_src = g_new0(AltEnumBool, 1);
  47    s_src->type = QTYPE_QSTRING;
  48    s_src->u.e = ENUM_ONE_VALUE1;
  49
  50    b_dst = QAPI_CLONE(AltEnumBool, b_src);
  51    g_assert(b_dst);
  52    g_assert_cmpint(b_dst->type, ==, b_src->type);
  53    g_assert_cmpint(b_dst->u.b, ==, b_src->u.b);
  54    s_dst = QAPI_CLONE(AltEnumBool, s_src);
  55    g_assert(s_dst);
  56    g_assert_cmpint(s_dst->type, ==, s_src->type);
  57    g_assert_cmpint(s_dst->u.e, ==, s_src->u.e);
  58
  59    qapi_free_AltEnumBool(b_src);
  60    qapi_free_AltEnumBool(s_src);
  61    qapi_free_AltEnumBool(b_dst);
  62    qapi_free_AltEnumBool(s_dst);
  63}
  64
  65static void test_clone_list(void)
  66{
  67    uint8List *src = NULL, *dst;
  68    uint8List *tmp = NULL;
  69    int i;
  70
  71    /* Build list in reverse */
  72    for (i = 10; i; i--) {
  73        QAPI_LIST_PREPEND(src, i);
  74    }
  75
  76    dst = QAPI_CLONE(uint8List, src);
  77    for (tmp = dst, i = 1; i <= 10; i++) {
  78        g_assert(tmp);
  79        g_assert_cmpint(tmp->value, ==, i);
  80        tmp = tmp->next;
  81    }
  82    g_assert(!tmp);
  83
  84    qapi_free_uint8List(src);
  85    qapi_free_uint8List(dst);
  86}
  87
  88static void test_clone_empty(void)
  89{
  90    Empty2 *src, *dst;
  91
  92    src = g_new0(Empty2, 1);
  93    dst = QAPI_CLONE(Empty2, src);
  94    g_assert(dst);
  95    qapi_free_Empty2(src);
  96    qapi_free_Empty2(dst);
  97}
  98
  99static void test_clone_complex1(void)
 100{
 101    UserDefFlatUnion *src, *dst;
 102
 103    src = g_new0(UserDefFlatUnion, 1);
 104    src->integer = 123;
 105    src->string = g_strdup("abc");
 106    src->enum1 = ENUM_ONE_VALUE1;
 107    src->u.value1.boolean = true;
 108
 109    dst = QAPI_CLONE(UserDefFlatUnion, src);
 110    g_assert(dst);
 111
 112    g_assert_cmpint(dst->integer, ==, 123);
 113    g_assert_cmpstr(dst->string, ==, "abc");
 114    g_assert_cmpint(dst->enum1, ==, ENUM_ONE_VALUE1);
 115    g_assert(dst->u.value1.boolean);
 116    g_assert(!dst->u.value1.has_a_b);
 117    g_assert_cmpint(dst->u.value1.a_b, ==, 0);
 118
 119    qapi_free_UserDefFlatUnion(src);
 120    qapi_free_UserDefFlatUnion(dst);
 121}
 122
 123static void test_clone_complex2(void)
 124{
 125    WrapAlternate *src, *dst;
 126
 127    src = g_new0(WrapAlternate, 1);
 128    src->alt = g_new(UserDefAlternate, 1);
 129    src->alt->type = QTYPE_QDICT;
 130    src->alt->u.udfu.integer = 42;
 131    /* Clone intentionally converts NULL into "" for strings */
 132    src->alt->u.udfu.string = NULL;
 133    src->alt->u.udfu.enum1 = ENUM_ONE_VALUE3;
 134    src->alt->u.udfu.u.value3.intb = 99;
 135    src->alt->u.udfu.u.value3.has_a_b = true;
 136    src->alt->u.udfu.u.value3.a_b = true;
 137
 138    dst = QAPI_CLONE(WrapAlternate, src);
 139    g_assert(dst);
 140    g_assert(dst->alt);
 141    g_assert_cmpint(dst->alt->type, ==, QTYPE_QDICT);
 142    g_assert_cmpint(dst->alt->u.udfu.integer, ==, 42);
 143    g_assert_cmpstr(dst->alt->u.udfu.string, ==, "");
 144    g_assert_cmpint(dst->alt->u.udfu.enum1, ==, ENUM_ONE_VALUE3);
 145    g_assert_cmpint(dst->alt->u.udfu.u.value3.intb, ==, 99);
 146    g_assert_cmpint(dst->alt->u.udfu.u.value3.has_a_b, ==, true);
 147    g_assert_cmpint(dst->alt->u.udfu.u.value3.a_b, ==, true);
 148
 149    qapi_free_WrapAlternate(src);
 150    qapi_free_WrapAlternate(dst);
 151}
 152
 153static void test_clone_complex3(void)
 154{
 155    UserDefOneList *src, *dst, *tail;
 156    UserDefOne *elt;
 157
 158    src = NULL;
 159    elt = g_new0(UserDefOne, 1);
 160    elt->integer = 3;
 161    elt->string = g_strdup("three");
 162    elt->has_enum1 = true;
 163    elt->enum1 = ENUM_ONE_VALUE3;
 164    QAPI_LIST_PREPEND(src, elt);
 165    elt = g_new0(UserDefOne, 1);
 166    elt->integer = 2;
 167    elt->string = g_strdup("two");
 168    QAPI_LIST_PREPEND(src, elt);
 169    elt = g_new0(UserDefOne, 1);
 170    elt->integer = 1;
 171    elt->string = g_strdup("one");
 172    QAPI_LIST_PREPEND(src, elt);
 173
 174    dst = QAPI_CLONE(UserDefOneList, src);
 175
 176    g_assert(dst);
 177    tail = dst;
 178    elt = tail->value;
 179    g_assert_cmpint(elt->integer, ==, 1);
 180    g_assert_cmpstr(elt->string, ==, "one");
 181    g_assert(!elt->has_enum1);
 182    tail = tail->next;
 183    elt = tail->value;
 184    g_assert_cmpint(elt->integer, ==, 2);
 185    g_assert_cmpstr(elt->string, ==, "two");
 186    g_assert(!elt->has_enum1);
 187    tail = tail->next;
 188    elt = tail->value;
 189    g_assert_cmpint(elt->integer, ==, 3);
 190    g_assert_cmpstr(elt->string, ==, "three");
 191    g_assert(elt->has_enum1);
 192    g_assert_cmpint(elt->enum1, ==, ENUM_ONE_VALUE3);
 193    g_assert(!tail->next);
 194
 195    qapi_free_UserDefOneList(src);
 196    qapi_free_UserDefOneList(dst);
 197}
 198
 199int main(int argc, char **argv)
 200{
 201    g_test_init(&argc, &argv, NULL);
 202
 203    g_test_add_func("/visitor/clone/struct", test_clone_struct);
 204    g_test_add_func("/visitor/clone/alternate", test_clone_alternate);
 205    g_test_add_func("/visitor/clone/list", test_clone_list);
 206    g_test_add_func("/visitor/clone/empty", test_clone_empty);
 207    g_test_add_func("/visitor/clone/complex1", test_clone_complex1);
 208    g_test_add_func("/visitor/clone/complex2", test_clone_complex2);
 209    g_test_add_func("/visitor/clone/complex3", test_clone_complex3);
 210
 211    return g_test_run();
 212}
 213