Skip to content

Commit b7be698

Browse files
committed
gio: Add test for DBus method calls over a UNIX fd pair
1 parent d2958b5 commit b7be698

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed

gio/tests/dbus_peer.rs

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Take a look at the license at the top of the repository in the LICENSE file.
2+
3+
#[cfg(unix)]
4+
#[test]
5+
fn test_gdbus_peer_connection() {
6+
use gio::{
7+
glib::{self, VariantTy},
8+
prelude::*,
9+
DBusConnection, DBusConnectionFlags, DBusNodeInfo, Socket,
10+
};
11+
use std::os::{fd::IntoRawFd, unix::net::UnixStream};
12+
13+
const EXAMPLE_XML: &str = r#"
14+
<node>
15+
<interface name='com.github.gtk_rs'>
16+
<method name='Hello'>
17+
<arg type='s' name='name' direction='in'/>
18+
<arg type='s' name='greet' direction='out'/>
19+
</method>
20+
</interface>
21+
</node>
22+
"#;
23+
24+
pub async fn spawn_server(fd: UnixStream) -> DBusConnection {
25+
let socket = unsafe { Socket::from_fd(fd.into_raw_fd()) }.unwrap();
26+
let socket_connection = socket.connection_factory_create_connection();
27+
28+
let guid = gio::dbus_generate_guid();
29+
30+
dbg!("server connecting");
31+
32+
let connection = DBusConnection::new_future(
33+
&socket_connection,
34+
Some(&guid),
35+
DBusConnectionFlags::AUTHENTICATION_SERVER
36+
.union(DBusConnectionFlags::DELAY_MESSAGE_PROCESSING),
37+
None,
38+
)
39+
.await
40+
.unwrap();
41+
42+
dbg!("server connected");
43+
44+
let interface_info = DBusNodeInfo::for_xml(EXAMPLE_XML)
45+
.unwrap()
46+
.lookup_interface("com.github.gtk_rs")
47+
.unwrap();
48+
49+
let _id = connection
50+
.register_object("/com/github/gtk_rs", &interface_info)
51+
.method_call(
52+
|_connection,
53+
_sender,
54+
_object_path,
55+
_interface_name,
56+
_method_name,
57+
parameters,
58+
invocation| {
59+
dbg!(
60+
_sender,
61+
_object_path,
62+
_interface_name,
63+
_method_name,
64+
&parameters,
65+
&invocation
66+
);
67+
68+
let name = parameters.child_get::<String>(0);
69+
invocation.return_value(Some(&(format!("Hello {name}!"),).to_variant()));
70+
},
71+
)
72+
.build()
73+
.unwrap();
74+
75+
dbg!("server starts message processing");
76+
77+
connection.start_message_processing();
78+
79+
dbg!("server awaiting calls");
80+
81+
connection
82+
}
83+
84+
pub async fn spawn_client(fd: UnixStream) -> DBusConnection {
85+
let socket_client = unsafe { Socket::from_fd(fd.into_raw_fd()) }.unwrap();
86+
let socket_connection_client = socket_client.connection_factory_create_connection();
87+
88+
dbg!("client connecting");
89+
90+
let connection = DBusConnection::new_future(
91+
&socket_connection_client,
92+
None,
93+
DBusConnectionFlags::AUTHENTICATION_CLIENT,
94+
None,
95+
)
96+
.await
97+
.unwrap();
98+
99+
dbg!("client connected");
100+
101+
connection
102+
}
103+
104+
let ctx = glib::MainContext::default();
105+
106+
let (x, y) = std::os::unix::net::UnixStream::pair().unwrap();
107+
108+
x.set_nonblocking(true).unwrap();
109+
y.set_nonblocking(true).unwrap();
110+
111+
ctx.block_on(async move {
112+
let ctx = glib::MainContext::default();
113+
114+
let server = ctx.spawn_local(spawn_server(x));
115+
let client = ctx.spawn_local(spawn_client(y));
116+
117+
let server = server.await.unwrap();
118+
let client = client.await.unwrap();
119+
120+
dbg!("calling method");
121+
122+
let result = client
123+
.call_future(
124+
None,
125+
"/com/github/gtk_rs",
126+
"com.github.gtk_rs",
127+
"Hello",
128+
Some(&("World",).into()),
129+
Some(VariantTy::new("(s)").unwrap()),
130+
gio::DBusCallFlags::NONE,
131+
10000,
132+
)
133+
.await
134+
.unwrap();
135+
136+
dbg!("method called");
137+
138+
dbg!(&result);
139+
140+
dbg!("closing client");
141+
client.close_future().await.unwrap();
142+
dbg!("closed client, closing server");
143+
server.close_future().await.unwrap();
144+
dbg!("closed server");
145+
146+
drop(client);
147+
drop(server);
148+
149+
assert_eq!(result.child_get::<String>(0), "Hello World!");
150+
151+
glib::timeout_future_with_priority(
152+
glib::Priority::LOW,
153+
std::time::Duration::from_millis(50),
154+
)
155+
.await;
156+
});
157+
}

0 commit comments

Comments
 (0)