nom-nom-nix-gc/tests/db.rs

104 lines
3.4 KiB
Rust

use std::{process::{Command, Child}, env::temp_dir, path::PathBuf, fs::remove_dir_all, time::Duration, panic};
use nom_nom_gc::models::{Configuration, AppState, User, UserUuid, BinaryCache, Project};
use tokio::time::sleep;
use uuid::Uuid;
use anyhow::{anyhow, Result, Context};
struct TestDB {
path: PathBuf,
pid: Child,
db_name: String,
port: u16
}
async fn setup_db() -> Result<TestDB> {
let mut dbdir = temp_dir();
let dir_uuid = Uuid::new_v4();
let db_name = "nom-nom-integration-test".to_string();
let port: u16 = 12345;
dbdir.push(dir_uuid.to_string());
let dbdir_str = dbdir.to_str().unwrap();
Command::new("initdb")
.arg(&dbdir)
.spawn()?
.wait()?;
let db_proc_handle = Command::new("postgres")
.args(["-D", dbdir_str, "-c", &format!("unix_socket_directories={}", dbdir_str), "-c", "listen_addresses=", "-c", &format!("port={}", &port.to_string())])
.spawn()?;
sleep(Duration::from_secs(1)).await;
Command::new("createdb")
.args([ "-h", dbdir_str, "-p", &port.to_string(), &db_name])
.spawn()?
.wait()?;
Ok(TestDB{ path: dbdir, pid: db_proc_handle, db_name, port })
}
fn teardown_db(mut db: TestDB) -> Result <()> {
println!("Stopping postgres");
db.pid.kill()?;
remove_dir_all(db.path)?;
Ok(())
}
/**
This function is the actual test main function.
We can't inline it in main, we need to make sure to teardown the DB
setup even if it fails.
*/
async fn run_test_db(db: &TestDB) -> Result<()> {
let mut dbpath = db.path.to_str().unwrap().to_string();
dbpath.push('/');
let conf = Configuration {
url: "http://localhost:9000".to_string(),
db_port: Some(db.port),
db_host: Some(dbpath),
db_name: db.db_name.clone()
};
let state = AppState::new(conf);
state.run_migrations().await?;
let test_user = User { uuid: UserUuid(Uuid::new_v4()), name: "test-user".to_owned() };
state.save_user(&test_user).await.context("should save user")?;
let reg_uuid = state.generate_registration_uuid(&test_user.uuid).await.context("should generate registration uuid for test user")?;
let usr2 = state.retrieve_registration_user(&reg_uuid).await?;
let usr2 = usr2.ok_or_else(||anyhow!("state.retrieve_registration_user(&reg_uuid) returns Nothing"))?;
if test_user != usr2 {
return Err(anyhow!("test_user != usr2: {:?} != {:?}", test_user, usr2));
}
let binary_cache = BinaryCache {
name: "test-cache".to_string(),
access_key: "access key".to_string(),
secret_key: "secret key".to_string(),
region: "reg-01".to_string(),
endpoint_url: "localhost:"
};
state.create_binary_cache(&binary_cache).await?;
let project = Project {
name: "super-duper-project".to_string(),
latest_closure_generation: 0
};
state.create_project(&binary_cache, &project).await?;
let token = state.create_project_token(&project).await?;
let project2 = state.get_project(&token).await?;
if project != project2 {
return Err(anyhow!("project != project2: {:?} != {:?}", project, project2));
}
assert_eq!(project, project2);
Ok(())
}
#[tokio::test]
async fn test_db() {
let mdb = setup_db().await;
let db = mdb.expect("setup db");
let res = run_test_db(&db).await;
teardown_db(db).expect("Failed to teardown DB.");
res.unwrap_or_else(|e| panic!("{}", e));
}