cli/tests: Refactor cob command tests
This commit is contained in:
parent
1f3dc6aea0
commit
d39e485c13
|
|
@ -3,7 +3,6 @@ use std::path::Path;
|
|||
use std::str::FromStr;
|
||||
use std::{fs, net, thread, time};
|
||||
|
||||
use radicle::cob;
|
||||
use radicle::git;
|
||||
use radicle::node;
|
||||
use radicle::node::address::Store as _;
|
||||
|
|
@ -16,7 +15,7 @@ use radicle::node::{Address, Alias, Config, Handle as _, DEFAULT_TIMEOUT};
|
|||
use radicle::prelude::RepoId;
|
||||
use radicle::profile;
|
||||
use radicle::profile::Home;
|
||||
use radicle::storage::{ReadStorage, RefUpdate, RemoteRepository};
|
||||
use radicle::storage::{ReadStorage, RemoteRepository};
|
||||
use radicle::test::fixtures;
|
||||
|
||||
use radicle_localtime::LocalTime;
|
||||
|
|
@ -32,6 +31,7 @@ use util::formula::formula;
|
|||
mod commands {
|
||||
mod checkout;
|
||||
mod clone;
|
||||
mod cob;
|
||||
}
|
||||
|
||||
/// Run a CLI test file.
|
||||
|
|
@ -130,101 +130,6 @@ fn rad_issue_list() {
|
|||
Environment::alice(["rad-init", "rad-issue", "rad-issue-list"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_update() {
|
||||
Environment::alice(["rad-init", "rad-cob-log"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_update_identity() {
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let working = environment.tempdir().join("working");
|
||||
let home = &profile.home;
|
||||
|
||||
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
|
||||
std::fs::create_dir_all(base).unwrap();
|
||||
std::fs::create_dir_all(working.clone()).unwrap();
|
||||
|
||||
// Setup a test repository.
|
||||
fixtures::repository(&working);
|
||||
|
||||
test("examples/rad-init.md", &working, Some(home), []).unwrap();
|
||||
test(
|
||||
"examples/rad-cob-update-identity.md",
|
||||
&working,
|
||||
Some(home),
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_multiset() {
|
||||
// `rad-cob-multiset` is a `jq` script, which requires `jq` to be installed.
|
||||
// We test whether `jq` is installed, and have this test succeed if it is not.
|
||||
// Programmatic skipping of tests is not supported as of 2024-08.
|
||||
if !program_reports_version("jq") {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let home = &profile.home;
|
||||
let working = environment.tempdir().join("working");
|
||||
|
||||
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
std::fs::create_dir_all(base).unwrap();
|
||||
std::fs::create_dir_all(working.clone()).unwrap();
|
||||
|
||||
// Copy over the script that implements the multiset COB.
|
||||
std::fs::copy(
|
||||
base.join("examples").join("rad-cob-multiset"),
|
||||
working.join("rad-cob-multiset"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Setup a test repository.
|
||||
fixtures::repository(&working);
|
||||
|
||||
test("examples/rad-init.md", &working, Some(home), []).unwrap();
|
||||
test("examples/rad-cob-multiset.md", &working, Some(home), []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_log() {
|
||||
Environment::alice(["rad-init", "rad-cob-log"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_show() {
|
||||
Environment::alice(["rad-init", "rad-cob-show"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_migrate() {
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let home = &profile.home;
|
||||
|
||||
home.cobs_db_mut()
|
||||
.unwrap()
|
||||
.raw_query(|conn| conn.execute("PRAGMA user_version = 0"))
|
||||
.unwrap();
|
||||
|
||||
environment.repository(&profile);
|
||||
|
||||
environment
|
||||
.tests(["rad-init", "rad-cob-migrate"], &profile)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_operations() {
|
||||
Environment::alice(["rad-init", "rad-cob-operations"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "part of many other tests"]
|
||||
fn rad_init() {
|
||||
|
|
@ -1463,128 +1368,6 @@ fn rad_diff() {
|
|||
test("examples/rad-diff.md", tmp, None, []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cob_replication() {
|
||||
let mut environment = Environment::new();
|
||||
let working = tempfile::tempdir().unwrap();
|
||||
let mut alice = environment.node("alice");
|
||||
let bob = environment.node("bob");
|
||||
|
||||
let rid = alice.project("heartwood", "");
|
||||
|
||||
let mut alice = alice.spawn();
|
||||
let mut bob = bob.spawn();
|
||||
let events = alice.handle.events();
|
||||
|
||||
alice.handle.follow(bob.id, None).unwrap();
|
||||
alice.connect(&bob);
|
||||
|
||||
bob.routes_to(&[(rid, alice.id)]);
|
||||
bob.fork(rid, working.path()).unwrap();
|
||||
|
||||
// Wait for Alice to fetch the clone refs.
|
||||
events
|
||||
.wait(
|
||||
|e| {
|
||||
matches!(
|
||||
e,
|
||||
Event::RefsFetched { updated, .. }
|
||||
if updated.iter().any(|u| matches!(u, RefUpdate::Created { .. }))
|
||||
)
|
||||
.then_some(())
|
||||
},
|
||||
time::Duration::from_secs(6),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let bob_repo = bob.storage.repository(rid).unwrap();
|
||||
let mut bob_issues = radicle::cob::issue::Issues::open(&bob_repo).unwrap();
|
||||
let mut bob_cache = radicle::cob::cache::InMemory::default();
|
||||
let issue = bob_issues
|
||||
.create(
|
||||
cob::Title::new("Something's fishy").unwrap(),
|
||||
"I don't know what it is",
|
||||
&[],
|
||||
&[],
|
||||
[],
|
||||
&mut bob_cache,
|
||||
&bob.signer,
|
||||
)
|
||||
.unwrap();
|
||||
log::debug!(target: "test", "Issue {} created", issue.id());
|
||||
|
||||
// Make sure that Bob's issue refs announcement has a different timestamp than his fork's
|
||||
// announcement, otherwise Alice will consider it stale.
|
||||
thread::sleep(time::Duration::from_millis(3));
|
||||
|
||||
bob.handle.announce_refs_for(rid, [bob.id]).unwrap();
|
||||
|
||||
// Wait for Alice to fetch the issue refs.
|
||||
events
|
||||
.iter()
|
||||
.find(|e| matches!(e, Event::RefsFetched { .. }))
|
||||
.unwrap();
|
||||
|
||||
let alice_repo = alice.storage.repository(rid).unwrap();
|
||||
let alice_issues = radicle::cob::issue::Issues::open(&alice_repo).unwrap();
|
||||
let alice_issue = alice_issues.get(issue.id()).unwrap().unwrap();
|
||||
|
||||
assert_eq!(alice_issue.title(), "Something's fishy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cob_deletion() {
|
||||
let mut environment = Environment::new();
|
||||
let working = tempfile::tempdir().unwrap();
|
||||
let mut alice = environment.node("alice");
|
||||
let bob = environment.node("bob");
|
||||
|
||||
let rid = alice.project("heartwood", "");
|
||||
|
||||
let mut alice = alice.spawn();
|
||||
let mut bob = bob.spawn();
|
||||
|
||||
alice.handle.seed(rid, Scope::All).unwrap();
|
||||
bob.handle.seed(rid, Scope::All).unwrap();
|
||||
alice.connect(&bob);
|
||||
bob.routes_to(&[(rid, alice.id)]);
|
||||
|
||||
let alice_repo = alice.storage.repository(rid).unwrap();
|
||||
let mut alice_issues = radicle::cob::issue::Cache::no_cache(&alice_repo).unwrap();
|
||||
let issue = alice_issues
|
||||
.create(
|
||||
cob::Title::new("Something's fishy").unwrap(),
|
||||
"I don't know what it is",
|
||||
&[],
|
||||
&[],
|
||||
[],
|
||||
&alice.signer,
|
||||
)
|
||||
.unwrap();
|
||||
let issue_id = issue.id();
|
||||
log::debug!(target: "test", "Issue {issue_id} created");
|
||||
|
||||
bob.rad("clone", &[rid.to_string().as_str()], working.path())
|
||||
.unwrap();
|
||||
|
||||
let bob_repo = bob.storage.repository(rid).unwrap();
|
||||
let bob_issues = radicle::cob::issue::Issues::open(&bob_repo).unwrap();
|
||||
assert!(bob_issues.get(issue_id).unwrap().is_some());
|
||||
|
||||
let mut alice_issues = radicle::cob::issue::Cache::no_cache(&alice_repo).unwrap();
|
||||
alice_issues.remove(issue_id, &alice.signer).unwrap();
|
||||
|
||||
log::debug!(target: "test", "Removing issue..");
|
||||
|
||||
radicle::assert_matches!(
|
||||
bob.handle.fetch(rid, alice.id, DEFAULT_TIMEOUT).unwrap(),
|
||||
radicle::node::FetchResult::Success { .. }
|
||||
);
|
||||
let bob_repo = bob.storage.repository(rid).unwrap();
|
||||
let bob_issues = radicle::cob::issue::Issues::open(&bob_repo).unwrap();
|
||||
assert!(bob_issues.get(issue_id).unwrap().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_sync() {
|
||||
let mut environment = Environment::new();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,230 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::util::environment::Environment;
|
||||
use crate::{program_reports_version, test};
|
||||
use radicle::node::Handle;
|
||||
use radicle::test::fixtures;
|
||||
|
||||
#[test]
|
||||
fn rad_cob_update() {
|
||||
Environment::alice(["rad-init", "rad-cob-log"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_update_identity() {
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let working = environment.tempdir().join("working");
|
||||
let home = &profile.home;
|
||||
|
||||
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
|
||||
std::fs::create_dir_all(base).unwrap();
|
||||
std::fs::create_dir_all(working.clone()).unwrap();
|
||||
|
||||
// Setup a test repository.
|
||||
fixtures::repository(&working);
|
||||
|
||||
test("examples/rad-init.md", &working, Some(home), []).unwrap();
|
||||
test(
|
||||
"examples/rad-cob-update-identity.md",
|
||||
&working,
|
||||
Some(home),
|
||||
[],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_multiset() {
|
||||
// `rad-cob-multiset` is a `jq` script, which requires `jq` to be installed.
|
||||
// We test whether `jq` is installed, and have this test succeed if it is not.
|
||||
// Programmatic skipping of tests is not supported as of 2024-08.
|
||||
if !program_reports_version("jq") {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let home = &profile.home;
|
||||
let working = environment.tempdir().join("working");
|
||||
|
||||
let base = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
std::fs::create_dir_all(base).unwrap();
|
||||
std::fs::create_dir_all(working.clone()).unwrap();
|
||||
|
||||
// Copy over the script that implements the multiset COB.
|
||||
std::fs::copy(
|
||||
base.join("examples").join("rad-cob-multiset"),
|
||||
working.join("rad-cob-multiset"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Setup a test repository.
|
||||
fixtures::repository(&working);
|
||||
|
||||
test("examples/rad-init.md", &working, Some(home), []).unwrap();
|
||||
test("examples/rad-cob-multiset.md", &working, Some(home), []).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_log() {
|
||||
Environment::alice(["rad-init", "rad-cob-log"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_show() {
|
||||
Environment::alice(["rad-init", "rad-cob-show"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_migrate() {
|
||||
let mut environment = Environment::new();
|
||||
let profile = environment.profile("alice");
|
||||
let home = &profile.home;
|
||||
|
||||
home.cobs_db_mut()
|
||||
.unwrap()
|
||||
.raw_query(|conn| conn.execute("PRAGMA user_version = 0"))
|
||||
.unwrap();
|
||||
|
||||
environment.repository(&profile);
|
||||
|
||||
environment
|
||||
.tests(["rad-init", "rad-cob-migrate"], &profile)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rad_cob_operations() {
|
||||
Environment::alice(["rad-init", "rad-cob-operations"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cob_replication() {
|
||||
let mut environment = Environment::new();
|
||||
let working = tempfile::tempdir().unwrap();
|
||||
let mut alice = environment.node("alice");
|
||||
let bob = environment.node("bob");
|
||||
|
||||
let rid = alice.project("heartwood", "");
|
||||
|
||||
let mut alice = alice.spawn();
|
||||
let mut bob = bob.spawn();
|
||||
let events = alice.handle.events();
|
||||
|
||||
alice.handle.follow(bob.id, None).unwrap();
|
||||
alice.connect(&bob);
|
||||
|
||||
bob.routes_to(&[(rid, alice.id)]);
|
||||
bob.fork(rid, working.path()).unwrap();
|
||||
|
||||
// Wait for Alice to fetch the clone refs.
|
||||
events
|
||||
.wait(
|
||||
|e| {
|
||||
matches!(
|
||||
e,
|
||||
radicle::node::Event::RefsFetched { updated, .. }
|
||||
if updated.iter().any(|u| matches!(u, radicle::storage::RefUpdate::Created { .. }))
|
||||
)
|
||||
.then_some(())
|
||||
},
|
||||
std::time::Duration::from_secs(6),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let bob_repo = radicle::storage::ReadStorage::repository(&bob.storage, rid).unwrap();
|
||||
let mut bob_issues = radicle::cob::issue::Issues::open(&bob_repo).unwrap();
|
||||
let mut bob_cache = radicle::cob::cache::InMemory::default();
|
||||
let issue = bob_issues
|
||||
.create(
|
||||
radicle::cob::Title::new("Something's fishy").unwrap(),
|
||||
"I don't know what it is",
|
||||
&[],
|
||||
&[],
|
||||
[],
|
||||
&mut bob_cache,
|
||||
&bob.signer,
|
||||
)
|
||||
.unwrap();
|
||||
log::debug!(target: "test", "Issue {} created", issue.id());
|
||||
|
||||
// Make sure that Bob's issue refs announcement has a different timestamp than his fork's
|
||||
// announcement, otherwise Alice will consider it stale.
|
||||
std::thread::sleep(std::time::Duration::from_millis(3));
|
||||
|
||||
bob.handle.announce_refs_for(rid, [bob.id]).unwrap();
|
||||
|
||||
// Wait for Alice to fetch the issue refs.
|
||||
events
|
||||
.iter()
|
||||
.find(|e| matches!(e, radicle::node::Event::RefsFetched { .. }))
|
||||
.unwrap();
|
||||
|
||||
let alice_repo = radicle::storage::ReadStorage::repository(&alice.storage, rid).unwrap();
|
||||
let alice_issues = radicle::cob::issue::Issues::open(&alice_repo).unwrap();
|
||||
let alice_issue = alice_issues.get(issue.id()).unwrap().unwrap();
|
||||
|
||||
assert_eq!(alice_issue.title(), "Something's fishy");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cob_deletion() {
|
||||
let mut environment = Environment::new();
|
||||
let working = tempfile::tempdir().unwrap();
|
||||
let mut alice = environment.node("alice");
|
||||
let bob = environment.node("bob");
|
||||
|
||||
let rid = alice.project("heartwood", "");
|
||||
|
||||
let mut alice = alice.spawn();
|
||||
let mut bob = bob.spawn();
|
||||
|
||||
alice
|
||||
.handle
|
||||
.seed(rid, radicle::node::policy::Scope::All)
|
||||
.unwrap();
|
||||
bob.handle
|
||||
.seed(rid, radicle::node::policy::Scope::All)
|
||||
.unwrap();
|
||||
alice.connect(&bob);
|
||||
bob.routes_to(&[(rid, alice.id)]);
|
||||
|
||||
let alice_repo = radicle::storage::ReadStorage::repository(&alice.storage, rid).unwrap();
|
||||
let mut alice_issues = radicle::cob::issue::Cache::no_cache(&alice_repo).unwrap();
|
||||
let issue = alice_issues
|
||||
.create(
|
||||
radicle::cob::Title::new("Something's fishy").unwrap(),
|
||||
"I don't know what it is",
|
||||
&[],
|
||||
&[],
|
||||
[],
|
||||
&alice.signer,
|
||||
)
|
||||
.unwrap();
|
||||
let issue_id = issue.id();
|
||||
log::debug!(target: "test", "Issue {issue_id} created");
|
||||
|
||||
bob.rad("clone", &[rid.to_string().as_str()], working.path())
|
||||
.unwrap();
|
||||
|
||||
let bob_repo = radicle::storage::ReadStorage::repository(&bob.storage, rid).unwrap();
|
||||
let bob_issues = radicle::cob::issue::Issues::open(&bob_repo).unwrap();
|
||||
assert!(bob_issues.get(issue_id).unwrap().is_some());
|
||||
|
||||
let mut alice_issues = radicle::cob::issue::Cache::no_cache(&alice_repo).unwrap();
|
||||
alice_issues.remove(issue_id, &alice.signer).unwrap();
|
||||
|
||||
log::debug!(target: "test", "Removing issue..");
|
||||
|
||||
radicle::assert_matches!(
|
||||
bob.handle
|
||||
.fetch(rid, alice.id, radicle::node::DEFAULT_TIMEOUT)
|
||||
.unwrap(),
|
||||
radicle::node::FetchResult::Success { .. }
|
||||
);
|
||||
let bob_repo = radicle::storage::ReadStorage::repository(&bob.storage, rid).unwrap();
|
||||
let bob_issues = radicle::cob::issue::Issues::open(&bob_repo).unwrap();
|
||||
assert!(bob_issues.get(issue_id).unwrap().is_none());
|
||||
}
|
||||
Loading…
Reference in New Issue