Skip to content

Commit

Permalink
fix server test
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelvlach committed Jan 9, 2024
1 parent 84752fa commit 66c4ffa
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 36 deletions.
27 changes: 19 additions & 8 deletions agdb_server/src/db_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,16 +709,18 @@ impl DbPool {
pub(crate) fn remove_user(&self, username: &str, config: &Config) -> ServerResult {
let user_id = self.find_user_id(username)?;
let dbs = self.find_user_databases(user_id)?;
for db in dbs.iter() {
self.get_pool_mut()?.remove(&db.name);
}
let mut ids = dbs
.into_iter()
.iter()
.map(|db| db.db_id.unwrap())
.collect::<Vec<DbId>>();
ids.push(user_id);
self.db_mut()?
.exec_mut(&QueryBuilder::remove().ids(ids).query())?;

for db in dbs.into_iter() {
self.get_pool_mut()?.remove(&db.name);
}

let user_dir = Path::new(&config.data_dir).join(username);
if user_dir.exists() {
std::fs::remove_dir_all(user_dir)?;
Expand Down Expand Up @@ -760,7 +762,14 @@ impl DbPool {
self.add_db_user(owner, db, new_owner, DbUserRole::Admin, user)?;
}

let server_db = self.get_pool_mut()?.remove(&db_name).unwrap();
let server_db = ServerDb(
self.get_pool()?
.get(&db_name)
.ok_or(db_not_found(&db_name))?
.0
.clone(),
);

server_db
.get_mut()?
.rename(target_name.to_string_lossy().as_ref())
Expand All @@ -770,21 +779,23 @@ impl DbPool {
&format!("db rename error: {}", e.description),
)
})?;
self.get_pool_mut()?.insert(new_name.to_string(), server_db);
database.name = new_name.to_string();

let backup_path = db_backup_file(owner, db, config);

if backup_path.exists() {
let new_backup_path = db_backup_file(new_owner, new_db, config);
let backups_dir = new_backup_path.parent().unwrap();
std::fs::create_dir_all(backups_dir)?;
std::fs::rename(backup_path, new_backup_path)?;
}

self.get_pool_mut()?.insert(new_name.to_string(), server_db);

database.name = new_name.to_string();
self.db_mut()?
.exec_mut(&QueryBuilder::insert().element(&database).query())?;

self.get_pool_mut()?.remove(&db_name).unwrap();

Ok(())
}

Expand Down
1 change: 0 additions & 1 deletion agdb_server/tests/routes/admin_user_remove_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ async fn remove_with_other() -> anyhow::Result<()> {
.admin_db_user_add(owner, db, user, DbUserRole::Write)
.await?;
server.api.admin_user_remove(owner).await?;
assert!(server.api.admin_db_list().await?.1.is_empty());
assert!(!Path::new(&server.data_dir).join(owner).exists());
server.api.user_login(user, user).await?;
assert!(server.api.db_list().await?.1.is_empty());
Expand Down
16 changes: 14 additions & 2 deletions agdb_server/tests/routes/server_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use crate::TestServer;
use crate::TestServerImpl;
use crate::ADMIN;
use agdb_api::AgdbApi;
use agdb_api::ReqwestClient;
use assert_cmd::cargo::CommandCargoExt;
use reqwest::StatusCode;
use std::process::Command;

#[tokio::test]
async fn error() -> anyhow::Result<()> {
Expand Down Expand Up @@ -64,7 +70,13 @@ async fn openapi() -> anyhow::Result<()> {

#[tokio::test]
async fn db_config_reuse() -> anyhow::Result<()> {
let mut server = TestServer::new().await?;
server.restart().await?;
let mut server = TestServerImpl::new().await?;
let mut client = AgdbApi::new(ReqwestClient::new(), &TestServer::url_base(), server.port);
client.user_login(ADMIN, ADMIN).await?;
client.admin_shutdown().await?;
assert!(server.process.wait()?.success());
server.process = Command::cargo_bin("agdb_server")?
.current_dir(&server.dir)
.spawn()?;
Ok(())
}
55 changes: 30 additions & 25 deletions agdb_server/tests/test_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use std::process::Child;
use std::process::Command;
use std::sync::atomic::AtomicU16;
use std::sync::atomic::Ordering;
use std::sync::RwLock;
use std::time::Duration;

const BINARY: &str = "agdb_server";
Expand All @@ -28,8 +27,8 @@ const SHUTDOWN_RETRY_ATTEMPTS: u16 = 100;
static PORT: AtomicU16 = AtomicU16::new(DEFAULT_PORT);
static COUNTER: AtomicU16 = AtomicU16::new(1);
static MUTEX: std::sync::OnceLock<tokio::sync::Mutex<()>> = std::sync::OnceLock::new();
static INSTANCES: AtomicU16 = AtomicU16::new(0);
static SERVER: RwLock<Option<TestServerImpl>> = RwLock::new(None);
static SERVER: std::sync::OnceLock<tokio::sync::RwLock<Option<TestServerImpl>>> =
std::sync::OnceLock::new();

pub struct TestServer {
pub dir: String,
Expand All @@ -43,6 +42,7 @@ struct TestServerImpl {
pub data_dir: String,
pub port: u16,
pub process: Child,
pub instances: u16,
}

impl TestServerImpl {
Expand Down Expand Up @@ -77,6 +77,7 @@ impl TestServerImpl {
data_dir,
port,
process,
instances: 1,
});
}
}
Expand Down Expand Up @@ -150,15 +151,16 @@ impl TestServer {
.get_or_init(|| tokio::sync::Mutex::new(()))
.lock()
.await;
INSTANCES.fetch_add(1, Ordering::Relaxed);
let global_server = SERVER.get_or_init(|| tokio::sync::RwLock::new(None));
let mut server_guard = global_server.try_write().unwrap();

if SERVER.read().unwrap().is_none() {
println!("CREATING");
*SERVER.write().unwrap() = Some(TestServerImpl::new().await?);
if server_guard.is_none() {
*server_guard = Some(TestServerImpl::new().await?);
} else {
server_guard.as_mut().unwrap().instances += 1;
}

let read_lock = SERVER.read().unwrap();
let server = read_lock.as_ref().unwrap();
let server = server_guard.as_ref().unwrap();

Ok(Self {
api: AgdbApi::new(ReqwestClient::new(), &Self::url_base(), server.port),
Expand All @@ -169,21 +171,21 @@ impl TestServer {
}

pub fn next_user_name(&mut self) -> String {
format!("db_user{}", COUNTER.fetch_add(1, Ordering::Relaxed))
format!("db_user{}", COUNTER.fetch_add(1, Ordering::SeqCst))
}

pub fn next_db_name(&mut self) -> String {
format!("db{}", COUNTER.fetch_add(1, Ordering::Relaxed))
format!("db{}", COUNTER.fetch_add(1, Ordering::SeqCst))
}

pub async fn restart(&mut self) -> anyhow::Result<()> {
let _guard = MUTEX
.get_or_init(|| tokio::sync::Mutex::new(()))
.lock()
.await;
*SERVER.write().unwrap() = Some(TestServerImpl::new().await?);
Ok(())
}
// pub async fn restart(&mut self) -> anyhow::Result<()> {
// let _guard = MUTEX
// .get_or_init(|| tokio::sync::Mutex::new(()))
// .lock()
// .await;
// *SERVER.write().await = Some(TestServerImpl::new().await?);
// Ok(())
// }

pub fn url(&self, uri: &str) -> String {
format!("{}:{}/api/v1{uri}", Self::url_base(), self.port)
Expand All @@ -203,17 +205,20 @@ impl Drop for TestServerImpl {

impl Drop for TestServer {
fn drop(&mut self) {
let mutex = MUTEX.get_or_init(|| tokio::sync::Mutex::new(()));
let mutex = MUTEX.get().unwrap();
let _guard = loop {
if let Ok(g) = mutex.try_lock() {
break g;
}
};
let instances = INSTANCES.fetch_sub(1, Ordering::Relaxed) - 1;

if instances == 0 {
println!("DROPPING");
*SERVER.write().unwrap() = None;
let global_server = SERVER.get().unwrap();
let mut server_guard = global_server.try_write().unwrap();
let server = server_guard.as_mut().unwrap();

if server.instances == 1 {
*server_guard = None;
} else {
server.instances -= 1;
}
}
}

0 comments on commit 66c4ffa

Please sign in to comment.