1 #include "qemu/osdep.h"
2 #include "qemu/sockets.h"
4 #include "qemu/sockets.h"
6 #include <gio/gunixfdlist.h>
8 #include "ui/dbus-display1.h"
10 static GDBusConnection
*
11 test_dbus_p2p_from_fd(int fd
)
13 g_autoptr(GError
) err
= NULL
;
14 g_autoptr(GSocket
) socket
= NULL
;
15 g_autoptr(GSocketConnection
) socketc
= NULL
;
16 GDBusConnection
*conn
;
19 socket
= g_socket_new_from_fd(_get_osfhandle(fd
), &err
);
21 socket
= g_socket_new_from_fd(fd
, &err
);
23 g_assert_no_error(err
);
25 socketc
= g_socket_connection_factory_create_connection(socket
);
26 g_assert(socketc
!= NULL
);
28 conn
= g_dbus_connection_new_sync(
29 G_IO_STREAM(socketc
), NULL
,
30 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT
|
31 G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING
,
33 g_assert_no_error(err
);
39 test_setup(QTestState
**qts
, GDBusConnection
**conn
)
43 *qts
= qtest_init("-display dbus,p2p=yes -name dbus-test");
45 g_assert_cmpint(qemu_socketpair(AF_UNIX
, SOCK_STREAM
, 0, pair
), ==, 0);
47 qtest_qmp_add_client(*qts
, "@dbus-display", pair
[1]);
49 *conn
= test_dbus_p2p_from_fd(pair
[0]);
50 g_dbus_connection_start_message_processing(*conn
);
54 test_dbus_display_vm(void)
56 g_autoptr(GError
) err
= NULL
;
57 g_autoptr(GDBusConnection
) conn
= NULL
;
58 g_autoptr(QemuDBusDisplay1VMProxy
) vm
= NULL
;
59 QTestState
*qts
= NULL
;
61 test_setup(&qts
, &conn
);
63 vm
= QEMU_DBUS_DISPLAY1_VM_PROXY(
64 qemu_dbus_display1_vm_proxy_new_sync(
66 G_DBUS_PROXY_FLAGS_NONE
,
68 DBUS_DISPLAY1_ROOT
"/VM",
71 g_assert_no_error(err
);
74 qemu_dbus_display1_vm_get_name(QEMU_DBUS_DISPLAY1_VM(vm
)),
80 typedef struct TestDBusConsoleRegister
{
83 GDBusConnection
*listener_conn
;
84 GDBusObjectManagerServer
*server
;
85 } TestDBusConsoleRegister
;
87 static gboolean
listener_handle_scanout(
88 QemuDBusDisplay1Listener
*object
,
89 GDBusMethodInvocation
*invocation
,
93 guint arg_pixman_format
,
95 TestDBusConsoleRegister
*test
)
97 g_main_loop_quit(test
->loop
);
99 return DBUS_METHOD_INVOCATION_HANDLED
;
103 test_dbus_console_setup_listener(TestDBusConsoleRegister
*test
)
105 g_autoptr(GDBusObjectSkeleton
) listener
= NULL
;
106 g_autoptr(QemuDBusDisplay1ListenerSkeleton
) iface
= NULL
;
108 test
->server
= g_dbus_object_manager_server_new(DBUS_DISPLAY1_ROOT
);
109 listener
= g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT
"/Listener");
110 iface
= QEMU_DBUS_DISPLAY1_LISTENER_SKELETON(
111 qemu_dbus_display1_listener_skeleton_new());
112 g_object_connect(iface
,
113 "signal::handle-scanout", listener_handle_scanout
, test
,
115 g_dbus_object_skeleton_add_interface(listener
,
116 G_DBUS_INTERFACE_SKELETON(iface
));
117 g_dbus_object_manager_server_export(test
->server
, listener
);
118 g_dbus_object_manager_server_set_connection(test
->server
,
119 test
->listener_conn
);
121 g_dbus_connection_start_message_processing(test
->listener_conn
);
125 test_dbus_console_registered(GObject
*source_object
,
129 TestDBusConsoleRegister
*test
= user_data
;
130 g_autoptr(GError
) err
= NULL
;
132 qemu_dbus_display1_console_call_register_listener_finish(
133 QEMU_DBUS_DISPLAY1_CONSOLE(source_object
),
139 if (g_error_matches(err
, G_DBUS_ERROR
, G_DBUS_ERROR_UNKNOWN_METHOD
)) {
140 g_test_skip("The VM doesn't have a console!");
141 g_main_loop_quit(test
->loop
);
145 g_assert_no_error(err
);
147 test
->listener_conn
= g_thread_join(test
->thread
);
148 test_dbus_console_setup_listener(test
);
152 test_dbus_p2p_server_setup_thread(gpointer data
)
154 return test_dbus_p2p_from_fd(GPOINTER_TO_INT(data
));
158 test_dbus_display_console(void)
160 g_autoptr(GError
) err
= NULL
;
161 g_autoptr(GDBusConnection
) conn
= NULL
;
162 g_autoptr(QemuDBusDisplay1ConsoleProxy
) console
= NULL
;
163 g_autoptr(GMainLoop
) loop
= NULL
;
164 QTestState
*qts
= NULL
;
166 TestDBusConsoleRegister test
= { 0, };
168 WSAPROTOCOL_INFOW info
;
169 g_autoptr(GVariant
) listener
= NULL
;
171 g_autoptr(GUnixFDList
) fd_list
= NULL
;
175 test_setup(&qts
, &conn
);
177 g_assert_cmpint(qemu_socketpair(AF_UNIX
, SOCK_STREAM
, 0, pair
), ==, 0);
179 fd_list
= g_unix_fd_list_new();
180 idx
= g_unix_fd_list_append(fd_list
, pair
[1], NULL
);
183 console
= QEMU_DBUS_DISPLAY1_CONSOLE_PROXY(
184 qemu_dbus_display1_console_proxy_new_sync(
186 G_DBUS_PROXY_FLAGS_NONE
,
188 "/org/qemu/Display1/Console_0",
191 g_assert_no_error(err
);
193 test
.loop
= loop
= g_main_loop_new(NULL
, FALSE
);
194 test
.thread
= g_thread_new(NULL
, test_dbus_p2p_server_setup_thread
,
195 GINT_TO_POINTER(pair
[0]));
198 if (WSADuplicateSocketW(_get_osfhandle(pair
[1]),
199 GetProcessId((HANDLE
) qtest_pid(qts
)),
200 &info
) == SOCKET_ERROR
)
202 g_autofree
char *emsg
= g_win32_error_message(WSAGetLastError());
203 g_error("WSADuplicateSocket failed: %s", emsg
);
206 listener
= g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE
,
212 qemu_dbus_display1_console_call_register_listener(
213 QEMU_DBUS_DISPLAY1_CONSOLE(console
),
217 g_variant_new_handle(idx
),
219 G_DBUS_CALL_FLAGS_NONE
,
225 test_dbus_console_registered
,
228 g_main_loop_run(loop
);
230 g_clear_object(&test
.server
);
231 g_clear_object(&test
.listener_conn
);
236 test_dbus_display_keyboard(void)
238 g_autoptr(GError
) err
= NULL
;
239 g_autoptr(GDBusConnection
) conn
= NULL
;
240 g_autoptr(QemuDBusDisplay1KeyboardProxy
) keyboard
= NULL
;
241 QTestState
*qts
= NULL
;
243 test_setup(&qts
, &conn
);
245 keyboard
= QEMU_DBUS_DISPLAY1_KEYBOARD_PROXY(
246 qemu_dbus_display1_keyboard_proxy_new_sync(
248 G_DBUS_PROXY_FLAGS_NONE
,
250 "/org/qemu/Display1/Console_0",
253 g_assert_no_error(err
);
255 g_assert_cmpint(qtest_inb(qts
, 0x64) & 0x1, ==, 0);
256 g_assert_cmpint(qtest_inb(qts
, 0x60), ==, 0);
258 qemu_dbus_display1_keyboard_call_press_sync(
259 QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard
),
260 0x1C, /* qnum enter */
261 G_DBUS_CALL_FLAGS_NONE
,
265 if (g_error_matches(err
, G_DBUS_ERROR
, G_DBUS_ERROR_UNKNOWN_METHOD
)) {
266 g_test_skip("The VM doesn't have a console!");
271 g_assert_no_error(err
);
273 /* may be should wait for interrupt? */
274 g_assert_cmpint(qtest_inb(qts
, 0x64) & 0x1, ==, 1);
275 g_assert_cmpint(qtest_inb(qts
, 0x60), ==, 0x5A); /* scan code 2 enter */
277 qemu_dbus_display1_keyboard_call_release_sync(
278 QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard
),
279 0x1C, /* qnum enter */
280 G_DBUS_CALL_FLAGS_NONE
,
284 g_assert_no_error(err
);
286 g_assert_cmpint(qtest_inb(qts
, 0x64) & 0x1, ==, 1);
287 g_assert_cmpint(qtest_inb(qts
, 0x60), ==, 0xF0); /* scan code 2 release */
288 g_assert_cmpint(qtest_inb(qts
, 0x60), ==, 0x5A); /* scan code 2 enter */
290 g_assert_cmpint(qemu_dbus_display1_keyboard_get_modifiers(
291 QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard
)), ==, 0);
297 main(int argc
, char **argv
)
299 g_test_init(&argc
, &argv
, NULL
);
301 qtest_add_func("/dbus-display/vm", test_dbus_display_vm
);
302 qtest_add_func("/dbus-display/console", test_dbus_display_console
);
303 qtest_add_func("/dbus-display/keyboard", test_dbus_display_keyboard
);