72 lines
1.8 KiB
Rust
72 lines
1.8 KiB
Rust
use sqlx::migrate::{MigrateDatabase, Migrator};
|
|
use sqlx::{sqlite::SqlitePoolOptions, Sqlite, SqlitePool};
|
|
use std::collections::HashSet;
|
|
use std::path::Path;
|
|
|
|
async fn setup_db() -> SqlitePool {
|
|
let url = "sqlite::memory:";
|
|
Sqlite::create_database(url).await.ok();
|
|
let pool = SqlitePoolOptions::new()
|
|
.max_connections(20)
|
|
.connect(url)
|
|
.await
|
|
.unwrap();
|
|
Migrator::new(Path::new("./migrations"))
|
|
.await
|
|
.unwrap()
|
|
.run(&pool)
|
|
.await
|
|
.unwrap();
|
|
|
|
sqlx::query(
|
|
"INSERT INTO pools (slug, name, cidr, kind, allowed_prefixes_json, enabled, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)"
|
|
)
|
|
.bind("vlan")
|
|
.bind("VLAN / zákaznické subnety")
|
|
.bind("10.91.0.0/16")
|
|
.bind("VLAN")
|
|
.bind("[20,21,22,23,24,25,26,27,28,29,30]")
|
|
.bind(1)
|
|
.bind(chrono::Utc::now().to_rfc3339())
|
|
.execute(&pool)
|
|
.await
|
|
.unwrap();
|
|
|
|
pool
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn concurrent_allocations_do_not_overlap() {
|
|
let pool = setup_db().await;
|
|
let mut handles = vec![];
|
|
|
|
for i in 0..5 {
|
|
let p = pool.clone();
|
|
handles.push(tokio::spawn(async move {
|
|
sub_aligator::handlers::allocations::allocate_in_tx(
|
|
&p,
|
|
1,
|
|
"10.91.0.0/16",
|
|
&[24],
|
|
24,
|
|
&format!("test allocation {}", i),
|
|
"",
|
|
"local",
|
|
)
|
|
.await
|
|
}));
|
|
}
|
|
|
|
let results: Vec<_> = futures::future::join_all(handles).await;
|
|
let mut cidrs = HashSet::new();
|
|
for r in results {
|
|
let Ok(Ok((allocation, _))) = r else { panic!("task failed") };
|
|
assert!(
|
|
cidrs.insert(allocation.cidr.clone()),
|
|
"duplicate CIDR allocated: {}",
|
|
allocation.cidr
|
|
);
|
|
}
|
|
|
|
assert_eq!(cidrs.len(), 5);
|
|
}
|