use crate::meta_storage::mem::MemMetaStorage;
use crate::meta_storage::psql::PsqlMetaStorage;
use crate::meta_storage::tests::utils::{
TicketView, dim_i, psql_backend, resolution_views, task_alpha, task_beta, views,
};
use crate::meta_storage::{
MetaBackend, MetaClientApi, MetaConnApi, MetaResolutionApi, MetaTicketApi,
};
use crate::schema::{Job, Resolution, Ticket};
const SCHEMA: &str = "operon_transfer";
async fn init<MSto: MetaBackend>(client: MSto::Client<'_>) {
client.init_schema().await.expect("init_schema");
client
.init_dimension_hash()
.await
.expect("init_dimension_hash");
client.init_ticket_hash().await.expect("init_ticket_hash");
let _ = client
.resolution(dim_i())
.init()
.await
.expect("resolution init");
client
.init_ticket_summary()
.await
.expect("init_ticket_summary");
client
.init_ticket_status_type()
.await
.expect("init_ticket_status_type");
let _ = client
.ticket(task_alpha())
.init()
.await
.expect("alpha init");
let _ = client.ticket(task_beta()).init().await.expect("beta init");
client
.resolution(dim_i())
.clear()
.await
.expect("resolution clear");
client
.ticket(task_alpha())
.clear()
.await
.expect("alpha clear");
client
.ticket(task_beta())
.clear()
.await
.expect("beta clear");
}
async fn populate<MSto: MetaBackend>(client: MSto::Client<'_>) {
client
.ticket(task_alpha())
.put(Ticket::new(0))
.await
.expect("alpha put");
client
.ticket(task_alpha())
.mark_done(Job { coordinate: [] })
.await
.expect("alpha mark_done");
client
.ticket(task_beta())
.put(Ticket::new(0).with_coordinate::<0>(0))
.await
.expect("beta put queued");
client
.ticket(task_beta())
.put(Ticket::new(3).with_coordinate::<0>(1))
.await
.expect("beta put waiting");
client
.ticket(task_beta())
.put(Ticket::new(1).with_coordinate::<0>(2))
.await
.expect("beta put");
let _tickets = client
.ticket(task_beta())
.raise_deps_done::<0>(task_alpha(), Job { coordinate: [] }, &[])
.await
.expect("beta raise_deps_done");
client
.ticket(task_beta())
.mark_done(Job { coordinate: [2] })
.await
.expect("beta mark_done");
client
.resolution(dim_i())
.put(Resolution {
coordinate: [],
ub: 3,
})
.await
.expect("resolution put");
}
#[derive(Debug, PartialEq, Eq)]
struct Snapshot {
alpha: Vec<TicketView>,
beta: Vec<TicketView>,
resolutions: Vec<(Vec<usize>, usize)>,
alpha_status: (i64, i64, i64),
beta_status: (i64, i64, i64),
}
async fn snapshot<MSto: MetaBackend>(client: MSto::Client<'_>) -> Snapshot {
Snapshot {
alpha: views(
&client
.ticket(task_alpha())
.dump()
.await
.expect("alpha dump"),
),
beta: views(&client.ticket(task_beta()).dump().await.expect("beta dump")),
resolutions: resolution_views(
&client
.resolution(dim_i())
.dump()
.await
.expect("resolution dump"),
),
alpha_status: client
.ticket(task_alpha())
.get_status()
.await
.expect("alpha status"),
beta_status: client
.ticket(task_beta())
.get_status()
.await
.expect("beta status"),
}
}
async fn transfer<Src: MetaBackend, Dst: MetaBackend>(src: Src::Client<'_>, dst: Dst::Client<'_>) {
let tickets = src.ticket(task_alpha()).dump().await.expect("alpha dump");
dst.ticket(task_alpha())
.hydrate(tickets)
.await
.expect("alpha load");
let tickets = src.ticket(task_beta()).dump().await.expect("beta dump");
dst.ticket(task_beta())
.hydrate(tickets)
.await
.expect("beta load");
let resolutions = src
.resolution(dim_i())
.dump()
.await
.expect("resolution dump");
dst.resolution(dim_i())
.hydrate(resolutions)
.await
.expect("resolution load");
}
#[tokio::test]
async fn mem_round_trips_through_mem() {
let source = MemMetaStorage::default();
let source_conn = source.scheduler_conn().await.expect("scheduler conn");
let source_client = source_conn.as_client();
init::<MemMetaStorage>(source_client).await;
populate::<MemMetaStorage>(source_client).await;
let target = MemMetaStorage::default();
let target_conn = target.scheduler_conn().await.expect("scheduler conn");
let target_client = target_conn.as_client();
init::<MemMetaStorage>(target_client).await;
transfer::<MemMetaStorage, MemMetaStorage>(source_client, target_client).await;
pretty_assertions::assert_eq!(
snapshot::<MemMetaStorage>(source_client).await,
snapshot::<MemMetaStorage>(target_client).await
);
}
#[tokio::test]
async fn psql_round_trips_through_mem() {
let Some(psql) = psql_backend(SCHEMA) else {
eprintln!("skipping: POSTGRES_URI is not set, so there is no Postgres to transfer with");
return;
};
let psql_conn = psql.scheduler_conn().await.expect("scheduler conn");
let psql_client = psql_conn.as_client();
init::<PsqlMetaStorage>(psql_client).await;
populate::<PsqlMetaStorage>(psql_client).await;
let before = snapshot::<PsqlMetaStorage>(psql_client).await;
let scratch = MemMetaStorage::default();
let scratch_conn = scratch.scheduler_conn().await.expect("scheduler conn");
let scratch_client = scratch_conn.as_client();
init::<MemMetaStorage>(scratch_client).await;
transfer::<PsqlMetaStorage, MemMetaStorage>(psql_client, scratch_client).await;
pretty_assertions::assert_eq!(before, snapshot::<MemMetaStorage>(scratch_client).await);
transfer::<MemMetaStorage, PsqlMetaStorage>(scratch_client, psql_client).await;
pretty_assertions::assert_eq!(before, snapshot::<PsqlMetaStorage>(psql_client).await);
}