Add error message if Xwayland dies out of tests & Refactors

This commit is contained in:
En-En 2025-03-13 23:58:31 +00:00 committed by Shawn Wallace
parent 0325cb1f48
commit d4dcee4e8d
3 changed files with 27 additions and 25 deletions

View file

@ -11,7 +11,7 @@ use smithay_client_toolkit::data_device_manager::WritePipe;
use std::io::{BufRead, BufReader, Read, Write}; use std::io::{BufRead, BufReader, Read, Write};
use std::os::fd::{AsFd, AsRawFd, BorrowedFd}; use std::os::fd::{AsFd, AsRawFd, BorrowedFd};
use std::os::unix::net::UnixStream; use std::os::unix::net::UnixStream;
use std::process::{Command, Stdio}; use std::process::{Command, ExitStatus, Stdio};
use wayland_server::{Display, ListeningSocket}; use wayland_server::{Display, ListeningSocket};
use xcb::x; use xcb::x;
@ -41,7 +41,7 @@ pub trait RunData {
} }
fn created_server(&self) {} fn created_server(&self) {}
fn connected_server(&self) {} fn connected_server(&self) {}
fn quit_rx(&self) -> Option<&UnixStream> { fn quit_rx(&self) -> Option<UnixStream> {
None None
} }
fn xwayland_ready(&self, _display: String, _pid: u32) {} fn xwayland_ready(&self, _display: String, _pid: u32) {}
@ -98,15 +98,17 @@ pub fn main(data: impl RunData) -> Option<()> {
PollFd::new(&finish_rx, PollFlags::IN), PollFd::new(&finish_rx, PollFlags::IN),
]; ];
fn xwayland_exit_code(rx: &mut UnixStream) -> Box<ExitStatus> {
let mut data = [0; (usize::BITS / 8) as usize];
rx.read_exact(&mut data).unwrap();
let data = usize::from_ne_bytes(data);
unsafe { Box::from_raw(data as *mut _) }
}
let connection = match poll(&mut ready_fds, -1) { let connection = match poll(&mut ready_fds, -1) {
Ok(_) => { Ok(_) => {
if !ready_fds[1].revents().is_empty() { if !ready_fds[1].revents().is_empty() {
let mut data = [0; (usize::BITS / 8) as usize]; let status = xwayland_exit_code(&mut finish_rx);
finish_rx.read_exact(&mut data).unwrap();
let data = usize::from_ne_bytes(data);
let status: Box<std::process::ExitStatus> =
unsafe { Box::from_raw(data as *mut _) };
error!("Xwayland exited early with {status}"); error!("Xwayland exited early with {status}");
return None; return None;
} }
@ -131,14 +133,18 @@ pub fn main(data: impl RunData) -> Option<()> {
// `finish_rx` only writes the status code of `Xwayland` exiting, so it is reasonable to use as // `finish_rx` only writes the status code of `Xwayland` exiting, so it is reasonable to use as
// the UnixStream of choice when not running the integration tests. // the UnixStream of choice when not running the integration tests.
let quit_rx = data.quit_rx().unwrap_or(&finish_rx); let (mut quit_rx, is_test_thread) = if let Some(quit_rx) = data.quit_rx() {
(quit_rx, true)
} else {
(finish_rx, false)
};
let mut fds = [ let mut fds = [
PollFd::from_borrowed_fd(server_fd, PollFlags::IN), PollFd::from_borrowed_fd(server_fd, PollFlags::IN),
PollFd::new(&xsock_wl, PollFlags::IN), PollFd::new(&xsock_wl, PollFlags::IN),
PollFd::from_borrowed_fd(display_fd, PollFlags::IN), PollFd::from_borrowed_fd(display_fd, PollFlags::IN),
PollFd::new(&ready_rx, PollFlags::IN), PollFd::new(&ready_rx, PollFlags::IN),
PollFd::new(quit_rx, PollFlags::IN), PollFd::new(&quit_rx, PollFlags::IN),
]; ];
let mut ready = false; let mut ready = false;
@ -149,6 +155,10 @@ pub fn main(data: impl RunData) -> Option<()> {
ready = true; ready = true;
} }
if !fds[4].revents().is_empty() { if !fds[4].revents().is_empty() {
if !is_test_thread {
let status = xwayland_exit_code(&mut quit_rx);
error!("Xwayland exited early with {status}");
}
return None; return None;
} }
} }

View file

@ -23,7 +23,7 @@ struct TestDataInner {
display: Mutex<Option<String>>, display: Mutex<Option<String>>,
server: Mutex<Option<UnixStream>>, server: Mutex<Option<UnixStream>>,
pid: Mutex<Option<u32>>, pid: Mutex<Option<u32>>,
quit_rx: Option<UnixStream>, quit_rx: Mutex<Option<UnixStream>>,
} }
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -33,7 +33,7 @@ impl TestData {
fn new(server: UnixStream, quit_rx: UnixStream) -> Self { fn new(server: UnixStream, quit_rx: UnixStream) -> Self {
Self(Arc::new(TestDataInner { Self(Arc::new(TestDataInner {
server: Mutex::new(server.into()), server: Mutex::new(server.into()),
quit_rx: Some(quit_rx), quit_rx: Mutex::new(Some(quit_rx)),
..Default::default() ..Default::default()
})) }))
} }
@ -55,8 +55,8 @@ impl xwls::RunData for TestData {
self.server_connected.store(true, Ordering::Relaxed); self.server_connected.store(true, Ordering::Relaxed);
} }
fn quit_rx(&self) -> Option<&UnixStream> { fn quit_rx(&self) -> Option<UnixStream> {
self.quit_rx.as_ref() self.quit_rx.lock().unwrap().take()
} }
fn xwayland_ready(&self, display: String, pid: u32) { fn xwayland_ready(&self, display: String, pid: u32) {
@ -825,7 +825,6 @@ fn quick_delete() {
assert_eq!(f.testwl.get_surface_data(surf), None); assert_eq!(f.testwl.get_surface_data(surf), None);
} }
// aaaaaaaaaa
#[test] #[test]
fn copy_from_x11() { fn copy_from_x11() {
let mut f = Fixture::new(); let mut f = Fixture::new();
@ -1064,13 +1063,7 @@ fn bad_clipboard_data() {
let mut f = Fixture::new(); let mut f = Fixture::new();
let mut connection = Connection::new(&f.display); let mut connection = Connection::new(&f.display);
let window = connection.new_window(connection.root, 0, 0, 20, 20, false); let window = connection.new_window(connection.root, 0, 0, 20, 20, false);
connection.map_window(window); f.map_as_toplevel(&mut connection, window);
f.wait_and_dispatch();
let surface = f
.testwl
.last_created_surface_id()
.expect("No surface created");
f.configure_and_verify_new_toplevel(&mut connection, window, surface);
connection.set_selection_owner(window); connection.set_selection_owner(window);
let request = connection.await_selection_request(); let request = connection.await_selection_request();

View file

@ -411,7 +411,7 @@ impl Server {
if noops { if noops {
dh.backend_handle() dh.backend_handle()
.create_global(&interface, interface.version, Arc::new(Handler)); .create_global(interface, interface.version, Arc::new(Handler));
} }
Self { Self {
@ -579,8 +579,7 @@ impl Server {
} }
}; };
while !pending_ret.is_empty() { while let Some((mime, pending)) = pending_ret.pop() {
let (mime, pending) = pending_ret.pop().unwrap();
match pending { match pending {
Some(pending) => try_transfer(&mut pending_ret, mime, pending), Some(pending) => try_transfer(&mut pending_ret, mime, pending),
None => { None => {