diff --git a/src/api.rs b/src/api.rs index 73f2b0a..d66ff7a 100644 --- a/src/api.rs +++ b/src/api.rs @@ -145,10 +145,10 @@ impl From for PathBuf { } } -#[derive(Serialize)] -struct Version { - major: i32, - minor: i32, +#[derive(PartialEq, Debug, Serialize, Deserialize)] +pub struct Version { + pub major: i32, + pub minor: i32, } #[get("/version")] diff --git a/src/api_tests.rs b/src/api_tests.rs new file mode 100644 index 0000000..7959770 --- /dev/null +++ b/src/api_tests.rs @@ -0,0 +1,54 @@ +use rocket::http::Status; +use rocket::local::Client; +use std::path::PathBuf; +use std::ops::Deref; +use std::sync::Arc; +use std::fs; + +use crate::api; +use crate::db; +use crate::index; +use crate::server; + +struct TestEnvironment { + pub client: Client, + command_sender: Arc, +} + +impl Drop for TestEnvironment { + fn drop(&mut self) { + self.command_sender.deref().exit().unwrap(); + } +} + +fn get_test_environment(db_name: &str) -> TestEnvironment +{ + let mut db_path = PathBuf::new(); + db_path.push("test"); + db_path.push(db_name); + if db_path.exists() { + fs::remove_file(&db_path).unwrap(); + } + + let db = Arc::new(db::DB::new(&db_path).unwrap()); + + let web_dir_path = PathBuf::from("web"); + let command_sender = index::init(db.clone()); + + let server = server::get_server(5050, "/", "/api", &web_dir_path, db, command_sender.clone()).unwrap(); + let client = Client::new(server).unwrap(); + TestEnvironment { client, command_sender } +} + +#[test] +fn version() { + let env = get_test_environment("api_version.sqlite"); + let client = &env.client; + let mut response = client.get("/api/version").dispatch(); + + assert_eq!(response.status(), Status::Ok); + + let response_body = response.body_string().unwrap(); + let response_json: api::Version = serde_json::from_str(&response_body).unwrap(); + assert_eq!(response_json, api::Version{major: 3, minor: 0}); +} diff --git a/src/index.rs b/src/index.rs index 6a48b5a..a76cdb5 100644 --- a/src/index.rs +++ b/src/index.rs @@ -34,6 +34,7 @@ no_arg_sql_function!( enum Command { REINDEX, + EXIT, } struct CommandReceiver { @@ -64,6 +65,14 @@ impl CommandSender { Err(_) => bail!("Trigger reindex channel error"), } } + + pub fn exit(&self) -> Result<(), errors::Error> { + let sender = self.sender.lock().unwrap(); + match sender.send(Command::EXIT) { + Ok(_) => Ok(()), + Err(_) => bail!("Index exit channel error"), + } + } } pub fn init(db: Arc) -> Arc { @@ -78,13 +87,6 @@ pub fn init(db: Arc) -> Arc { update_loop(db, &command_receiver); }); - // Trigger auto-indexing - let db_ref = db.clone(); - let command_sender_clone = command_sender.clone(); - std::thread::spawn(move || { - self_trigger(db_ref.deref(), &command_sender_clone); - }); - command_sender } @@ -456,18 +458,15 @@ where { loop { // Wait for a command - if let Err(e) = command_buffer.receiver.recv() { - error!("Error while waiting on index command buffer: {}", e); + if command_buffer.receiver.recv().is_err() { return; } // Flush the buffer to ignore spammy requests loop { match command_buffer.receiver.try_recv() { - Err(TryRecvError::Disconnected) => { - error!("Error while flushing index command buffer"); - return; - } + Err(TryRecvError::Disconnected) => return, + Ok(Command::EXIT) => return, Err(TryRecvError::Empty) => break, Ok(_) => (), } diff --git a/src/main.rs b/src/main.rs index c5b97c8..c9a8cb2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -211,6 +211,13 @@ fn run() -> Result<()> { info!("Initializing index"); let command_sender = index::init(db.clone()); + // Trigger auto-indexing + let db_auto_index = db.clone(); + let command_sender_auto_index = command_sender.clone(); + std::thread::spawn(move || { + index::self_trigger(db_auto_index.deref(), &command_sender_auto_index); + }); + // API mount target let prefix_url = config.prefix_url.unwrap_or_else(|| "".to_string()); let api_url = format!("{}/api", &prefix_url);