| 8a3334b7 Andy McCall ↶ |
1 |
|
| 2 |
|
| 3 |
use oxy_core::repo::Repo; |
| 4 |
use oxygenhub::config::Config; |
| 5 |
use oxygenhub::db; |
| 6 |
use oxygenhub::repos::RepoName; |
| 7 |
use std::path::Path; |
| 8 |
|
| 9 |
fn hermetic() { |
| 10 |
static ONCE: std::sync::Once = std::sync::Once::new(); |
| 11 |
static DIR: std::sync::OnceLock<tempfile::TempDir> = std::sync::OnceLock::new(); |
| 12 |
ONCE.call_once(|| { |
| 13 |
let d = tempfile::tempdir().unwrap(); |
| 14 |
std::env::set_var("OXY_HOME", d.path()); |
| 15 |
DIR.set(d).ok(); |
| 16 |
}); |
| 17 |
} |
| 18 |
|
| 19 |
fn write(root: &Path, rel: &str, content: &[u8]) { |
| 20 |
let p = root.join(rel); |
| 21 |
std::fs::create_dir_all(p.parent().unwrap()).unwrap(); |
| 22 |
std::fs::write(p, content).unwrap(); |
| 23 |
} |
| 24 |
|
| 25 |
#[tokio::test(flavor = "multi_thread")] |
| 26 |
async fn every_repository_is_garbage_collected_in_turn() { |
| 27 |
hermetic(); |
| 28 |
let dir = tempfile::tempdir().unwrap(); |
| 29 |
let mut config = Config::load(dir.path()).unwrap(); |
| 30 |
config.auth.push_tokens = vec!["site".into()]; |
| 31 |
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); |
| 32 |
let port = listener.local_addr().unwrap().port(); |
| 33 |
config.server.base_url = format!("http://127.0.0.1:{port}"); |
| 34 |
assert_eq!(config.retention.gc_hour, 3, "nightly at 03:00 UTC by default"); |
| 35 |
let app = oxygenhub::build(config).await.unwrap(); |
| 36 |
let router = oxygenhub::router(app.clone()); |
| 37 |
tokio::spawn(async move { axum::serve(listener, router).await.unwrap() }); |
| 38 |
db::accounts::create_account(&app.db, "andy", "[email protected]", "x", "salt", true).await.unwrap(); |
| 39 |
for name in ["one", "two"] { |
| 40 |
app.repos.create(&RepoName::parse(&format!("andy/{name}")).unwrap(), None).unwrap(); |
| 41 |
db::repos::create(&app.db, "andy", name, "", hub_api::Visibility::Public).await.unwrap(); |
| 42 |
} |
| 43 |
|
| 44 |
let work = tempfile::tempdir().unwrap(); |
| 45 |
let mut c = Repo::init(work.path()).unwrap(); |
| 46 |
c.config.set("remote.origin.url", &format!("http://127.0.0.1:{port}/andy/one")).unwrap(); |
| 47 |
c.config.set("remote.origin.token", "site").unwrap(); |
| 48 |
c.save_config().unwrap(); |
| 49 |
for i in 0..3 { |
| 50 |
write(work.path(), &format!("f{i}.txt"), format!("{i}\n").as_bytes()); |
| 51 |
c.commit(&format!("c{i}"), &[]).unwrap(); |
| 52 |
} |
| 53 |
assert!(c.push("origin", false).unwrap().iter().all(|r| r.ok)); |
| 54 |
let hosted = app.repos.dir(&RepoName::parse("andy/one").unwrap()); |
| 55 |
let before = Repo::open(&hosted).unwrap(); |
| 56 |
assert!(before.store().loose_count().unwrap() > 0, "the push left loose objects"); |
| 57 |
drop(before); |
| 58 |
|
| 59 |
let done = oxygenhub::maintenance::gc_all(&app).await; |
| 60 |
assert_eq!(done.len(), 2, "{done:?}"); |
| 61 |
assert!(done.iter().all(|d| !d.failed), "{done:?}"); |
| 62 |
assert!(done[0].summary.contains("packed"), "{}", done[0]); |
| 63 |
let after = Repo::open(&hosted).unwrap(); |
| 64 |
assert_eq!(after.store().loose_count().unwrap(), 0, "everything is in a pack"); |
| 65 |
assert_eq!(after.store().pack_count(), 1); |
| 66 |
assert_eq!(after.bookmark_heads().unwrap(), c.bookmark_heads().unwrap(), "and the history is intact"); |
| 67 |
|
| 68 |
let again = tempfile::tempdir().unwrap(); |
| 69 |
let d = Repo::clone(&format!("http://127.0.0.1:{port}/andy/one"), again.path()).unwrap(); |
| 70 |
assert_eq!(std::fs::read(again.path().join("f2.txt")).unwrap(), b"2\n"); |
| 71 |
let _ = d; |
| 72 |
} |