added tests that are currently failing
This commit is contained in:
parent
3c2137f224
commit
b3498b8e1e
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ build
|
||||
detee_challenge_nodes
|
||||
.cargo
|
||||
.idea
|
||||
.tmp
|
||||
|
124
src/datastore.rs
124
src/datastore.rs
@ -49,7 +49,7 @@ impl std::fmt::Display for SigningError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let error_message = match self {
|
||||
SigningError::CorruptedKey => "The public key is corrupted",
|
||||
SigningError::KeyNotFound => "Did not find the public key",
|
||||
SigningError::KeyNotFound => "Did not find the private key",
|
||||
};
|
||||
write!(f, "{}", error_message)
|
||||
}
|
||||
@ -280,3 +280,125 @@ impl Store {
|
||||
.find(|k| !self.conns.contains(k))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use dashmap::DashMap;
|
||||
use ed25519_dalek::SigningKey;
|
||||
use rand::rngs::OsRng;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
#[test]
|
||||
fn test_node_info_creation() {
|
||||
let keypair = SigningKey::generate(&mut OsRng);
|
||||
let node_info = NodeInfo {
|
||||
pubkey: keypair.verifying_key(),
|
||||
updated_at: SystemTime::now(),
|
||||
public: true,
|
||||
};
|
||||
|
||||
assert_eq!(node_info.pubkey, keypair.verifying_key());
|
||||
assert!(node_info.updated_at >= UNIX_EPOCH);
|
||||
assert!(node_info.public);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_store_creation() {
|
||||
let store = Store {
|
||||
nodes: DashMap::new(),
|
||||
conns: DashSet::new(),
|
||||
keys: DashMap::new(),
|
||||
};
|
||||
|
||||
assert!(store.nodes.is_empty());
|
||||
assert!(store.conns.is_empty());
|
||||
assert!(store.keys.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_signing_error_from_hex_error() {
|
||||
let hex_error: Result<(), hex::FromHexError> =
|
||||
Err(hex::FromHexError::InvalidHexCharacter { c: 'a', index: 0 });
|
||||
let signing_error: SigningError = hex_error.unwrap_err().into();
|
||||
|
||||
match signing_error {
|
||||
SigningError::CorruptedKey => assert!(true),
|
||||
_ => assert!(false, "Expected SigningError::CorruptedKey"),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_sign_message_with_key() {
|
||||
let keypair = SigningKey::generate(&mut OsRng);
|
||||
let pubkey_hex = hex::encode(keypair.verifying_key().as_bytes());
|
||||
let store = Store {
|
||||
nodes: DashMap::new(),
|
||||
conns: DashSet::new(),
|
||||
keys: DashMap::new(),
|
||||
};
|
||||
store.keys.insert(keypair.verifying_key(), keypair);
|
||||
|
||||
let message = "Test message";
|
||||
let result = store.sign_message_with_key(message, &pubkey_hex).await;
|
||||
|
||||
assert!(result.is_ok());
|
||||
if let Ok(signature) = result {
|
||||
assert!(!signature.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_process_node_update() {
|
||||
let keypair = SigningKey::generate(&mut OsRng);
|
||||
let node_update = NodeUpdate {
|
||||
ip: "127.0.0.1".to_string(),
|
||||
keypair: hex::encode(keypair.as_bytes()),
|
||||
updated_at: Some(prost_types::Timestamp {
|
||||
seconds: SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs() as i64,
|
||||
nanos: 0,
|
||||
}),
|
||||
public: true,
|
||||
};
|
||||
|
||||
let store = Store {
|
||||
nodes: DashMap::new(),
|
||||
conns: DashSet::new(),
|
||||
keys: DashMap::new(),
|
||||
};
|
||||
|
||||
let result = store.process_node_update(node_update).await;
|
||||
|
||||
assert!(result);
|
||||
assert!(store.nodes.contains_key("127.0.0.1"));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_full_node_list() {
|
||||
let keypair = SigningKey::generate(&mut OsRng);
|
||||
let node_info = NodeInfo {
|
||||
pubkey: keypair.verifying_key(),
|
||||
updated_at: SystemTime::now(),
|
||||
public: true,
|
||||
};
|
||||
|
||||
let store = Store {
|
||||
nodes: DashMap::new(),
|
||||
conns: DashSet::new(),
|
||||
keys: DashMap::new(),
|
||||
};
|
||||
|
||||
store.nodes.insert("127.0.0.1".to_string(), node_info);
|
||||
store.keys.insert(keypair.verifying_key(), keypair.clone());
|
||||
|
||||
let node_list = store.get_full_node_list().await;
|
||||
|
||||
assert_eq!(node_list.len(), 1);
|
||||
assert_eq!(node_list[0].ip, "127.0.0.1");
|
||||
assert_eq!(node_list[0].keypair, hex::encode(keypair.as_bytes()));
|
||||
assert!(node_list[0].public);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use tokio::fs::File;
|
||||
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
const DATA_SIZE: usize = 78;
|
||||
const DATA_SIZE: usize = 76;
|
||||
|
||||
enum Error {
|
||||
CorruptedIP,
|
||||
@ -20,6 +20,7 @@ impl From<AddrParseError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Node {
|
||||
ip: Ipv4Addr,
|
||||
keypair: SigningKey,
|
||||
@ -50,7 +51,7 @@ impl Node {
|
||||
let mut result = [0; DATA_SIZE];
|
||||
result[0..4].copy_from_slice(&self.ip.octets());
|
||||
result[4..68].copy_from_slice(&self.keypair.to_keypair_bytes());
|
||||
result[69..DATA_SIZE].copy_from_slice(
|
||||
result[68..DATA_SIZE].copy_from_slice(
|
||||
&self
|
||||
.joined_at
|
||||
.duration_since(UNIX_EPOCH)
|
||||
@ -66,7 +67,7 @@ impl Node {
|
||||
let ip: Ipv4Addr = ip.into();
|
||||
let keypair: [u8; KEYPAIR_LENGTH] = bytes[4..68].try_into().unwrap();
|
||||
let keypair: SigningKey = SigningKey::from_keypair_bytes(&keypair).unwrap();
|
||||
let joined_at: [u8; 8] = bytes[69..DATA_SIZE].try_into().unwrap();
|
||||
let joined_at: [u8; 8] = bytes[68..DATA_SIZE].try_into().unwrap();
|
||||
let joined_at: u64 = u64::from_le_bytes(joined_at);
|
||||
let joined_at = SystemTime::UNIX_EPOCH + Duration::from_secs(joined_at);
|
||||
Self {
|
||||
@ -99,10 +100,148 @@ impl FileManager {
|
||||
|
||||
async fn get_node_by_id(&self, id: u64) -> std::io::Result<Node> {
|
||||
let mut file = self.file.lock().await;
|
||||
file.seek(SeekFrom::Start(id.wrapping_mul(DATA_SIZE.try_into().unwrap_or(0))))
|
||||
.await?;
|
||||
file.seek(SeekFrom::Start(
|
||||
id.wrapping_mul(DATA_SIZE.try_into().unwrap_or(0)),
|
||||
))
|
||||
.await?;
|
||||
let mut node_bytes = [0; DATA_SIZE];
|
||||
file.read_exact(&mut node_bytes).await?;
|
||||
Ok(Node::from_bytes(node_bytes))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use ed25519_dalek::SigningKey;
|
||||
use rand::rngs::OsRng;
|
||||
use std::io::Result;
|
||||
use tokio::fs::remove_file;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
const TEST_FILE_PREFIX: &str = ".tmp/test_";
|
||||
fn get_test_file_name(function: &str) -> String {
|
||||
TEST_FILE_PREFIX.to_string() + function
|
||||
}
|
||||
async fn setup_test_file(function: &str) -> Result<FileManager> {
|
||||
let path = get_test_file_name(function);
|
||||
let mut file = File::create(path.clone()).await?;
|
||||
file.flush().await?;
|
||||
drop(file);
|
||||
FileManager::init(&path).await
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_node_to_bytes_and_back() {
|
||||
let keypair = SigningKey::generate(&mut OsRng);
|
||||
|
||||
let original_node = Node {
|
||||
ip: "192.168.1.1".parse().unwrap(),
|
||||
keypair: keypair.clone(),
|
||||
joined_at: SystemTime::now(),
|
||||
};
|
||||
|
||||
let node_bytes = original_node.clone().to_bytes();
|
||||
let restored_node = Node::from_bytes(node_bytes);
|
||||
|
||||
assert_eq!(original_node.ip_as_string(), restored_node.ip_as_string());
|
||||
assert_eq!(
|
||||
original_node.keypair.to_keypair_bytes(),
|
||||
restored_node.keypair.to_keypair_bytes()
|
||||
);
|
||||
assert_eq!(
|
||||
original_node
|
||||
.joined_at
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs(),
|
||||
restored_node
|
||||
.joined_at
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn setup_file_manager() {
|
||||
match setup_test_file("setup_file_manager").await {
|
||||
Err(e) => {
|
||||
panic!("Could not init File Manager: {}", e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_file_manager_append_and_retrieve_node() -> Result<()> {
|
||||
let function_name = "test_file_manager_append_and_retrieve_node";
|
||||
let manager = setup_test_file(function_name).await?;
|
||||
|
||||
let keypair = SigningKey::generate(&mut OsRng);
|
||||
|
||||
let node = Node {
|
||||
ip: "192.168.1.1".parse().unwrap(),
|
||||
keypair: keypair.clone(),
|
||||
joined_at: SystemTime::now(),
|
||||
};
|
||||
|
||||
manager.append_node(node.clone()).await.unwrap();
|
||||
|
||||
let retrieved_node = manager.get_node_by_id(0).await.unwrap();
|
||||
|
||||
assert_eq!(node.ip_as_string(), retrieved_node.ip_as_string());
|
||||
assert_eq!(
|
||||
node.keypair.to_keypair_bytes(),
|
||||
retrieved_node.keypair.to_keypair_bytes()
|
||||
);
|
||||
assert_eq!(node.joined_at, retrieved_node.joined_at);
|
||||
|
||||
remove_file(get_test_file_name(function_name)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_file_manager_multiple_nodes() -> Result<()> {
|
||||
let function_name = "test_file_manager_multiple_nodes";
|
||||
let manager = setup_test_file(function_name).await?;
|
||||
|
||||
let keypair1 = SigningKey::generate(&mut OsRng);
|
||||
let node1 = Node {
|
||||
ip: "192.168.1.1".parse().unwrap(),
|
||||
keypair: keypair1.clone(),
|
||||
joined_at: SystemTime::now(),
|
||||
};
|
||||
|
||||
let keypair2 = SigningKey::generate(&mut OsRng);
|
||||
let node2 = Node {
|
||||
ip: "10.0.0.1".parse().unwrap(),
|
||||
keypair: keypair2.clone(),
|
||||
joined_at: SystemTime::now(),
|
||||
};
|
||||
|
||||
manager.append_node(node1.clone()).await.unwrap();
|
||||
manager.append_node(node2.clone()).await.unwrap();
|
||||
|
||||
let retrieved_node1 = manager.get_node_by_id(0).await?;
|
||||
let retrieved_node2 = manager.get_node_by_id(1).await?;
|
||||
|
||||
assert_eq!(node1.ip_as_string(), retrieved_node1.ip_as_string());
|
||||
assert_eq!(
|
||||
node1.keypair.to_keypair_bytes(),
|
||||
retrieved_node1.keypair.to_keypair_bytes()
|
||||
);
|
||||
|
||||
assert_eq!(node2.ip_as_string(), retrieved_node2.ip_as_string());
|
||||
assert_eq!(
|
||||
node2.keypair.to_keypair_bytes(),
|
||||
retrieved_node2.keypair.to_keypair_bytes()
|
||||
);
|
||||
|
||||
remove_file(get_test_file_name(function_name)).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user