xref: /openbmc/qemu/tests/unit/test-clone-visitor.c (revision 1be5a765c08cee3a9587c8a8d3fc2ea247b13f9c)
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  
test_clone_struct(void)15  static 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  
test_clone_alternate(void)39  static 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  
test_clone_list(void)65  static 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  
test_clone_empty(void)88  static 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  
test_clone_complex1(void)99  static 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  
test_clone_complex2(void)123  static 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  
test_clone_complex3(void)153  static 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  
main(int argc,char ** argv)199  int 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