node: e2e test for canonical ref update
Adds a test to ensure that canonical reference updates are received on the node events stream. Added a helper to `NodeHandle` for perfoming a commit to a reference and signing the nodes references, to help with this use case.
This commit is contained in:
parent
0d96af5d07
commit
7d2f0e387c
|
|
@ -352,6 +352,72 @@ impl<G: Signer<Signature> + cyphernet::Ecdh> NodeHandle<G> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.id()
|
.id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform a commit to `refname` by generating a blob of random data to a
|
||||||
|
/// random path in a new tree.
|
||||||
|
///
|
||||||
|
/// If the reference does not exist, a new one will be created with the new
|
||||||
|
/// commit as its target.
|
||||||
|
///
|
||||||
|
/// If the reference already exists, then its target is used as the parent
|
||||||
|
/// of the new commit, and the reference will be updated.
|
||||||
|
///
|
||||||
|
/// The `rad/sigrefs` are then updated to reflect the new change.
|
||||||
|
pub fn commit_to(&self, rid: RepoId, refname: impl AsRef<git::RefStr>) {
|
||||||
|
use radicle::test::arbitrary;
|
||||||
|
|
||||||
|
let refname = refname.as_ref();
|
||||||
|
let repo = self.storage.repository(rid).unwrap();
|
||||||
|
let raw = &repo.backend;
|
||||||
|
|
||||||
|
let info = self.storage.info();
|
||||||
|
let author = git::raw::Signature::now(&info.name(), &info.email()).unwrap();
|
||||||
|
|
||||||
|
let tree = {
|
||||||
|
let mut tb = raw.treebuilder(None).unwrap();
|
||||||
|
let blob = raw.blob(&arbitrary::vec::<u8>(100)).unwrap();
|
||||||
|
tb.insert(
|
||||||
|
arbitrary::alphanumeric(10),
|
||||||
|
blob,
|
||||||
|
git::raw::FileMode::Blob.into(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let oid = tb.write().unwrap();
|
||||||
|
raw.find_tree(oid).unwrap()
|
||||||
|
};
|
||||||
|
let parent = {
|
||||||
|
let target = raw
|
||||||
|
.find_reference(refname.as_str())
|
||||||
|
.ok()
|
||||||
|
.and_then(|r| r.target());
|
||||||
|
target.and_then(|oid| raw.find_commit(oid).ok())
|
||||||
|
};
|
||||||
|
match parent {
|
||||||
|
None => repo
|
||||||
|
.backend
|
||||||
|
.commit(
|
||||||
|
Some(refname.as_str()),
|
||||||
|
&author,
|
||||||
|
&author,
|
||||||
|
"New commit",
|
||||||
|
&tree,
|
||||||
|
&[],
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
Some(parent) => repo
|
||||||
|
.backend
|
||||||
|
.commit(
|
||||||
|
Some(refname.as_str()),
|
||||||
|
&author,
|
||||||
|
&author,
|
||||||
|
"New commit",
|
||||||
|
&tree,
|
||||||
|
&[&parent],
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
};
|
||||||
|
repo.sign_refs(&self.signer).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node<MockSigner> {
|
impl Node<MockSigner> {
|
||||||
|
|
|
||||||
|
|
@ -1504,3 +1504,43 @@ fn test_channel_reader_limit() {
|
||||||
"actual: {reason}"
|
"actual: {reason}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fetch_emits_canonical_ref_update() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let scale = config::scale();
|
||||||
|
let mut alice = Node::init(tmp.path(), config::relay("alice"));
|
||||||
|
let bob = Node::init(tmp.path(), config::relay("bob"));
|
||||||
|
|
||||||
|
let (repo, _) = fixtures::repository(tmp.path());
|
||||||
|
fixtures::populate(&repo, scale.max(3));
|
||||||
|
|
||||||
|
let rid = alice.project_from("acme", "", &repo);
|
||||||
|
|
||||||
|
let mut alice = alice.spawn();
|
||||||
|
let mut bob = bob.spawn();
|
||||||
|
let bob_events = bob.handle.events();
|
||||||
|
|
||||||
|
bob.handle.seed(rid, Scope::All).unwrap();
|
||||||
|
alice.connect(&bob);
|
||||||
|
|
||||||
|
let result = bob.handle.fetch(rid, alice.id, DEFAULT_TIMEOUT).unwrap();
|
||||||
|
assert!(result.is_success());
|
||||||
|
|
||||||
|
let default_branch: git::Qualified = {
|
||||||
|
let repo = alice.storage.repository(rid).unwrap();
|
||||||
|
let proj = repo.project().unwrap();
|
||||||
|
git::lit::refs_heads(proj.default_branch()).into()
|
||||||
|
};
|
||||||
|
alice.commit_to(rid, &default_branch);
|
||||||
|
|
||||||
|
bob_events
|
||||||
|
.wait(
|
||||||
|
|e| {
|
||||||
|
matches!(e, Event::CanonicalRefUpdated { refname, .. } if *refname == default_branch)
|
||||||
|
.then_some(())
|
||||||
|
},
|
||||||
|
time::Duration::from_secs(9 * scale as u64),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue