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 | detee_challenge_nodes | ||||||
| .cargo | .cargo | ||||||
| .idea | .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 { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
|         let error_message = match self { |         let error_message = match self { | ||||||
|             SigningError::CorruptedKey => "The public key is corrupted", |             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) |         write!(f, "{}", error_message) | ||||||
|     } |     } | ||||||
| @ -280,3 +280,125 @@ impl Store { | |||||||
|             .find(|k| !self.conns.contains(k)) |             .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::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom}; | ||||||
| use tokio::sync::Mutex; | use tokio::sync::Mutex; | ||||||
| 
 | 
 | ||||||
| const DATA_SIZE: usize = 78; | const DATA_SIZE: usize = 76; | ||||||
| 
 | 
 | ||||||
| enum Error { | enum Error { | ||||||
|     CorruptedIP, |     CorruptedIP, | ||||||
| @ -20,6 +20,7 @@ impl From<AddrParseError> for Error { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Clone)] | ||||||
| struct Node { | struct Node { | ||||||
|     ip: Ipv4Addr, |     ip: Ipv4Addr, | ||||||
|     keypair: SigningKey, |     keypair: SigningKey, | ||||||
| @ -50,7 +51,7 @@ impl Node { | |||||||
|         let mut result = [0; DATA_SIZE]; |         let mut result = [0; DATA_SIZE]; | ||||||
|         result[0..4].copy_from_slice(&self.ip.octets()); |         result[0..4].copy_from_slice(&self.ip.octets()); | ||||||
|         result[4..68].copy_from_slice(&self.keypair.to_keypair_bytes()); |         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 |             &self | ||||||
|                 .joined_at |                 .joined_at | ||||||
|                 .duration_since(UNIX_EPOCH) |                 .duration_since(UNIX_EPOCH) | ||||||
| @ -66,7 +67,7 @@ impl Node { | |||||||
|         let ip: Ipv4Addr = ip.into(); |         let ip: Ipv4Addr = ip.into(); | ||||||
|         let keypair: [u8; KEYPAIR_LENGTH] = bytes[4..68].try_into().unwrap(); |         let keypair: [u8; KEYPAIR_LENGTH] = bytes[4..68].try_into().unwrap(); | ||||||
|         let keypair: SigningKey = SigningKey::from_keypair_bytes(&keypair).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: u64 = u64::from_le_bytes(joined_at); | ||||||
|         let joined_at = SystemTime::UNIX_EPOCH + Duration::from_secs(joined_at); |         let joined_at = SystemTime::UNIX_EPOCH + Duration::from_secs(joined_at); | ||||||
|         Self { |         Self { | ||||||
| @ -99,10 +100,148 @@ impl FileManager { | |||||||
| 
 | 
 | ||||||
|     async fn get_node_by_id(&self, id: u64) -> std::io::Result<Node> { |     async fn get_node_by_id(&self, id: u64) -> std::io::Result<Node> { | ||||||
|         let mut file = self.file.lock().await; |         let mut file = self.file.lock().await; | ||||||
|         file.seek(SeekFrom::Start(id.wrapping_mul(DATA_SIZE.try_into().unwrap_or(0)))) |         file.seek(SeekFrom::Start( | ||||||
|             .await?; |             id.wrapping_mul(DATA_SIZE.try_into().unwrap_or(0)), | ||||||
|  |         )) | ||||||
|  |         .await?; | ||||||
|         let mut node_bytes = [0; DATA_SIZE]; |         let mut node_bytes = [0; DATA_SIZE]; | ||||||
|         file.read_exact(&mut node_bytes).await?; |         file.read_exact(&mut node_bytes).await?; | ||||||
|         Ok(Node::from_bytes(node_bytes)) |         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