From 51449aad438a5cc1e749b65bc67481f881db2be9 Mon Sep 17 00:00:00 2001 From: Dmitry Porokh Date: Thu, 4 Jun 2026 16:23:08 -0700 Subject: [PATCH 1/4] test(api-core): simplify site explorer tests Use direct imports for `sqlx_test` and `PgPool`, and cache the underlay segment in tests to avoid repeated unwraps. Signed-off-by: Dmitry Porokh --- crates/api-core/src/tests/site_explorer.rs | 443 +++++++++------------ 1 file changed, 183 insertions(+), 260 deletions(-) diff --git a/crates/api-core/src/tests/site_explorer.rs b/crates/api-core/src/tests/site_explorer.rs index fe0ccbc080..e082339170 100644 --- a/crates/api-core/src/tests/site_explorer.rs +++ b/crates/api-core/src/tests/site_explorer.rs @@ -49,8 +49,10 @@ use rpc::site_explorer::{ ExploredDpu as RpcExploredDpu, ExploredManagedHost as RpcExploredManagedHost, }; use rpc::{DiscoveryData, DiscoveryInfo, MachineDiscoveryInfo}; +use sqlx::PgPool; use tonic::Request; +use crate::sqlx_test; use crate::tests::common; use crate::tests::common::api_fixtures; use crate::tests::common::api_fixtures::TestEnvOverrides; @@ -188,11 +190,12 @@ impl FakePowerShelf { } } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_default_pause_ingestion_and_poweron( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let bmc_mac_address = "6a:6b:6c:6d:6e:6f".parse().unwrap(); let mut txn = pool.begin().await?; @@ -218,13 +221,13 @@ async fn test_site_explorer_default_pause_ingestion_and_poweron( let mut machines = vec![FakeMachine::new( &bmc_mac_address.to_string(), "Vendor1", - env.underlay_segment.unwrap(), + underlay_segment, )]; machines.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; assert_eq!( - db::machine_interface::count_by_segment_id(&mut txn, &env.underlay_segment.unwrap()) + db::machine_interface::count_by_segment_id(&mut txn, &underlay_segment) .await .unwrap(), 1 @@ -361,17 +364,14 @@ async fn test_site_explorer_default_pause_ingestion_and_poweron( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_handle_redfish_error_powers_on_machine( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new( - "6a:6b:6c:6d:6e:70", - "Vendor1", - env.underlay_segment.unwrap(), - ); + let mut machine = FakeMachine::new("6a:6b:6c:6d:6e:70", "Vendor1", underlay_segment); machine.discover_dhcp(&env).await?; let bmc_ip: IpAddr = machine.ip.parse()?; @@ -449,9 +449,10 @@ async fn test_handle_redfish_error_powers_on_machine( Ok(()) } -#[crate::sqlx_test] -async fn test_site_explorer_main(pool: sqlx::PgPool) -> Result<(), Box> { +#[sqlx_test] +async fn test_site_explorer_main(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); // Let's create 3 machines on the underlay, and 1 on the admin network // The 1 on the admin network is not supposed to be searched. This is verified @@ -459,23 +460,11 @@ async fn test_site_explorer_main(pool: sqlx::PgPool) -> Result<(), Box Result<(), Box Result<(), Box = machines .iter() - .filter(|m| m.segment == env.underlay_segment.unwrap()) + .filter(|m| m.segment == underlay_segment) .map(|m| m.ip.to_string()) .collect(); expected_addresses.sort(); @@ -866,17 +855,14 @@ async fn test_site_explorer_main(pool: sqlx::PgPool) -> Result<(), Box Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new( - "AA:AB:AC:AD:AA:11", - "Vendor1", - env.underlay_segment.unwrap(), - ); + let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:11", "Vendor1", underlay_segment); machine.discover_dhcp(&env).await?; // expected_machine WITHOUT a NoDpu declaration -- the host is @@ -974,17 +960,14 @@ async fn test_site_explorer_skips_unexpected_zero_dpu_host( /// BlueField has been stripped as "DPU in NIC mode") should be ingested as /// a zero-DPU managed host -- the operator has already opted into "treat /// as zero-DPU" semantics by declaring NicMode. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_ingests_nic_mode_host_with_no_observed_dpus( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new( - "AA:AB:AC:AD:AA:22", - "Vendor1", - env.underlay_segment.unwrap(), - ); + let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:22", "Vendor1", underlay_segment); machine.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; @@ -1064,17 +1047,14 @@ async fn test_site_explorer_ingests_nic_mode_host_with_no_observed_dpus( /// declared `dpu_mode = "no_dpu"` ingests as a zero-DPU managed host. The /// `NoDpu` fast-path in `identify_managed_hosts` short-circuits before any /// DPU PCIe enumeration, so this holds regardless of what the BMC reports. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_ingests_no_dpu_host( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new( - "AA:AB:AC:AD:AA:33", - "Vendor1", - env.underlay_segment.unwrap(), - ); + let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:33", "Vendor1", underlay_segment); machine.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; @@ -1149,11 +1129,12 @@ async fn test_site_explorer_ingests_no_dpu_host( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_audit_exploration_results( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let mut txn = pool.begin().await?; for (bmc_mac_address, serial_number, fallback_dpu_serial_numbers) in [ @@ -1194,55 +1175,27 @@ async fn test_site_explorer_audit_exploration_results( // This will be our expected DPU, and it will have the // expected serial number, but we assume no DPUs are expected, // should it still shouldn't be counted as `expected` . - FakeMachine::new( - "5a:5b:5c:5d:5e:5f", - "Vendor1", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("5a:5b:5c:5d:5e:5f", "Vendor1", underlay_segment), // This will be expected but unauthorized, and the serial is mismatched - FakeMachine::new( - "0a:0b:0c:0d:0e:0f", - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("0a:0b:0c:0d:0e:0f", "Vendor3", underlay_segment), // This host will be expected but missing credentials, and the serial is mismatched - FakeMachine::new( - "1a:1b:1c:1d:1e:1f", - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("1a:1b:1c:1d:1e:1f", "Vendor3", underlay_segment), // This host will be expected, but the serial number will be mismatched. - FakeMachine::new( - "2a:2b:2c:2d:2e:2f", - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("2a:2b:2c:2d:2e:2f", "Vendor3", underlay_segment), // This will be expected, with a good serial number. // It will also have associated DPUs and should get a managed host. - FakeMachine::new( - "3a:3b:3c:3d:3e:3f", - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("3a:3b:3c:3d:3e:3f", "Vendor3", underlay_segment), // This host is not expected. - FakeMachine::new( - "ab:cd:ef:ab:cd:ef", - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("ab:cd:ef:ab:cd:ef", "Vendor3", underlay_segment), // This DPU is really not expected. (i.e. no DB entry) - FakeMachine::new( - "ef:cd:ab:ef:cd:ab", - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("ef:cd:ab:ef:cd:ab", "Vendor3", underlay_segment), ]; machines.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; assert_eq!( - db::machine_interface::count_by_segment_id(&mut txn, &env.underlay_segment.unwrap()) + db::machine_interface::count_by_segment_id(&mut txn, &underlay_segment) .await .unwrap(), 7 @@ -1560,30 +1513,21 @@ async fn test_site_explorer_audit_exploration_results( Ok(()) } -#[crate::sqlx_test] -async fn test_site_explorer_reexplore( - pool: sqlx::PgPool, -) -> Result<(), Box> { +#[sqlx_test] +async fn test_site_explorer_reexplore(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let mut machines = vec![ - FakeMachine::new( - "B8:3F:D2:90:97:A6", - "Vendor1", - env.underlay_segment.unwrap(), - ), - FakeMachine::new( - "AA:AB:AC:AD:AA:02", - "Vendor2", - env.underlay_segment.unwrap(), - ), + FakeMachine::new("B8:3F:D2:90:97:A6", "Vendor1", underlay_segment), + FakeMachine::new("AA:AB:AC:AD:AA:02", "Vendor2", underlay_segment), ]; machines.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; assert_eq!( - db::machine_interface::count_by_segment_id(&mut txn, &env.underlay_segment.unwrap()) + db::machine_interface::count_by_segment_id(&mut txn, &underlay_segment) .await .unwrap(), 2 @@ -1747,9 +1691,9 @@ async fn test_site_explorer_reexplore( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_clear_last_known_error( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool).await; let mut txn = db::Transaction::begin(&env.pool).await?; @@ -1792,9 +1736,9 @@ async fn test_site_explorer_clear_last_known_error( } // Test that discover_machines will reject request of machine that was not created by site-explorer when create_machines = true -#[crate::sqlx_test] +#[sqlx_test] async fn test_disable_machine_creation_outside_site_explorer( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let mut config = common::api_fixtures::get_config(); config.site_explorer = SiteExplorerConfig { @@ -1848,21 +1792,18 @@ async fn test_disable_machine_creation_outside_site_explorer( Ok(()) } -#[crate::sqlx_test] -async fn test_fallback_dpu_serial(pool: sqlx::PgPool) -> Result<(), Box> { +#[sqlx_test] +async fn test_fallback_dpu_serial(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); const HOST1_DPU_BMC_MAC: &str = "B8:3F:D2:90:97:A6"; const HOST1_BMC_MAC: &str = "AA:AB:AC:AD:AA:02"; const HOST1_DPU_SERIAL_NUMBER: &str = "host1_dpu_serial_number"; - let mut host1_dpu_bmc = FakeMachine::new( - HOST1_DPU_BMC_MAC, - "NVIDIA/BF/BMC", - env.underlay_segment.unwrap(), - ); + let mut host1_dpu_bmc = FakeMachine::new(HOST1_DPU_BMC_MAC, "NVIDIA/BF/BMC", underlay_segment); - let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2", env.underlay_segment.unwrap()); + let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2", underlay_segment); // Create dhcp entries and machine_interface entries for the machines for machine in [&mut host1_dpu_bmc, &mut host1_bmc] { @@ -2052,10 +1993,8 @@ async fn test_fallback_dpu_serial(pool: sqlx::PgPool) -> Result<(), Box Result<(), Box> { +#[sqlx_test] +async fn test_site_explorer_health_report(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let (host_machine_id, dpu_machine_id) = common::api_fixtures::create_managed_host(&env).await.into(); @@ -2198,9 +2137,9 @@ async fn fetch_exploration_report(env: &TestEnv) -> rpc::site_explorer::SiteExpl .into_inner() } -#[crate::sqlx_test] +#[sqlx_test] async fn test_fetch_host_primary_interface_mac( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let mut mock_dpus = (0..NUM_DPUS).map(|_| DpuConfig::default()).collect_vec(); @@ -2264,9 +2203,9 @@ async fn test_fetch_host_primary_interface_mac( /// Test the [`api_fixtures::site_explorer::new_host`] factory with various configurations and make /// sure they work. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_new_host_fixture( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env_with_overrides( pool.clone(), @@ -2306,9 +2245,9 @@ async fn test_site_explorer_new_host_fixture( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_fixtures_singledpu( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool).await; @@ -2375,9 +2314,9 @@ async fn test_site_explorer_fixtures_singledpu( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_fixtures_multidpu( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool).await; @@ -2452,9 +2391,9 @@ async fn test_site_explorer_fixtures_multidpu( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_fixtures_zerodpu_site_explorer_before_host_dhcp( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env_with_overrides( pool.clone(), @@ -2541,9 +2480,9 @@ async fn test_site_explorer_fixtures_zerodpu_site_explorer_before_host_dhcp( /// chance to run (and a machine_interface is created for its MAC with no machine-id), that /// site-explorer can "repair" the situation when it discovers the machine, by migrating the machine /// interface to the new managed host. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_fixtures_zerodpu_dhcp_before_site_explorer( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env_with_overrides( pool.clone(), @@ -2664,22 +2603,17 @@ async fn test_site_explorer_fixtures_zerodpu_dhcp_before_site_explorer( Ok(()) } -#[crate::sqlx_test] -async fn test_site_explorer_unknown_vendor( - pool: sqlx::PgPool, -) -> Result<(), Box> { +#[sqlx_test] +async fn test_site_explorer_unknown_vendor(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new( - "B8:3F:D2:90:97:A7", - "Vendor1", - env.underlay_segment.unwrap(), - ); + let mut machine = FakeMachine::new("B8:3F:D2:90:97:A7", "Vendor1", underlay_segment); machine.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; assert_eq!( - db::machine_interface::count_by_segment_id(&mut txn, &env.underlay_segment.unwrap()) + db::machine_interface::count_by_segment_id(&mut txn, &underlay_segment) .await .unwrap(), 1 @@ -2750,10 +2684,8 @@ async fn test_site_explorer_unknown_vendor( Ok(()) } -#[crate::sqlx_test] -async fn test_delete_explored_endpoint( - pool: sqlx::PgPool, -) -> Result<(), Box> { +#[sqlx_test] +async fn test_delete_explored_endpoint(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; // Delete an endpoint that doesn't exist @@ -2880,23 +2812,18 @@ async fn test_delete_explored_endpoint( Ok(()) } -#[crate::sqlx_test] -async fn test_machine_creation_with_sku( - pool: sqlx::PgPool, -) -> Result<(), Box> { +#[sqlx_test] +async fn test_machine_creation_with_sku(pool: PgPool) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); const HOST1_DPU_BMC_MAC: &str = "B8:3F:D2:90:97:A6"; const HOST1_BMC_MAC: &str = "AA:AB:AC:AD:AA:02"; const HOST1_DPU_SERIAL_NUMBER: &str = "host1_dpu_serial_number"; - let mut host1_dpu_bmc = FakeMachine::new( - HOST1_DPU_BMC_MAC, - "NVIDIA/BF/BMC", - env.underlay_segment.unwrap(), - ); + let mut host1_dpu_bmc = FakeMachine::new(HOST1_DPU_BMC_MAC, "NVIDIA/BF/BMC", underlay_segment); - let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2", env.underlay_segment.unwrap()); + let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2", underlay_segment); // Create dhcp entries and machine_interface entries for the machines for machine in [&mut host1_dpu_bmc, &mut host1_bmc] { @@ -3043,11 +2970,12 @@ async fn test_machine_creation_with_sku( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_expected_machine_device_type_metrics( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let test_sku_gpu_id = format!("test-sku-gpu-{}", uuid::Uuid::new_v4()); let test_sku_no_type_id = format!("test-sku-no-type-{}", uuid::Uuid::new_v4()); @@ -3057,21 +2985,9 @@ async fn test_expected_machine_device_type_metrics( // Create fake machines with network interfaces so they can be discovered let mut machines = vec![ - FakeMachine::new( - EXPECTED_MACHINE_1_MAC, - "Vendor1", - env.underlay_segment.unwrap(), - ), - FakeMachine::new( - EXPECTED_MACHINE_2_MAC, - "Vendor2", - env.underlay_segment.unwrap(), - ), - FakeMachine::new( - EXPECTED_MACHINE_3_MAC, - "Vendor3", - env.underlay_segment.unwrap(), - ), + FakeMachine::new(EXPECTED_MACHINE_1_MAC, "Vendor1", underlay_segment), + FakeMachine::new(EXPECTED_MACHINE_2_MAC, "Vendor2", underlay_segment), + FakeMachine::new(EXPECTED_MACHINE_3_MAC, "Vendor3", underlay_segment), ]; machines.discover_dhcp(&env).await?; @@ -3354,11 +3270,12 @@ async fn test_expected_machine_device_type_metrics( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_power_shelf_discovery( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let mut power_shelf = FakePowerShelf::new( "B8:3F:D2:90:97:B0".parse().unwrap(), @@ -3367,7 +3284,7 @@ async fn test_site_explorer_power_shelf_discovery( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env @@ -3376,7 +3293,7 @@ async fn test_site_explorer_power_shelf_discovery( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -3501,17 +3418,18 @@ async fn test_site_explorer_power_shelf_discovery( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_switch_discovery( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let bmc_mac: MacAddress = "B8:3F:D2:90:97:C0".parse().unwrap(); let serial_number = "SW-SN-001".to_string(); let bmc_username = "ADMIN".to_string(); let bmc_password = "Pwd2023".to_string(); - let segment = env.underlay_segment.unwrap(); + let segment = underlay_segment; let response = env .api @@ -3519,7 +3437,7 @@ async fn test_site_explorer_switch_discovery( DhcpDiscovery::builder( bmc_mac.to_string(), match segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -3656,11 +3574,12 @@ async fn test_site_explorer_switch_discovery( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_power_shelf_with_expected_config( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf using the new FakePowerShelf struct let mut power_shelf = FakePowerShelf::new( @@ -3670,7 +3589,7 @@ async fn test_site_explorer_power_shelf_with_expected_config( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env @@ -3679,7 +3598,7 @@ async fn test_site_explorer_power_shelf_with_expected_config( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -3786,11 +3705,12 @@ async fn test_site_explorer_power_shelf_with_expected_config( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_power_shelf_creation_limit( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); // Create multiple power shelf machines using FakePowerShelf let mut power_shelves = vec![ @@ -3801,7 +3721,7 @@ async fn test_site_explorer_power_shelf_creation_limit( "admin".to_string(), "password".to_string(), "PowerShelfVendor1".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ), FakePowerShelf::new( "B8:3F:D2:90:97:B3".parse().unwrap(), @@ -3810,7 +3730,7 @@ async fn test_site_explorer_power_shelf_creation_limit( "admin".to_string(), "password".to_string(), "PowerShelfVendor2".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ), FakePowerShelf::new( "B8:3F:D2:90:97:B4".parse().unwrap(), @@ -3819,7 +3739,7 @@ async fn test_site_explorer_power_shelf_creation_limit( "admin".to_string(), "password".to_string(), "PowerShelfVendor3".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ), ]; for power_shelf in &mut power_shelves { @@ -3829,7 +3749,7 @@ async fn test_site_explorer_power_shelf_creation_limit( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -3949,11 +3869,12 @@ async fn test_site_explorer_power_shelf_creation_limit( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_power_shelf_disabled( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf machine using FakePowerShelf let mut power_shelf = FakePowerShelf::new( @@ -3963,7 +3884,7 @@ async fn test_site_explorer_power_shelf_disabled( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env .api @@ -3971,7 +3892,7 @@ async fn test_site_explorer_power_shelf_disabled( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -4075,11 +3996,12 @@ async fn test_site_explorer_power_shelf_disabled( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_power_shelf_error_handling( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf machine using FakePowerShelf let mut power_shelf = FakePowerShelf::new( @@ -4089,7 +4011,7 @@ async fn test_site_explorer_power_shelf_error_handling( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env @@ -4098,7 +4020,7 @@ async fn test_site_explorer_power_shelf_error_handling( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -4183,9 +4105,9 @@ async fn test_site_explorer_power_shelf_error_handling( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_creates_power_shelf( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let mut config = common::api_fixtures::get_config(); config.dpu_config.dpu_models = HashMap::new(); @@ -4194,6 +4116,7 @@ async fn test_site_explorer_creates_power_shelf( TestEnvOverrides::with_config(config), ) .await; + let underlay_segment = env.underlay_segment.unwrap(); let endpoint_explorer = Arc::new(MockEndpointExplorer::default()); let test_meter = TestMeter::default(); @@ -4229,7 +4152,7 @@ async fn test_site_explorer_creates_power_shelf( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env @@ -4238,7 +4161,7 @@ async fn test_site_explorer_creates_power_shelf( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -4400,10 +4323,8 @@ async fn test_site_explorer_creates_power_shelf( } /// Test power shelf state history functionality -#[crate::sqlx_test] -async fn test_power_shelf_state_history( - pool: sqlx::PgPool, -) -> Result<(), Box> { +#[sqlx_test] +async fn test_power_shelf_state_history(pool: PgPool) -> Result<(), Box> { let mut config = common::api_fixtures::get_config(); config.dpu_config.dpu_models = HashMap::new(); let env = common::api_fixtures::create_test_env_with_overrides( @@ -4411,6 +4332,7 @@ async fn test_power_shelf_state_history( TestEnvOverrides::with_config(config), ) .await; + let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf using FakePowerShelf let mut power_shelf = FakePowerShelf::new( @@ -4420,7 +4342,7 @@ async fn test_power_shelf_state_history( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env @@ -4429,7 +4351,7 @@ async fn test_power_shelf_state_history( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -4633,9 +4555,9 @@ async fn test_power_shelf_state_history( } /// Test power shelf state history with multiple power shelves -#[crate::sqlx_test] +#[sqlx_test] async fn test_power_shelf_state_history_multiple( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let mut config = common::api_fixtures::get_config(); config.dpu_config.dpu_models = HashMap::new(); @@ -4644,6 +4566,7 @@ async fn test_power_shelf_state_history_multiple( TestEnvOverrides::with_config(config), ) .await; + let underlay_segment = env.underlay_segment.unwrap(); // Create multiple power shelves let power_shelf1 = FakePowerShelf::new( @@ -4653,7 +4576,7 @@ async fn test_power_shelf_state_history_multiple( "admin".to_string(), "password".to_string(), "PowerShelfVendor1".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let power_shelf2 = FakePowerShelf::new( @@ -4663,7 +4586,7 @@ async fn test_power_shelf_state_history_multiple( "admin".to_string(), "password".to_string(), "PowerShelfVendor2".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); // Create expected power shelf entries in the database @@ -4911,9 +4834,9 @@ async fn test_power_shelf_state_history_multiple( } /// Test power shelf state history error handling -#[crate::sqlx_test] +#[sqlx_test] async fn test_power_shelf_state_history_error_handling( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let mut config = common::api_fixtures::get_config(); config.dpu_config.dpu_models = HashMap::new(); @@ -4922,6 +4845,7 @@ async fn test_power_shelf_state_history_error_handling( TestEnvOverrides::with_config(config), ) .await; + let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf using FakePowerShelf let mut power_shelf = FakePowerShelf::new( @@ -4931,7 +4855,7 @@ async fn test_power_shelf_state_history_error_handling( "admin".to_string(), "password".to_string(), "TestVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); let response = env @@ -4940,7 +4864,7 @@ async fn test_power_shelf_state_history_error_handling( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), match power_shelf.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), + s if s == underlay_segment => "192.0.1.1".to_string(), _ => "192.0.2.1".to_string(), }, ) @@ -5131,11 +5055,12 @@ async fn test_power_shelf_state_history_error_handling( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_power_shelf_discovery_with_static_ip( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; + let underlay_segment = env.underlay_segment.unwrap(); let power_shelf = FakePowerShelf::new( "B8:3F:D2:90:97:B0".parse().unwrap(), @@ -5144,7 +5069,7 @@ async fn test_site_explorer_power_shelf_discovery_with_static_ip( "admin".to_string(), "password".to_string(), "PowerShelfVendor".to_string(), - env.underlay_segment.unwrap(), + underlay_segment, ); tracing::info!( @@ -5262,10 +5187,8 @@ async fn test_site_explorer_power_shelf_discovery_with_static_ip( } /// Test the get_machine_position_info API endpoint -#[crate::sqlx_test] -async fn test_get_machine_position_info( - pool: sqlx::PgPool, -) -> Result<(), Box> { +#[sqlx_test] +async fn test_get_machine_position_info(pool: PgPool) -> Result<(), Box> { use rpc::forge::forge_server::Forge; let env = common::api_fixtures::create_test_env(pool.clone()).await; @@ -5320,9 +5243,9 @@ async fn test_get_machine_position_info( } /// Test get_machine_position_info with a machine that has no explored endpoint -#[crate::sqlx_test] +#[sqlx_test] async fn test_get_machine_position_info_no_endpoint( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { use rpc::forge::forge_server::Forge; @@ -5361,9 +5284,9 @@ async fn test_get_machine_position_info_no_endpoint( /// This exercises the full wire (site-explorer iteration → per-host mode /// resolution → `check_and_configure_dpu_mode` → mock Redfish /// `set_nic_mode`) that the unit tests only cover in pieces. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_auto_corrects_nic_mode_per_expected_machine( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { use model::expected_machine::{DpuMode, ExpectedMachine, ExpectedMachineData}; use model::site_explorer::NicMode; @@ -5437,9 +5360,9 @@ async fn test_site_explorer_auto_corrects_nic_mode_per_expected_machine( /// orphan: `audit_exploration_results` emits an `OrphanManagedHost` health /// alert on the host's Machine. Re-adding the entry clears the alert on the /// next iteration. -#[crate::sqlx_test] +#[sqlx_test] async fn test_orphan_managed_host_alert_emitted( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let host_config = ManagedHostConfig::default(); @@ -5532,9 +5455,9 @@ fn endpoint_explore_call_count(env: &TestEnv, bmc_ip: IpAddr) -> usize { .count() } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_bumps_report_version( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let mh = common::api_fixtures::create_managed_host(&env).await; @@ -5558,9 +5481,9 @@ async fn test_refresh_endpoint_report_bumps_report_version( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_rejects_nonexistent_endpoint( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; @@ -5577,9 +5500,9 @@ async fn test_refresh_endpoint_report_rejects_nonexistent_endpoint( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_rejects_duplicate_refresh( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let mh = common::api_fixtures::create_managed_host(&env).await; @@ -5603,9 +5526,9 @@ async fn test_refresh_endpoint_report_rejects_duplicate_refresh( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_lock_blocks_periodic_probe( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let mh = common::api_fixtures::create_managed_host(&env).await; @@ -5636,9 +5559,9 @@ async fn test_refresh_endpoint_report_lock_blocks_periodic_probe( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_failure_persists_error_and_bumps_version( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let mh = common::api_fixtures::create_managed_host(&env).await; @@ -5669,9 +5592,9 @@ async fn test_refresh_endpoint_report_failure_persists_error_and_bumps_version( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_clears_pending_requested_exploration( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let mh = common::api_fixtures::create_managed_host(&env).await; @@ -5699,9 +5622,9 @@ async fn test_refresh_endpoint_report_clears_pending_requested_exploration( Ok(()) } -#[crate::sqlx_test] +#[sqlx_test] async fn test_refresh_endpoint_report_lock_is_per_endpoint( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let mh_a = common::api_fixtures::create_managed_host(&env).await; @@ -5784,9 +5707,9 @@ fn expected_switch_fixture( /// When a switch is rediscovered with a chassis serial that hashes to a new /// `SwitchId`, the BMC MAC check must keep us from inserting a second record. -#[crate::sqlx_test] +#[sqlx_test] async fn switch_skips_creation_when_bmc_mac_already_used( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let bmc_mac: MacAddress = "B8:3F:D2:90:97:D0".parse().unwrap(); @@ -5859,9 +5782,9 @@ async fn switch_skips_creation_when_bmc_mac_already_used( /// `MissingHardwareInfo::Serial` rather than give us a junk `SwitchId`, and /// no record gets created. The next exploration cycle picks the switch up /// once a real serial is reported. -#[crate::sqlx_test] +#[sqlx_test] async fn switch_treats_na_chassis_serial_as_missing( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let bmc_mac: MacAddress = "B8:3F:D2:90:97:D2".parse().unwrap(); @@ -5901,9 +5824,9 @@ async fn switch_treats_na_chassis_serial_as_missing( /// Power-shelf companion to `switch_skips_creation_when_bmc_mac_already_used`: /// a second call to `create_power_shelf` for the same BMC MAC must not insert /// a second row, even if the inputs we'd hash into a `PowerShelfId` differ. -#[crate::sqlx_test] +#[sqlx_test] async fn power_shelf_skips_creation_when_bmc_mac_already_used( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; let bmc_mac: MacAddress = "B8:3F:D2:90:97:E0".parse().unwrap(); @@ -6041,9 +5964,9 @@ async fn power_shelf_skips_creation_when_bmc_mac_already_used( /// covering the static-assignments-segment counterpart to the DHCP `discover()` recovery hook: /// devices whose IP lives outside any Carbide-managed network never reach `discover()`, so this /// per-row preallocation is what gets their rows onto the books. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_reconcile_creates_missing_preallocations( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; @@ -6162,9 +6085,9 @@ async fn test_site_explorer_reconcile_creates_missing_preallocations( /// Site-explorer's reconciliation pass must materialize `ExpectedHostNic.fixed_ip` /// reservations too, not just BMC IPs. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_reconcile_preallocates_host_nic_fixed_ip( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; @@ -6228,9 +6151,9 @@ async fn test_site_explorer_reconcile_preallocates_host_nic_fixed_ip( /// Running `try_preallocate_one` twice for the same (mac, ip) must be a no-op the second time /// -- no new rows, no errors. This is the steady-state behavior since site-explorer iterates /// continuously and re-issues the same calls on every pass. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_reconcile_is_idempotent( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; @@ -6279,9 +6202,9 @@ async fn test_site_explorer_reconcile_is_idempotent( /// A per-entry conflict (e.g., two expected_machines configured with the same static IP -- a /// genuine operator misconfiguration) must not abort the whole reconciliation pass. The /// conflicting entry gets logged and skipped; the rest of the iteration continues. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_reconcile_tolerates_per_entry_conflicts( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; @@ -6354,9 +6277,9 @@ async fn test_site_explorer_reconcile_tolerates_per_entry_conflicts( /// host-NIC `fixed_ip` paths. Calls `try_preallocate_one` directly the same way the /// expected_switches loop does, and verifies the resulting row carries the configured /// IP with `InterfaceType::Data`. -#[crate::sqlx_test] +#[sqlx_test] async fn test_site_explorer_reconcile_preallocates_nvos_ip( - pool: sqlx::PgPool, + pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; From 7690cf42d5ac4e3085157a796a81b98c2351d485 Mon Sep 17 00:00:00 2001 From: Dmitry Porokh Date: Thu, 4 Jun 2026 17:09:59 -0700 Subject: [PATCH 2/4] test(api-core): deduplicate site explorer test construction Introduce a test-env construction trait for creating SiteExplorer instances and reuse the env-provided test meter instead of allocating per-test meters. Signed-off-by: Dmitry Porokh --- crates/api-core/src/tests/site_explorer.rs | 364 ++++----------------- 1 file changed, 66 insertions(+), 298 deletions(-) diff --git a/crates/api-core/src/tests/site_explorer.rs b/crates/api-core/src/tests/site_explorer.rs index e082339170..eb8d8d3e78 100644 --- a/crates/api-core/src/tests/site_explorer.rs +++ b/crates/api-core/src/tests/site_explorer.rs @@ -22,7 +22,6 @@ use std::sync::Arc; use carbide_site_explorer::config::{SiteExplorerConfig, SiteExplorerExploreMode}; use carbide_site_explorer::{SiteExplorer, endpoint_exploration_work_key}; -use carbide_utils::test_support::test_meter::TestMeter; use carbide_uuid::network::NetworkSegmentId; use common::api_fixtures::TestEnv; use common::api_fixtures::endpoint_explorer::MockEndpointExplorer; @@ -137,6 +136,34 @@ impl DiscoverDhcp for Vec { } } +trait SiteExplorerConstructor { + fn new_site_explorer( + &self, + explorer_config: SiteExplorerConfig, + endpoint_explorer: &Arc, + ) -> SiteExplorer; +} + +impl SiteExplorerConstructor for TestEnv { + fn new_site_explorer( + &self, + explorer_config: SiteExplorerConfig, + endpoint_explorer: &Arc, + ) -> SiteExplorer { + SiteExplorer::new( + self.pool.clone(), + explorer_config, + self.test_meter.meter(), + endpoint_explorer.clone(), + Arc::new(self.config.get_firmware_config()), + self.common_pools.clone(), + self.api.work_lock_manager_handle.clone(), + self.rms_sim.as_rms_client(), + self.test_credential_manager.clone(), + ) + } +} + struct FakePowerShelf { pub bmc_mac_address: MacAddress, pub serial_number: String, @@ -249,18 +276,7 @@ async fn test_site_explorer_default_pause_ingestion_and_poweron( create_machines: Arc::new(true.into()), ..Default::default() }; - let test_meter = TestMeter::default(); - let explorer = SiteExplorer::new( - env.pool.clone(), - explorer_config, - test_meter.meter(), - endpoint_explorer.clone(), - Arc::new(env.config.get_firmware_config()), - env.common_pools.clone(), - env.api.work_lock_manager_handle.clone(), - env.rms_sim.as_rms_client(), - env.test_credential_manager.clone(), - ); + let explorer = env.new_site_explorer(explorer_config, &endpoint_explorer); // check the ingestion state of the machine let response = env @@ -413,18 +429,7 @@ async fn test_handle_redfish_error_powers_on_machine( create_machines: Arc::new(true.into()), ..Default::default() }; - let test_meter = TestMeter::default(); - let explorer = SiteExplorer::new( - env.pool.clone(), - explorer_config, - test_meter.meter(), - endpoint_explorer.clone(), - Arc::new(env.config.get_firmware_config()), - env.common_pools.clone(), - env.api.work_lock_manager_handle.clone(), - env.rms_sim.as_rms_client(), - env.test_credential_manager.clone(), - ); + let explorer = env.new_site_explorer(explorer_config, &endpoint_explorer); explorer.run_single_iteration().await?; @@ -576,18 +581,8 @@ async fn test_site_explorer_main(pool: PgPool) -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box Result<(), Box Result<(), Box Result<(), Box Result<(), Box Date: Thu, 4 Jun 2026 18:03:52 -0700 Subject: [PATCH 3/4] test(core-api): simplify site explorer fixture setup Refactor fake machine and power shelf test helpers to use default relay addresses and credentials, reducing repetitive setup across site explorer tests. Signed-off-by: Dmitry Porokh --- crates/api-core/src/tests/site_explorer.rs | 309 +++++---------------- 1 file changed, 76 insertions(+), 233 deletions(-) diff --git a/crates/api-core/src/tests/site_explorer.rs b/crates/api-core/src/tests/site_explorer.rs index eb8d8d3e78..0fe2078c6b 100644 --- a/crates/api-core/src/tests/site_explorer.rs +++ b/crates/api-core/src/tests/site_explorer.rs @@ -22,7 +22,6 @@ use std::sync::Arc; use carbide_site_explorer::config::{SiteExplorerConfig, SiteExplorerExploreMode}; use carbide_site_explorer::{SiteExplorer, endpoint_exploration_work_key}; -use carbide_uuid::network::NetworkSegmentId; use common::api_fixtures::TestEnv; use common::api_fixtures::endpoint_explorer::MockEndpointExplorer; use config_version::ConfigVersion; @@ -68,16 +67,28 @@ use crate::tests::common::rpc_builder::DhcpDiscovery; struct FakeMachine { pub mac: MacAddress, pub dhcp_vendor: String, - pub segment: NetworkSegmentId, + pub relay_address: &'static str, pub ip: String, } +const UNDERLAY_RELAY: &str = "192.0.1.1"; +const ADMIN_RELAY: &str = "192.0.2.1"; + impl FakeMachine { - fn new(mac: &str, vendor: &str, segment: NetworkSegmentId) -> Self { + fn new_admin(mac: &str, vendor: &str) -> Self { + Self { + mac: mac.parse().unwrap(), + dhcp_vendor: vendor.to_string(), + relay_address: ADMIN_RELAY, + ip: String::new(), + } + } + + fn new(mac: &str, vendor: &str) -> Self { Self { mac: mac.parse().unwrap(), dhcp_vendor: vendor.to_string(), - segment, + relay_address: UNDERLAY_RELAY, ip: String::new(), } } @@ -104,14 +115,10 @@ trait DiscoverDhcp { impl DiscoverDhcp for FakeMachine { async fn discover_dhcp(&mut self, env: &TestEnv) -> Result<(), Box> { - let relay_address = match self.segment { - s if s == env.underlay_segment.unwrap() => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }; let response = env .api .discover_dhcp( - DhcpDiscovery::builder(self.mac, relay_address) + DhcpDiscovery::builder(self.mac, self.relay_address) .vendor_string(&self.dhcp_vendor) .tonic_request(), ) @@ -167,32 +174,21 @@ impl SiteExplorerConstructor for TestEnv { struct FakePowerShelf { pub bmc_mac_address: MacAddress, pub serial_number: String, - pub bmc_username: String, - pub bmc_password: String, - #[allow(dead_code)] - pub dhcp_vendor: String, - pub segment: NetworkSegmentId, + pub bmc_username: &'static str, + pub bmc_password: &'static str, + pub relay_address: &'static str, pub ip: String, // DHCP assigned IP (may be different from ip_address) } impl FakePowerShelf { - fn new( - bmc_mac_address: MacAddress, - ip: String, - serial_number: String, - bmc_username: String, - bmc_password: String, - dhcp_vendor: String, - segment: NetworkSegmentId, - ) -> Self { + fn new(bmc_mac_address: &str, ip: &str, serial_number: &str) -> Self { Self { - bmc_mac_address, - ip, - serial_number, - bmc_username, - bmc_password, - dhcp_vendor, - segment, + bmc_mac_address: bmc_mac_address.parse().unwrap(), + ip: ip.to_string(), + serial_number: serial_number.to_string(), + bmc_username: "admin", + bmc_password: "password", + relay_address: UNDERLAY_RELAY, } } @@ -202,8 +198,8 @@ impl FakePowerShelf { model::expected_power_shelf::ExpectedPowerShelf { expected_power_shelf_id: None, bmc_mac_address: self.bmc_mac_address, - bmc_username: self.bmc_username.clone(), - bmc_password: self.bmc_password.clone(), + bmc_username: self.bmc_username.to_string(), + bmc_password: self.bmc_password.to_string(), serial_number: self.serial_number.clone(), bmc_ip_address: Some(self.ip.parse().unwrap()), metadata: Metadata { @@ -245,11 +241,7 @@ async fn test_site_explorer_default_pause_ingestion_and_poweron( .unwrap(); txn.commit().await?; - let mut machines = vec![FakeMachine::new( - &bmc_mac_address.to_string(), - "Vendor1", - underlay_segment, - )]; + let mut machines = vec![FakeMachine::new(&bmc_mac_address.to_string(), "Vendor1")]; machines.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; @@ -385,9 +377,8 @@ async fn test_handle_redfish_error_powers_on_machine( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new("6a:6b:6c:6d:6e:70", "Vendor1", underlay_segment); + let mut machine = FakeMachine::new("6a:6b:6c:6d:6e:70", "Vendor1"); machine.discover_dhcp(&env).await?; let bmc_ip: IpAddr = machine.ip.parse()?; @@ -465,17 +456,13 @@ async fn test_site_explorer_main(pool: PgPool) -> Result<(), Box Result<(), Box = machines .iter() - .filter(|m| m.segment == underlay_segment) + .filter(|m| m.relay_address == UNDERLAY_RELAY) .map(|m| m.ip.to_string()) .collect(); expected_addresses.sort(); @@ -855,9 +842,8 @@ async fn test_site_explorer_skips_unexpected_zero_dpu_host( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:11", "Vendor1", underlay_segment); + let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:11", "Vendor1"); machine.discover_dhcp(&env).await?; // expected_machine WITHOUT a NoDpu declaration -- the host is @@ -951,9 +937,8 @@ async fn test_site_explorer_ingests_nic_mode_host_with_no_observed_dpus( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:22", "Vendor1", underlay_segment); + let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:22", "Vendor1"); machine.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; @@ -1027,9 +1012,8 @@ async fn test_site_explorer_ingests_no_dpu_host( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); - let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:33", "Vendor1", underlay_segment); + let mut machine = FakeMachine::new("AA:AB:AC:AD:AA:33", "Vendor1"); machine.discover_dhcp(&env).await?; let mut txn = env.pool.begin().await?; @@ -1139,20 +1123,20 @@ async fn test_site_explorer_audit_exploration_results( // This will be our expected DPU, and it will have the // expected serial number, but we assume no DPUs are expected, // should it still shouldn't be counted as `expected` . - FakeMachine::new("5a:5b:5c:5d:5e:5f", "Vendor1", underlay_segment), + FakeMachine::new("5a:5b:5c:5d:5e:5f", "Vendor1"), // This will be expected but unauthorized, and the serial is mismatched - FakeMachine::new("0a:0b:0c:0d:0e:0f", "Vendor3", underlay_segment), + FakeMachine::new("0a:0b:0c:0d:0e:0f", "Vendor3"), // This host will be expected but missing credentials, and the serial is mismatched - FakeMachine::new("1a:1b:1c:1d:1e:1f", "Vendor3", underlay_segment), + FakeMachine::new("1a:1b:1c:1d:1e:1f", "Vendor3"), // This host will be expected, but the serial number will be mismatched. - FakeMachine::new("2a:2b:2c:2d:2e:2f", "Vendor3", underlay_segment), + FakeMachine::new("2a:2b:2c:2d:2e:2f", "Vendor3"), // This will be expected, with a good serial number. // It will also have associated DPUs and should get a managed host. - FakeMachine::new("3a:3b:3c:3d:3e:3f", "Vendor3", underlay_segment), + FakeMachine::new("3a:3b:3c:3d:3e:3f", "Vendor3"), // This host is not expected. - FakeMachine::new("ab:cd:ef:ab:cd:ef", "Vendor3", underlay_segment), + FakeMachine::new("ab:cd:ef:ab:cd:ef", "Vendor3"), // This DPU is really not expected. (i.e. no DB entry) - FakeMachine::new("ef:cd:ab:ef:cd:ab", "Vendor3", underlay_segment), + FakeMachine::new("ef:cd:ab:ef:cd:ab", "Vendor3"), ]; machines.discover_dhcp(&env).await?; @@ -1473,8 +1457,8 @@ async fn test_site_explorer_reexplore(pool: PgPool) -> Result<(), Box Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); const HOST1_DPU_BMC_MAC: &str = "B8:3F:D2:90:97:A6"; const HOST1_BMC_MAC: &str = "AA:AB:AC:AD:AA:02"; const HOST1_DPU_SERIAL_NUMBER: &str = "host1_dpu_serial_number"; - let mut host1_dpu_bmc = FakeMachine::new(HOST1_DPU_BMC_MAC, "NVIDIA/BF/BMC", underlay_segment); + let mut host1_dpu_bmc = FakeMachine::new(HOST1_DPU_BMC_MAC, "NVIDIA/BF/BMC"); - let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2", underlay_segment); + let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2"); // Create dhcp entries and machine_interface entries for the machines for machine in [&mut host1_dpu_bmc, &mut host1_bmc] { @@ -2530,7 +2513,7 @@ async fn test_site_explorer_unknown_vendor(pool: PgPool) -> Result<(), Box Result<(), Box Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); const HOST1_DPU_BMC_MAC: &str = "B8:3F:D2:90:97:A6"; const HOST1_BMC_MAC: &str = "AA:AB:AC:AD:AA:02"; const HOST1_DPU_SERIAL_NUMBER: &str = "host1_dpu_serial_number"; - let mut host1_dpu_bmc = FakeMachine::new(HOST1_DPU_BMC_MAC, "NVIDIA/BF/BMC", underlay_segment); + let mut host1_dpu_bmc = FakeMachine::new(HOST1_DPU_BMC_MAC, "NVIDIA/BF/BMC"); - let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2", underlay_segment); + let mut host1_bmc = FakeMachine::new(HOST1_BMC_MAC, "Vendor2"); // Create dhcp entries and machine_interface entries for the machines for machine in [&mut host1_dpu_bmc, &mut host1_bmc] { @@ -2876,7 +2858,6 @@ async fn test_expected_machine_device_type_metrics( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); let test_sku_gpu_id = format!("test-sku-gpu-{}", uuid::Uuid::new_v4()); let test_sku_no_type_id = format!("test-sku-no-type-{}", uuid::Uuid::new_v4()); @@ -2886,9 +2867,9 @@ async fn test_expected_machine_device_type_metrics( // Create fake machines with network interfaces so they can be discovered let mut machines = vec![ - FakeMachine::new(EXPECTED_MACHINE_1_MAC, "Vendor1", underlay_segment), - FakeMachine::new(EXPECTED_MACHINE_2_MAC, "Vendor2", underlay_segment), - FakeMachine::new(EXPECTED_MACHINE_3_MAC, "Vendor3", underlay_segment), + FakeMachine::new(EXPECTED_MACHINE_1_MAC, "Vendor1"), + FakeMachine::new(EXPECTED_MACHINE_2_MAC, "Vendor2"), + FakeMachine::new(EXPECTED_MACHINE_3_MAC, "Vendor3"), ]; machines.discover_dhcp(&env).await?; @@ -3166,27 +3147,15 @@ async fn test_site_explorer_power_shelf_discovery( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); - let mut power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B0".parse().unwrap(), - "".to_string(), - "PS123456789".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor".to_string(), - underlay_segment, - ); + let mut power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B0", "", "PS123456789"); let response = env .api .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -3450,28 +3419,16 @@ async fn test_site_explorer_power_shelf_with_expected_config( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf using the new FakePowerShelf struct - let mut power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B1".parse().unwrap(), - "192.168.1.100".parse().unwrap(), - "PS123456789".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor".to_string(), - underlay_segment, - ); + let mut power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B1", "192.168.1.100", "PS123456789"); let response = env .api .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -3570,37 +3527,12 @@ async fn test_site_explorer_power_shelf_creation_limit( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); // Create multiple power shelf machines using FakePowerShelf let mut power_shelves = vec![ - FakePowerShelf::new( - "B8:3F:D2:90:97:B2".parse().unwrap(), - "".to_string(), - "PS123456790".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor1".to_string(), - underlay_segment, - ), - FakePowerShelf::new( - "B8:3F:D2:90:97:B3".parse().unwrap(), - "".to_string(), - "PS123456791".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor2".to_string(), - underlay_segment, - ), - FakePowerShelf::new( - "B8:3F:D2:90:97:B4".parse().unwrap(), - "".to_string(), - "PS123456792".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor3".to_string(), - underlay_segment, - ), + FakePowerShelf::new("B8:3F:D2:90:97:B2", "", "PS123456790"), + FakePowerShelf::new("B8:3F:D2:90:97:B3", "", "PS123456791"), + FakePowerShelf::new("B8:3F:D2:90:97:B4", "", "PS123456792"), ]; for power_shelf in &mut power_shelves { let response = env @@ -3608,10 +3540,7 @@ async fn test_site_explorer_power_shelf_creation_limit( .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -3724,27 +3653,15 @@ async fn test_site_explorer_power_shelf_disabled( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf machine using FakePowerShelf - let mut power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B5".parse().unwrap(), - "".to_string(), - "PS123456793".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor".to_string(), - underlay_segment, - ); + let mut power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B5", "", "PS123456793"); let response = env .api .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -3841,28 +3758,16 @@ async fn test_site_explorer_power_shelf_error_handling( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf machine using FakePowerShelf - let mut power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B6".parse().unwrap(), - "".to_string(), - "PS123456794".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor".to_string(), - underlay_segment, - ); + let mut power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B6", "", "PS123456794"); let response = env .api .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -3946,7 +3851,6 @@ async fn test_site_explorer_creates_power_shelf( TestEnvOverrides::with_config(config), ) .await; - let underlay_segment = env.underlay_segment.unwrap(); let endpoint_explorer = Arc::new(MockEndpointExplorer::default()); let explorer_config = SiteExplorerConfig { @@ -3964,25 +3868,14 @@ async fn test_site_explorer_creates_power_shelf( let explorer = env.new_site_explorer(explorer_config, &endpoint_explorer); // Create a power shelf using FakePowerShelf - let mut power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B0".parse().unwrap(), - "".to_string(), - "PS123456789".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor".to_string(), - underlay_segment, - ); + let mut power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B0", "", "PS123456789"); let response = env .api .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -4151,28 +4044,16 @@ async fn test_power_shelf_state_history(pool: PgPool) -> Result<(), Box "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -4374,28 +4255,11 @@ async fn test_power_shelf_state_history_multiple( TestEnvOverrides::with_config(config), ) .await; - let underlay_segment = env.underlay_segment.unwrap(); // Create multiple power shelves - let power_shelf1 = FakePowerShelf::new( - "B8:3F:D2:90:97:B0".parse().unwrap(), - "192.0.1.2".parse().unwrap(), - "PS123456789".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor1".to_string(), - underlay_segment, - ); + let power_shelf1 = FakePowerShelf::new("B8:3F:D2:90:97:B0", "192.0.1.2", "PS123456789"); - let power_shelf2 = FakePowerShelf::new( - "B8:3F:D2:90:97:B1".parse().unwrap(), - "192.0.1.3".parse().unwrap(), - "PS987654321".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor2".to_string(), - underlay_segment, - ); + let power_shelf2 = FakePowerShelf::new("B8:3F:D2:90:97:B1", "192.0.1.3", "PS987654321"); // Create expected power shelf entries in the database let mut txn = env.pool.begin().await?; @@ -4642,28 +4506,16 @@ async fn test_power_shelf_state_history_error_handling( TestEnvOverrides::with_config(config), ) .await; - let underlay_segment = env.underlay_segment.unwrap(); // Create a power shelf using FakePowerShelf - let mut power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B0".parse().unwrap(), - "".to_string(), - "PS999999999".to_string(), - "admin".to_string(), - "password".to_string(), - "TestVendor".to_string(), - underlay_segment, - ); + let mut power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B0", "", "PS999999999"); let response = env .api .discover_dhcp( DhcpDiscovery::builder( power_shelf.bmc_mac_address.to_string(), - match power_shelf.segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, + power_shelf.relay_address.to_string(), ) .tonic_request(), ) @@ -4846,17 +4698,8 @@ async fn test_site_explorer_power_shelf_discovery_with_static_ip( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); - let power_shelf = FakePowerShelf::new( - "B8:3F:D2:90:97:B0".parse().unwrap(), - "192.0.1.180".to_string(), - "PS123456789".to_string(), - "admin".to_string(), - "password".to_string(), - "PowerShelfVendor".to_string(), - underlay_segment, - ); + let power_shelf = FakePowerShelf::new("B8:3F:D2:90:97:B0", "192.0.1.180", "PS123456789"); tracing::info!( "Static ip {} assigned to power shelf mac {}", From 99f4b4bea386e60c16149ce9cd7ab000aef78d02 Mon Sep 17 00:00:00 2001 From: Dmitry Porokh Date: Thu, 4 Jun 2026 18:36:09 -0700 Subject: [PATCH 4/4] test(core-api): test_site_explorer_switch_discovery simplified Signed-off-by: Dmitry Porokh --- crates/api-core/src/tests/site_explorer.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/crates/api-core/src/tests/site_explorer.rs b/crates/api-core/src/tests/site_explorer.rs index 0fe2078c6b..67628c77df 100644 --- a/crates/api-core/src/tests/site_explorer.rs +++ b/crates/api-core/src/tests/site_explorer.rs @@ -3273,26 +3273,15 @@ async fn test_site_explorer_switch_discovery( pool: PgPool, ) -> Result<(), Box> { let env = common::api_fixtures::create_test_env(pool.clone()).await; - let underlay_segment = env.underlay_segment.unwrap(); let bmc_mac: MacAddress = "B8:3F:D2:90:97:C0".parse().unwrap(); let serial_number = "SW-SN-001".to_string(); let bmc_username = "ADMIN".to_string(); let bmc_password = "Pwd2023".to_string(); - let segment = underlay_segment; let response = env .api - .discover_dhcp( - DhcpDiscovery::builder( - bmc_mac.to_string(), - match segment { - s if s == underlay_segment => "192.0.1.1".to_string(), - _ => "192.0.2.1".to_string(), - }, - ) - .tonic_request(), - ) + .discover_dhcp(DhcpDiscovery::builder(bmc_mac.to_string(), UNDERLAY_RELAY).tonic_request()) .await? .into_inner(); tracing::info!("DHCP with mac {} assigned ip {}", bmc_mac, response.address);