config: add TestConfig
This commit is contained in:
parent
f92c9c6027
commit
e212e0b8b1
7 changed files with 175 additions and 6 deletions
127
src/it/test_config.rs
Normal file
127
src/it/test_config.rs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
use {
|
||||
crate::it::test_error::TestError,
|
||||
isnt::std_1::primitive::IsntConstPtrExt,
|
||||
jay_config::_private::{
|
||||
bincode_ops,
|
||||
ipc::{ClientMessage, ServerMessage},
|
||||
ConfigEntry, VERSION,
|
||||
},
|
||||
std::{cell::Cell, ops::Deref, ptr, rc::Rc},
|
||||
};
|
||||
|
||||
pub static TEST_CONFIG_ENTRY: ConfigEntry = ConfigEntry {
|
||||
version: VERSION,
|
||||
init,
|
||||
unref,
|
||||
handle_msg,
|
||||
};
|
||||
|
||||
#[thread_local]
|
||||
static mut CONFIG: *const TestConfig = ptr::null();
|
||||
|
||||
pub fn with_test_config<T, F>(f: F) -> T
|
||||
where
|
||||
F: FnOnce(Rc<TestConfig>) -> T,
|
||||
{
|
||||
unsafe {
|
||||
let tc = Rc::new(TestConfig {
|
||||
srv: Cell::new(None),
|
||||
});
|
||||
let old = CONFIG;
|
||||
CONFIG = tc.deref();
|
||||
let res = f(tc.clone());
|
||||
CONFIG = old;
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn init(
|
||||
srv_data: *const u8,
|
||||
srv_unref: unsafe extern "C" fn(data: *const u8),
|
||||
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize),
|
||||
_msg: *const u8,
|
||||
_size: usize,
|
||||
) -> *const u8 {
|
||||
let tc = CONFIG;
|
||||
assert!(tc.is_not_null());
|
||||
Rc::increment_strong_count(tc);
|
||||
{
|
||||
let tc = &*tc;
|
||||
tc.srv.set(Some(ServerData {
|
||||
srv_data,
|
||||
srv_unref,
|
||||
srv_handler,
|
||||
}));
|
||||
}
|
||||
tc.cast()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn unref(data: *const u8) {
|
||||
Rc::decrement_strong_count(data.cast::<TestConfig>());
|
||||
}
|
||||
|
||||
unsafe extern "C" fn handle_msg(data: *const u8, msg: *const u8, size: usize) {
|
||||
let _tc = &*data.cast::<TestConfig>();
|
||||
let msg = std::slice::from_raw_parts(msg, size);
|
||||
let res = bincode::decode_from_slice::<ServerMessage, _>(msg, bincode_ops());
|
||||
let (msg, _) = match res {
|
||||
Ok(msg) => msg,
|
||||
Err(e) => {
|
||||
log::error!("could not deserialize message: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
match msg {
|
||||
ServerMessage::Configure { .. } => {}
|
||||
ServerMessage::Response { .. } => {}
|
||||
ServerMessage::InvokeShortcut { .. } => {}
|
||||
ServerMessage::NewInputDevice { .. } => {}
|
||||
ServerMessage::DelInputDevice { .. } => {}
|
||||
ServerMessage::ConnectorConnect { .. } => {}
|
||||
ServerMessage::ConnectorDisconnect { .. } => {}
|
||||
ServerMessage::NewConnector { .. } => {}
|
||||
ServerMessage::DelConnector { .. } => {}
|
||||
ServerMessage::TimerExpired { .. } => {}
|
||||
ServerMessage::GraphicsInitialized => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct ServerData {
|
||||
srv_data: *const u8,
|
||||
srv_unref: unsafe extern "C" fn(data: *const u8),
|
||||
srv_handler: unsafe extern "C" fn(data: *const u8, msg: *const u8, size: usize),
|
||||
}
|
||||
|
||||
pub struct TestConfig {
|
||||
srv: Cell<Option<ServerData>>,
|
||||
}
|
||||
|
||||
impl TestConfig {
|
||||
fn send(&self, msg: ClientMessage) -> Result<(), TestError> {
|
||||
let srv = match self.srv.get() {
|
||||
Some(srv) => srv,
|
||||
_ => bail!("srv not set"),
|
||||
};
|
||||
let mut buf = vec![];
|
||||
bincode::encode_into_std_write(msg, &mut buf, bincode_ops()).unwrap();
|
||||
unsafe {
|
||||
(srv.srv_handler)(srv.srv_data, buf.as_ptr(), buf.len());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn quit(&self) -> Result<(), TestError> {
|
||||
self.send(ClientMessage::Quit)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestConfig {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if let Some(srv) = self.srv.take() {
|
||||
(srv.srv_unref)(srv.srv_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ use {
|
|||
it::{
|
||||
test_backend::TestBackend,
|
||||
test_client::TestClient,
|
||||
test_config::TestConfig,
|
||||
test_error::{TestError, TestErrorExt},
|
||||
test_ifs::test_display::TestDisplay,
|
||||
test_transport::TestTransport,
|
||||
|
|
@ -25,6 +26,7 @@ pub struct TestRun {
|
|||
pub errors: Stack<String>,
|
||||
pub server_addr: c::sockaddr_un,
|
||||
pub dir: String,
|
||||
pub cfg: Rc<TestConfig>,
|
||||
}
|
||||
|
||||
impl TestRun {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ macro_rules! tassert_eq {
|
|||
mod t0001_shm_formats;
|
||||
mod t0002_window;
|
||||
mod t0003_multi_window;
|
||||
mod t0004_quit;
|
||||
|
||||
pub trait TestCase {
|
||||
fn name(&self) -> &'static str;
|
||||
|
|
@ -76,5 +77,6 @@ pub fn tests() -> Vec<&'static dyn TestCase> {
|
|||
t0001_shm_formats,
|
||||
t0002_window,
|
||||
t0003_multi_window,
|
||||
t0004_quit,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
15
src/it/tests/t0004_quit.rs
Normal file
15
src/it/tests/t0004_quit.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use {
|
||||
crate::it::{test_error::TestError, testrun::TestRun},
|
||||
std::{future::pending, rc::Rc},
|
||||
};
|
||||
|
||||
testcase!();
|
||||
|
||||
/// Quit
|
||||
async fn test(run: Rc<TestRun>) -> Result<(), TestError> {
|
||||
for _ in 0..2 {
|
||||
run.state.eng.yield_now().await;
|
||||
}
|
||||
run.cfg.quit()?;
|
||||
pending().await
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue