Browse Source

Improved `IFError`, wrote `TestInterface` and some tests for `Transport`

interface-2
Lev 3 years ago
parent
commit
1f7c9efcc1
  1. 10
      Cargo.lock
  2. 1
      Cargo.toml
  3. 3
      src/crypto.rs
  4. 37
      src/interface.rs
  5. 1
      src/lib.rs
  6. 3
      src/res.rs
  7. 54
      src/transport.rs

10
Cargo.lock generated

@ -65,6 +65,15 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b"
[[package]]
name = "core-error"
version = "0.0.1-rc4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7851bcb61e74ebcf5f2f1f1ee119f647c03fec697768bbcc86c26654fd21f977"
dependencies = [
"version_check",
]
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.1" version = "0.5.1"
@ -214,6 +223,7 @@ dependencies = [
name = "ironforce" name = "ironforce"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"core-error",
"rand", "rand",
"rand_os", "rand_os",
"rayon", "rayon",

1
Cargo.toml

@ -18,6 +18,7 @@ rand = "*"
rsa = { version = "0.5", features = ["serde"] } rsa = { version = "0.5", features = ["serde"] }
serde = { version = "1.0", features = ["derive", "alloc"], default-features = false } serde = { version = "1.0", features = ["derive", "alloc"], default-features = false }
rayon = { version = "1.5.1", optional = true } rayon = { version = "1.5.1", optional = true }
core-error = "0.0.1-rc4"
[profile.dev.package.num-bigint-dig] [profile.dev.package.num-bigint-dig]
opt-level = 3 opt-level = 3

3
src/crypto.rs

@ -74,6 +74,9 @@ fn test_encrypt() {
); );
} }
#[cfg(test)]
use alloc::vec;
#[test] #[test]
fn test_invalid_encrypt() { fn test_invalid_encrypt() {
let data = vec![0, 5, 8, 135, 67]; let data = vec![0, 5, 8, 135, 67];

37
src/interface.rs

@ -12,6 +12,7 @@ pub(crate) type TargetingData = String;
/// In an std environment we require that the interface can be send safely between threads /// In an std environment we require that the interface can be send safely between threads
#[cfg(not(std))] #[cfg(not(std))]
pub trait InterfaceRequirements {} pub trait InterfaceRequirements {}
#[cfg(std)] #[cfg(std)]
pub trait InterfaceRequirements = Send + Sync; pub trait InterfaceRequirements = Send + Sync;
@ -39,3 +40,39 @@ pub trait Interface: InterfaceRequirements {
/// The implementations of this function shouldn't wait for new messages, but /// The implementations of this function shouldn't wait for new messages, but
fn receive(&mut self) -> IFResult<Option<(MessageBytes, TargetingData /*interface data*/)>>; fn receive(&mut self) -> IFResult<Option<(MessageBytes, TargetingData /*interface data*/)>>;
} }
#[cfg(test)]
pub mod test_interface {
use crate::interface::{Interface, InterfaceRequirements, TargetingData};
use crate::message::MessageBytes;
use crate::res::IFResult;
use alloc::vec::Vec;
#[derive(Default)]
pub struct TestInterface {
messages: Vec<(Vec<u8>, TargetingData)>,
}
impl InterfaceRequirements for TestInterface {}
impl Interface for TestInterface {
fn main_loop_iteration(&mut self) -> IFResult<()> {
Ok(())
}
fn id(&self) -> &str {
"test_interface"
}
fn send(&mut self, message: &[u8], interface_data: Option<TargetingData>) -> IFResult<()> {
self.messages.push((Vec::from(message), interface_data.unwrap_or_default()));
Ok(())
}
fn receive(&mut self) -> IFResult<Option<(MessageBytes, TargetingData)>> {
Ok(
self.messages.pop()
)
}
}
}

1
src/lib.rs

@ -4,6 +4,7 @@
extern crate alloc; extern crate alloc;
extern crate rand; extern crate rand;
extern crate rsa; extern crate rsa;
extern crate core_error;
mod crypto; mod crypto;
mod ironforce; mod ironforce;

3
src/res.rs

@ -3,13 +3,14 @@ use alloc::string::String;
use core::fmt::Debug; use core::fmt::Debug;
/// An enum for all errors that may occur /// An enum for all errors that may occur
#[derive(Clone, PartialEq, Debug)]
pub enum IFError { pub enum IFError {
/// An error that was created in some dependency and then converted to `IFError` /// An error that was created in some dependency and then converted to `IFError`
General(String), General(String),
} }
impl<T: Debug> From<T> for IFError { impl<T: Debug + core_error::Error> From<T> for IFError {
/// Convert from other error /// Convert from other error
fn from(e: T) -> Self { fn from(e: T) -> Self {
Self::General(format!("{:?}", e)) Self::General(format!("{:?}", e))

54
src/transport.rs

@ -1,6 +1,7 @@
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::string::String; use alloc::string::String;
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::vec;
use crate::interface::{Interface, TargetingData}; use crate::interface::{Interface, TargetingData};
use crate::message::MessageBytes; use crate::message::MessageBytes;
use crate::res::IFResult; use crate::res::IFResult;
@ -10,7 +11,7 @@ use rayon::prelude::*;
/// An identification of a peer - something that we can use to send a message to id /// An identification of a peer - something that we can use to send a message to id
#[derive(Clone, Debug)] #[derive(Clone, Debug, PartialEq)]
pub struct PeerInfo { pub struct PeerInfo {
/// Something to locally identify this peer /// Something to locally identify this peer
pub peer_id: u64, pub peer_id: u64,
@ -38,6 +39,11 @@ pub struct Transport {
} }
impl Transport { impl Transport {
/// Create new transport with given interfaces
pub fn new(interfaces: Vec<Box<dyn Interface>>) -> Self {
Self { interfaces, peers: vec![] }
}
/// Find a peer in `self.peers` by its id /// Find a peer in `self.peers` by its id
fn get_peer_by_id(&self, peer_id: u64) -> Option<PeerInfo> { fn get_peer_by_id(&self, peer_id: u64) -> Option<PeerInfo> {
self.peers.iter().find(|peer| peer.peer_id == peer_id).cloned() self.peers.iter().find(|peer| peer.peer_id == peer_id).cloned()
@ -73,16 +79,16 @@ impl Transport {
// Broadcast // Broadcast
None => { None => {
#[cfg(not(std))] #[cfg(not(std))]
{ {
for interface in &mut self.interfaces { for interface in &mut self.interfaces {
interface.send(&message, None)?; interface.send(&message, None)?;
}
} }
}
// If we have concurrency, we will do it concurrently // If we have concurrency, we will do it concurrently
#[cfg(std)] #[cfg(std)]
{ {
self.interfaces.par_iter_mut().map(|interface| interface.send(&message, None)).for_each(drop); self.interfaces.par_iter_mut().map(|interface| interface.send(&message, None)).for_each(drop);
} }
Ok(()) Ok(())
} }
// Singlecast // Singlecast
@ -93,3 +99,35 @@ impl Transport {
} }
} }
} }
#[cfg(test)]
use crate::interface::test_interface::TestInterface;
#[cfg(test)]
use alloc::string::ToString;
#[test]
fn test_adding_peer_to_transport() {
let mut transport = Transport::new(vec![Box::new(TestInterface::default())]);
let (interface_id, interface_targeting_data) = ("test_interface".to_string(), "hi".to_string());
assert!(transport.get_peer_by_parameters(interface_id.as_str(), interface_targeting_data.as_str()).is_none());
let peer_id = transport.find_or_add_peer(interface_id.clone(), interface_targeting_data.clone());
let peer = PeerInfo {
peer_id,
interface_id: interface_id.clone(),
interface_targeting_data: interface_targeting_data.clone(),
};
assert_eq!(transport.get_peer_by_parameters(interface_id.as_str(), interface_targeting_data.as_str()), Some(&peer));
assert_eq!(transport.get_peer_by_id(peer_id), Some(peer));
}
#[test]
fn test_transport_sending() {
let mut transport = Transport::new(vec![Box::new(TestInterface::default())]);
let (interface_id, interface_targeting_data) = ("test_interface".to_string(), "hi".to_string());
let peer_id = transport.find_or_add_peer(interface_id.clone(), interface_targeting_data.clone());
transport.send_message(vec![239, 123], None).unwrap();
assert_eq!(transport.interfaces[0].receive().unwrap(), Some((vec![239u8, 123], "".to_string())));
assert!(transport.interfaces[0].receive() == IFResult::Ok(None));
transport.send_message(vec![239, 123], Some(peer_id)).unwrap();
assert_eq!(transport.interfaces[0].receive(), IFResult::Ok(Some((vec![239, 123], interface_targeting_data))));
}

Loading…
Cancel
Save