From d4dcee4e8ddba1496fcdd0aa66fff1af8c005ac7 Mon Sep 17 00:00:00 2001 From: En-En <39373446+En-En-Code@users.noreply.github.com> Date: Thu, 13 Mar 2025 23:58:31 +0000 Subject: [PATCH] Add error message if Xwayland dies out of tests & Refactors --- src/lib.rs | 30 ++++++++++++++++++++---------- tests/integration.rs | 17 +++++------------ testwl/src/lib.rs | 5 ++--- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8c3982c..cc95dbe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ use smithay_client_toolkit::data_device_manager::WritePipe; use std::io::{BufRead, BufReader, Read, Write}; use std::os::fd::{AsFd, AsRawFd, BorrowedFd}; use std::os::unix::net::UnixStream; -use std::process::{Command, Stdio}; +use std::process::{Command, ExitStatus, Stdio}; use wayland_server::{Display, ListeningSocket}; use xcb::x; @@ -41,7 +41,7 @@ pub trait RunData { } fn created_server(&self) {} fn connected_server(&self) {} - fn quit_rx(&self) -> Option<&UnixStream> { + fn quit_rx(&self) -> Option { None } 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), ]; + fn xwayland_exit_code(rx: &mut UnixStream) -> Box { + 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) { Ok(_) => { if !ready_fds[1].revents().is_empty() { - let mut data = [0; (usize::BITS / 8) as usize]; - finish_rx.read_exact(&mut data).unwrap(); - let data = usize::from_ne_bytes(data); - let status: Box = - unsafe { Box::from_raw(data as *mut _) }; - + let status = xwayland_exit_code(&mut finish_rx); error!("Xwayland exited early with {status}"); 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 // 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 = [ PollFd::from_borrowed_fd(server_fd, PollFlags::IN), PollFd::new(&xsock_wl, PollFlags::IN), PollFd::from_borrowed_fd(display_fd, PollFlags::IN), PollFd::new(&ready_rx, PollFlags::IN), - PollFd::new(quit_rx, PollFlags::IN), + PollFd::new(&quit_rx, PollFlags::IN), ]; let mut ready = false; @@ -149,6 +155,10 @@ pub fn main(data: impl RunData) -> Option<()> { ready = true; } 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; } } diff --git a/tests/integration.rs b/tests/integration.rs index 9cad70a..540b94d 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -23,7 +23,7 @@ struct TestDataInner { display: Mutex>, server: Mutex>, pid: Mutex>, - quit_rx: Option, + quit_rx: Mutex>, } #[derive(Default, Clone)] @@ -33,7 +33,7 @@ impl TestData { fn new(server: UnixStream, quit_rx: UnixStream) -> Self { Self(Arc::new(TestDataInner { server: Mutex::new(server.into()), - quit_rx: Some(quit_rx), + quit_rx: Mutex::new(Some(quit_rx)), ..Default::default() })) } @@ -55,8 +55,8 @@ impl xwls::RunData for TestData { self.server_connected.store(true, Ordering::Relaxed); } - fn quit_rx(&self) -> Option<&UnixStream> { - self.quit_rx.as_ref() + fn quit_rx(&self) -> Option { + self.quit_rx.lock().unwrap().take() } fn xwayland_ready(&self, display: String, pid: u32) { @@ -825,7 +825,6 @@ fn quick_delete() { assert_eq!(f.testwl.get_surface_data(surf), None); } -// aaaaaaaaaa #[test] fn copy_from_x11() { let mut f = Fixture::new(); @@ -1064,13 +1063,7 @@ fn bad_clipboard_data() { let mut f = Fixture::new(); let mut connection = Connection::new(&f.display); let window = connection.new_window(connection.root, 0, 0, 20, 20, false); - connection.map_window(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); + f.map_as_toplevel(&mut connection, window); connection.set_selection_owner(window); let request = connection.await_selection_request(); diff --git a/testwl/src/lib.rs b/testwl/src/lib.rs index 734274a..7feed28 100644 --- a/testwl/src/lib.rs +++ b/testwl/src/lib.rs @@ -411,7 +411,7 @@ impl Server { if noops { dh.backend_handle() - .create_global(&interface, interface.version, Arc::new(Handler)); + .create_global(interface, interface.version, Arc::new(Handler)); } Self { @@ -579,8 +579,7 @@ impl Server { } }; - while !pending_ret.is_empty() { - let (mime, pending) = pending_ret.pop().unwrap(); + while let Some((mime, pending)) = pending_ret.pop() { match pending { Some(pending) => try_transfer(&mut pending_ret, mime, pending), None => {