use std::error::Error;
use std::path::PathBuf;
use event_listener::Event;
use event_listener::EventListener;
use fsipc::legacy::fsipcProxy;
use super::logger::{Logger, LoggerPing};
use super::timefail::Timefail;
use super::LOGGER_PATH;
use modio_logger_db::{Datastore, SqlitePoolBuilder};
use zbus::Connection;
use tempfile;
#[derive(Clone)]
pub struct TestPaths {
pub timefail_path: PathBuf,
pub timeadjust_path: PathBuf,
pub dbpath: PathBuf,
}
pub struct Tempbase {
#[allow(dead_code)]
dir: tempfile::TempDir,
#[allow(dead_code)]
dbfile: tempfile::NamedTempFile,
pub paths: TestPaths,
}
impl Tempbase {
#[must_use]
pub fn new() -> Self {
let dir = tempfile::Builder::new()
.prefix("modio-logger")
.tempdir()
.expect("Error tempdir");
let dbfile = tempfile::Builder::new()
.prefix("database")
.suffix(".sqlite")
.tempfile_in(dir.path())
.expect("Error on tempfile");
let paths = TestPaths {
dbpath: dbfile.path().to_path_buf(),
timeadjust_path: dir.path().join("timeadjust"),
timefail_path: dir.path().join("timefail"),
};
Self { dir, dbfile, paths }
}
}
impl Default for Tempbase {
fn default() -> Self {
Self::new()
}
}
#[allow(dead_code)]
pub async fn test_server_with_paths(
name: String,
ready: Event,
done: EventListener,
paths: TestPaths,
) {
let timefail = Timefail::new(paths.timefail_path, paths.timeadjust_path);
let pool = SqlitePoolBuilder::new()
.migrate(true)
.db_path(&paths.dbpath)
.build()
.await
.expect("Error opening database");
let ds = Datastore::new(pool)
.await
.expect("Error initializing datastore");
let logger = Logger::new(timefail, ds)
.await
.expect("Error spawning logger");
let loggerp = LoggerPing {};
let conn = Connection::session()
.await
.expect("Error connecting to session bus");
conn.object_server()
.at(LOGGER_PATH, logger)
.await
.expect("Error binding path");
conn.object_server()
.at(LOGGER_PATH, loggerp)
.await
.expect("Error binding path");
conn.request_name(name.clone())
.await
.expect("Error requesting name");
ready.notify(1);
done.await;
conn.release_name(name.clone())
.await
.expect("failed to release our name");
}
#[allow(dead_code)]
pub async fn test_server(name: String, ready: Event, done: EventListener) {
let _ = env_logger::builder().is_test(true).try_init();
let base = Tempbase::new();
test_server_with_paths(name, ready, done, base.paths).await;
}
#[allow(dead_code)]
pub async fn launch_server(
line: u32,
) -> Result<
(
fsipcProxy<'static>,
event_listener::Event,
async_std::task::JoinHandle<()>,
),
Box<dyn Error>,
> {
let test_complete = event_listener::Event::new();
let test_waiter = test_complete.listen();
let server = event_listener::Event::new();
let server_ready = server.listen();
let server_name = format!("se.modio.logger.TestCase{}", line);
dbg!(&server_name);
let client_name = server_name.clone();
let task = async_std::task::spawn(test_server(server_name, server, test_waiter));
server_ready.await;
let conn = zbus::Connection::session().await?;
let proxy = fsipcProxy::builder(&conn)
.path(LOGGER_PATH)?
.destination(client_name)?
.build()
.await?;
Ok((proxy, test_complete, task))
}