xref: /qemu/tests/qtest/readconfig-test.c (revision beecc4b78d0d622a39e22edc6301be5282c4f2b5)
1f6a5f380SDaniel P. Berrangé /*
2f6a5f380SDaniel P. Berrangé  * Validate -readconfig
3f6a5f380SDaniel P. Berrangé  *
4f6a5f380SDaniel P. Berrangé  * Copyright (c) 2022 Red Hat, Inc.
5f6a5f380SDaniel P. Berrangé  *
6f6a5f380SDaniel P. Berrangé  * This work is licensed under the terms of the GNU GPL, version 2 or later.
7f6a5f380SDaniel P. Berrangé  * See the COPYING file in the top-level directory.
8f6a5f380SDaniel P. Berrangé  */
9f6a5f380SDaniel P. Berrangé 
10f6a5f380SDaniel P. Berrangé #include "qemu/osdep.h"
11f6a5f380SDaniel P. Berrangé #include "libqtest.h"
12f6a5f380SDaniel P. Berrangé #include "qapi/error.h"
13f6a5f380SDaniel P. Berrangé #include "qapi/qapi-visit-machine.h"
14f6a5f380SDaniel P. Berrangé #include "qapi/qapi-visit-qom.h"
15f6a5f380SDaniel P. Berrangé #include "qapi/qapi-visit-ui.h"
16f6a5f380SDaniel P. Berrangé #include "qapi/qmp/qdict.h"
17f6a5f380SDaniel P. Berrangé #include "qapi/qmp/qlist.h"
18f6a5f380SDaniel P. Berrangé #include "qapi/qobject-input-visitor.h"
19f6a5f380SDaniel P. Berrangé #include "qapi/qmp/qstring.h"
20f6a5f380SDaniel P. Berrangé #include "qemu/units.h"
21f6a5f380SDaniel P. Berrangé 
22f6a5f380SDaniel P. Berrangé static QTestState *qtest_init_with_config(const char *cfgdata)
23f6a5f380SDaniel P. Berrangé {
24f6a5f380SDaniel P. Berrangé     GError *error = NULL;
25f6a5f380SDaniel P. Berrangé     g_autofree char *args = NULL;
26f6a5f380SDaniel P. Berrangé     int cfgfd = -1;
27f6a5f380SDaniel P. Berrangé     g_autofree char *cfgpath = NULL;
28f6a5f380SDaniel P. Berrangé     QTestState *qts;
29f6a5f380SDaniel P. Berrangé     ssize_t ret;
30f6a5f380SDaniel P. Berrangé 
31f6a5f380SDaniel P. Berrangé     cfgfd = g_file_open_tmp("readconfig-test-XXXXXX", &cfgpath, &error);
32f6a5f380SDaniel P. Berrangé     g_assert_no_error(error);
33f6a5f380SDaniel P. Berrangé     g_assert_cmpint(cfgfd, >=, 0);
34f6a5f380SDaniel P. Berrangé 
35f6a5f380SDaniel P. Berrangé     ret = qemu_write_full(cfgfd, cfgdata, strlen(cfgdata));
369c23d719SDaniel P. Berrangé     close(cfgfd);
37f6a5f380SDaniel P. Berrangé     if (ret < 0) {
38f6a5f380SDaniel P. Berrangé         unlink(cfgpath);
39f6a5f380SDaniel P. Berrangé     }
40f6a5f380SDaniel P. Berrangé     g_assert_cmpint(ret, ==, strlen(cfgdata));
41f6a5f380SDaniel P. Berrangé 
42f6a5f380SDaniel P. Berrangé     args = g_strdup_printf("-nodefaults -machine none -readconfig %s", cfgpath);
43f6a5f380SDaniel P. Berrangé 
44f6a5f380SDaniel P. Berrangé     qts = qtest_init(args);
45f6a5f380SDaniel P. Berrangé 
46f6a5f380SDaniel P. Berrangé     unlink(cfgpath);
47f6a5f380SDaniel P. Berrangé 
48f6a5f380SDaniel P. Berrangé     return qts;
49f6a5f380SDaniel P. Berrangé }
50f6a5f380SDaniel P. Berrangé 
51f6a5f380SDaniel P. Berrangé static void test_x86_memdev_resp(QObject *res)
52f6a5f380SDaniel P. Berrangé {
53f6a5f380SDaniel P. Berrangé     Visitor *v;
54f6a5f380SDaniel P. Berrangé     g_autoptr(MemdevList) memdevs = NULL;
55f6a5f380SDaniel P. Berrangé     Memdev *memdev;
56f6a5f380SDaniel P. Berrangé 
57f6a5f380SDaniel P. Berrangé     g_assert(res);
58f6a5f380SDaniel P. Berrangé     v = qobject_input_visitor_new(res);
59f6a5f380SDaniel P. Berrangé     visit_type_MemdevList(v, NULL, &memdevs, &error_abort);
60f6a5f380SDaniel P. Berrangé 
61f6a5f380SDaniel P. Berrangé     g_assert(memdevs);
62f6a5f380SDaniel P. Berrangé     g_assert(memdevs->value);
63f6a5f380SDaniel P. Berrangé     g_assert(!memdevs->next);
64f6a5f380SDaniel P. Berrangé 
65f6a5f380SDaniel P. Berrangé     memdev = memdevs->value;
66f6a5f380SDaniel P. Berrangé     g_assert_cmpstr(memdev->id, ==, "ram");
67f6a5f380SDaniel P. Berrangé     g_assert_cmpint(memdev->size, ==, 200 * MiB);
68f6a5f380SDaniel P. Berrangé 
69f6a5f380SDaniel P. Berrangé     visit_free(v);
70f6a5f380SDaniel P. Berrangé }
71f6a5f380SDaniel P. Berrangé 
72f6a5f380SDaniel P. Berrangé static void test_x86_memdev(void)
73f6a5f380SDaniel P. Berrangé {
74f6a5f380SDaniel P. Berrangé     QDict *resp;
75f6a5f380SDaniel P. Berrangé     QTestState *qts;
76f6a5f380SDaniel P. Berrangé     const char *cfgdata =
77f6a5f380SDaniel P. Berrangé         "[memory]\n"
78f6a5f380SDaniel P. Berrangé         "size = \"200\"";
79f6a5f380SDaniel P. Berrangé 
80f6a5f380SDaniel P. Berrangé     qts = qtest_init_with_config(cfgdata);
81f6a5f380SDaniel P. Berrangé     /* Test valid command */
82f6a5f380SDaniel P. Berrangé     resp = qtest_qmp(qts, "{ 'execute': 'query-memdev' }");
83f6a5f380SDaniel P. Berrangé     test_x86_memdev_resp(qdict_get(resp, "return"));
84f6a5f380SDaniel P. Berrangé     qobject_unref(resp);
85f6a5f380SDaniel P. Berrangé 
86f6a5f380SDaniel P. Berrangé     qtest_quit(qts);
87f6a5f380SDaniel P. Berrangé }
88f6a5f380SDaniel P. Berrangé 
89f6a5f380SDaniel P. Berrangé 
90f6a5f380SDaniel P. Berrangé #ifdef CONFIG_SPICE
91f6a5f380SDaniel P. Berrangé static void test_spice_resp(QObject *res)
92f6a5f380SDaniel P. Berrangé {
93f6a5f380SDaniel P. Berrangé     Visitor *v;
94f6a5f380SDaniel P. Berrangé     g_autoptr(SpiceInfo) spice = NULL;
95f6a5f380SDaniel P. Berrangé 
96f6a5f380SDaniel P. Berrangé     g_assert(res);
97f6a5f380SDaniel P. Berrangé     v = qobject_input_visitor_new(res);
989c23d719SDaniel P. Berrangé     visit_type_SpiceInfo(v, "spice", &spice, &error_abort);
99f6a5f380SDaniel P. Berrangé 
100f6a5f380SDaniel P. Berrangé     g_assert(spice);
101f6a5f380SDaniel P. Berrangé     g_assert(spice->enabled);
102f6a5f380SDaniel P. Berrangé 
103f6a5f380SDaniel P. Berrangé     visit_free(v);
104f6a5f380SDaniel P. Berrangé }
105f6a5f380SDaniel P. Berrangé 
106f6a5f380SDaniel P. Berrangé static void test_spice(void)
107f6a5f380SDaniel P. Berrangé {
108f6a5f380SDaniel P. Berrangé     QDict *resp;
109f6a5f380SDaniel P. Berrangé     QTestState *qts;
110f6a5f380SDaniel P. Berrangé     const char *cfgdata =
111f6a5f380SDaniel P. Berrangé         "[spice]\n"
112*beecc4b7SMarc-André Lureau #ifndef WIN32
113*beecc4b7SMarc-André Lureau         "unix = \"on\"\n"
114*beecc4b7SMarc-André Lureau #endif
115*beecc4b7SMarc-André Lureau         "disable-ticketing = \"on\"\n";
116f6a5f380SDaniel P. Berrangé 
117f6a5f380SDaniel P. Berrangé     qts = qtest_init_with_config(cfgdata);
118f6a5f380SDaniel P. Berrangé     /* Test valid command */
119f6a5f380SDaniel P. Berrangé     resp = qtest_qmp(qts, "{ 'execute': 'query-spice' }");
120f6a5f380SDaniel P. Berrangé     test_spice_resp(qdict_get(resp, "return"));
121f6a5f380SDaniel P. Berrangé     qobject_unref(resp);
122f6a5f380SDaniel P. Berrangé 
123f6a5f380SDaniel P. Berrangé     qtest_quit(qts);
124f6a5f380SDaniel P. Berrangé }
125f6a5f380SDaniel P. Berrangé #endif
126f6a5f380SDaniel P. Berrangé 
127f6a5f380SDaniel P. Berrangé static void test_object_rng_resp(QObject *res)
128f6a5f380SDaniel P. Berrangé {
129f6a5f380SDaniel P. Berrangé     Visitor *v;
130f6a5f380SDaniel P. Berrangé     g_autoptr(ObjectPropertyInfoList) objs = NULL;
131f6a5f380SDaniel P. Berrangé     ObjectPropertyInfoList *tmp;
132f6a5f380SDaniel P. Berrangé     ObjectPropertyInfo *obj;
133f6a5f380SDaniel P. Berrangé     bool seen_rng = false;
134f6a5f380SDaniel P. Berrangé 
135f6a5f380SDaniel P. Berrangé     g_assert(res);
136f6a5f380SDaniel P. Berrangé     v = qobject_input_visitor_new(res);
137f6a5f380SDaniel P. Berrangé     visit_type_ObjectPropertyInfoList(v, NULL, &objs, &error_abort);
138f6a5f380SDaniel P. Berrangé 
139f6a5f380SDaniel P. Berrangé     g_assert(objs);
140f6a5f380SDaniel P. Berrangé     tmp = objs;
141f6a5f380SDaniel P. Berrangé     while (tmp) {
142f6a5f380SDaniel P. Berrangé         g_assert(tmp->value);
143f6a5f380SDaniel P. Berrangé 
144f6a5f380SDaniel P. Berrangé         obj = tmp->value;
145f6a5f380SDaniel P. Berrangé         if (g_str_equal(obj->name, "rng0") &&
146f6a5f380SDaniel P. Berrangé             g_str_equal(obj->type, "child<rng-builtin>")) {
147f6a5f380SDaniel P. Berrangé             seen_rng = true;
1489c23d719SDaniel P. Berrangé             break;
149f6a5f380SDaniel P. Berrangé         }
150f6a5f380SDaniel P. Berrangé 
151f6a5f380SDaniel P. Berrangé         tmp = tmp->next;
152f6a5f380SDaniel P. Berrangé     }
153f6a5f380SDaniel P. Berrangé 
154f6a5f380SDaniel P. Berrangé     g_assert(seen_rng);
155f6a5f380SDaniel P. Berrangé 
156f6a5f380SDaniel P. Berrangé     visit_free(v);
157f6a5f380SDaniel P. Berrangé }
158f6a5f380SDaniel P. Berrangé 
159f6a5f380SDaniel P. Berrangé static void test_object_rng(void)
160f6a5f380SDaniel P. Berrangé {
161f6a5f380SDaniel P. Berrangé     QDict *resp;
162f6a5f380SDaniel P. Berrangé     QTestState *qts;
163f6a5f380SDaniel P. Berrangé     const char *cfgdata =
164f6a5f380SDaniel P. Berrangé         "[object]\n"
165f6a5f380SDaniel P. Berrangé         "qom-type = \"rng-builtin\"\n"
166f6a5f380SDaniel P. Berrangé         "id = \"rng0\"\n";
167f6a5f380SDaniel P. Berrangé 
168f6a5f380SDaniel P. Berrangé     qts = qtest_init_with_config(cfgdata);
169f6a5f380SDaniel P. Berrangé     /* Test valid command */
170f6a5f380SDaniel P. Berrangé     resp = qtest_qmp(qts,
171f6a5f380SDaniel P. Berrangé                      "{ 'execute': 'qom-list',"
172f6a5f380SDaniel P. Berrangé                      "  'arguments': {'path': '/objects' }}");
173f6a5f380SDaniel P. Berrangé     test_object_rng_resp(qdict_get(resp, "return"));
174f6a5f380SDaniel P. Berrangé     qobject_unref(resp);
175f6a5f380SDaniel P. Berrangé 
176f6a5f380SDaniel P. Berrangé     qtest_quit(qts);
177f6a5f380SDaniel P. Berrangé }
178f6a5f380SDaniel P. Berrangé 
179f6a5f380SDaniel P. Berrangé int main(int argc, char *argv[])
180f6a5f380SDaniel P. Berrangé {
181f6a5f380SDaniel P. Berrangé     const char *arch;
182f6a5f380SDaniel P. Berrangé     g_test_init(&argc, &argv, NULL);
183f6a5f380SDaniel P. Berrangé 
184f6a5f380SDaniel P. Berrangé     arch = qtest_get_arch();
185f6a5f380SDaniel P. Berrangé 
186f6a5f380SDaniel P. Berrangé     if (g_str_equal(arch, "i386") ||
187f6a5f380SDaniel P. Berrangé         g_str_equal(arch, "x86_64")) {
188f6a5f380SDaniel P. Berrangé         qtest_add_func("readconfig/x86/memdev", test_x86_memdev);
189f6a5f380SDaniel P. Berrangé     }
190f6a5f380SDaniel P. Berrangé #ifdef CONFIG_SPICE
191f6a5f380SDaniel P. Berrangé     qtest_add_func("readconfig/spice", test_spice);
192f6a5f380SDaniel P. Berrangé #endif
193f6a5f380SDaniel P. Berrangé 
194f6a5f380SDaniel P. Berrangé     qtest_add_func("readconfig/object-rng", test_object_rng);
195f6a5f380SDaniel P. Berrangé 
196f6a5f380SDaniel P. Berrangé     return g_test_run();
197f6a5f380SDaniel P. Berrangé }
198