Basic framework for testing RoutingTable load/save
This commit is contained in:
		@@ -13,6 +13,8 @@ mod stats_accounting;
 | 
				
			|||||||
mod tasks;
 | 
					mod tasks;
 | 
				
			||||||
mod types;
 | 
					mod types;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod tests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::*;
 | 
					use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::crypto::*;
 | 
					use crate::crypto::*;
 | 
				
			||||||
@@ -290,8 +292,8 @@ impl RoutingTable {
 | 
				
			|||||||
        debug!("finished routing table terminate");
 | 
					        debug!("finished routing table terminate");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Serialize routing table to table store
 | 
					    /// Serialize the routing table.
 | 
				
			||||||
    async fn save_buckets(&self) -> EyreResult<()> {
 | 
					    fn serialized_buckets(&self) -> EyreResult<(BTreeMap<CryptoKind, Vec<Vec<u8>>>, Vec<Vec<u8>>)> {
 | 
				
			||||||
        // Since entries are shared by multiple buckets per cryptokind
 | 
					        // Since entries are shared by multiple buckets per cryptokind
 | 
				
			||||||
        // we need to get the list of all unique entries when serializing
 | 
					        // we need to get the list of all unique entries when serializing
 | 
				
			||||||
        let mut all_entries: Vec<Arc<BucketEntry>> = Vec::new();
 | 
					        let mut all_entries: Vec<Arc<BucketEntry>> = Vec::new();
 | 
				
			||||||
@@ -319,6 +321,13 @@ impl RoutingTable {
 | 
				
			|||||||
            all_entry_bytes.push(entry_bytes);
 | 
					            all_entry_bytes.push(entry_bytes);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok((serialized_bucket_map, all_entry_bytes))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write the serialized routing table to the table store.
 | 
				
			||||||
 | 
					    async fn save_buckets(&self) -> EyreResult<()> {
 | 
				
			||||||
 | 
					        let (serialized_bucket_map, all_entry_bytes) = self.serialized_buckets()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let table_store = self.unlocked_inner.network_manager().table_store();
 | 
					        let table_store = self.unlocked_inner.network_manager().table_store();
 | 
				
			||||||
        let tdb = table_store.open("routing_table", 1).await?;
 | 
					        let tdb = table_store.open("routing_table", 1).await?;
 | 
				
			||||||
        let dbx = tdb.transact();
 | 
					        let dbx = tdb.transact();
 | 
				
			||||||
@@ -333,7 +342,6 @@ impl RoutingTable {
 | 
				
			|||||||
        dbx.commit().await?;
 | 
					        dbx.commit().await?;
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Deserialize routing table from table store
 | 
					    /// Deserialize routing table from table store
 | 
				
			||||||
    async fn load_buckets(&self) -> EyreResult<()> {
 | 
					    async fn load_buckets(&self) -> EyreResult<()> {
 | 
				
			||||||
        // Deserialize bucket map and all entries from the table store
 | 
					        // Deserialize bucket map and all entries from the table store
 | 
				
			||||||
@@ -350,7 +358,18 @@ impl RoutingTable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Reconstruct all entries
 | 
					        // Reconstruct all entries
 | 
				
			||||||
        let inner = &mut *self.inner.write();
 | 
					        let inner = &mut *self.inner.write();
 | 
				
			||||||
 | 
					        self.populate_routing_table(inner, serialized_bucket_map, all_entry_bytes)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Write the deserialized table store data to the routing table.
 | 
				
			||||||
 | 
					    pub fn populate_routing_table(
 | 
				
			||||||
 | 
					        &self,
 | 
				
			||||||
 | 
					        inner: &mut RoutingTableInner,
 | 
				
			||||||
 | 
					        serialized_bucket_map: BTreeMap<CryptoKind, Vec<Vec<u8>>>,
 | 
				
			||||||
 | 
					        all_entry_bytes: Vec<Vec<u8>>,
 | 
				
			||||||
 | 
					    ) -> EyreResult<()> {
 | 
				
			||||||
        let mut all_entries: Vec<Arc<BucketEntry>> = Vec::with_capacity(all_entry_bytes.len());
 | 
					        let mut all_entries: Vec<Arc<BucketEntry>> = Vec::with_capacity(all_entry_bytes.len());
 | 
				
			||||||
        for entry_bytes in all_entry_bytes {
 | 
					        for entry_bytes in all_entry_bytes {
 | 
				
			||||||
            let entryinner =
 | 
					            let entryinner =
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								veilid-core/src/routing_table/tests/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								veilid-core/src/routing_table/tests/mod.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					pub mod test_serialize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::*;
 | 
				
			||||||
							
								
								
									
										80
									
								
								veilid-core/src/routing_table/tests/test_serialize.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								veilid-core/src/routing_table/tests/test_serialize.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					use crate::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn fake_routing_table() -> routing_table::RoutingTable {
 | 
				
			||||||
 | 
					    let veilid_config = VeilidConfig::new();
 | 
				
			||||||
 | 
					    let block_store = BlockStore::new(veilid_config.clone());
 | 
				
			||||||
 | 
					    let protected_store = ProtectedStore::new(veilid_config.clone());
 | 
				
			||||||
 | 
					    let table_store = TableStore::new(veilid_config.clone());
 | 
				
			||||||
 | 
					    let crypto = Crypto::new(
 | 
				
			||||||
 | 
					        veilid_config.clone(),
 | 
				
			||||||
 | 
					        table_store.clone(),
 | 
				
			||||||
 | 
					        protected_store.clone(),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let storage_manager = storage_manager::StorageManager::new(
 | 
				
			||||||
 | 
					        veilid_config.clone(),
 | 
				
			||||||
 | 
					        crypto.clone(),
 | 
				
			||||||
 | 
					        protected_store.clone(),
 | 
				
			||||||
 | 
					        table_store.clone(),
 | 
				
			||||||
 | 
					        block_store.clone(),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let network_manager = network_manager::NetworkManager::new(
 | 
				
			||||||
 | 
					        veilid_config.clone(),
 | 
				
			||||||
 | 
					        storage_manager,
 | 
				
			||||||
 | 
					        protected_store.clone(),
 | 
				
			||||||
 | 
					        table_store.clone(),
 | 
				
			||||||
 | 
					        block_store.clone(),
 | 
				
			||||||
 | 
					        crypto.clone(),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    routing_table::RoutingTable::new(network_manager)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn test_routingtable_buckets_round_trip() {
 | 
				
			||||||
 | 
					    let original = fake_routing_table();
 | 
				
			||||||
 | 
					    let copy = fake_routing_table();
 | 
				
			||||||
 | 
					    original.init().await.unwrap();
 | 
				
			||||||
 | 
					    copy.init().await.unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add lots of routes to `original` here to exercise all various types.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let (serialized_bucket_map, all_entry_bytes) = original.serialized_buckets().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    copy.populate_routing_table(
 | 
				
			||||||
 | 
					        &mut copy.inner.write(),
 | 
				
			||||||
 | 
					        serialized_bucket_map,
 | 
				
			||||||
 | 
					        all_entry_bytes,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let original_inner = &*original.inner.read();
 | 
				
			||||||
 | 
					    let copy_inner = &*copy.inner.read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let routing_table_keys: Vec<_> = original_inner.buckets.keys().clone().collect();
 | 
				
			||||||
 | 
					    let copy_keys: Vec<_> = copy_inner.buckets.keys().clone().collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert_eq!(routing_table_keys.len(), copy_keys.len());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for crypto in routing_table_keys {
 | 
				
			||||||
 | 
					        // The same keys are present in the original and copy RoutingTables.
 | 
				
			||||||
 | 
					        let original_buckets = original_inner.buckets.get(&crypto).unwrap();
 | 
				
			||||||
 | 
					        let copy_buckets = copy_inner.buckets.get(&crypto).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Recurse into RoutingTable.inner.buckets
 | 
				
			||||||
 | 
					        for (left_buckets, right_buckets) in original_buckets.iter().zip(copy_buckets.iter()) {
 | 
				
			||||||
 | 
					            // Recurse into RoutingTable.inner.buckets.entries
 | 
				
			||||||
 | 
					            for ((left_crypto, left_entries), (right_crypto, right_entries)) in
 | 
				
			||||||
 | 
					                left_buckets.entries().zip(right_buckets.entries())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                assert_eq!(left_crypto, right_crypto);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                assert_eq!(
 | 
				
			||||||
 | 
					                    format!("{:?}", left_entries),
 | 
				
			||||||
 | 
					                    format!("{:?}", right_entries)
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn test_all() {
 | 
				
			||||||
 | 
					    test_routingtable_buckets_round_trip().await;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -12,4 +12,5 @@ use super::*;
 | 
				
			|||||||
pub use common::*;
 | 
					pub use common::*;
 | 
				
			||||||
pub use crypto::tests::*;
 | 
					pub use crypto::tests::*;
 | 
				
			||||||
pub use network_manager::tests::*;
 | 
					pub use network_manager::tests::*;
 | 
				
			||||||
 | 
					pub use routing_table::tests::*;
 | 
				
			||||||
pub use veilid_api::tests::*;
 | 
					pub use veilid_api::tests::*;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
#![cfg(not(target_arch = "wasm32"))]
 | 
					#![cfg(not(target_arch = "wasm32"))]
 | 
				
			||||||
use crate::crypto::tests::*;
 | 
					use crate::crypto::tests::*;
 | 
				
			||||||
use crate::network_manager::tests::*;
 | 
					use crate::network_manager::tests::*;
 | 
				
			||||||
 | 
					use crate::routing_table::tests::*;
 | 
				
			||||||
use crate::tests::common::*;
 | 
					use crate::tests::common::*;
 | 
				
			||||||
use crate::veilid_api::tests::*;
 | 
					use crate::veilid_api::tests::*;
 | 
				
			||||||
use crate::*;
 | 
					use crate::*;
 | 
				
			||||||
@@ -173,5 +174,13 @@ cfg_if! {
 | 
				
			|||||||
            })
 | 
					            })
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[test]
 | 
				
			||||||
 | 
					        #[serial]
 | 
				
			||||||
 | 
					        fn run_test_routing_table_serialize() {
 | 
				
			||||||
 | 
					            setup();
 | 
				
			||||||
 | 
					            block_on(async {
 | 
				
			||||||
 | 
					                routing_table::tests::test_serialize::test_all().await;
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user