From e892ceb909d077755ec262e9340677d42bd17899 Mon Sep 17 00:00:00 2001 From: Michael Dougherty Date: Wed, 16 Sep 2020 14:51:52 -0700 Subject: [PATCH 1/5] Add automocked HolochainP2pCellT trait (automock works with async_trait now!!!) --- Cargo.lock | 33 ++++++- crates/holochain/Cargo.toml | 2 +- crates/holochain/src/conductor/cell.rs | 1 + crates/holochain/src/core/ribosome.rs | 1 + .../src/core/ribosome/host_fn/call_remote.rs | 1 + crates/holochain/src/core/state/cascade.rs | 1 + .../core/workflow/publish_dht_ops_workflow.rs | 1 + crates/holochain_p2p/Cargo.toml | 2 + crates/holochain_p2p/src/lib.rs | 93 ++++++++++++++++--- crates/holochain_p2p/src/mock.rs | 1 + crates/types/Cargo.toml | 2 +- 11 files changed, 122 insertions(+), 16 deletions(-) create mode 100644 crates/holochain_p2p/src/mock.rs diff --git a/Cargo.lock b/Cargo.lock index 7d606b58cd..c07d944696 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,7 +1250,7 @@ dependencies = [ "lazy_static", "maplit", "matches", - "mockall", + "mockall 0.7.2", "must_future", "nanoid", "num_cpus", @@ -1324,6 +1324,7 @@ dependencies = [ name = "holochain_p2p" version = "0.0.1" dependencies = [ + "async-trait", "fixt", "futures", "ghost_actor", @@ -1333,6 +1334,7 @@ dependencies = [ "holochain_types", "holochain_zome_types", "kitsune_p2p", + "mockall 0.8.1", "serde", "serde_bytes", "thiserror", @@ -1965,7 +1967,22 @@ dependencies = [ "downcast", "fragile", "lazy_static", - "mockall_derive", + "mockall_derive 0.7.2", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ecfc6340c5b98a9a270b56e5f43353d87ebb18d9458a9301344bc79317c563" +dependencies = [ + "cfg-if", + "downcast", + "fragile", + "lazy_static", + "mockall_derive 0.8.1", "predicates", "predicates-tree", ] @@ -1982,6 +1999,18 @@ dependencies = [ "syn 1.0.41", ] +[[package]] +name = "mockall_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b873f753808fe0c3827ce76edb3ace27804966dfde3043adfac1c24d0a2559df" +dependencies = [ + "cfg-if", + "proc-macro2 1.0.21", + "quote 1.0.7", + "syn 1.0.41", +] + [[package]] name = "mortal" version = "0.2.2" diff --git a/crates/holochain/Cargo.toml b/crates/holochain/Cargo.toml index e65f0d7f91..42bb7494c4 100644 --- a/crates/holochain/Cargo.toml +++ b/crates/holochain/Cargo.toml @@ -10,7 +10,7 @@ edition = "2018" [dependencies] anyhow = "1.0.26" -async-trait = "0.1.24" +async-trait = "0.1" base64 = "0.10.1" cfg-if = "0.1" chrono = "0.4.6" diff --git a/crates/holochain/src/conductor/cell.rs b/crates/holochain/src/conductor/cell.rs index bf4fc676b6..68f692d8da 100644 --- a/crates/holochain/src/conductor/cell.rs +++ b/crates/holochain/src/conductor/cell.rs @@ -36,6 +36,7 @@ use futures::future::FutureExt; use hash_type::AnyDht; use holo_hash::*; use holochain_keystore::Signature; +use holochain_p2p::HolochainP2pCellT; use holochain_serialized_bytes::SerializedBytes; use holochain_state::{ db::GetDb, diff --git a/crates/holochain/src/core/ribosome.rs b/crates/holochain/src/core/ribosome.rs index 7d93b8bccc..d17ffb3286 100644 --- a/crates/holochain/src/core/ribosome.rs +++ b/crates/holochain/src/core/ribosome.rs @@ -486,6 +486,7 @@ pub mod wasm_test { let mut host_access = $host_access.clone(); let input = $input.clone(); tokio::task::spawn(async move { + use holochain_p2p::HolochainP2pCellT; // ensure type of test wasm use std::convert::TryInto; use $crate::core::ribosome::RibosomeT; diff --git a/crates/holochain/src/core/ribosome/host_fn/call_remote.rs b/crates/holochain/src/core/ribosome/host_fn/call_remote.rs index 180b21d0bf..838d1f9f6f 100644 --- a/crates/holochain/src/core/ribosome/host_fn/call_remote.rs +++ b/crates/holochain/src/core/ribosome/host_fn/call_remote.rs @@ -1,6 +1,7 @@ use crate::core::ribosome::error::RibosomeResult; use crate::core::ribosome::CallContext; use crate::core::ribosome::RibosomeT; +use holochain_p2p::HolochainP2pCellT; use holochain_zome_types::CallRemoteInput; use holochain_zome_types::CallRemoteOutput; use holochain_zome_types::ZomeCallResponse; diff --git a/crates/holochain/src/core/state/cascade.rs b/crates/holochain/src/core/state/cascade.rs index 74713dedbb..f4dde81b58 100644 --- a/crates/holochain/src/core/state/cascade.rs +++ b/crates/holochain/src/core/state/cascade.rs @@ -18,6 +18,7 @@ use holo_hash::{ hash_type::{self, AnyDht}, AnyDhtHash, EntryHash, HasHash, HeaderHash, }; +use holochain_p2p::HolochainP2pCellT; use holochain_p2p::{ actor::{GetLinksOptions, GetMetaOptions, GetOptions}, HolochainP2pCell, diff --git a/crates/holochain/src/core/workflow/publish_dht_ops_workflow.rs b/crates/holochain/src/core/workflow/publish_dht_ops_workflow.rs index 8086441a68..a03ce11691 100644 --- a/crates/holochain/src/core/workflow/publish_dht_ops_workflow.rs +++ b/crates/holochain/src/core/workflow/publish_dht_ops_workflow.rs @@ -25,6 +25,7 @@ use crate::core::{ use fallible_iterator::FallibleIterator; use holo_hash::*; use holochain_p2p::HolochainP2pCell; +use holochain_p2p::HolochainP2pCellT; use holochain_state::{ buffer::{BufferedStore, KvBufFresh}, db::AUTHORED_DHT_OPS, diff --git a/crates/holochain_p2p/Cargo.toml b/crates/holochain_p2p/Cargo.toml index b6388d4625..013a2d5d5d 100644 --- a/crates/holochain_p2p/Cargo.toml +++ b/crates/holochain_p2p/Cargo.toml @@ -11,6 +11,7 @@ categories = [ "network-programming" ] edition = "2018" [dependencies] +async-trait = "0.1" fixt = { path = "../fixt" } futures = "0.3" ghost_actor = "0.2.1" @@ -20,6 +21,7 @@ holochain_serialized_bytes = "=0.0.43" holochain_types = { version = "0.0.1", path = "../types" } holochain_zome_types = { version = "0.0.1", path = "../zome_types" } kitsune_p2p = { version = "0.0.1", path = "../kitsune_p2p/kitsune_p2p" } +mockall = "0.8.1" serde = { version = "1.0.104", features = [ "derive" ] } serde_bytes = "0.11" thiserror = "1.0.18" diff --git a/crates/holochain_p2p/src/lib.rs b/crates/holochain_p2p/src/lib.rs index cb1d029b9d..c95eb567ef 100644 --- a/crates/holochain_p2p/src/lib.rs +++ b/crates/holochain_p2p/src/lib.rs @@ -22,6 +22,74 @@ use holochain_types::{ pub use spawn::*; pub use test::HolochainP2pCellFixturator; +#[mockall::automock] +#[async_trait::async_trait] +/// A wrapper around HolochainP2pSender that partially applies the dna_hash / agent_pub_key. +/// I.e. a sender that is tied to a specific cell. +pub trait HolochainP2pCellT { + /// owned getter + fn dna_hash(&self) -> DnaHash; + + /// owned getter + fn from_agent(&self) -> AgentPubKey; + + /// The p2p module must be informed at runtime which dna/agent pairs it should be tracking. + async fn join(&mut self) -> actor::HolochainP2pResult<()>; + + /// If a cell is deactivated, we'll need to \"leave\" the network module as well. + async fn leave(&mut self) -> actor::HolochainP2pResult<()>; + + /// Invoke a zome function on a remote node (if you have been granted the capability). + async fn call_remote( + &mut self, + to_agent: AgentPubKey, + zome_name: ZomeName, + fn_name: FunctionName, + cap: Option, + request: SerializedBytes, + ) -> actor::HolochainP2pResult; + + /// Publish data to the correct neighborhood. + async fn publish( + &mut self, + request_validation_receipt: bool, + dht_hash: holo_hash::AnyDhtHash, + ops: Vec<(holo_hash::DhtOpHash, holochain_types::dht_op::DhtOp)>, + timeout_ms: Option, + ) -> actor::HolochainP2pResult<()>; + + /// Request a validation package. + async fn get_validation_package(&mut self) -> actor::HolochainP2pResult<()>; + + /// Get an entry from the DHT. + async fn get( + &mut self, + dht_hash: holo_hash::AnyDhtHash, + options: actor::GetOptions, + ) -> actor::HolochainP2pResult>; + + /// Get metadata from the DHT. + async fn get_meta( + &mut self, + dht_hash: holo_hash::AnyDhtHash, + options: actor::GetMetaOptions, + ) -> actor::HolochainP2pResult>; + + /// Get links from the DHT. + async fn get_links( + &mut self, + link_key: WireLinkMetaKey, + options: actor::GetLinksOptions, + ) -> actor::HolochainP2pResult>; + + /// Send a validation receipt to a remote node. + async fn send_validation_receipt( + &mut self, + to_agent: AgentPubKey, + receipt: SerializedBytes, + ) -> actor::HolochainP2pResult<()>; +} + /// A wrapper around HolochainP2pSender that partially applies the dna_hash / agent_pub_key. /// I.e. a sender that is tied to a specific cell. #[derive(Clone)] @@ -31,33 +99,34 @@ pub struct HolochainP2pCell { from_agent: Arc, } -impl HolochainP2pCell { +#[async_trait::async_trait] +impl HolochainP2pCellT for HolochainP2pCell { /// owned getter - pub fn dna_hash(&self) -> DnaHash { + fn dna_hash(&self) -> DnaHash { (*self.dna_hash).clone() } /// owned getter - pub fn from_agent(&self) -> AgentPubKey { + fn from_agent(&self) -> AgentPubKey { (*self.from_agent).clone() } /// The p2p module must be informed at runtime which dna/agent pairs it should be tracking. - pub async fn join(&mut self) -> actor::HolochainP2pResult<()> { + async fn join(&mut self) -> actor::HolochainP2pResult<()> { self.sender .join((*self.dna_hash).clone(), (*self.from_agent).clone()) .await } /// If a cell is deactivated, we'll need to \"leave\" the network module as well. - pub async fn leave(&mut self) -> actor::HolochainP2pResult<()> { + async fn leave(&mut self) -> actor::HolochainP2pResult<()> { self.sender .leave((*self.dna_hash).clone(), (*self.from_agent).clone()) .await } /// Invoke a zome function on a remote node (if you have been granted the capability). - pub async fn call_remote( + async fn call_remote( &mut self, to_agent: AgentPubKey, zome_name: ZomeName, @@ -79,7 +148,7 @@ impl HolochainP2pCell { } /// Publish data to the correct neighborhood. - pub async fn publish( + async fn publish( &mut self, request_validation_receipt: bool, dht_hash: holo_hash::AnyDhtHash, @@ -99,7 +168,7 @@ impl HolochainP2pCell { } /// Request a validation package. - pub async fn get_validation_package(&mut self) -> actor::HolochainP2pResult<()> { + async fn get_validation_package(&mut self) -> actor::HolochainP2pResult<()> { self.sender .get_validation_package(actor::GetValidationPackage { dna_hash: (*self.dna_hash).clone(), @@ -109,7 +178,7 @@ impl HolochainP2pCell { } /// Get an entry from the DHT. - pub async fn get( + async fn get( &mut self, dht_hash: holo_hash::AnyDhtHash, options: actor::GetOptions, @@ -126,7 +195,7 @@ impl HolochainP2pCell { } /// Get metadata from the DHT. - pub async fn get_meta( + async fn get_meta( &mut self, dht_hash: holo_hash::AnyDhtHash, options: actor::GetMetaOptions, @@ -142,7 +211,7 @@ impl HolochainP2pCell { } /// Get links from the DHT. - pub async fn get_links( + async fn get_links( &mut self, link_key: WireLinkMetaKey, options: actor::GetLinksOptions, @@ -158,7 +227,7 @@ impl HolochainP2pCell { } /// Send a validation receipt to a remote node. - pub async fn send_validation_receipt( + async fn send_validation_receipt( &mut self, to_agent: AgentPubKey, receipt: SerializedBytes, diff --git a/crates/holochain_p2p/src/mock.rs b/crates/holochain_p2p/src/mock.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/crates/holochain_p2p/src/mock.rs @@ -0,0 +1 @@ + diff --git a/crates/types/Cargo.toml b/crates/types/Cargo.toml index 224965a11b..0a1d460711 100644 --- a/crates/types/Cargo.toml +++ b/crates/types/Cargo.toml @@ -13,7 +13,7 @@ edition = "2018" [dependencies] anyhow = "1.0.26" -async-trait = "0.1.24" +async-trait = "0.1" backtrace = "0.3.27" base64 = "0.10.1" chrono = "0.4.6" From 85a2dfad32f03908617c947ebc308a0821216ff1 Mon Sep 17 00:00:00 2001 From: Michael Dougherty Date: Wed, 16 Sep 2020 15:10:23 -0700 Subject: [PATCH 2/5] Make cascade and some sys validation checks generic over Network --- crates/holochain/src/conductor/cell.rs | 9 ++++--- crates/holochain/src/core/state/cascade.rs | 26 ++++++++++--------- .../src/core/sys_validate/present.rs | 20 +++++++------- .../core/workflow/sys_validation_workflow.rs | 7 +++-- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/crates/holochain/src/conductor/cell.rs b/crates/holochain/src/conductor/cell.rs index 68f692d8da..5bd86e8b22 100644 --- a/crates/holochain/src/conductor/cell.rs +++ b/crates/holochain/src/conductor/cell.rs @@ -95,14 +95,15 @@ impl PartialEq for Cell { /// The [Conductor] manages a collection of Cells, and will call functions /// on the Cell when a Conductor API method is called (either a /// [CellConductorApi] or an [AppInterfaceApi]) -pub struct Cell +pub struct Cell where - CA: CellConductorApiT, + Api: CellConductorApiT, + P2pCell: holochain_p2p::HolochainP2pCellT, { id: CellId, - conductor_api: CA, + conductor_api: Api, env: EnvironmentWrite, - holochain_p2p_cell: holochain_p2p::HolochainP2pCell, + holochain_p2p_cell: P2pCell, queue_triggers: InitialQueueTriggers, } diff --git a/crates/holochain/src/core/state/cascade.rs b/crates/holochain/src/core/state/cascade.rs index f4dde81b58..0817ed8bef 100644 --- a/crates/holochain/src/core/state/cascade.rs +++ b/crates/holochain/src/core/state/cascade.rs @@ -58,19 +58,20 @@ mod test; pub mod error; -pub struct Cascade<'a, M = MetadataBuf, C = MetadataBuf> +pub struct Cascade<'a, Network = HolochainP2pCell, MetaVault = MetadataBuf, MetaCache = MetadataBuf> where - M: MetadataBufT, - C: MetadataBufT, + Network: HolochainP2pCellT, + MetaVault: MetadataBufT, + MetaCache: MetadataBufT, { element_vault: &'a ElementBuf, - meta_vault: &'a M, + meta_vault: &'a MetaVault, element_cache: &'a mut ElementBuf, - meta_cache: &'a mut C, + meta_cache: &'a mut MetaCache, env: EnvironmentRead, - network: HolochainP2pCell, + network: Network, } #[derive(Debug)] @@ -90,19 +91,20 @@ enum Search { /// Should these functions be sync or async? /// Depends on how much computation, and if writes are involved -impl<'a, M, C> Cascade<'a, M, C> +impl<'a, Network, MetaVault, MetaCache> Cascade<'a, Network, MetaVault, MetaCache> where - C: MetadataBufT, - M: MetadataBufT, + MetaCache: MetadataBufT, + MetaVault: MetadataBufT, + Network: HolochainP2pCellT, { /// Constructs a [Cascade], taking references to all necessary databases pub fn new( env: EnvironmentRead, element_vault: &'a ElementBuf, - meta_vault: &'a M, + meta_vault: &'a MetaVault, element_cache: &'a mut ElementBuf, - meta_cache: &'a mut C, - network: HolochainP2pCell, + meta_cache: &'a mut MetaCache, + network: Network, ) -> Self { Cascade { env, diff --git a/crates/holochain/src/core/sys_validate/present.rs b/crates/holochain/src/core/sys_validate/present.rs index 115ef9a3e5..cc7f65eede 100644 --- a/crates/holochain/src/core/sys_validate/present.rs +++ b/crates/holochain/src/core/sys_validate/present.rs @@ -2,7 +2,7 @@ //! either being held locally or existing on the DHT use super::*; use crate::core::workflow::sys_validation_workflow::types::{CheckLevel, Dependency}; -use holochain_p2p::HolochainP2pCell; +use holochain_p2p::HolochainP2pCellT; macro_rules! check_holding { ($f:ident, $($hash:expr),+ => $dep:ident, $($ws:expr),+ ) => {{ @@ -42,7 +42,7 @@ macro_rules! check_holding_meta { pub async fn check_holding_entry_all( hash: &EntryHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, check_level: CheckLevel, ) -> SysValidationResult> { match check_level { @@ -63,7 +63,7 @@ async fn check_holding_entry_inner( pub async fn check_holding_header_all( hash: &HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, check_level: CheckLevel, ) -> SysValidationResult> { match check_level { @@ -83,7 +83,7 @@ async fn check_holding_header_inner( pub async fn check_holding_element_all( hash: &HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, check_level: CheckLevel, ) -> SysValidationResult> { match check_level { @@ -106,7 +106,7 @@ pub async fn check_holding_prev_header_all( author: &AgentPubKey, prev_header_hash: &HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, check_level: CheckLevel, ) -> SysValidationResult> { match check_level { @@ -137,7 +137,7 @@ pub async fn check_holding_store_entry_all( entry_hash: &EntryHash, header_hash: &HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, check_level: CheckLevel, ) -> SysValidationResult> { match check_level { @@ -165,7 +165,7 @@ async fn check_holding_store_entry_inner( pub async fn check_holding_link_add_all( header_hash: &HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, check_level: CheckLevel, ) -> SysValidationResult> { match check_level { @@ -328,7 +328,7 @@ async fn check_holding_element( pub async fn check_entry_exists( entry_hash: EntryHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, ) -> SysValidationResult> { check_holding_entry!(workspace, check_holding_entry, &entry_hash); let mut cascade = workspace.cascade(network); @@ -343,7 +343,7 @@ pub async fn check_entry_exists( pub async fn check_header_exists( hash: HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, ) -> SysValidationResult> { check_holding_el!(workspace, check_holding_header, &hash); let mut cascade = workspace.cascade(network); @@ -358,7 +358,7 @@ pub async fn check_header_exists( pub async fn check_element_exists( hash: HeaderHash, workspace: &mut SysValidationWorkspace, - network: HolochainP2pCell, + network: impl HolochainP2pCellT, ) -> SysValidationResult> { check_holding_el!(workspace, check_holding_element, &hash); let mut cascade = workspace.cascade(network); diff --git a/crates/holochain/src/core/workflow/sys_validation_workflow.rs b/crates/holochain/src/core/workflow/sys_validation_workflow.rs index 4968007155..cd9870f387 100644 --- a/crates/holochain/src/core/workflow/sys_validation_workflow.rs +++ b/crates/holochain/src/core/workflow/sys_validation_workflow.rs @@ -20,7 +20,7 @@ use error::WorkflowResult; use fallible_iterator::FallibleIterator; use holo_hash::DhtOpHash; use holochain_keystore::Signature; -use holochain_p2p::HolochainP2pCell; +use holochain_p2p::{HolochainP2pCell, HolochainP2pCellT}; use holochain_state::{ buffer::{BufferedStore, KvBufFresh}, db::INTEGRATION_LIMBO, @@ -561,7 +561,10 @@ pub struct SysValidationWorkspace { } impl<'a> SysValidationWorkspace { - pub fn cascade(&'a mut self, network: HolochainP2pCell) -> Cascade<'a> { + pub fn cascade( + &'a mut self, + network: Network, + ) -> Cascade<'a, Network> { Cascade::new( self.validation_limbo.env().clone(), &self.element_vault, From 99882e2c6e5b3b0fda52d0385fcaf97422ecfb2c Mon Sep 17 00:00:00 2001 From: Michael Dougherty Date: Wed, 16 Sep 2020 15:40:57 -0700 Subject: [PATCH 3/5] automock ConductorHandle --- Cargo.lock | 33 +-- crates/holochain/Cargo.toml | 2 +- crates/holochain/src/conductor/cell/test.rs | 2 +- crates/holochain/src/conductor/compat.rs | 6 +- crates/holochain/src/conductor/conductor.rs | 6 +- crates/holochain/src/conductor/handle.rs | 226 +------------------- 6 files changed, 11 insertions(+), 264 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c07d944696..ed2b97ad6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1250,7 +1250,7 @@ dependencies = [ "lazy_static", "maplit", "matches", - "mockall 0.7.2", + "mockall", "must_future", "nanoid", "num_cpus", @@ -1334,7 +1334,7 @@ dependencies = [ "holochain_types", "holochain_zome_types", "kitsune_p2p", - "mockall 0.8.1", + "mockall", "serde", "serde_bytes", "thiserror", @@ -1957,21 +1957,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "mockall" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01458f8a19b10cb28195290942e3149161c75acf67ebc8fbf714ab67a2b943bc" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "lazy_static", - "mockall_derive 0.7.2", - "predicates", - "predicates-tree", -] - [[package]] name = "mockall" version = "0.8.1" @@ -1982,23 +1967,11 @@ dependencies = [ "downcast", "fragile", "lazy_static", - "mockall_derive 0.8.1", + "mockall_derive", "predicates", "predicates-tree", ] -[[package]] -name = "mockall_derive" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a673cb441f78cd9af4f5919c28576a3cc325fb6b54e42f7047dacce3c718c17b" -dependencies = [ - "cfg-if", - "proc-macro2 1.0.21", - "quote 1.0.7", - "syn 1.0.41", -] - [[package]] name = "mockall_derive" version = "0.8.1" diff --git a/crates/holochain/Cargo.toml b/crates/holochain/Cargo.toml index 42bb7494c4..8a31e55739 100644 --- a/crates/holochain/Cargo.toml +++ b/crates/holochain/Cargo.toml @@ -36,7 +36,7 @@ holochain_zome_types = { version = "0.0.1", path = "../zome_types" } human-panic = "1.0.3" lazy_static = "1.4.0" legacy = { path = "../legacy", package = "holochain_legacy" } -mockall = "0.7.0" +mockall = "0.8" must_future = "0.1.1" nanoid = "0.3" num_cpus = "1.8" diff --git a/crates/holochain/src/conductor/cell/test.rs b/crates/holochain/src/conductor/cell/test.rs index ab6cdd8935..f8bd23aad8 100644 --- a/crates/holochain/src/conductor/cell/test.rs +++ b/crates/holochain/src/conductor/cell/test.rs @@ -29,7 +29,7 @@ async fn test_cell_handle_publish() { let holochain_p2p_cell = holochain_p2p.to_cell(dna.clone(), agent.clone()); - let mut mock_handler = crate::conductor::handle::mock::MockConductorHandle::new(); + let mut mock_handler = crate::conductor::handle::MockConductorHandleT::new(); mock_handler .expect_sync_get_dna() .returning(|_| Some(fixt!(DnaFile))); diff --git a/crates/holochain/src/conductor/compat.rs b/crates/holochain/src/conductor/compat.rs index 792be3e393..e2be002ca0 100644 --- a/crates/holochain/src/conductor/compat.rs +++ b/crates/holochain/src/conductor/compat.rs @@ -186,9 +186,7 @@ fn extract_app_interfaces( pub mod tests { use super::*; - use crate::conductor::{ - handle::mock::MockConductorHandle, paths::EnvironmentRootPath, Conductor, - }; + use crate::conductor::{handle::MockConductorHandleT, paths::EnvironmentRootPath, Conductor}; use holochain_types::{app::MembraneProof, test_utils::fake_dna_zomes}; use holochain_wasm_test_utils::TestWasm; use matches::assert_matches; @@ -347,7 +345,7 @@ pub mod tests { .await .unwrap(); - let mut handle = MockConductorHandle::new(); + let mut handle = MockConductorHandleT::new(); handle .expect_sync_install_dna() .with(predicate::eq(dna1.clone())) diff --git a/crates/holochain/src/conductor/conductor.rs b/crates/holochain/src/conductor/conductor.rs index ba37635dba..308090291b 100755 --- a/crates/holochain/src/conductor/conductor.rs +++ b/crates/holochain/src/conductor/conductor.rs @@ -65,7 +65,7 @@ use futures::future::{self, TryFutureExt}; use holo_hash::DnaHash; #[cfg(test)] -use super::handle::mock::MockConductorHandle; +use super::handle::MockConductorHandleT; use fallible_iterator::FallibleIterator; use holochain_zome_types::entry_def::EntryDef; @@ -734,7 +734,7 @@ mod builder { #[cfg(test)] state: Option, #[cfg(test)] - mock_handle: Option, + mock_handle: Option, } impl ConductorBuilder { @@ -886,7 +886,7 @@ mod builder { /// Pass a mock handle in, which will be returned regardless of whatever /// else happens to this builder #[cfg(test)] - pub fn with_mock_handle(mut self, handle: MockConductorHandle) -> Self { + pub fn with_mock_handle(mut self, handle: MockConductorHandleT) -> Self { self.mock_handle = Some(handle); self } diff --git a/crates/holochain/src/conductor/handle.rs b/crates/holochain/src/conductor/handle.rs index 209d736944..c942e1f862 100644 --- a/crates/holochain/src/conductor/handle.rs +++ b/crates/holochain/src/conductor/handle.rs @@ -80,6 +80,7 @@ use holochain_zome_types::entry_def::EntryDef; pub type ConductorHandle = Arc; /// Base trait for ConductorHandle +#[mockall::automock] #[async_trait::async_trait] pub trait ConductorHandleT: Send + Sync { /// Returns error if conductor is shutting down @@ -429,228 +430,3 @@ impl ConductorHandleT for ConductorHandleImpl { Ok(lock.get_state_from_handle().await?) } } - -#[cfg(test)] -pub mod mock { - use super::*; - use mockall::mock; - - // Unfortunate workaround to get mockall to work with async_trait, due to the complexity of each. - // The mock! expansion here creates mocks on a non-async version of the API, and then the actual trait is implemented - // by delegating each async trait method to its sync counterpart - // See https://github.com/asomers/mockall/issues/75 - mock! { - - pub ConductorHandle { - fn sync_check_running(&self) -> ConductorResult<()>; - - fn sync_add_admin_interfaces( - &self, - configs: Vec, - ) -> ConductorResult<()>; - - fn sync_add_app_interface( - &self, - port: u16, - ) -> ConductorResult; - - fn sync_install_dna(&self, dna: DnaFile) -> ConductorResult<()>; - - fn sync_list_dnas(&self) -> ConductorResult>; - - fn sync_add_dnas(&self) -> ConductorResult<()>; - - fn sync_get_dna(&self, hash: &DnaHash) -> Option; - - fn sync_get_entry_def(&self, key: &EntryDefBufferKey) -> Option; - - fn sync_dispatch_holochain_p2p_event(&self, cell_id: &CellId, event: holochain_p2p::event::HolochainP2pEvent) -> ConductorResult<()>; - - fn sync_call_zome( - &self, - invocation: ZomeCallInvocation, - ) -> ConductorApiResult; - - fn sync_autonomic_cue(&self, cue: AutonomicCue, cell_id: &CellId) -> ConductorApiResult<()>; - - fn sync_take_shutdown_handle(&self) -> Option; - - fn sync_get_arbitrary_admin_websocket_port(&self) -> Option; - - fn sync_shutdown(&self); - - fn sync_keystore(&self) -> &KeystoreSender; - - fn sync_holochain_p2p(&self) -> &holochain_p2p::HolochainP2pRef; - - fn sync_install_app( - &self, - app_id: AppId, - cell_data_with_proofs: Vec<(InstalledCell, Option)>, - ) -> ConductorResult<()>; - - fn sync_setup_cells(&self) -> ConductorResult>; - - fn sync_activate_app(&self, app_id: AppId) -> ConductorResult<()>; - - fn sync_deactivate_app(&self, app_id: AppId) -> ConductorResult<()>; - - fn sync_list_cell_ids(&self) -> ConductorResult>; - - fn sync_dump_cell_state(&self, cell_id: &CellId) -> ConductorApiResult; - - fn sync_get_app_info(&self, app_id: &AppId) -> ConductorResult>; - - #[cfg(test)] - fn sync_get_cell_env(&self, cell_id: &CellId) -> ConductorApiResult; - - #[cfg(test)] - fn sync_get_cell_triggers( - &self, - cell_id: &CellId, - ) -> ConductorApiResult; - - #[cfg(test)] - fn sync_get_state_from_handle(&self) -> ConductorApiResult; - } - - trait Clone { - fn clone(&self) -> Self; - } - } - - #[async_trait::async_trait] - impl ConductorHandleT for MockConductorHandle { - async fn check_running(&self) -> ConductorResult<()> { - self.sync_check_running() - } - - async fn add_admin_interfaces( - self: Arc, - configs: Vec, - ) -> ConductorResult<()> { - self.sync_add_admin_interfaces(configs) - } - - async fn add_app_interface(self: Arc, port: u16) -> ConductorResult { - self.sync_add_app_interface(port) - } - - async fn add_dnas(&self) -> ConductorResult<()> { - self.sync_add_dnas() - } - - async fn install_dna(&self, dna: DnaFile) -> ConductorResult<()> { - self.sync_install_dna(dna) - } - - async fn list_dnas(&self) -> ConductorResult> { - self.sync_list_dnas() - } - - async fn get_dna(&self, hash: &DnaHash) -> Option { - self.sync_get_dna(hash) - } - - async fn get_entry_def(&self, key: &EntryDefBufferKey) -> Option { - self.sync_get_entry_def(key) - } - - async fn dispatch_holochain_p2p_event( - &self, - cell_id: &CellId, - event: holochain_p2p::event::HolochainP2pEvent, - ) -> ConductorResult<()> { - self.sync_dispatch_holochain_p2p_event(cell_id, event) - } - - async fn call_zome( - &self, - invocation: ZomeCallInvocation, - ) -> ConductorApiResult { - self.sync_call_zome(invocation) - } - - async fn autonomic_cue( - &self, - cue: AutonomicCue, - cell_id: &CellId, - ) -> ConductorApiResult<()> { - self.sync_autonomic_cue(cue, cell_id) - } - - async fn take_shutdown_handle(&self) -> Option { - self.sync_take_shutdown_handle() - } - - async fn get_arbitrary_admin_websocket_port(&self) -> Option { - self.sync_get_arbitrary_admin_websocket_port() - } - - async fn shutdown(&self) { - self.sync_shutdown() - } - - fn keystore(&self) -> &KeystoreSender { - self.sync_keystore() - } - - fn holochain_p2p(&self) -> &holochain_p2p::HolochainP2pRef { - self.sync_holochain_p2p() - } - - async fn install_app( - self: Arc, - app_id: AppId, - cell_data_with_proofs: Vec<(InstalledCell, Option)>, - ) -> ConductorResult<()> { - self.sync_install_app(app_id, cell_data_with_proofs) - } - - /// Setup the cells from the database - /// Only creates any cells that are not already created - async fn setup_cells(self: Arc) -> ConductorResult> { - self.sync_setup_cells() - } - - async fn activate_app(&self, app_id: AppId) -> ConductorResult<()> { - self.sync_activate_app(app_id) - } - - async fn deactivate_app(&self, app_id: AppId) -> ConductorResult<()> { - self.sync_deactivate_app(app_id) - } - - async fn list_cell_ids(&self) -> ConductorResult> { - self.sync_list_cell_ids() - } - - /// Dump the cells state - async fn dump_cell_state(&self, cell_id: &CellId) -> ConductorApiResult { - self.sync_dump_cell_state(cell_id) - } - - async fn get_app_info(&self, app_id: &AppId) -> ConductorResult> { - self.sync_get_app_info(app_id) - } - - #[cfg(test)] - async fn get_cell_env(&self, cell_id: &CellId) -> ConductorApiResult { - self.sync_get_cell_env(cell_id) - } - - #[cfg(test)] - async fn get_cell_triggers( - &self, - cell_id: &CellId, - ) -> ConductorApiResult { - self.sync_get_cell_triggers(cell_id) - } - - // HACK: remove when B-01593 lands - #[cfg(test)] - async fn get_state_from_handle(&self) -> ConductorApiResult { - self.sync_get_state_from_handle() - } - } -} From 21c43a0915cb7c47f8e5537c040a7465e6ef75e4 Mon Sep 17 00:00:00 2001 From: Michael Dougherty Date: Wed, 16 Sep 2020 17:40:41 -0700 Subject: [PATCH 4/5] Clippy --- crates/holochain/src/conductor/handle.rs | 5 +++++ crates/holochain/src/core/state/metadata.rs | 6 ++++-- crates/holochain_p2p/src/lib.rs | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/holochain/src/conductor/handle.rs b/crates/holochain/src/conductor/handle.rs index c942e1f862..3cb60e4d12 100644 --- a/crates/holochain/src/conductor/handle.rs +++ b/crates/holochain/src/conductor/handle.rs @@ -93,6 +93,7 @@ pub trait ConductorHandleT: Send + Sync { /// around having a circular reference in the types. /// /// Never use a ConductorHandle for different Conductor here! + #[allow(clippy::ptr_arg)] async fn add_admin_interfaces( self: Arc, configs: Vec, @@ -153,6 +154,7 @@ pub trait ConductorHandleT: Send + Sync { /// Install Cells into ConductorState based on installation info, and run /// genesis on all new source chains + #[allow(clippy::ptr_arg)] async fn install_app( self: Arc, app_id: AppId, @@ -164,15 +166,18 @@ pub trait ConductorHandleT: Send + Sync { async fn setup_cells(self: Arc) -> ConductorResult>; /// Activate an app + #[allow(clippy::ptr_arg)] async fn activate_app(&self, app_id: AppId) -> ConductorResult<()>; /// Deactivate an app + #[allow(clippy::ptr_arg)] async fn deactivate_app(&self, app_id: AppId) -> ConductorResult<()>; /// List Cell Ids async fn list_cell_ids(&self) -> ConductorResult>; /// Dump the cells state + #[allow(clippy::ptr_arg)] async fn dump_cell_state(&self, cell_id: &CellId) -> ConductorApiResult; /// Get info about an installed App, whether active or inactive diff --git a/crates/holochain/src/core/state/metadata.rs b/crates/holochain/src/core/state/metadata.rs index 3f0f5f42fc..dc9d64459b 100755 --- a/crates/holochain/src/core/state/metadata.rs +++ b/crates/holochain/src/core/state/metadata.rs @@ -43,8 +43,10 @@ mod sys_meta; #[cfg(test)] mod mock; -/// Trait for the [MetadataBuf] -/// Needed for mocking +/// Trait for the [MetadataBuf], needed for mocking +/// +/// Unfortunately this cannot be automocked because of the lifetimes required +/// for returning iterators from these trait methods, which automock doesn't support. #[async_trait::async_trait] pub trait MetadataBufT

where diff --git a/crates/holochain_p2p/src/lib.rs b/crates/holochain_p2p/src/lib.rs index c95eb567ef..19af883574 100644 --- a/crates/holochain_p2p/src/lib.rs +++ b/crates/holochain_p2p/src/lib.rs @@ -50,6 +50,7 @@ pub trait HolochainP2pCellT { ) -> actor::HolochainP2pResult; /// Publish data to the correct neighborhood. + #[allow(clippy::ptr_arg)] async fn publish( &mut self, request_validation_receipt: bool, From 340e7a664605af8f2383777d109e08444a0cac5b Mon Sep 17 00:00:00 2001 From: Michael Dougherty Date: Wed, 16 Sep 2020 18:32:17 -0700 Subject: [PATCH 5/5] Fixes --- crates/holochain/src/conductor/cell/test.rs | 2 +- crates/holochain/src/conductor/compat.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/holochain/src/conductor/cell/test.rs b/crates/holochain/src/conductor/cell/test.rs index f8bd23aad8..cb218f0eb4 100644 --- a/crates/holochain/src/conductor/cell/test.rs +++ b/crates/holochain/src/conductor/cell/test.rs @@ -31,7 +31,7 @@ async fn test_cell_handle_publish() { let mut mock_handler = crate::conductor::handle::MockConductorHandleT::new(); mock_handler - .expect_sync_get_dna() + .expect_get_dna() .returning(|_| Some(fixt!(DnaFile))); let mock_handler: crate::conductor::handle::ConductorHandle = Arc::new(mock_handler); diff --git a/crates/holochain/src/conductor/compat.rs b/crates/holochain/src/conductor/compat.rs index e2be002ca0..4af02b80fd 100644 --- a/crates/holochain/src/conductor/compat.rs +++ b/crates/holochain/src/conductor/compat.rs @@ -347,22 +347,22 @@ pub mod tests { let mut handle = MockConductorHandleT::new(); handle - .expect_sync_install_dna() + .expect_install_dna() .with(predicate::eq(dna1.clone())) .times(1) .returning(|_| Ok(())); handle - .expect_sync_install_dna() + .expect_install_dna() .with(predicate::eq(dna1a.clone())) .times(1) .returning(|_| Ok(())); handle - .expect_sync_install_dna() + .expect_install_dna() .with(predicate::eq(dna2.clone())) .times(1) .returning(|_| Ok(())); handle - .expect_sync_install_app() + .expect_install_app() .with( predicate::eq("LEGACY".to_string()), predicate::function(move |data: &Vec<(InstalledCell, Option)>| { @@ -375,16 +375,16 @@ pub mod tests { .times(1) .returning(|_, _| Ok(())); handle - .expect_sync_activate_app() + .expect_activate_app() .with(predicate::eq("LEGACY".to_string())) .times(1) .returning(|_| Ok(())); handle - .expect_sync_setup_cells() + .expect_setup_cells() .times(1) .returning(|| Ok(vec![])); handle - .expect_sync_add_app_interface() + .expect_add_app_interface() .with(predicate::eq(1111)) .times(1) .returning(|port| Ok(port));