diff --git a/Cargo.lock b/Cargo.lock index caaac27..aa9d86f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,7 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.8", + "regex-automata", "serde", ] @@ -518,13 +518,12 @@ name = "horust-commands-lib" version = "0.1.0" dependencies = [ "anyhow", + "env_logger", + "log", "prost", "prost-build", "serde", "serde_json", - "tokio", - "tracing", - "tracing-test", ] [[package]] @@ -688,12 +687,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.161" @@ -716,16 +709,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.22" @@ -738,15 +721,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - [[package]] name = "memchr" version = "2.7.4" @@ -804,16 +778,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -844,35 +808,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1088,15 +1023,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "redox_syscall" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" -dependencies = [ - "bitflags", -] - [[package]] name = "redox_users" version = "0.4.6" @@ -1116,17 +1042,8 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1137,15 +1054,9 @@ checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.5" @@ -1222,12 +1133,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "serde" version = "1.0.214" @@ -1281,15 +1186,6 @@ dependencies = [ "serde", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shellexpand" version = "3.1.0" @@ -1305,15 +1201,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - [[package]] name = "slab" version = "0.4.9" @@ -1414,16 +1301,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - [[package]] name = "tinyvec" version = "1.8.0" @@ -1446,28 +1323,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", - "bytes", "libc", "mio", - "parking_lot", "pin-project-lite", - "signal-hook-registry", "socket2", - "tokio-macros", "windows-sys 0.52.0", ] -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "toml" version = "0.8.19" @@ -1515,21 +1377,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" version = "0.1.32" @@ -1537,57 +1387,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "tracing-test" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "557b891436fe0d5e0e363427fc7f217abf9ccd510d5136549847bdcbcd011d68" -dependencies = [ - "tracing-core", - "tracing-subscriber", - "tracing-test-macro", -] - -[[package]] -name = "tracing-test-macro" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" -dependencies = [ - "quote", - "syn", ] [[package]] @@ -1634,12 +1433,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - [[package]] name = "wait-timeout" version = "0.2.0" diff --git a/commands/Cargo.toml b/commands/Cargo.toml index eaa34b8..6611029 100644 --- a/commands/Cargo.toml +++ b/commands/Cargo.toml @@ -10,11 +10,10 @@ serde = { version = "~1.0", features = ["derive"] } serde_json = "~1.0" prost = "~0.13" anyhow = "~1.0" -tokio = { version = "~1.41", features = ["full"] } -tracing = "0.1" +log = "~0.4" [dev-dependencies] -tracing-test = { version = "0.2", features = ["no-env-filter"] } +env_logger = "~0.11" [build-dependencies] prost-build = { version = "~0.13" } \ No newline at end of file diff --git a/commands/src/client.rs b/commands/src/client.rs new file mode 100644 index 0000000..d4efe8a --- /dev/null +++ b/commands/src/client.rs @@ -0,0 +1,79 @@ +use crate::proto::messages::horust_msg_message::MessageType; +use crate::proto::messages::{ + horust_msg_request, horust_msg_response, HorustMsgMessage, HorustMsgRequest, + HorustMsgServiceStatusRequest, +}; +use crate::{HorustMsgServiceStatus, UdsConnectionHandler}; +use anyhow::{anyhow, Context}; +use anyhow::{bail, Result}; +use log::{debug, info}; +use std::net::Shutdown; +use std::os::unix::net::UnixStream; +use std::path::Path; + +fn new_request(request_type: horust_msg_request::Request) -> HorustMsgMessage { + HorustMsgMessage { + message_type: Some(MessageType::Request(HorustMsgRequest { + request: Some(request_type), + })), + } +} + +// if anything is none it will return none +// if the response was an error it will return Some(Err). +fn unwrap_response(response: HorustMsgMessage) -> Option> { + if let MessageType::Response(resp) = response.message_type? { + let v = resp.response?; + return match &v { + horust_msg_response::Response::Error(error) => { + Some(Err(anyhow!("Error: {}", error.error_string))) + } + horust_msg_response::Response::StatusResponse(_status) => Some(Ok(v)), + }; + } + None +} + +pub struct ClientHandler { + uds_connection_handler: UdsConnectionHandler, +} +impl ClientHandler { + pub fn new_client(socket_path: &Path) -> Result { + Ok(Self { + uds_connection_handler: UdsConnectionHandler::new( + UnixStream::connect(socket_path).context("Could not create stream")?, + ), + }) + } + pub fn send_status_request( + &mut self, + service_name: String, + ) -> Result<(String, HorustMsgServiceStatus)> { + let status = new_request(horust_msg_request::Request::StatusRequest( + HorustMsgServiceStatusRequest { service_name }, + )); + self.uds_connection_handler.send_message(status)?; + // server is waiting for EOF. + self.uds_connection_handler + .socket + .shutdown(Shutdown::Write)?; + //Reads all bytes until EOF in this source, appending them to buf. + let received = self.uds_connection_handler.receive_message()?; + debug!("Client: received: {received:?}"); + let response = unwrap_response(received).unwrap()?; + if let horust_msg_response::Response::StatusResponse(resp) = response { + Ok(( + resp.service_name, + HorustMsgServiceStatus::try_from(resp.service_status).unwrap(), + )) + } else { + bail!("Invalid response received: {:?}", response); + } + } + + pub fn client(mut self, service_name: String) -> Result<()> { + let received = self.send_status_request(service_name)?; + info!("Client: received: {received:?}"); + Ok(()) + } +} diff --git a/commands/src/commands.proto b/commands/src/commands.proto index cb5149e..1c7b111 100644 --- a/commands/src/commands.proto +++ b/commands/src/commands.proto @@ -1,26 +1,57 @@ syntax = "proto3"; -package tutorial; +package messages; -message Person { - string name = 1; - int32 id = 2; // Unique ID number for this person. - string email = 3; - - enum PhoneType { - MOBILE = 0; - HOME = 1; - WORK = 2; +message HorustMsgMessage { + oneof message_type { + HorustMsgRequest request = 1; + HorustMsgResponse response = 2; } - - message PhoneNumber { - string number = 1; - PhoneType type = 2; +} +message HorustMsgRequest { + oneof request { + HorustMsgServiceStatusRequest status_request = 1; + HorustMsgServiceChangeRequest change_request = 2; + } +} +message HorustMsgResponse { + oneof response { + HorustMsgError error = 1; + HorustMsgServiceStatusResponse status_response = 2; } +} + +message HorustMsgError { + string error_string = 1; +} - repeated PhoneNumber phones = 4; +message HorustMsgServiceStatusRequest { + string service_name = 1; } -// Our address book file is just one of these. -message AddressBook { - repeated Person people = 1; -} \ No newline at end of file +message HorustMsgServiceStatusResponse { + string service_name = 1; + HorustMsgServiceStatus service_status = 2; +} + +message HorustMsgServiceChangeRequest { + string service_name = 1; + HorustMsgServiceStatus service_status = 2; +} + +// return the current status - similar to HorustServiceStatusReponse. +message HorustMsgServiceChangeResponse { + string service_name = 1; + HorustMsgServiceStatus service_status = 2; +} + +enum HorustMsgServiceStatus { + STARTING = 0; + STARTED = 1; + RUNNING = 2; + INKILLING = 3; + SUCCESS = 4; + FINISHED = 5; + FINISHEDFAILED = 6; + FAILED = 7; + INITIAL = 8; +} diff --git a/commands/src/lib.rs b/commands/src/lib.rs index 6ba0f56..9ba13da 100644 --- a/commands/src/lib.rs +++ b/commands/src/lib.rs @@ -1,108 +1,47 @@ +extern crate core; + +mod client; #[rustfmt::skip] mod proto; - -use anyhow::{bail, Context, Result}; +mod server; +use crate::proto::messages::HorustMsgMessage; +pub use crate::proto::messages::HorustMsgServiceStatus; +use anyhow::{Context, Result}; +pub use client::ClientHandler; +use log::debug; +use prost::Message; +pub use server::CommandsHandlerTrait; +use std::io::{Read, Write}; +use std::os::unix::net::UnixStream; use std::path::{Path, PathBuf}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::{UnixListener, UnixStream}; -use tracing::info; -pub struct CommandsUdsConnectionHandler { +/// socket_name should be the pid of the horust process. +pub fn get_path(socket_folder_path: &Path, horust_pid: i32) -> PathBuf { + socket_folder_path.join(format!("horust-{horust_pid}.sock")) +} + +pub struct UdsConnectionHandler { socket: UnixStream, } -impl CommandsUdsConnectionHandler { - fn get_path(socket_folder: &Path, socket_name: u32) -> PathBuf { - socket_folder.join(format!("hourst-{socket_name}.sock")) - } - fn new(socket: UnixStream) -> Self { +impl UdsConnectionHandler { + pub fn new(socket: UnixStream) -> Self { Self { socket } } - pub async fn new_client(socket_path: PathBuf) -> Result { - Ok(Self { - socket: UnixStream::connect(socket_path) - .await - .context("Could not create stream")?, - }) - } - - pub async fn client(mut self) -> Result<()> { - info!("client: sending data"); + pub fn send_message(&mut self, message: HorustMsgMessage) -> Result<()> { + debug!("Sending message: {:?}", message); + let mut buf = Vec::new(); + // Serialize the message into a byte array. + message.encode(&mut buf)?; self.socket - .write_all(b"Hello?") - .await // we write bytes, &[u8] + .write_all(&buf) .context("Failed at writing onto the unix stream")?; - info!("client: Completed."); - // server is waiting for EOF. - self.socket.shutdown().await?; - - let mut buf = String::new(); - info!("client: reading back:"); - //Reads all bytes until EOF in this source, appending them to buf. - self.socket - .read_to_string(&mut buf) - .await // we write bytes, &[u8] - .context("Failed at writing onto the unix stream")?; - info!("Client received: {}", buf); Ok(()) } - - pub async fn server(mut self) -> Result<()> { - let mut message = String::new(); - info!("Server: receving data"); - // Reads all bytes until EOF in this source, appending them to buf. - self.socket - .read_to_string(&mut message) - .await - .context("Failed at reading the unix stream")?; - info!("Server: Received data: {message}"); - self.socket - .write_all(message.as_bytes()) - .await - .context("Failed at reading the unix stream")?; - - info!("Server: has written back {}", message); - Ok(()) - } -} -pub struct CommandsUdsServer { - unix_listener: UnixListener, -} -impl CommandsUdsServer { - pub async fn new(socket_path: &Path) -> Result { - Ok(Self { - unix_listener: UnixListener::bind(socket_path) - .context("Could not create the unix socket")?, - }) - } - pub async fn start(&mut self) -> Result<()> { - // put the server logic in a loop to accept several connections - loop { - self.accept().await?; - } - Ok(()) - } - pub async fn accept(&mut self) -> Result<()> { - match self.unix_listener.accept().await { - Ok((stream, _addr)) => { - tokio::spawn(async move { - CommandsUdsConnectionHandler::new(stream) - .server() - .await - .unwrap(); - }) - .await? - } - Err(e) => { - bail!("error accepting connction: {e}") - } - }; - Ok(()) + pub fn receive_message(&mut self) -> Result { + let mut buf = Vec::new(); + self.socket.read_to_end(&mut buf)?; + let received = HorustMsgMessage::decode(buf.as_slice())?; + debug!("Received message: {:?}", received); + Ok(received) } } - -fn create_uds() {} - -fn listen_uds() {} - -fn send_message() {} -fn receive_message() {} diff --git a/commands/src/proto/mod.rs b/commands/src/proto/mod.rs index 8b13789..ba63992 100644 --- a/commands/src/proto/mod.rs +++ b/commands/src/proto/mod.rs @@ -1 +1 @@ - +pub mod messages; diff --git a/commands/src/server.rs b/commands/src/server.rs new file mode 100644 index 0000000..05003fc --- /dev/null +++ b/commands/src/server.rs @@ -0,0 +1,129 @@ +use crate::proto::messages::horust_msg_message::MessageType::Request; +use crate::proto::messages::{ + horust_msg_message, horust_msg_request, horust_msg_response, HorustMsgError, HorustMsgMessage, + HorustMsgRequest, HorustMsgResponse, HorustMsgServiceStatus, HorustMsgServiceStatusResponse, +}; +use crate::UdsConnectionHandler; +use anyhow::{anyhow, Result}; +use log::{error, info}; +use std::io::ErrorKind; +use std::os::unix::net::UnixListener; + +pub trait CommandsHandlerTrait { + fn start(&mut self) -> Result<()> { + // put the server logic in a loop to accept several connections + loop { + self.accept().expect("TODO: panic message"); + } + } + fn get_unix_listener(&mut self) -> &mut UnixListener; + fn accept(&mut self) -> Result<()> { + match self.get_unix_listener().accept() { + Ok((stream, _addr)) => { + let conn_handler = UdsConnectionHandler::new(stream); + if let Err(err) = self.handle_connection(conn_handler) { + //todo: send response back. + error!("Error handling connection: {}", err); + } + } + Err(e) => { + let kind = e.kind(); + if !matches!(kind, ErrorKind::WouldBlock) { + error!("Error accepting connction: {e} - you might need to restart Horust."); + } + } + }; + Ok(()) + } + fn handle_connection(&self, mut uds_conn_handler: UdsConnectionHandler) -> Result<()> { + let received = uds_conn_handler + .receive_message()? + .message_type + .ok_or(anyhow!("No request found in message sent from client."))?; + + if let Request(HorustMsgRequest { + request: Some(request), + }) = received + { + let response = match request { + horust_msg_request::Request::StatusRequest(status_request) => { + info!("Requested status for {}", status_request.service_name); + + let service_status = self.get_service_status(&status_request.service_name); + service_status + .map(|status| { + new_horust_msg_service_status_response( + status_request.service_name, + status, + ) + }) + .unwrap_or_else(|err| { + new_horust_msg_error_response(format!( + "Error from status handler: {err}", + )) + }) + } + horust_msg_request::Request::ChangeRequest(change_request) => { + info!( + "Requested service update for {} to {}", + change_request.service_name, change_request.service_status + ); + new_horust_msg_error_response("Unimplemented!".to_string()) + /*self.update_service_status( + &change_request.service_name, + HorustMsgServiceStatus::from_i32(change_request.service_status).unwrap(), + ) + .map(|new_status| { + // TODO: + new_horust_msg_service_status_response( + change_request.service_name, + new_status, + ) + }) + .unwrap_or_else(|err| { + new_horust_msg_error_response(format!("Error from change handler: {err}")) + })*/ + } + }; + uds_conn_handler.send_message(response)?; + } + Ok(()) + } + + fn get_service_status(&self, service_name: &str) -> Result; + fn update_service_status( + &self, + service_name: &str, + new_status: HorustMsgServiceStatus, + ) -> Result<()>; +} + +pub fn new_horust_msg_error_response(error: String) -> HorustMsgMessage { + HorustMsgMessage { + message_type: Some(horust_msg_message::MessageType::Response( + HorustMsgResponse { + response: Some(horust_msg_response::Response::Error(HorustMsgError { + error_string: error, + })), + }, + )), + } +} + +pub fn new_horust_msg_service_status_response( + service_name: String, + status: HorustMsgServiceStatus, +) -> HorustMsgMessage { + HorustMsgMessage { + message_type: Some(horust_msg_message::MessageType::Response( + HorustMsgResponse { + response: Some(horust_msg_response::Response::StatusResponse( + HorustMsgServiceStatusResponse { + service_name, + service_status: status.into(), + }, + )), + }, + )), + } +} diff --git a/commands/tests/simple.rs b/commands/tests/simple.rs index f228a5a..fa5bf89 100644 --- a/commands/tests/simple.rs +++ b/commands/tests/simple.rs @@ -1,31 +1,76 @@ use anyhow::Result; -use horust_commands_lib::{CommandsUdsConnectionHandler, CommandsUdsServer}; +use std::os::unix::net::UnixListener; + +use horust_commands_lib::{ClientHandler, CommandsHandlerTrait, HorustMsgServiceStatus}; +use log::info; use std::path::PathBuf; -use tracing::info; -use tracing_test::traced_test; +use std::sync::{Arc, Barrier}; +use std::thread; -#[tokio::test] -#[traced_test] -async fn test_simple() -> Result<()> { +struct MockCommandsHandler { + unix_listener: UnixListener, +} +impl MockCommandsHandler { + // full socket path (not the folder). + pub fn new(socket_path: PathBuf) -> Self { + Self { + unix_listener: UnixListener::bind(socket_path).unwrap(), + } + } +} +impl CommandsHandlerTrait for MockCommandsHandler { + fn get_unix_listener(&mut self) -> &mut UnixListener { + &mut self.unix_listener + } + + fn get_service_status(&self, service_name: &str) -> Result { + Ok(match service_name { + "Running" => HorustMsgServiceStatus::Running, + "Started" => HorustMsgServiceStatus::Started, + _ => unimplemented!(), + }) + } + + fn update_service_status( + &self, + service_name: &str, + new_status: HorustMsgServiceStatus, + ) -> Result<()> { + todo!() + } +} +fn init() { + let _ = env_logger::builder().is_test(true).try_init(); +} +#[test] +fn test_simple() -> Result<()> { info!("Starting"); + init(); let socket_path: PathBuf = "/tmp/simple.sock".into(); if socket_path.exists() { std::fs::remove_file(&socket_path)?; } let socket_path2 = socket_path.clone(); - let s_handle = tokio::spawn(async move { - let mut uds = CommandsUdsServer::new(&socket_path2).await.unwrap(); + let barrier_server = Arc::new(Barrier::new(2)); + let barrier_client = Arc::clone(&barrier_server); + let s_handle = thread::spawn(move || { + let mut uds = MockCommandsHandler::new(socket_path2); info!("uds created"); - uds.accept().await.unwrap(); + barrier_server.wait(); + uds.accept().unwrap(); + uds.accept().unwrap(); }); - let c_handle = tokio::spawn(async { - let client = CommandsUdsConnectionHandler::new_client(socket_path) - .await - .unwrap(); - client.client().await.unwrap(); + + let c_handle = thread::spawn(move || { + barrier_client.wait(); + let client = ClientHandler::new_client(&socket_path).unwrap(); + client.client("Running".into()).unwrap(); + + let client = ClientHandler::new_client(&socket_path).unwrap(); + client.client("Started".into()).unwrap(); }); - s_handle.await?; - c_handle.await?; + s_handle.join().unwrap(); + c_handle.join().unwrap(); Ok(()) }