test(compositor): add protocol unit tests and stale identifier rejection

Stale identifier rejection (state.rs):
- WeftShellWindowData gains a closed: AtomicBool field (default false).
- Dispatch<ZweftShellWindowV1, WeftShellWindowData>::request() checks the
  closed flag before processing any request; posts a DefunctWindow error
  (code 0) if the window has been closed, satisfying the error enum
  defined in the protocol XML.

Unit tests (protocols/mod.rs, 5 tests):
- window_data_stores_fields: verifies app_id, title, role, and initial
  closed state are stored correctly.
- closed_flag_transition: verifies AtomicBool store/load round-trip.
- manager_interface_name_and_version: confirms generated interface name
  zweft_shell_manager_v1 and version 1.
- window_interface_name_and_version: confirms generated interface name
  zweft_shell_window_v1 and version 1.
- defunct_window_error_code: confirms Error::DefunctWindow == 0 as
  declared in the protocol XML.

Also adds scripts/wsl-test.sh for running cargo test with the
libdisplay-info shim in place.
This commit is contained in:
Marco Allegretti 2026-03-11 08:12:11 +01:00
parent 2bb657e8fc
commit 3abc83f9ed
3 changed files with 95 additions and 2 deletions

View file

@ -28,6 +28,7 @@ pub struct WeftShellWindowData {
pub app_id: String,
pub title: String,
pub role: String,
pub closed: std::sync::atomic::AtomicBool,
}
impl WeftShellState {
@ -40,3 +41,58 @@ impl WeftShellState {
Self { _global: global }
}
}
#[cfg(test)]
mod tests {
use std::sync::atomic::Ordering;
use wayland_server::Resource;
use super::*;
#[test]
fn window_data_stores_fields() {
let d = WeftShellWindowData {
app_id: "com.example.test".into(),
title: "Test Window".into(),
role: "normal".into(),
closed: std::sync::atomic::AtomicBool::new(false),
};
assert_eq!(d.app_id, "com.example.test");
assert_eq!(d.title, "Test Window");
assert_eq!(d.role, "normal");
assert!(!d.closed.load(Ordering::Relaxed));
}
#[test]
fn closed_flag_transition() {
let d = WeftShellWindowData {
app_id: String::new(),
title: String::new(),
role: String::new(),
closed: std::sync::atomic::AtomicBool::new(false),
};
assert!(!d.closed.load(Ordering::Relaxed));
d.closed.store(true, Ordering::Relaxed);
assert!(d.closed.load(Ordering::Relaxed));
}
#[test]
fn manager_interface_name_and_version() {
let iface = ZweftShellManagerV1::interface();
assert_eq!(iface.name, "zweft_shell_manager_v1");
assert_eq!(iface.version, 1);
}
#[test]
fn window_interface_name_and_version() {
let iface = ZweftShellWindowV1::interface();
assert_eq!(iface.name, "zweft_shell_window_v1");
assert_eq!(iface.version, 1);
}
#[test]
fn defunct_window_error_code() {
let code = server::zweft_shell_window_v1::Error::DefunctWindow as u32;
assert_eq!(code, 0);
}
}

View file

@ -19,7 +19,7 @@ use smithay::{
reexports::{
calloop::{LoopHandle, LoopSignal},
wayland_server::{
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New,
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
backend::{ClientData, ClientId, DisconnectReason},
protocol::{wl_buffer::WlBuffer, wl_output::WlOutput, wl_surface::WlSurface},
},
@ -457,6 +457,7 @@ impl Dispatch<ZweftShellManagerV1, ()> for WeftCompositorState {
app_id,
title,
role,
closed: std::sync::atomic::AtomicBool::new(false),
},
);
window.configure(x, y, width, height, 0);
@ -471,10 +472,17 @@ impl Dispatch<ZweftShellWindowV1, WeftShellWindowData> for WeftCompositorState {
_client: &Client,
resource: &ZweftShellWindowV1,
request: zweft_shell_window_v1::Request,
_data: &WeftShellWindowData,
data: &WeftShellWindowData,
_dh: &DisplayHandle,
_data_init: &mut DataInit<'_, Self>,
) {
if data.closed.load(std::sync::atomic::Ordering::Relaxed) {
resource.post_error(
crate::protocols::server::zweft_shell_window_v1::Error::DefunctWindow as u32,
"request on closed window",
);
return;
}
match request {
zweft_shell_window_v1::Request::Destroy => {}
zweft_shell_window_v1::Request::UpdateMetadata { title, role } => {

29
scripts/wsl-test.sh Normal file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
set -e
PROJECT="/mnt/c/Users/might/Desktop/Development/Systems/WEFT OS"
FAKE_PC_DIR="$HOME/.local/fake-pkgconfig"
mkdir -p "$FAKE_PC_DIR"
cat > "$FAKE_PC_DIR/libdisplay-info.pc" << 'EOF'
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib64
includedir=/usr/include
Name: libdisplay-info
Description: EDID and DisplayID library (version shim for cargo check)
Version: 0.2.9
Libs: -L${libdir} -ldisplay-info
Cflags: -I${includedir}
EOF
source "$HOME/.cargo/env"
export PKG_CONFIG_PATH="$FAKE_PC_DIR:/usr/lib64/pkgconfig:/usr/share/pkgconfig"
cd "$PROJECT"
echo "==> cargo test -p weft-compositor"
cargo test -p weft-compositor 2>&1
echo ""
echo "ALL DONE"