radicle: populate MockRepository

The MockStorage holds an inventory of repositories and their
identities but when asking for a MockRepository, none of this
information is transferred.

Add `id` and `doc` fields to MockRepository for defining some of its
functionality.

In addition, add a generator for a nonempty MockStorage to use in
tests that will expect the storage to be populated.

Signed-off-by: Fintan Halpenny <fintan.halpenny@gmail.com>
X-Clacks-Overhead: GNU Terry Pratchett
This commit is contained in:
Fintan Halpenny 2023-03-03 17:03:11 +00:00
parent 8c02a8116e
commit d476d35887
No known key found for this signature in database
GPG Key ID: 2552FB6F64066CB7
5 changed files with 56 additions and 13 deletions

View File

@ -75,7 +75,15 @@ impl<S, G> DerefMut for Peer<S, G> {
impl Peer<MockStorage, MockSigner> { impl Peer<MockStorage, MockSigner> {
pub fn new(name: &'static str, ip: impl Into<net::IpAddr>) -> Self { pub fn new(name: &'static str, ip: impl Into<net::IpAddr>) -> Self {
Self::config(name, ip, MockStorage::empty(), Config::default()) Self::with_storage(name, ip, MockStorage::empty())
}
pub fn with_storage(
name: &'static str,
ip: impl Into<net::IpAddr>,
storage: MockStorage,
) -> Self {
Self::config(name, ip, storage, Config::default())
} }
} }

View File

@ -581,7 +581,9 @@ fn test_refs_announcement_relay() {
#[test] #[test]
fn test_refs_announcement_no_subscribe() { fn test_refs_announcement_no_subscribe() {
let mut alice = Peer::new("alice", [7, 7, 7, 7]); let storage = arbitrary::nonempty_storage(1);
let rid = *storage.inventory.keys().next().unwrap();
let mut alice = Peer::with_storage("alice", [7, 7, 7, 7], storage);
let bob = Peer::new("bob", [8, 8, 8, 8]); let bob = Peer::new("bob", [8, 8, 8, 8]);
let eve = Peer::new("eve", [9, 9, 9, 9]); let eve = Peer::new("eve", [9, 9, 9, 9]);
let id = arbitrary::gen(1); let id = arbitrary::gen(1);
@ -589,18 +591,19 @@ fn test_refs_announcement_no_subscribe() {
alice.track_repo(&id, tracking::Scope::All).unwrap(); alice.track_repo(&id, tracking::Scope::All).unwrap();
alice.connect_to(&bob); alice.connect_to(&bob);
alice.connect_to(&eve); alice.connect_to(&eve);
alice.receive(bob.id(), bob.refs_announcement(id)); alice.receive(bob.id(), bob.refs_announcement(rid));
assert!(alice.messages(eve.id()).next().is_none()); assert!(alice.messages(eve.id()).next().is_none());
} }
#[test] #[test]
fn test_gossip_during_fetch() { fn test_gossip_during_fetch() {
let mut alice = Peer::new("alice", [7, 7, 7, 7]); let storage = arbitrary::nonempty_storage(1);
let rid = *storage.inventory.keys().next().unwrap();
let mut alice = Peer::with_storage("alice", [7, 7, 7, 7], storage);
let bob = Peer::new("bob", [8, 8, 8, 8]); let bob = Peer::new("bob", [8, 8, 8, 8]);
let eve = Peer::new("eve", [9, 9, 9, 9]); let eve = Peer::new("eve", [9, 9, 9, 9]);
let now = LocalTime::now().as_millis(); let now = LocalTime::now().as_millis();
let rid = arbitrary::gen::<Id>(1);
let (send, _recv) = chan::bounded::<node::FetchResult>(1); let (send, _recv) = chan::bounded::<node::FetchResult>(1);
let inventory1 = BoundedVec::try_from(arbitrary::vec(1)).unwrap(); let inventory1 = BoundedVec::try_from(arbitrary::vec(1)).unwrap();
let inventory2 = BoundedVec::try_from(arbitrary::vec(1)).unwrap(); let inventory2 = BoundedVec::try_from(arbitrary::vec(1)).unwrap();

View File

@ -299,6 +299,16 @@ impl Doc<Verified> {
Ok(oid.into()) Ok(oid.into())
} }
#[cfg(any(test, feature = "test"))]
pub(crate) fn unverified(self) -> Doc<Unverified> {
Doc {
payload: self.payload,
delegates: self.delegates,
threshold: self.threshold,
verified: PhantomData,
}
}
} }
impl Doc<Unverified> { impl Doc<Unverified> {

View File

@ -58,6 +58,14 @@ pub fn vec<T: Eq + Arbitrary>(size: usize) -> Vec<T> {
vec vec
} }
pub fn nonempty_storage(size: usize) -> MockStorage {
let mut storage = gen::<MockStorage>(size);
storage
.inventory
.insert(gen::<Id>(size), gen::<Doc<Verified>>(size));
storage
}
pub fn gen<T: Arbitrary>(size: usize) -> T { pub fn gen<T: Arbitrary>(size: usize) -> T {
let mut gen = qcheck::Gen::new(size); let mut gen = qcheck::Gen::new(size);

View File

@ -55,28 +55,42 @@ impl ReadStorage for MockStorage {
Ok(self.inventory.keys().cloned().collect::<Vec<_>>()) Ok(self.inventory.keys().cloned().collect::<Vec<_>>())
} }
fn repository(&self, _proj: Id) -> Result<Self::Repository, Error> { fn repository(&self, rid: Id) -> Result<Self::Repository, Error> {
Ok(MockRepository {}) let doc = self
.inventory
.get(&rid)
.expect("Mockstorage::repository: missing doc");
Ok(MockRepository {
id: rid,
doc: doc.clone(),
})
} }
} }
impl WriteStorage for MockStorage { impl WriteStorage for MockStorage {
type RepositoryMut = MockRepository; type RepositoryMut = MockRepository;
fn repository_mut(&self, _rid: Id) -> Result<Self::RepositoryMut, Error> { fn repository_mut(&self, rid: Id) -> Result<Self::RepositoryMut, Error> {
Ok(MockRepository {}) let doc = self.inventory.get(&rid).unwrap();
Ok(MockRepository {
id: rid,
doc: doc.clone(),
})
} }
fn create(&self, _rid: Id) -> Result<Self::RepositoryMut, Error> { fn create(&self, _rid: Id) -> Result<Self::RepositoryMut, Error> {
Ok(MockRepository {}) todo!()
} }
} }
pub struct MockRepository {} pub struct MockRepository {
id: Id,
doc: Doc<Verified>,
}
impl ReadRepository for MockRepository { impl ReadRepository for MockRepository {
fn id(&self) -> Id { fn id(&self) -> Id {
todo!() self.id
} }
fn is_empty(&self) -> Result<bool, git2::Error> { fn is_empty(&self) -> Result<bool, git2::Error> {
@ -146,7 +160,7 @@ impl ReadRepository for MockRepository {
fn identity_doc( fn identity_doc(
&self, &self,
) -> Result<(Oid, crate::identity::Doc<crate::crypto::Unverified>), IdentityError> { ) -> Result<(Oid, crate::identity::Doc<crate::crypto::Unverified>), IdentityError> {
todo!() Ok((git2::Oid::zero().into(), self.doc.clone().unverified()))
} }
} }