Add a qtest that starts a q35 machine with thunderbolt-root-port and
verifies that regular VGA remains non-hotpluggable while thunderbolt-vga
can be hotplugged behind the Thunderbolt root port.

The test also checks the constrained thunderbolt-vga display defaults used
by the macOS validation flow.

Signed-off-by: Dmitry R <[email protected]>
---
 tests/qtest/display-vga-test.c | 68 ++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/tests/qtest/display-vga-test.c b/tests/qtest/display-vga-test.c
index 75b341a9c6..c5f526a56e 100644
--- a/tests/qtest/display-vga-test.c
+++ b/tests/qtest/display-vga-test.c
@@ -9,6 +9,21 @@
 
 #include "qemu/osdep.h"
 #include "libqtest.h"
+#include "qobject/qdict.h"
+
+static void assert_qom_uint(QTestState *qts, const char *path,
+                            const char *property, uint64_t expected)
+{
+    QDict *rsp;
+
+    rsp = qtest_qmp(qts, "{ 'execute': 'qom-get', 'arguments': {"
+                          "'path': %s,"
+                          "'property': %s"
+                          "} }", path, property);
+    g_assert(qdict_haskey(rsp, "return"));
+    g_assert_cmpuint(qdict_get_uint(rsp, "return"), ==, expected);
+    qobject_unref(rsp);
+}
 
 static void pci_multihead(void)
 {
@@ -18,6 +33,51 @@ static void pci_multihead(void)
     qtest_quit(qts);
 }
 
+static void thunderbolt_vga_hotplug(void)
+{
+    QTestState *qts;
+    QDict *rsp;
+    QDict *err;
+
+    qts = qtest_init("-machine q35 -display none -nodefaults -vga none "
+                     "-device VGA,id=bootvga,bus=pcie.0,addr=0x02 "
+                     "-device thunderbolt-root-port,id=tbrp0,bus=pcie.0,"
+                     "chassis=1,slot=1,addr=0x05");
+
+    rsp = qtest_qmp(qts, "{ 'execute': 'device_add', "
+                          "'arguments': {"
+                          "'driver': 'VGA',"
+                          "'id': 'badstd',"
+                          "'bus': 'tbrp0',"
+                          "'addr': '0x01'"
+                          "} }");
+    g_assert(qdict_haskey(rsp, "error"));
+    err = qdict_get_qdict(rsp, "error");
+    g_assert_cmpstr(qdict_get_str(err, "desc"), ==,
+                    "Device 'VGA' does not support hotplugging");
+    qobject_unref(rsp);
+
+    rsp = qtest_qmp(qts, "{ 'execute': 'device_add', "
+                          "'arguments': {"
+                          "'driver': 'thunderbolt-vga',"
+                          "'id': 'tbvga0',"
+                          "'bus': 'tbrp0',"
+                          "'addr': '0x00'"
+                          "} }");
+    g_assert(qdict_haskey(rsp, "return"));
+    g_assert(!qdict_haskey(rsp, "error"));
+    qobject_unref(rsp);
+
+    assert_qom_uint(qts, "/machine/peripheral/tbvga0", "vgamem_mb", 4);
+    assert_qom_uint(qts, "/machine/peripheral/tbvga0", "xres", 1280);
+    assert_qom_uint(qts, "/machine/peripheral/tbvga0", "yres", 800);
+    assert_qom_uint(qts, "/machine/peripheral/tbvga0", "xmax", 1280);
+    assert_qom_uint(qts, "/machine/peripheral/tbvga0", "ymax", 800);
+    assert_qom_uint(qts, "/machine/peripheral/tbvga0", "refresh_rate", 60000);
+
+    qtest_quit(qts);
+}
+
 static void test_vga(gconstpointer data)
 {
     QTestState *qts;
@@ -31,6 +91,7 @@ int main(int argc, char **argv)
     static const char *devices[] = {
         "cirrus-vga",
         "VGA",
+        "thunderbolt-vga",
         "secondary-vga",
         "virtio-gpu-pci",
         "virtio-vga"
@@ -50,5 +111,12 @@ int main(int argc, char **argv)
         qtest_add_func("/display/pci/multihead", pci_multihead);
     }
 
+    if (qtest_has_machine("q35") &&
+        qtest_has_device("thunderbolt-root-port") &&
+        qtest_has_device("thunderbolt-vga")) {
+        qtest_add_func("/display/pci/thunderbolt-vga-hotplug",
+                       thunderbolt_vga_hotplug);
+    }
+
     return g_test_run();
 }
-- 
2.47.3


Reply via email to