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