From b4a4250256c6a5511301597cae42547f070c62d3 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Tue, 4 Feb 2025 16:45:13 +0000 Subject: [PATCH 1/6] test: [#1235] add tests for DatabaseWhitelist --- .../src/whitelist/repository/persisted.rs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/packages/tracker-core/src/whitelist/repository/persisted.rs b/packages/tracker-core/src/whitelist/repository/persisted.rs index c3c4a2601..a54274f16 100644 --- a/packages/tracker-core/src/whitelist/repository/persisted.rs +++ b/packages/tracker-core/src/whitelist/repository/persisted.rs @@ -60,3 +60,94 @@ impl DatabaseWhitelist { self.database.load_whitelist() } } + +#[cfg(test)] +mod tests { + mod the_persisted_whitelist_repository { + + use torrust_tracker_configuration::Core; + use torrust_tracker_test_helpers::configuration::ephemeral_sqlite_database; + + use crate::core_tests::sample_info_hash; + use crate::databases::setup::initialize_database; + use crate::whitelist::repository::persisted::DatabaseWhitelist; + + fn initialize_database_whitelist() -> DatabaseWhitelist { + let configuration = ephemeral_configuration_for_listed_tracker(); + let database = initialize_database(&configuration); + DatabaseWhitelist::new(database) + } + + fn ephemeral_configuration_for_listed_tracker() -> Core { + let mut config = Core { + listed: true, + ..Default::default() + }; + + let temp_file = ephemeral_sqlite_database(); + temp_file.to_str().unwrap().clone_into(&mut config.database.path); + + config + } + + #[test] + fn should_add_a_new_infohash_to_the_list() { + let whitelist = initialize_database_whitelist(); + + let infohash = sample_info_hash(); + + let _result = whitelist.add(&infohash); + + assert_eq!(whitelist.load_from_database().unwrap(), vec!(infohash)); + } + + #[test] + fn should_remove_a_infohash_from_the_list() { + let whitelist = initialize_database_whitelist(); + + let infohash = sample_info_hash(); + + let _result = whitelist.add(&infohash); + + let _result = whitelist.remove(&infohash); + + assert_eq!(whitelist.load_from_database().unwrap(), vec!()); + } + + #[test] + fn should_load_all_infohashes_from_the_database() { + let whitelist = initialize_database_whitelist(); + + let infohash = sample_info_hash(); + + let _result = whitelist.add(&infohash); + + let result = whitelist.load_from_database().unwrap(); + + assert_eq!(result, vec!(infohash)); + } + + #[test] + fn should_not_add_the_same_infohash_to_the_list_twice() { + let whitelist = initialize_database_whitelist(); + + let infohash = sample_info_hash(); + + let _result = whitelist.add(&infohash); + let _result = whitelist.add(&infohash); + + assert_eq!(whitelist.load_from_database().unwrap(), vec!(infohash)); + } + + #[test] + fn should_not_fail_removing_an_infohash_that_is_not_in_the_list() { + let whitelist = initialize_database_whitelist(); + + let infohash = sample_info_hash(); + + let result = whitelist.remove(&infohash); + + assert!(result.is_ok()); + } + } +} From 933b6b0ef6f4c9afc48c31b8882b50bd9539e987 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Tue, 4 Feb 2025 17:30:47 +0000 Subject: [PATCH 2/6] test: [#1235] add tests for WhitelistAuthorization --- .../src/whitelist/authorization.rs | 94 +++++++++++++++++-- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/packages/tracker-core/src/whitelist/authorization.rs b/packages/tracker-core/src/whitelist/authorization.rs index 285f6613e..cb5f4acbf 100644 --- a/packages/tracker-core/src/whitelist/authorization.rs +++ b/packages/tracker-core/src/whitelist/authorization.rs @@ -61,33 +61,107 @@ impl WhitelistAuthorization { #[cfg(test)] mod tests { - mod configured_as_whitelisted { + mod the_whitelist_authorization_for_announce_and_scrape_actions { + use std::sync::Arc; + + use torrust_tracker_configuration::Core; + + use crate::whitelist::authorization::WhitelistAuthorization; + use crate::whitelist::repository::in_memory::InMemoryWhitelist; + + fn initialize_whitelist_authorization_with(config: &Core) -> Arc { + let (whitelist_authorization, _in_memory_whitelist) = + initialize_whitelist_authorization_and_dependencies_with(config); + whitelist_authorization + } + + fn initialize_whitelist_authorization_and_dependencies_with( + config: &Core, + ) -> (Arc, Arc) { + let in_memory_whitelist = Arc::new(InMemoryWhitelist::default()); + let whitelist_authorization = Arc::new(WhitelistAuthorization::new(config, &in_memory_whitelist.clone())); + + (whitelist_authorization, in_memory_whitelist) + } + + mod when_the_tacker_is_configured_as_listed { + + use torrust_tracker_configuration::Core; - mod handling_authorization { use crate::core_tests::sample_info_hash; - use crate::whitelist::whitelist_tests::initialize_whitelist_services_for_listed_tracker; + use crate::error::Error; + use crate::whitelist::authorization::tests::the_whitelist_authorization_for_announce_and_scrape_actions::{ + initialize_whitelist_authorization_and_dependencies_with, initialize_whitelist_authorization_with, + }; + + fn configuration_for_listed_tracker() -> Core { + Core { + listed: true, + ..Default::default() + } + } #[tokio::test] - async fn it_should_authorize_the_announce_and_scrape_actions_on_whitelisted_torrents() { - let (whitelist_authorization, whitelist_manager) = initialize_whitelist_services_for_listed_tracker(); + async fn should_authorize_a_whitelisted_infohash() { + let (whitelist_authorization, in_memory_whitelist) = + initialize_whitelist_authorization_and_dependencies_with(&configuration_for_listed_tracker()); let info_hash = sample_info_hash(); - let result = whitelist_manager.add_torrent_to_whitelist(&info_hash).await; - assert!(result.is_ok()); + let _unused = in_memory_whitelist.add(&info_hash).await; let result = whitelist_authorization.authorize(&info_hash).await; + assert!(result.is_ok()); } #[tokio::test] - async fn it_should_not_authorize_the_announce_and_scrape_actions_on_not_whitelisted_torrents() { - let (whitelist_authorization, _whitelist_manager) = initialize_whitelist_services_for_listed_tracker(); + async fn should_not_authorize_a_non_whitelisted_infohash() { + let whitelist_authorization = initialize_whitelist_authorization_with(&configuration_for_listed_tracker()); + + let result = whitelist_authorization.authorize(&sample_info_hash()).await; + + assert!(matches!(result.unwrap_err(), Error::TorrentNotWhitelisted { .. })); + } + } + + mod when_the_tacker_is_not_configured_as_listed { + + use torrust_tracker_configuration::Core; + + use crate::core_tests::sample_info_hash; + use crate::whitelist::authorization::tests::the_whitelist_authorization_for_announce_and_scrape_actions::{ + initialize_whitelist_authorization_and_dependencies_with, initialize_whitelist_authorization_with, + }; + + fn configuration_for_non_listed_tracker() -> Core { + Core { + listed: false, + ..Default::default() + } + } + + #[tokio::test] + async fn should_authorize_a_whitelisted_infohash() { + let (whitelist_authorization, in_memory_whitelist) = + initialize_whitelist_authorization_and_dependencies_with(&configuration_for_non_listed_tracker()); let info_hash = sample_info_hash(); + let _unused = in_memory_whitelist.add(&info_hash).await; + let result = whitelist_authorization.authorize(&info_hash).await; - assert!(result.is_err()); + + assert!(result.is_ok()); + } + + #[tokio::test] + async fn should_also_authorize_a_non_whitelisted_infohash() { + let whitelist_authorization = initialize_whitelist_authorization_with(&configuration_for_non_listed_tracker()); + + let result = whitelist_authorization.authorize(&sample_info_hash()).await; + + assert!(result.is_ok()); } } } From 1735dfce6e5d44431ca568e0c330e2a18cd37167 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Tue, 4 Feb 2025 17:39:28 +0000 Subject: [PATCH 3/6] refactor: [#1235] remove unused methods --- packages/tracker-core/src/whitelist/manager.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/packages/tracker-core/src/whitelist/manager.rs b/packages/tracker-core/src/whitelist/manager.rs index c78a59470..e810f170e 100644 --- a/packages/tracker-core/src/whitelist/manager.rs +++ b/packages/tracker-core/src/whitelist/manager.rs @@ -48,20 +48,6 @@ impl WhitelistManager { Ok(()) } - /// It removes a torrent from the whitelist in the database. - /// - /// # Errors - /// - /// Will return a `database::Error` if unable to remove the `info_hash` from the whitelist database. - pub fn remove_torrent_from_database_whitelist(&self, info_hash: &InfoHash) -> Result<(), databases::error::Error> { - self.database_whitelist.remove(info_hash) - } - - /// It adds a torrent from the whitelist in memory. - pub async fn add_torrent_to_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.in_memory_whitelist.add(info_hash).await - } - /// It removes a torrent from the whitelist in memory. pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { self.in_memory_whitelist.remove(info_hash).await From f32f0bfc1bab808f0209a7af5454cac935a1d99b Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 5 Feb 2025 08:45:31 +0000 Subject: [PATCH 4/6] refactor: [#1235] remove pun method only used for testing Now that we inject dependencies we can write assert using the dependencies instead of exposing public methods. --- packages/tracker-core/src/core_tests.rs | 21 +++++++ .../tracker-core/src/whitelist/manager.rs | 55 +++++++++++++------ .../src/whitelist/repository/persisted.rs | 17 +----- src/bootstrap/app.rs | 1 + src/container.rs | 2 + tests/servers/api/environment.rs | 5 ++ .../api/v1/contract/context/whitelist.rs | 12 +--- 7 files changed, 70 insertions(+), 43 deletions(-) diff --git a/packages/tracker-core/src/core_tests.rs b/packages/tracker-core/src/core_tests.rs index f6b47acd0..ac99770d4 100644 --- a/packages/tracker-core/src/core_tests.rs +++ b/packages/tracker-core/src/core_tests.rs @@ -5,8 +5,12 @@ use std::sync::Arc; use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes, PeerId}; use bittorrent_primitives::info_hash::InfoHash; use torrust_tracker_configuration::Configuration; +#[cfg(test)] +use torrust_tracker_configuration::Core; use torrust_tracker_primitives::peer::Peer; use torrust_tracker_primitives::DurationSinceUnixEpoch; +#[cfg(test)] +use torrust_tracker_test_helpers::configuration::ephemeral_sqlite_database; use super::announce_handler::AnnounceHandler; use super::databases::setup::initialize_database; @@ -103,3 +107,20 @@ pub fn initialize_handlers(config: &Configuration) -> (Arc, Arc (announce_handler, scrape_handler) } + +/// # Panics +/// +/// Will panic if the temporary file path is not a valid UFT string. +#[cfg(test)] +#[must_use] +pub fn ephemeral_configuration_for_listed_tracker() -> Core { + let mut config = Core { + listed: true, + ..Default::default() + }; + + let temp_file = ephemeral_sqlite_database(); + temp_file.to_str().unwrap().clone_into(&mut config.database.path); + + config +} diff --git a/packages/tracker-core/src/whitelist/manager.rs b/packages/tracker-core/src/whitelist/manager.rs index e810f170e..9d2ba249b 100644 --- a/packages/tracker-core/src/whitelist/manager.rs +++ b/packages/tracker-core/src/whitelist/manager.rs @@ -53,11 +53,6 @@ impl WhitelistManager { self.in_memory_whitelist.remove(info_hash).await } - /// It checks if a torrent is whitelisted. - pub async fn is_info_hash_whitelisted(&self, info_hash: &InfoHash) -> bool { - self.in_memory_whitelist.contains(info_hash).await - } - /// It loads the whitelist from the database. /// /// # Errors @@ -81,17 +76,41 @@ mod tests { use std::sync::Arc; - use torrust_tracker_test_helpers::configuration; + use torrust_tracker_configuration::Core; + use crate::core_tests::ephemeral_configuration_for_listed_tracker; + use crate::databases::setup::initialize_database; + use crate::databases::Database; use crate::whitelist::manager::WhitelistManager; - use crate::whitelist::whitelist_tests::initialize_whitelist_services; + use crate::whitelist::repository::in_memory::InMemoryWhitelist; + use crate::whitelist::repository::persisted::DatabaseWhitelist; - fn initialize_whitelist_manager_for_whitelisted_tracker() -> Arc { - let config = configuration::ephemeral_listed(); + struct WhitelistManagerDeps { + pub _database: Arc>, + pub _database_whitelist: Arc, + pub in_memory_whitelist: Arc, + } - let (_whitelist_authorization, whitelist_manager) = initialize_whitelist_services(&config); + fn initialize_whitelist_manager_for_whitelisted_tracker() -> (Arc, Arc) { + let config = ephemeral_configuration_for_listed_tracker(); + initialize_whitelist_manager_and_deps(&config) + } - whitelist_manager + fn initialize_whitelist_manager_and_deps(config: &Core) -> (Arc, Arc) { + let database = initialize_database(config); + let database_whitelist = Arc::new(DatabaseWhitelist::new(database.clone())); + let in_memory_whitelist = Arc::new(InMemoryWhitelist::default()); + + let whitelist_manager = Arc::new(WhitelistManager::new(database_whitelist.clone(), in_memory_whitelist.clone())); + + ( + whitelist_manager, + Arc::new(WhitelistManagerDeps { + _database: database, + _database_whitelist: database_whitelist, + in_memory_whitelist, + }), + ) } mod configured_as_whitelisted { @@ -102,18 +121,18 @@ mod tests { #[tokio::test] async fn it_should_add_a_torrent_to_the_whitelist() { - let whitelist_manager = initialize_whitelist_manager_for_whitelisted_tracker(); + let (whitelist_manager, services) = initialize_whitelist_manager_for_whitelisted_tracker(); let info_hash = sample_info_hash(); whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); - assert!(whitelist_manager.is_info_hash_whitelisted(&info_hash).await); + assert!(services.in_memory_whitelist.contains(&info_hash).await); } #[tokio::test] async fn it_should_remove_a_torrent_from_the_whitelist() { - let whitelist_manager = initialize_whitelist_manager_for_whitelisted_tracker(); + let (whitelist_manager, services) = initialize_whitelist_manager_for_whitelisted_tracker(); let info_hash = sample_info_hash(); @@ -121,7 +140,7 @@ mod tests { whitelist_manager.remove_torrent_from_whitelist(&info_hash).await.unwrap(); - assert!(!whitelist_manager.is_info_hash_whitelisted(&info_hash).await); + assert!(!services.in_memory_whitelist.contains(&info_hash).await); } mod persistence { @@ -130,7 +149,7 @@ mod tests { #[tokio::test] async fn it_should_load_the_whitelist_from_the_database() { - let whitelist_manager = initialize_whitelist_manager_for_whitelisted_tracker(); + let (whitelist_manager, services) = initialize_whitelist_manager_for_whitelisted_tracker(); let info_hash = sample_info_hash(); @@ -138,11 +157,11 @@ mod tests { whitelist_manager.remove_torrent_from_memory_whitelist(&info_hash).await; - assert!(!whitelist_manager.is_info_hash_whitelisted(&info_hash).await); + assert!(!services.in_memory_whitelist.contains(&info_hash).await); whitelist_manager.load_whitelist_from_database().await.unwrap(); - assert!(whitelist_manager.is_info_hash_whitelisted(&info_hash).await); + assert!(services.in_memory_whitelist.contains(&info_hash).await); } } } diff --git a/packages/tracker-core/src/whitelist/repository/persisted.rs b/packages/tracker-core/src/whitelist/repository/persisted.rs index a54274f16..5101b5e35 100644 --- a/packages/tracker-core/src/whitelist/repository/persisted.rs +++ b/packages/tracker-core/src/whitelist/repository/persisted.rs @@ -65,10 +65,7 @@ impl DatabaseWhitelist { mod tests { mod the_persisted_whitelist_repository { - use torrust_tracker_configuration::Core; - use torrust_tracker_test_helpers::configuration::ephemeral_sqlite_database; - - use crate::core_tests::sample_info_hash; + use crate::core_tests::{ephemeral_configuration_for_listed_tracker, sample_info_hash}; use crate::databases::setup::initialize_database; use crate::whitelist::repository::persisted::DatabaseWhitelist; @@ -78,18 +75,6 @@ mod tests { DatabaseWhitelist::new(database) } - fn ephemeral_configuration_for_listed_tracker() -> Core { - let mut config = Core { - listed: true, - ..Default::default() - }; - - let temp_file = ephemeral_sqlite_database(); - temp_file.to_str().unwrap().clone_into(&mut config.database.path); - - config - } - #[test] fn should_add_a_new_infohash_to_the_list() { let whitelist = initialize_database_whitelist(); diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs index e0e81c70c..0236215f2 100644 --- a/src/bootstrap/app.rs +++ b/src/bootstrap/app.rs @@ -141,6 +141,7 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer { scrape_handler, keys_handler, authentication_service, + in_memory_whitelist, whitelist_authorization, ban_service, http_stats_event_sender, diff --git a/src/container.rs b/src/container.rs index 51c55e533..47cc39ed3 100644 --- a/src/container.rs +++ b/src/container.rs @@ -10,6 +10,7 @@ use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepo use bittorrent_tracker_core::torrent::repository::persisted::DatabasePersistentTorrentRepository; use bittorrent_tracker_core::whitelist; use bittorrent_tracker_core::whitelist::manager::WhitelistManager; +use bittorrent_tracker_core::whitelist::repository::in_memory::InMemoryWhitelist; use tokio::sync::RwLock; use torrust_tracker_configuration::{Core, HttpApi, HttpTracker, UdpTracker}; @@ -23,6 +24,7 @@ pub struct AppContainer { pub scrape_handler: Arc, pub keys_handler: Arc, pub authentication_service: Arc, + pub in_memory_whitelist: Arc, pub whitelist_authorization: Arc, pub ban_service: Arc>, pub http_stats_event_sender: Arc>>, diff --git a/tests/servers/api/environment.rs b/tests/servers/api/environment.rs index 61351024d..02d6465e1 100644 --- a/tests/servers/api/environment.rs +++ b/tests/servers/api/environment.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use bittorrent_primitives::info_hash::InfoHash; use bittorrent_tracker_core::authentication::service::AuthenticationService; use bittorrent_tracker_core::databases::Database; +use bittorrent_tracker_core::whitelist::repository::in_memory::InMemoryWhitelist; use futures::executor::block_on; use torrust_tracker_api_client::connection_info::{ConnectionInfo, Origin}; use torrust_tracker_configuration::Configuration; @@ -22,6 +23,7 @@ where pub database: Arc>, pub authentication_service: Arc, + pub in_memory_whitelist: Arc, pub registar: Registar, pub server: ApiServer, @@ -70,6 +72,7 @@ impl Environment { database: app_container.database.clone(), authentication_service: app_container.authentication_service.clone(), + in_memory_whitelist: app_container.in_memory_whitelist.clone(), registar: Registar::default(), server, @@ -84,6 +87,7 @@ impl Environment { database: self.database.clone(), authentication_service: self.authentication_service.clone(), + in_memory_whitelist: self.in_memory_whitelist.clone(), registar: self.registar.clone(), server: self @@ -106,6 +110,7 @@ impl Environment { database: self.database, authentication_service: self.authentication_service, + in_memory_whitelist: self.in_memory_whitelist, registar: Registar::default(), server: self.server.stop().await.unwrap(), diff --git a/tests/servers/api/v1/contract/context/whitelist.rs b/tests/servers/api/v1/contract/context/whitelist.rs index 945cb00b5..ca359650f 100644 --- a/tests/servers/api/v1/contract/context/whitelist.rs +++ b/tests/servers/api/v1/contract/context/whitelist.rs @@ -31,9 +31,8 @@ async fn should_allow_whitelisting_a_torrent() { assert_ok(response).await; assert!( - env.http_api_container - .whitelist_manager - .is_info_hash_whitelisted(&InfoHash::from_str(&info_hash).unwrap()) + env.in_memory_whitelist + .contains(&InfoHash::from_str(&info_hash).unwrap()) .await ); @@ -181,12 +180,7 @@ async fn should_allow_removing_a_torrent_from_the_whitelist() { .await; assert_ok(response).await; - assert!( - !env.http_api_container - .whitelist_manager - .is_info_hash_whitelisted(&info_hash) - .await - ); + assert!(!env.in_memory_whitelist.contains(&info_hash).await); env.stop().await; } From 2862c7706c0753dcd1b5c114205336202a94cd84 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 5 Feb 2025 08:50:26 +0000 Subject: [PATCH 5/6] refactor: [#1235] remove another pub methog only used for testing --- packages/tracker-core/src/whitelist/manager.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/tracker-core/src/whitelist/manager.rs b/packages/tracker-core/src/whitelist/manager.rs index 9d2ba249b..5efe6e15a 100644 --- a/packages/tracker-core/src/whitelist/manager.rs +++ b/packages/tracker-core/src/whitelist/manager.rs @@ -48,11 +48,6 @@ impl WhitelistManager { Ok(()) } - /// It removes a torrent from the whitelist in memory. - pub async fn remove_torrent_from_memory_whitelist(&self, info_hash: &InfoHash) -> bool { - self.in_memory_whitelist.remove(info_hash).await - } - /// It loads the whitelist from the database. /// /// # Errors @@ -155,7 +150,7 @@ mod tests { whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); - whitelist_manager.remove_torrent_from_memory_whitelist(&info_hash).await; + services.in_memory_whitelist.remove(&info_hash).await; assert!(!services.in_memory_whitelist.contains(&info_hash).await); From e994aa2d41da89a7a522a6a748712170cb3f9cb9 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Wed, 5 Feb 2025 10:07:06 +0000 Subject: [PATCH 6/6] refactor: [#1235] WhitelistManager tests --- packages/tracker-core/src/whitelist/manager.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/tracker-core/src/whitelist/manager.rs b/packages/tracker-core/src/whitelist/manager.rs index 5efe6e15a..e1cd2f89e 100644 --- a/packages/tracker-core/src/whitelist/manager.rs +++ b/packages/tracker-core/src/whitelist/manager.rs @@ -82,7 +82,7 @@ mod tests { struct WhitelistManagerDeps { pub _database: Arc>, - pub _database_whitelist: Arc, + pub database_whitelist: Arc, pub in_memory_whitelist: Arc, } @@ -102,7 +102,7 @@ mod tests { whitelist_manager, Arc::new(WhitelistManagerDeps { _database: database, - _database_whitelist: database_whitelist, + database_whitelist, in_memory_whitelist, }), ) @@ -123,6 +123,7 @@ mod tests { whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); assert!(services.in_memory_whitelist.contains(&info_hash).await); + assert!(services.database_whitelist.load_from_database().unwrap().contains(&info_hash)); } #[tokio::test] @@ -136,6 +137,7 @@ mod tests { whitelist_manager.remove_torrent_from_whitelist(&info_hash).await.unwrap(); assert!(!services.in_memory_whitelist.contains(&info_hash).await); + assert!(!services.database_whitelist.load_from_database().unwrap().contains(&info_hash)); } mod persistence { @@ -148,11 +150,7 @@ mod tests { let info_hash = sample_info_hash(); - whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap(); - - services.in_memory_whitelist.remove(&info_hash).await; - - assert!(!services.in_memory_whitelist.contains(&info_hash).await); + services.database_whitelist.add(&info_hash).unwrap(); whitelist_manager.load_whitelist_from_database().await.unwrap();