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"
16*407bc4bfSDaniel P. Berrangé #include "qobject/qdict.h"
17*407bc4bfSDaniel P. Berrangé #include "qobject/qlist.h"
18f6a5f380SDaniel P. Berrangé #include "qapi/qobject-input-visitor.h"
19*407bc4bfSDaniel P. Berrangé #include "qobject/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
200bc55e2eaSThomas Huth #if defined(CONFIG_POSIX) && defined(CONFIG_SLIRP)
201bc55e2eaSThomas Huth
make_temp_img(const char * template,const char * format,int size)202bc55e2eaSThomas Huth static char *make_temp_img(const char *template, const char *format, int size)
203bc55e2eaSThomas Huth {
204bc55e2eaSThomas Huth GError *error = NULL;
205bc55e2eaSThomas Huth char *temp_name;
206bc55e2eaSThomas Huth int fd;
207bc55e2eaSThomas Huth
208bc55e2eaSThomas Huth /* Create a temporary image names */
209bc55e2eaSThomas Huth fd = g_file_open_tmp(template, &temp_name, &error);
210bc55e2eaSThomas Huth if (fd == -1) {
211bc55e2eaSThomas Huth fprintf(stderr, "unable to create file: %s\n", error->message);
212bc55e2eaSThomas Huth g_error_free(error);
213bc55e2eaSThomas Huth return NULL;
214bc55e2eaSThomas Huth }
215bc55e2eaSThomas Huth close(fd);
216bc55e2eaSThomas Huth
217bc55e2eaSThomas Huth if (!mkimg(temp_name, format, size)) {
218bc55e2eaSThomas Huth fprintf(stderr, "qemu-img failed to create %s\n", temp_name);
219bc55e2eaSThomas Huth g_free(temp_name);
220bc55e2eaSThomas Huth return NULL;
221bc55e2eaSThomas Huth }
222bc55e2eaSThomas Huth
223bc55e2eaSThomas Huth return temp_name;
224bc55e2eaSThomas Huth }
225bc55e2eaSThomas Huth
226bc55e2eaSThomas Huth struct device {
227bc55e2eaSThomas Huth const char *name;
228bc55e2eaSThomas Huth const char *type;
229bc55e2eaSThomas Huth };
230bc55e2eaSThomas Huth
test_docs_q35(const char * input_file,struct device * devices)231bc55e2eaSThomas Huth static void test_docs_q35(const char *input_file, struct device *devices)
232bc55e2eaSThomas Huth {
233bc55e2eaSThomas Huth QTestState *qts;
234bc55e2eaSThomas Huth QDict *resp;
235bc55e2eaSThomas Huth QObject *qobj;
236bc55e2eaSThomas Huth int ret, i;
237bc55e2eaSThomas Huth g_autofree char *cfg_file = NULL, *sedcmd = NULL;
238bc55e2eaSThomas Huth g_autofree char *hd_file = NULL, *cd_file = NULL;
239bc55e2eaSThomas Huth
240bc55e2eaSThomas Huth /* Check that all the devices are available in the QEMU binary */
241bc55e2eaSThomas Huth for (i = 0; devices[i].name; i++) {
242bc55e2eaSThomas Huth if (!qtest_has_device(devices[i].type)) {
243bc55e2eaSThomas Huth g_test_skip("one of the required devices is not available");
244bc55e2eaSThomas Huth return;
245bc55e2eaSThomas Huth }
246bc55e2eaSThomas Huth }
247bc55e2eaSThomas Huth
248bc55e2eaSThomas Huth hd_file = make_temp_img("qtest_disk_XXXXXX.qcow2", "qcow2", 1);
249bc55e2eaSThomas Huth cd_file = make_temp_img("qtest_cdrom_XXXXXX.iso", "raw", 1);
250bc55e2eaSThomas Huth if (!hd_file || !cd_file) {
251bc55e2eaSThomas Huth g_test_skip("could not create disk images");
252bc55e2eaSThomas Huth goto cleanup;
253bc55e2eaSThomas Huth }
254bc55e2eaSThomas Huth
255bc55e2eaSThomas Huth /* Create a temporary config file where we replace the disk image names */
256bc55e2eaSThomas Huth ret = g_file_open_tmp("q35-emulated-XXXXXX.cfg", &cfg_file, NULL);
257bc55e2eaSThomas Huth if (ret == -1) {
258bc55e2eaSThomas Huth g_test_skip("could not create temporary config file");
259bc55e2eaSThomas Huth goto cleanup;
260bc55e2eaSThomas Huth }
261bc55e2eaSThomas Huth close(ret);
262bc55e2eaSThomas Huth
263bc55e2eaSThomas Huth sedcmd = g_strdup_printf("sed -e 's,guest.qcow2,%s,' -e 's,install.iso,%s,'"
264bc55e2eaSThomas Huth " %s %s > '%s'",
265bc55e2eaSThomas Huth hd_file, cd_file,
266bc55e2eaSThomas Huth !qtest_has_accel("kvm") ? "-e '/accel/d'" : "",
267bc55e2eaSThomas Huth input_file, cfg_file);
268bc55e2eaSThomas Huth ret = system(sedcmd);
269bc55e2eaSThomas Huth if (ret) {
270bc55e2eaSThomas Huth g_test_skip("could not modify temporary config file");
271bc55e2eaSThomas Huth goto cleanup;
272bc55e2eaSThomas Huth }
273bc55e2eaSThomas Huth
274bc55e2eaSThomas Huth qts = qtest_initf("-machine none -nodefaults -readconfig %s", cfg_file);
275bc55e2eaSThomas Huth
276bc55e2eaSThomas Huth /* Check memory size */
277bc55e2eaSThomas Huth resp = qtest_qmp(qts, "{ 'execute': 'query-memdev' }");
278bc55e2eaSThomas Huth test_x86_memdev_resp(qdict_get(resp, "return"), "pc.ram", 1024);
279bc55e2eaSThomas Huth qobject_unref(resp);
280bc55e2eaSThomas Huth
281bc55e2eaSThomas Huth resp = qtest_qmp(qts, "{ 'execute': 'qom-list',"
282bc55e2eaSThomas Huth " 'arguments': {'path': '/machine/peripheral' }}");
283bc55e2eaSThomas Huth qobj = qdict_get(resp, "return");
284bc55e2eaSThomas Huth
285bc55e2eaSThomas Huth /* Check that all the devices have been created */
286bc55e2eaSThomas Huth for (i = 0; devices[i].name; i++) {
287bc55e2eaSThomas Huth test_object_available(qobj, devices[i].name, devices[i].type);
288bc55e2eaSThomas Huth }
289bc55e2eaSThomas Huth
290bc55e2eaSThomas Huth qobject_unref(resp);
291bc55e2eaSThomas Huth
292bc55e2eaSThomas Huth qtest_quit(qts);
293bc55e2eaSThomas Huth
294bc55e2eaSThomas Huth cleanup:
295bc55e2eaSThomas Huth if (hd_file) {
296bc55e2eaSThomas Huth unlink(hd_file);
297bc55e2eaSThomas Huth }
298bc55e2eaSThomas Huth if (cd_file) {
299bc55e2eaSThomas Huth unlink(cd_file);
300bc55e2eaSThomas Huth }
301bc55e2eaSThomas Huth if (cfg_file) {
302bc55e2eaSThomas Huth unlink(cfg_file);
303bc55e2eaSThomas Huth }
304bc55e2eaSThomas Huth }
305bc55e2eaSThomas Huth
test_docs_q35_emulated(void)306bc55e2eaSThomas Huth static void test_docs_q35_emulated(void)
307bc55e2eaSThomas Huth {
308bc55e2eaSThomas Huth struct device devices[] = {
309bc55e2eaSThomas Huth { "ich9-pcie-port-1", "ioh3420" },
310bc55e2eaSThomas Huth { "ich9-pcie-port-2", "ioh3420" },
311bc55e2eaSThomas Huth { "ich9-pcie-port-3", "ioh3420" },
312bc55e2eaSThomas Huth { "ich9-pcie-port-4", "ioh3420" },
313bc55e2eaSThomas Huth { "ich9-pci-bridge", "i82801b11-bridge" },
314bc55e2eaSThomas Huth { "ich9-ehci-1", "ich9-usb-ehci1" },
315bc55e2eaSThomas Huth { "ich9-ehci-2", "ich9-usb-ehci2" },
316bc55e2eaSThomas Huth { "ich9-uhci-1", "ich9-usb-uhci1" },
317bc55e2eaSThomas Huth { "ich9-uhci-2", "ich9-usb-uhci2" },
318bc55e2eaSThomas Huth { "ich9-uhci-3", "ich9-usb-uhci3" },
319bc55e2eaSThomas Huth { "ich9-uhci-4", "ich9-usb-uhci4" },
320bc55e2eaSThomas Huth { "ich9-uhci-5", "ich9-usb-uhci5" },
321bc55e2eaSThomas Huth { "ich9-uhci-6", "ich9-usb-uhci6" },
322bc55e2eaSThomas Huth { "sata-disk", "ide-hd" },
323bc55e2eaSThomas Huth { "sata-optical-disk", "ide-cd" },
324bc55e2eaSThomas Huth { "net", "e1000" },
325bc55e2eaSThomas Huth { "video", "VGA" },
326bc55e2eaSThomas Huth { "ich9-hda-audio", "ich9-intel-hda" },
327bc55e2eaSThomas Huth { "ich9-hda-duplex", "hda-duplex" },
328bc55e2eaSThomas Huth { NULL, NULL }
329bc55e2eaSThomas Huth };
330bc55e2eaSThomas Huth
331bc55e2eaSThomas Huth test_docs_q35("docs/config/q35-emulated.cfg", devices);
332bc55e2eaSThomas Huth }
333bc55e2eaSThomas Huth
test_docs_q35_virtio_graphical(void)334bc55e2eaSThomas Huth static void test_docs_q35_virtio_graphical(void)
335bc55e2eaSThomas Huth {
336bc55e2eaSThomas Huth struct device devices[] = {
337bc55e2eaSThomas Huth { "pcie.1", "pcie-root-port" },
338bc55e2eaSThomas Huth { "pcie.2", "pcie-root-port" },
339bc55e2eaSThomas Huth { "pcie.3", "pcie-root-port" },
340bc55e2eaSThomas Huth { "pcie.4", "pcie-root-port" },
341bc55e2eaSThomas Huth { "pcie.5", "pcie-root-port" },
342bc55e2eaSThomas Huth { "pcie.6", "pcie-root-port" },
343bc55e2eaSThomas Huth { "pcie.7", "pcie-root-port" },
344bc55e2eaSThomas Huth { "pcie.8", "pcie-root-port" },
345bc55e2eaSThomas Huth { "scsi", "virtio-scsi-pci" },
346bc55e2eaSThomas Huth { "scsi-disk", "scsi-hd" },
347bc55e2eaSThomas Huth { "scsi-optical-disk", "scsi-cd" },
348bc55e2eaSThomas Huth { "net", "virtio-net-pci" },
349bc55e2eaSThomas Huth { "usb", "nec-usb-xhci" },
350bc55e2eaSThomas Huth { "tablet", "usb-tablet" },
351bc55e2eaSThomas Huth { "video", "qxl-vga" },
352bc55e2eaSThomas Huth { "sound", "ich9-intel-hda" },
353bc55e2eaSThomas Huth { "duplex", "hda-duplex" },
354bc55e2eaSThomas Huth { NULL, NULL }
355bc55e2eaSThomas Huth };
356bc55e2eaSThomas Huth
357bc55e2eaSThomas Huth test_docs_q35("docs/config/q35-virtio-graphical.cfg", devices);
358bc55e2eaSThomas Huth }
359bc55e2eaSThomas Huth
test_docs_q35_virtio_serial(void)360bc55e2eaSThomas Huth static void test_docs_q35_virtio_serial(void)
361bc55e2eaSThomas Huth {
362bc55e2eaSThomas Huth struct device devices[] = {
363bc55e2eaSThomas Huth { "pcie.1", "pcie-root-port" },
364bc55e2eaSThomas Huth { "pcie.2", "pcie-root-port" },
365bc55e2eaSThomas Huth { "pcie.3", "pcie-root-port" },
366bc55e2eaSThomas Huth { "pcie.4", "pcie-root-port" },
367bc55e2eaSThomas Huth { "pcie.5", "pcie-root-port" },
368bc55e2eaSThomas Huth { "pcie.6", "pcie-root-port" },
369bc55e2eaSThomas Huth { "pcie.7", "pcie-root-port" },
370bc55e2eaSThomas Huth { "pcie.8", "pcie-root-port" },
371bc55e2eaSThomas Huth { "scsi", "virtio-scsi-pci" },
372bc55e2eaSThomas Huth { "scsi-disk", "scsi-hd" },
373bc55e2eaSThomas Huth { "scsi-optical-disk", "scsi-cd" },
374bc55e2eaSThomas Huth { "net", "virtio-net-pci" },
375bc55e2eaSThomas Huth { NULL, NULL }
376bc55e2eaSThomas Huth };
377bc55e2eaSThomas Huth
378bc55e2eaSThomas Huth test_docs_q35("docs/config/q35-virtio-serial.cfg", devices);
379bc55e2eaSThomas Huth }
380bc55e2eaSThomas Huth
381bc55e2eaSThomas Huth #endif /* CONFIG_LINUX */
382bc55e2eaSThomas 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é }
397bc55e2eaSThomas Huth #if defined(CONFIG_POSIX) && defined(CONFIG_SLIRP)
398bc55e2eaSThomas Huth qtest_add_func("readconfig/x86/q35-emulated", test_docs_q35_emulated);
399bc55e2eaSThomas Huth qtest_add_func("readconfig/x86/q35-virtio-graphical",
400bc55e2eaSThomas Huth test_docs_q35_virtio_graphical);
401bc55e2eaSThomas Huth if (g_test_slow()) {
402bc55e2eaSThomas Huth /*
403bc55e2eaSThomas Huth * q35-virtio-serial.cfg is a subset of q35-virtio-graphical.cfg,
404bc55e2eaSThomas Huth * so we can skip the test in quick mode
405bc55e2eaSThomas Huth */
406bc55e2eaSThomas Huth qtest_add_func("readconfig/x86/q35-virtio-serial",
407bc55e2eaSThomas Huth test_docs_q35_virtio_serial);
408bc55e2eaSThomas Huth }
409bc55e2eaSThomas 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