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()
|
||||
.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> {
|
||||
|
|
|
|||
|
|
@ -1504,3 +1504,43 @@ fn test_channel_reader_limit() {
|
|||
"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