xref: /openbmc/qemu/tests/qtest/readconfig-test.c (revision bc55e2ea)
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é 
qtest_init_with_config(const char * cfgdata)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é 
test_x86_memdev_resp(QObject * res,const char * mem_id,int size)515a7d4dc9SThomas Huth static void test_x86_memdev_resp(QObject *res, const char *mem_id, int size)
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;
665a7d4dc9SThomas Huth     g_assert_cmpstr(memdev->id, ==, mem_id);
675a7d4dc9SThomas Huth     g_assert_cmpint(memdev->size, ==, size * MiB);
68f6a5f380SDaniel P. Berrangé 
69f6a5f380SDaniel P. Berrangé     visit_free(v);
70f6a5f380SDaniel P. Berrangé }
71f6a5f380SDaniel P. Berrangé 
test_x86_memdev(void)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' }");
835a7d4dc9SThomas Huth     test_x86_memdev_resp(qdict_get(resp, "return"), "ram", 200);
84f6a5f380SDaniel P. Berrangé     qobject_unref(resp);
85f6a5f380SDaniel P. Berrangé 
86f6a5f380SDaniel P. Berrangé     qtest_quit(qts);
87f6a5f380SDaniel P. Berrangé }
88f6a5f380SDaniel P. Berrangé 
8901013d2cSThomas Huth /* FIXME: The test is currently broken on FreeBSD */
9001013d2cSThomas Huth #if defined(CONFIG_SPICE) && !defined(__FreeBSD__)
test_spice_resp(QObject * res)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é 
test_spice(void)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"
112beecc4b7SMarc-André Lureau #ifndef WIN32
113beecc4b7SMarc-André Lureau         "unix = \"on\"\n"
114beecc4b7SMarc-André Lureau #endif
115beecc4b7SMarc-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é 
test_object_available(QObject * res,const char * name,const char * type)12779571e7fSThomas Huth static void test_object_available(QObject *res, const char *name,
12879571e7fSThomas Huth                                   const char *type)
129f6a5f380SDaniel P. Berrangé {
130f6a5f380SDaniel P. Berrangé     Visitor *v;
131f6a5f380SDaniel P. Berrangé     g_autoptr(ObjectPropertyInfoList) objs = NULL;
132f6a5f380SDaniel P. Berrangé     ObjectPropertyInfoList *tmp;
133f6a5f380SDaniel P. Berrangé     ObjectPropertyInfo *obj;
13479571e7fSThomas Huth     bool object_available = false;
13579571e7fSThomas Huth     g_autofree char *childtype = g_strdup_printf("child<%s>", type);
136f6a5f380SDaniel P. Berrangé 
137f6a5f380SDaniel P. Berrangé     g_assert(res);
138f6a5f380SDaniel P. Berrangé     v = qobject_input_visitor_new(res);
139f6a5f380SDaniel P. Berrangé     visit_type_ObjectPropertyInfoList(v, NULL, &objs, &error_abort);
140f6a5f380SDaniel P. Berrangé 
141f6a5f380SDaniel P. Berrangé     g_assert(objs);
142f6a5f380SDaniel P. Berrangé     tmp = objs;
143f6a5f380SDaniel P. Berrangé     while (tmp) {
144f6a5f380SDaniel P. Berrangé         g_assert(tmp->value);
145f6a5f380SDaniel P. Berrangé 
146f6a5f380SDaniel P. Berrangé         obj = tmp->value;
14779571e7fSThomas Huth         if (g_str_equal(obj->name, name) && g_str_equal(obj->type, childtype)) {
14879571e7fSThomas Huth             object_available = true;
1499c23d719SDaniel P. Berrangé             break;
150f6a5f380SDaniel P. Berrangé         }
151f6a5f380SDaniel P. Berrangé 
152f6a5f380SDaniel P. Berrangé         tmp = tmp->next;
153f6a5f380SDaniel P. Berrangé     }
154f6a5f380SDaniel P. Berrangé 
15579571e7fSThomas Huth     g_assert(object_available);
156f6a5f380SDaniel P. Berrangé 
157f6a5f380SDaniel P. Berrangé     visit_free(v);
158f6a5f380SDaniel P. Berrangé }
159f6a5f380SDaniel P. Berrangé 
test_object_rng(void)160f6a5f380SDaniel P. Berrangé static void test_object_rng(void)
161f6a5f380SDaniel P. Berrangé {
162f6a5f380SDaniel P. Berrangé     QDict *resp;
163f6a5f380SDaniel P. Berrangé     QTestState *qts;
164f6a5f380SDaniel P. Berrangé     const char *cfgdata =
165f6a5f380SDaniel P. Berrangé         "[object]\n"
166f6a5f380SDaniel P. Berrangé         "qom-type = \"rng-builtin\"\n"
167f6a5f380SDaniel P. Berrangé         "id = \"rng0\"\n";
168f6a5f380SDaniel P. Berrangé 
169f6a5f380SDaniel P. Berrangé     qts = qtest_init_with_config(cfgdata);
170f6a5f380SDaniel P. Berrangé     /* Test valid command */
171f6a5f380SDaniel P. Berrangé     resp = qtest_qmp(qts,
172f6a5f380SDaniel P. Berrangé                      "{ 'execute': 'qom-list',"
173f6a5f380SDaniel P. Berrangé                      "  'arguments': {'path': '/objects' }}");
17479571e7fSThomas Huth     test_object_available(qdict_get(resp, "return"), "rng0", "rng-builtin");
175f6a5f380SDaniel P. Berrangé     qobject_unref(resp);
176f6a5f380SDaniel P. Berrangé 
177f6a5f380SDaniel P. Berrangé     qtest_quit(qts);
178f6a5f380SDaniel P. Berrangé }
179f6a5f380SDaniel P. Berrangé 
test_docs_config_ich9(void)180201aa17eSThomas Huth static void test_docs_config_ich9(void)
181201aa17eSThomas Huth {
182201aa17eSThomas Huth     QTestState *qts;
183201aa17eSThomas Huth     QDict *resp;
184201aa17eSThomas Huth     QObject *qobj;
185201aa17eSThomas Huth 
186201aa17eSThomas Huth     qts = qtest_initf("-nodefaults -readconfig docs/config/ich9-ehci-uhci.cfg");
187201aa17eSThomas Huth 
188201aa17eSThomas Huth     resp = qtest_qmp(qts, "{ 'execute': 'qom-list',"
189201aa17eSThomas Huth                           "  'arguments': {'path': '/machine/peripheral' }}");
190201aa17eSThomas Huth     qobj = qdict_get(resp, "return");
191201aa17eSThomas Huth     test_object_available(qobj, "ehci", "ich9-usb-ehci1");
192201aa17eSThomas Huth     test_object_available(qobj, "uhci-1", "ich9-usb-uhci1");
193201aa17eSThomas Huth     test_object_available(qobj, "uhci-2", "ich9-usb-uhci2");
194201aa17eSThomas Huth     test_object_available(qobj, "uhci-3", "ich9-usb-uhci3");
195201aa17eSThomas Huth     qobject_unref(resp);
196201aa17eSThomas Huth 
197201aa17eSThomas Huth     qtest_quit(qts);
198201aa17eSThomas Huth }
199201aa17eSThomas Huth 
200*bc55e2eaSThomas Huth #if defined(CONFIG_POSIX) && defined(CONFIG_SLIRP)
201*bc55e2eaSThomas Huth 
make_temp_img(const char * template,const char * format,int size)202*bc55e2eaSThomas Huth static char *make_temp_img(const char *template, const char *format, int size)
203*bc55e2eaSThomas Huth {
204*bc55e2eaSThomas Huth     GError *error = NULL;
205*bc55e2eaSThomas Huth     char *temp_name;
206*bc55e2eaSThomas Huth     int fd;
207*bc55e2eaSThomas Huth 
208*bc55e2eaSThomas Huth     /* Create a temporary image names */
209*bc55e2eaSThomas Huth     fd = g_file_open_tmp(template, &temp_name, &error);
210*bc55e2eaSThomas Huth     if (fd == -1) {
211*bc55e2eaSThomas Huth         fprintf(stderr, "unable to create file: %s\n", error->message);
212*bc55e2eaSThomas Huth         g_error_free(error);
213*bc55e2eaSThomas Huth         return NULL;
214*bc55e2eaSThomas Huth     }
215*bc55e2eaSThomas Huth     close(fd);
216*bc55e2eaSThomas Huth 
217*bc55e2eaSThomas Huth     if (!mkimg(temp_name, format, size)) {
218*bc55e2eaSThomas Huth         fprintf(stderr, "qemu-img failed to create %s\n", temp_name);
219*bc55e2eaSThomas Huth         g_free(temp_name);
220*bc55e2eaSThomas Huth         return NULL;
221*bc55e2eaSThomas Huth     }
222*bc55e2eaSThomas Huth 
223*bc55e2eaSThomas Huth     return temp_name;
224*bc55e2eaSThomas Huth }
225*bc55e2eaSThomas Huth 
226*bc55e2eaSThomas Huth struct device {
227*bc55e2eaSThomas Huth     const char *name;
228*bc55e2eaSThomas Huth     const char *type;
229*bc55e2eaSThomas Huth };
230*bc55e2eaSThomas Huth 
test_docs_q35(const char * input_file,struct device * devices)231*bc55e2eaSThomas Huth static void test_docs_q35(const char *input_file, struct device *devices)
232*bc55e2eaSThomas Huth {
233*bc55e2eaSThomas Huth     QTestState *qts;
234*bc55e2eaSThomas Huth     QDict *resp;
235*bc55e2eaSThomas Huth     QObject *qobj;
236*bc55e2eaSThomas Huth     int ret, i;
237*bc55e2eaSThomas Huth     g_autofree char *cfg_file = NULL, *sedcmd = NULL;
238*bc55e2eaSThomas Huth     g_autofree char *hd_file = NULL, *cd_file = NULL;
239*bc55e2eaSThomas Huth 
240*bc55e2eaSThomas Huth     /* Check that all the devices are available in the QEMU binary */
241*bc55e2eaSThomas Huth     for (i = 0; devices[i].name; i++) {
242*bc55e2eaSThomas Huth         if (!qtest_has_device(devices[i].type)) {
243*bc55e2eaSThomas Huth             g_test_skip("one of the required devices is not available");
244*bc55e2eaSThomas Huth             return;
245*bc55e2eaSThomas Huth         }
246*bc55e2eaSThomas Huth     }
247*bc55e2eaSThomas Huth 
248*bc55e2eaSThomas Huth     hd_file = make_temp_img("qtest_disk_XXXXXX.qcow2", "qcow2", 1);
249*bc55e2eaSThomas Huth     cd_file = make_temp_img("qtest_cdrom_XXXXXX.iso", "raw", 1);
250*bc55e2eaSThomas Huth     if (!hd_file || !cd_file) {
251*bc55e2eaSThomas Huth         g_test_skip("could not create disk images");
252*bc55e2eaSThomas Huth         goto cleanup;
253*bc55e2eaSThomas Huth     }
254*bc55e2eaSThomas Huth 
255*bc55e2eaSThomas Huth     /* Create a temporary config file where we replace the disk image names */
256*bc55e2eaSThomas Huth     ret = g_file_open_tmp("q35-emulated-XXXXXX.cfg", &cfg_file, NULL);
257*bc55e2eaSThomas Huth     if (ret == -1) {
258*bc55e2eaSThomas Huth         g_test_skip("could not create temporary config file");
259*bc55e2eaSThomas Huth         goto cleanup;
260*bc55e2eaSThomas Huth     }
261*bc55e2eaSThomas Huth     close(ret);
262*bc55e2eaSThomas Huth 
263*bc55e2eaSThomas Huth     sedcmd = g_strdup_printf("sed -e 's,guest.qcow2,%s,' -e 's,install.iso,%s,'"
264*bc55e2eaSThomas Huth                              " %s %s > '%s'",
265*bc55e2eaSThomas Huth                              hd_file, cd_file,
266*bc55e2eaSThomas Huth                              !qtest_has_accel("kvm") ? "-e '/accel/d'" : "",
267*bc55e2eaSThomas Huth                              input_file, cfg_file);
268*bc55e2eaSThomas Huth     ret = system(sedcmd);
269*bc55e2eaSThomas Huth     if (ret) {
270*bc55e2eaSThomas Huth         g_test_skip("could not modify temporary config file");
271*bc55e2eaSThomas Huth         goto cleanup;
272*bc55e2eaSThomas Huth     }
273*bc55e2eaSThomas Huth 
274*bc55e2eaSThomas Huth     qts = qtest_initf("-machine none -nodefaults -readconfig %s", cfg_file);
275*bc55e2eaSThomas Huth 
276*bc55e2eaSThomas Huth     /* Check memory size */
277*bc55e2eaSThomas Huth     resp = qtest_qmp(qts, "{ 'execute': 'query-memdev' }");
278*bc55e2eaSThomas Huth     test_x86_memdev_resp(qdict_get(resp, "return"), "pc.ram", 1024);
279*bc55e2eaSThomas Huth     qobject_unref(resp);
280*bc55e2eaSThomas Huth 
281*bc55e2eaSThomas Huth     resp = qtest_qmp(qts, "{ 'execute': 'qom-list',"
282*bc55e2eaSThomas Huth                           "  'arguments': {'path': '/machine/peripheral' }}");
283*bc55e2eaSThomas Huth     qobj = qdict_get(resp, "return");
284*bc55e2eaSThomas Huth 
285*bc55e2eaSThomas Huth     /* Check that all the devices have been created */
286*bc55e2eaSThomas Huth     for (i = 0; devices[i].name; i++) {
287*bc55e2eaSThomas Huth         test_object_available(qobj, devices[i].name, devices[i].type);
288*bc55e2eaSThomas Huth     }
289*bc55e2eaSThomas Huth 
290*bc55e2eaSThomas Huth     qobject_unref(resp);
291*bc55e2eaSThomas Huth 
292*bc55e2eaSThomas Huth     qtest_quit(qts);
293*bc55e2eaSThomas Huth 
294*bc55e2eaSThomas Huth cleanup:
295*bc55e2eaSThomas Huth     if (hd_file) {
296*bc55e2eaSThomas Huth         unlink(hd_file);
297*bc55e2eaSThomas Huth     }
298*bc55e2eaSThomas Huth     if (cd_file) {
299*bc55e2eaSThomas Huth         unlink(cd_file);
300*bc55e2eaSThomas Huth     }
301*bc55e2eaSThomas Huth     if (cfg_file) {
302*bc55e2eaSThomas Huth         unlink(cfg_file);
303*bc55e2eaSThomas Huth     }
304*bc55e2eaSThomas Huth }
305*bc55e2eaSThomas Huth 
test_docs_q35_emulated(void)306*bc55e2eaSThomas Huth static void test_docs_q35_emulated(void)
307*bc55e2eaSThomas Huth {
308*bc55e2eaSThomas Huth     struct device devices[] = {
309*bc55e2eaSThomas Huth         { "ich9-pcie-port-1", "ioh3420" },
310*bc55e2eaSThomas Huth         { "ich9-pcie-port-2", "ioh3420" },
311*bc55e2eaSThomas Huth         { "ich9-pcie-port-3", "ioh3420" },
312*bc55e2eaSThomas Huth         { "ich9-pcie-port-4", "ioh3420" },
313*bc55e2eaSThomas Huth         { "ich9-pci-bridge", "i82801b11-bridge" },
314*bc55e2eaSThomas Huth         { "ich9-ehci-1", "ich9-usb-ehci1" },
315*bc55e2eaSThomas Huth         { "ich9-ehci-2", "ich9-usb-ehci2" },
316*bc55e2eaSThomas Huth         { "ich9-uhci-1", "ich9-usb-uhci1" },
317*bc55e2eaSThomas Huth         { "ich9-uhci-2", "ich9-usb-uhci2" },
318*bc55e2eaSThomas Huth         { "ich9-uhci-3", "ich9-usb-uhci3" },
319*bc55e2eaSThomas Huth         { "ich9-uhci-4", "ich9-usb-uhci4" },
320*bc55e2eaSThomas Huth         { "ich9-uhci-5", "ich9-usb-uhci5" },
321*bc55e2eaSThomas Huth         { "ich9-uhci-6", "ich9-usb-uhci6" },
322*bc55e2eaSThomas Huth         { "sata-disk", "ide-hd" },
323*bc55e2eaSThomas Huth         { "sata-optical-disk", "ide-cd" },
324*bc55e2eaSThomas Huth         { "net", "e1000" },
325*bc55e2eaSThomas Huth         { "video", "VGA" },
326*bc55e2eaSThomas Huth         { "ich9-hda-audio", "ich9-intel-hda" },
327*bc55e2eaSThomas Huth         { "ich9-hda-duplex", "hda-duplex" },
328*bc55e2eaSThomas Huth         { NULL, NULL }
329*bc55e2eaSThomas Huth     };
330*bc55e2eaSThomas Huth 
331*bc55e2eaSThomas Huth     test_docs_q35("docs/config/q35-emulated.cfg", devices);
332*bc55e2eaSThomas Huth }
333*bc55e2eaSThomas Huth 
test_docs_q35_virtio_graphical(void)334*bc55e2eaSThomas Huth static void test_docs_q35_virtio_graphical(void)
335*bc55e2eaSThomas Huth {
336*bc55e2eaSThomas Huth     struct device devices[] = {
337*bc55e2eaSThomas Huth         { "pcie.1", "pcie-root-port" },
338*bc55e2eaSThomas Huth         { "pcie.2", "pcie-root-port" },
339*bc55e2eaSThomas Huth         { "pcie.3", "pcie-root-port" },
340*bc55e2eaSThomas Huth         { "pcie.4", "pcie-root-port" },
341*bc55e2eaSThomas Huth         { "pcie.5", "pcie-root-port" },
342*bc55e2eaSThomas Huth         { "pcie.6", "pcie-root-port" },
343*bc55e2eaSThomas Huth         { "pcie.7", "pcie-root-port" },
344*bc55e2eaSThomas Huth         { "pcie.8", "pcie-root-port" },
345*bc55e2eaSThomas Huth         { "scsi", "virtio-scsi-pci" },
346*bc55e2eaSThomas Huth         { "scsi-disk", "scsi-hd" },
347*bc55e2eaSThomas Huth         { "scsi-optical-disk", "scsi-cd" },
348*bc55e2eaSThomas Huth         { "net", "virtio-net-pci" },
349*bc55e2eaSThomas Huth         { "usb", "nec-usb-xhci" },
350*bc55e2eaSThomas Huth         { "tablet", "usb-tablet" },
351*bc55e2eaSThomas Huth         { "video", "qxl-vga" },
352*bc55e2eaSThomas Huth         { "sound", "ich9-intel-hda" },
353*bc55e2eaSThomas Huth         { "duplex", "hda-duplex" },
354*bc55e2eaSThomas Huth         { NULL, NULL }
355*bc55e2eaSThomas Huth     };
356*bc55e2eaSThomas Huth 
357*bc55e2eaSThomas Huth     test_docs_q35("docs/config/q35-virtio-graphical.cfg", devices);
358*bc55e2eaSThomas Huth }
359*bc55e2eaSThomas Huth 
test_docs_q35_virtio_serial(void)360*bc55e2eaSThomas Huth static void test_docs_q35_virtio_serial(void)
361*bc55e2eaSThomas Huth {
362*bc55e2eaSThomas Huth     struct device devices[] = {
363*bc55e2eaSThomas Huth         { "pcie.1", "pcie-root-port" },
364*bc55e2eaSThomas Huth         { "pcie.2", "pcie-root-port" },
365*bc55e2eaSThomas Huth         { "pcie.3", "pcie-root-port" },
366*bc55e2eaSThomas Huth         { "pcie.4", "pcie-root-port" },
367*bc55e2eaSThomas Huth         { "pcie.5", "pcie-root-port" },
368*bc55e2eaSThomas Huth         { "pcie.6", "pcie-root-port" },
369*bc55e2eaSThomas Huth         { "pcie.7", "pcie-root-port" },
370*bc55e2eaSThomas Huth         { "pcie.8", "pcie-root-port" },
371*bc55e2eaSThomas Huth         { "scsi", "virtio-scsi-pci" },
372*bc55e2eaSThomas Huth         { "scsi-disk", "scsi-hd" },
373*bc55e2eaSThomas Huth         { "scsi-optical-disk", "scsi-cd" },
374*bc55e2eaSThomas Huth         { "net", "virtio-net-pci" },
375*bc55e2eaSThomas Huth         { NULL, NULL }
376*bc55e2eaSThomas Huth     };
377*bc55e2eaSThomas Huth 
378*bc55e2eaSThomas Huth     test_docs_q35("docs/config/q35-virtio-serial.cfg", devices);
379*bc55e2eaSThomas Huth }
380*bc55e2eaSThomas Huth 
381*bc55e2eaSThomas Huth #endif /* CONFIG_LINUX */
382*bc55e2eaSThomas Huth 
main(int argc,char * argv[])383f6a5f380SDaniel P. Berrangé int main(int argc, char *argv[])
384f6a5f380SDaniel P. Berrangé {
385f6a5f380SDaniel P. Berrangé     const char *arch;
386f6a5f380SDaniel P. Berrangé     g_test_init(&argc, &argv, NULL);
387f6a5f380SDaniel P. Berrangé 
388f6a5f380SDaniel P. Berrangé     arch = qtest_get_arch();
389f6a5f380SDaniel P. Berrangé 
390f6a5f380SDaniel P. Berrangé     if (g_str_equal(arch, "i386") ||
391f6a5f380SDaniel P. Berrangé         g_str_equal(arch, "x86_64")) {
392f6a5f380SDaniel P. Berrangé         qtest_add_func("readconfig/x86/memdev", test_x86_memdev);
393335da811SThomas Huth         if (qtest_has_device("ich9-usb-ehci1") &&
394335da811SThomas Huth             qtest_has_device("ich9-usb-uhci1")) {
395201aa17eSThomas Huth             qtest_add_func("readconfig/x86/ich9-ehci-uhci", test_docs_config_ich9);
396f6a5f380SDaniel P. Berrangé         }
397*bc55e2eaSThomas Huth #if defined(CONFIG_POSIX) && defined(CONFIG_SLIRP)
398*bc55e2eaSThomas Huth         qtest_add_func("readconfig/x86/q35-emulated", test_docs_q35_emulated);
399*bc55e2eaSThomas Huth         qtest_add_func("readconfig/x86/q35-virtio-graphical",
400*bc55e2eaSThomas Huth                        test_docs_q35_virtio_graphical);
401*bc55e2eaSThomas Huth         if (g_test_slow()) {
402*bc55e2eaSThomas Huth             /*
403*bc55e2eaSThomas Huth              * q35-virtio-serial.cfg is a subset of q35-virtio-graphical.cfg,
404*bc55e2eaSThomas Huth              * so we can skip the test in quick mode
405*bc55e2eaSThomas Huth              */
406*bc55e2eaSThomas Huth             qtest_add_func("readconfig/x86/q35-virtio-serial",
407*bc55e2eaSThomas Huth                            test_docs_q35_virtio_serial);
408*bc55e2eaSThomas Huth         }
409*bc55e2eaSThomas Huth #endif
410335da811SThomas Huth     }
41101013d2cSThomas Huth #if defined(CONFIG_SPICE) && !defined(__FreeBSD__)
412f6a5f380SDaniel P. Berrangé     qtest_add_func("readconfig/spice", test_spice);
413f6a5f380SDaniel P. Berrangé #endif
414f6a5f380SDaniel P. Berrangé 
415f6a5f380SDaniel P. Berrangé     qtest_add_func("readconfig/object-rng", test_object_rng);
416f6a5f380SDaniel P. Berrangé 
417f6a5f380SDaniel P. Berrangé     return g_test_run();
418f6a5f380SDaniel P. Berrangé }
419