From ca6b76197410b1689554b03c98d3f98a97a0ac54 Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 10:12:56 -0700 Subject: [PATCH 1/7] Sharded tests --- ipa-core/src/net/test.rs | 235 ++++++++++++++++++++++------------ ipa-core/src/net/transport.rs | 144 ++++++++++++--------- 2 files changed, 234 insertions(+), 145 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 679626adb..63513f0be 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -10,6 +10,7 @@ #![allow(clippy::missing_panics_doc)] use std::{ collections::HashSet, + iter::zip, net::{SocketAddr, TcpListener}, ops::Index, }; @@ -45,6 +46,38 @@ pub const DEFAULT_TEST_PORTS: Ports = Ports { shards: [6000, 6001, 6002], }; +/// A network with 4 shards per helper. +pub const TWO_SHARDS: [Ports; 2] = [ + Ports { + ring: [3000, 3001, 3002], + shards: [6000, 6001, 6002], + }, + Ports { + ring: [3010, 3011, 3012], + shards: [6010, 6011, 6012], + }, +]; + +/// A network with 4 shards per helper. +pub const FOUR_SHARDS: [Ports; 4] = [ + Ports { + ring: [10000, 10001, 10002], + shards: [10005, 10006, 10007], + }, + Ports { + ring: [10010, 10011, 10012], + shards: [10015, 10016, 10017], + }, + Ports { + ring: [10020, 10021, 10022], + shards: [10025, 10026, 10027], + }, + Ports { + ring: [10030, 10031, 10032], + shards: [10035, 10036, 10037], + }, +]; + /// Configuration of a server that can be reached via socket or port. pub struct AddressableTestServer { /// The identity of this server in the network. @@ -87,17 +120,18 @@ impl AddressableTestServer { /// Either a single Ring on MPC connection or all of the shards in a Helper. pub struct TestNetwork { pub network: NetworkConfig, // Contains Clients config - pub servers: Vec, + pub servers: Vec>, } impl TestNetwork { /// Helper function that creates [`PeerConfig`] fn create_peers( - servers: &[AddressableTestServer], + servers: &[Option], conf: &TestConfigBuilder, ) -> Vec { servers .iter() + .flatten() .map(|addr_server| { let port = addr_server .config @@ -130,50 +164,39 @@ impl TestNetwork { } impl TestNetwork { - #[must_use] - /// Gets a ref to the first shard in this network. - pub fn get_first_shard(&self) -> &AddressableTestServer { - self.servers.first().unwrap() - } - - /// Gets a mut ref to the first shard in this network. - pub fn get_first_shard_mut(&mut self) -> &mut AddressableTestServer { - self.servers.get_mut(0).unwrap() - } -} - -impl TestNetwork { - /// Creates 3 mpc test servers and creates a network. - fn new_mpc(ix: ShardIndex, ports: Vec>, conf: &TestConfigBuilder) -> Self { - let servers: Vec<_> = HelperIdentity::make_three() - .into_iter() + /// Creates all the shards for a helper and creates a network. + fn new_shards(id: HelperIdentity, ports: Vec>, conf: &TestConfigBuilder) -> Self { + let servers: Vec<_> = (0..conf.shard_count) + .map(ShardIndex) .zip(ports) - .map(|(id, p)| { + .map(|(ix, p)| { let sid = ShardedHelperIdentity::new(id, ix); - AddressableTestServer::new(sid, p, conf) + Some(AddressableTestServer::new(sid, p, conf)) }) .collect(); let peers = Self::create_peers(servers.as_slice(), conf); + assert_eq!(servers.len(), peers.len()); let client_config = conf.create_client_config(); - let network = NetworkConfig::::new_mpc(peers, client_config); + let network = NetworkConfig::::new_shards(peers, client_config); TestNetwork { network, servers } } } -impl TestNetwork { - /// Creates all the shards for a helper and creates a network. - fn new_shards(id: HelperIdentity, ports: Vec>, conf: &TestConfigBuilder) -> Self { - let servers: Vec<_> = (0..conf.shard_count) - .map(ShardIndex) +impl TestNetwork { + /// Creates 3 mpc test servers and creates a network. + fn new_mpc(ix: ShardIndex, ports: Vec>, conf: &TestConfigBuilder) -> Self { + let servers: Vec<_> = HelperIdentity::make_three() + .into_iter() .zip(ports) - .map(|(ix, p)| { + .map(|(id, p)| { let sid = ShardedHelperIdentity::new(id, ix); - AddressableTestServer::new(sid, p, conf) + Some(AddressableTestServer::new(sid, p, conf)) }) .collect(); let peers = Self::create_peers(servers.as_slice(), conf); + assert_eq!(servers.len(), peers.len()); let client_config = conf.create_client_config(); - let network = NetworkConfig::::new_shards(peers, client_config); + let network = NetworkConfig::::new_mpc(peers, client_config); TestNetwork { network, servers } } } @@ -217,12 +240,19 @@ fn server_config_https( } } +pub struct TestApp { + pub mpc_server: AddressableTestServer, + pub shard_server: AddressableTestServer, + pub mpc_network_config: NetworkConfig, + pub shard_network_config: NetworkConfig, +} + /// Uber container for test configuration. Provides access to a vec of MPC rings and 3 sharding /// networks (one for each Helper) pub struct TestConfig { pub disable_https: bool, pub rings: Vec>, - pub shards: Vec>, + pub shards: [TestNetwork; 3], } impl TestConfig { @@ -239,11 +269,6 @@ impl TestConfig { self.shards.get(id.as_index()).unwrap() } - /// Gets a mut ref to the entire shard network for a specific helper. - pub fn get_shards_for_helper_mut(&mut self, id: HelperIdentity) -> &mut TestNetwork { - self.shards.get_mut(id.as_index()).unwrap() - } - /// Creates a new [`TestConfig`] using the provided configuration. fn new(conf: &TestConfigBuilder) -> Self { let rings = (0..conf.shard_count) @@ -253,19 +278,47 @@ impl TestConfig { TestNetwork::::new_mpc(s, ports, conf) }) .collect(); - let shards = HelperIdentity::make_three() - .into_iter() - .map(|id| { - let ports = conf.get_ports_for_helper_identity(id); - TestNetwork::::new_shards(id, ports, conf) - }) - .collect(); + let shards = HelperIdentity::make_three().map(|id| { + let ports = conf.get_ports_for_helper_identity(id); + TestNetwork::::new_shards(id, ports, conf) + }); Self { disable_https: conf.disable_https, rings, shards, } } + + #[must_use] + pub fn into_apps(self) -> Vec { + let mut list = vec![]; + let [s0, s1, s2] = self.shards; + // Transposing shards networks from + let shards_in_rings: Vec<_> = zip(zip(s2.servers, s1.servers), s0.servers) + .map(|((ss2, ss1), ss0)| { + [ + (ss0, s0.network.clone()), + (ss1, s1.network.clone()), + (ss2, s2.network.clone()), + ] + }) + .collect(); + for (shards_in_ring, ring_network) in zip(shards_in_rings, self.rings.into_iter()) { + for (mut option_mpc_server, (mut option_shard_server, shard_network_config)) in + zip(ring_network.servers.into_iter(), shards_in_ring) + { + let mpc_server = option_mpc_server.take().unwrap(); + let shard_server = option_shard_server.take().unwrap(); + list.push(TestApp { + mpc_server, + shard_server, + mpc_network_config: ring_network.network.clone(), + shard_network_config, + }); + } + } + list + } } impl TestConfig { @@ -340,6 +393,22 @@ impl TestConfigBuilder { self } + #[must_use] + pub fn four_shards(self) -> Self { + self.with_ports_by_ring(FOUR_SHARDS.to_vec()) + } + + #[must_use] + pub fn two_shards(self) -> Self { + self.with_ports_by_ring(TWO_SHARDS.to_vec()) + } + + #[must_use] + pub fn with_shard_count(mut self, value: u32) -> Self { + self.shard_count = value; + self + } + #[must_use] pub fn with_use_http1_option(mut self, value: bool) -> Self { self.use_http1 = value; @@ -395,7 +464,7 @@ pub struct TestServer { pub transport: MpcHttpTransport, pub server: IpaHttpServer, pub client: IpaHttpClient, - pub request_handler: Option>>, + pub request_handler: Option>>, } impl TestServer { @@ -416,7 +485,7 @@ impl TestServer { #[derive(Default)] pub struct TestServerBuilder { - handler: Option>>, + handler: Option>>, metrics: Option, disable_https: bool, use_http1: bool, @@ -427,7 +496,7 @@ impl TestServerBuilder { #[must_use] pub fn with_request_handler( mut self, - handler: Arc>, + handler: Arc>, ) -> Self { self.handler = Some(handler); self @@ -470,7 +539,7 @@ impl TestServerBuilder { // TODO: add disble_matchkey here .build(); let leaders_ring = test_config.rings.pop().unwrap(); - let first_server = leaders_ring.servers.into_iter().next().unwrap(); + let first_server = leaders_ring.servers.into_iter().next().unwrap().unwrap(); let clients = IpaHttpClient::from_conf( &IpaRuntime::current(), &leaders_ring.network, @@ -482,7 +551,7 @@ impl TestServerBuilder { IpaRuntime::current(), HelperIdentity::ONE, first_server.config, - leaders_ring.network.clone(), + leaders_ring.network, &clients, handler, ); @@ -619,14 +688,14 @@ JMepVZwIWJrVhnxdcmzOuONoeLZPZraFpw== ", b" -----BEGIN CERTIFICATE----- -MIIBZTCCAQugAwIBAgIIXTgB/bkN/aUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAwwJ -bG9jYWxob3N0MB4XDTI0MTAwNjIyMTIwM1oXDTI1MDEwNTIyMTIwM1owFDESMBAG -A1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEyzSofZIX -XgLUKGumrN3SEXOMOAKXcl1VshTBzvyVwxxnD01WVLgS80/TELEltT8SMj1Cgu7I -tkDx3EVPjq4pOKNHMEUwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA4GA1UdDwEB/wQE +MIIBZTCCAQugAwIBAgIITIDzw5k9qXIwCgYIKoZIzj0EAwIwFDESMBAGA1UEAwwJ +bG9jYWxob3N0MB4XDTI0MTAwNjIyMTIxMVoXDTI1MDEwNTIyMTIxMVowFDESMBAG +A1UEAwwJbG9jYWxob3N0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/p17+uh9 +L3dqJlI2MFg2GxpCIhnOko83MokiFC5GnpVWL5xEAWHn4xi0ML8G4n5jK0PoX0FE +/RTWxkUO/PKSvaNHMEUwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA4GA1UdDwEB/wQE AwICpDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwCgYIKoZIzj0EAwID -SAAwRQIhAN93g0zfB/4VyhNOaY1uCb4af4qMxcz1wp0yZ7HKAyWqAiBVPgv4X7aR -JMepVZwIWJrVhnxdcmzOuONoeLZPZraFpw== +SAAwRQIhAI2hchWc0AedR4FdqbI1mckihN9a1bNciT8i3pOZGHm/AiB4JA9M14xw +xYxSeDvd5vt4ROlqgvLMcOOUjbFF7YAT6g== -----END CERTIFICATE----- ", ]; @@ -694,48 +763,52 @@ a0778c3e9960576cbef4312a3b7ca34137880fd588c11047bd8b6a8b70b5a151 mod tests { use super::{get_test_certificate_and_key, TestConfigBuilder}; use crate::{ + config::NetworkConfig, helpers::HelperIdentity, - net::test::{Ports, TEST_CERTS, TEST_KEYS}, + net::{ + test::{Ports, FOUR_SHARDS, TEST_CERTS, TEST_KEYS}, + ConnectionFlavor, + }, sharding::{ShardIndex, ShardedHelperIdentity}, }; + fn assert_eq_configs(nc1: &NetworkConfig, nc2: &NetworkConfig) { + let urls1: Vec<_> = nc1.vec_peers().into_iter().map(|p| p.url).collect(); + let urls2: Vec<_> = nc2.vec_peers().into_iter().map(|p| p.url).collect(); + assert_eq!(urls1, urls2); + } + /// This simple test makes sure that testing networks are created properly. /// The network itself won't be excersized as that's tested elsewhere. #[test] fn create_4_shard_http_network() { - let ports: Vec = vec![ - Ports { - ring: [10000, 10001, 10002], - shards: [10005, 10006, 10007], - }, - Ports { - ring: [10010, 10011, 10012], - shards: [10015, 10016, 10017], - }, - Ports { - ring: [10020, 10021, 10022], - shards: [10025, 10026, 10027], - }, - Ports { - ring: [10030, 10031, 10032], - shards: [10035, 10036, 10037], - }, - ]; // Providing ports and no https certs to keep this test fast let conf = TestConfigBuilder::default() .with_disable_https_option(true) - .with_ports_by_ring(ports) + .four_shards() .build(); assert!(conf.disable_https); assert_eq!(conf.rings.len(), 4); assert_eq!(conf.shards.len(), 3); - let shards_2 = conf.get_shards_for_helper(HelperIdentity::TWO); - assert_eq!(shards_2.get_first_shard().config.port, Some(10006)); - let second_helper_third_shard_configs = &shards_2.servers[2]; - assert_eq!(second_helper_third_shard_configs.config.port, Some(10026)); - let leader_ring_configs = &conf.leaders_ring().servers; - assert_eq!(leader_ring_configs[2].config.port, Some(10002)); + + let apps = conf.into_apps(); + for (i, ports) in FOUR_SHARDS.iter().enumerate() { + for (j, port) in ports.ring.into_iter().enumerate() { + assert_eq!(apps[i * 3 + j].mpc_server.config.port, Some(port)); + assert_eq_configs( + &apps[i * 3].mpc_network_config, + &apps[i * 3 + j].mpc_network_config, + ); + } + for (j, port) in ports.shards.into_iter().enumerate() { + assert_eq!(apps[i * 3 + j].shard_server.config.port, Some(port)); + assert_eq_configs( + &apps[j].shard_network_config, + &apps[i * 3 + j].shard_network_config, + ); + } + } } #[test] diff --git a/ipa-core/src/net/transport.rs b/ipa-core/src/net/transport.rs index 13f0c4662..f77ca48d8 100644 --- a/ipa-core/src/net/transport.rs +++ b/ipa-core/src/net/transport.rs @@ -371,10 +371,9 @@ mod tests { }, net::{ client::ClientIdentity, - test::{ClientIdentities, TestConfig, TestConfigBuilder, TestServer}, + test::{ClientIdentities, TestApp, TestConfig, TestConfigBuilder, TestServer}, }, secret_sharing::{replicated::semi_honest::AdditiveShare, IntoShares}, - sharding::ShardedHelperIdentity, test_fixture::Reconstruct, AppConfig, AppSetup, HelperApp, }; @@ -448,70 +447,72 @@ mod tests { ); } - // TODO(651): write a test for an error while reading the body (after error handling is finalized) - async fn make_helpers(mut conf: TestConfig) -> [HelperApp; 3] { - let leaders_ring = conf.rings.pop().unwrap(); - join_all(zip(HelperIdentity::make_three(), leaders_ring.servers).map( - |(id, mut addr_server)| { - let (setup, mpc_handler) = AppSetup::new(AppConfig::default()); - let sid = ShardedHelperIdentity::new(id, ShardIndex::FIRST); - let identities = ClientIdentities::new(conf.disable_https, sid); - - // Ring config - let clients = IpaHttpClient::from_conf( - &IpaRuntime::current(), - &leaders_ring.network, - &identities.helper, - ); - let (transport, server) = MpcHttpTransport::new( - IpaRuntime::current(), - id, - addr_server.config.clone(), - leaders_ring.network.clone(), - &clients, - Some(mpc_handler), - ); - - // Shard Config - let helper_shards = conf.get_shards_for_helper(id); - let addr_shard = helper_shards.get_first_shard(); - let shard_network_config = helper_shards.network.clone(); - let shard_clients = IpaHttpClient::::shards_from_conf( - &IpaRuntime::current(), - &shard_network_config, - &identities.shard, - ); - let (shard_transport, shard_server) = ShardHttpTransport::new( - IpaRuntime::current(), - sid.shard_index, - addr_shard.config.clone(), - shard_network_config, - shard_clients, - None, // This will come online once we go into Query Workflow - ); - - let helper_shards = conf.get_shards_for_helper_mut(id); - let addr_shard = helper_shards.get_first_shard_mut(); - let ring_socket = addr_server.socket.take(); - let sharding_socket = addr_shard.socket.take(); - - async move { - join( - server.start_on(&IpaRuntime::current(), ring_socket, ()), - shard_server.start_on(&IpaRuntime::current(), sharding_socket, ()), - ) - .await; - setup.connect(transport, shard_transport) - } + async fn start_app(mut test_app: TestApp, disable_https: bool) -> HelperApp { + let (setup, mpc_handler, shard_handler) = AppSetup::new(AppConfig::default()); + let sid = test_app.mpc_server.id; + let identities = ClientIdentities::new(disable_https, sid); + + // Ring config + let clients = IpaHttpClient::from_conf( + &IpaRuntime::current(), + &test_app.mpc_network_config, + &identities.helper, + ); + let (transport, server) = MpcHttpTransport::new( + IpaRuntime::current(), + sid.helper_identity, + test_app.mpc_server.config, + test_app.mpc_network_config, + &clients, + Some(mpc_handler), + ); + + // Shard Config + let shard_clients = IpaHttpClient::::shards_from_conf( + &IpaRuntime::current(), + &test_app.shard_network_config, + &identities.shard, + ); + let (shard_transport, shard_server) = ShardHttpTransport::new( + IpaRuntime::current(), + Sharded { + shard_id: sid.shard_index, + shard_count: test_app.shard_network_config.shard_count(), }, - )) + test_app.shard_server.config, + test_app.shard_network_config, + shard_clients, + Some(shard_handler), + ); + + join( + server.start_on( + &IpaRuntime::current(), + test_app.mpc_server.socket.take(), + (), + ), + shard_server.start_on( + &IpaRuntime::current(), + test_app.shard_server.socket.take(), + (), + ), + ) + .await; + setup.connect(transport, shard_transport) + } + + // TODO(651): write a test for an error while reading the body (after error handling is finalized) + async fn make_helpers(conf: TestConfig) -> Vec { + let disable_https = conf.disable_https; + join_all( + conf.into_apps() + .into_iter() + .map(|a| start_app(a, disable_https)), + ) .await - .try_into() - .ok() - .unwrap() } - async fn test_three_helpers(conf: TestConfig) { + async fn test_make_helpers(conf: TestConfig) { let clients = IpaHttpClient::from_conf( &IpaRuntime::current(), &conf.leaders_ring().network, @@ -582,12 +583,27 @@ mod tests { let conf = TestConfigBuilder::default() .with_disable_https_option(true) .build(); - test_three_helpers(conf).await; + test_make_helpers(conf).await; } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn three_helpers_https() { let conf = TestConfigBuilder::default().build(); - test_three_helpers(conf).await; + test_make_helpers(conf).await; + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn two_shards_https() { + let conf = TestConfigBuilder::default().two_shards().build(); + test_make_helpers(conf).await; + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn four_shards_http() { + let conf = TestConfigBuilder::default() + .with_shard_count(4) + .with_disable_https_option(true) + .build(); + test_make_helpers(conf).await; } } From 0870b0167913397b67f4fdb10214580ae5f1cb76 Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 10:38:36 -0700 Subject: [PATCH 2/7] Fixed compile errors from branching --- ipa-core/src/net/test.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 63513f0be..41a7c179d 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -464,7 +464,7 @@ pub struct TestServer { pub transport: MpcHttpTransport, pub server: IpaHttpServer, pub client: IpaHttpClient, - pub request_handler: Option>>, + pub request_handler: Option>>, } impl TestServer { @@ -485,7 +485,7 @@ impl TestServer { #[derive(Default)] pub struct TestServerBuilder { - handler: Option>>, + handler: Option>>, metrics: Option, disable_https: bool, use_http1: bool, @@ -496,7 +496,7 @@ impl TestServerBuilder { #[must_use] pub fn with_request_handler( mut self, - handler: Arc>, + handler: Arc>, ) -> Self { self.handler = Some(handler); self From 56b6bfb926cc47faddcfa74616d3529e1f664fbf Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 10:59:08 -0700 Subject: [PATCH 3/7] Moved start_app to test --- ipa-core/src/net/test.rs | 49 +++++++++++++++++++++++++- ipa-core/src/net/transport.rs | 65 +++-------------------------------- 2 files changed, 52 insertions(+), 62 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 41a7c179d..627c9ad20 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -46,7 +46,7 @@ pub const DEFAULT_TEST_PORTS: Ports = Ports { shards: [6000, 6001, 6002], }; -/// A network with 4 shards per helper. +/// A network with two shards per helper. pub const TWO_SHARDS: [Ports; 2] = [ Ports { ring: [3000, 3001, 3002], @@ -240,6 +240,7 @@ fn server_config_https( } } +/// This struct contains the components needed to start a new IPA app from a [`TestConfig`]. pub struct TestApp { pub mpc_server: AddressableTestServer, pub shard_server: AddressableTestServer, @@ -247,6 +248,52 @@ pub struct TestApp { pub shard_network_config: NetworkConfig, } +#[cfg(all(test, web_test, descriptive_gate))] +impl TestApp { + pub async fn start_app(mut self, disable_https: bool) -> crate::HelperApp { + let (setup, mpc_handler) = crate::AppSetup::new(crate::AppConfig::default()); + let sid = self.mpc_server.id; + let identities = ClientIdentities::new(disable_https, sid); + + // Ring config + let clients = IpaHttpClient::from_conf( + &IpaRuntime::current(), + &self.mpc_network_config, + &identities.helper, + ); + let (transport, server) = MpcHttpTransport::new( + IpaRuntime::current(), + sid.helper_identity, + self.mpc_server.config, + self.mpc_network_config, + &clients, + Some(mpc_handler), + ); + + // Shard Config + let shard_clients = IpaHttpClient::::shards_from_conf( + &IpaRuntime::current(), + &self.shard_network_config, + &identities.shard, + ); + let (shard_transport, shard_server) = super::ShardHttpTransport::new( + IpaRuntime::current(), + sid.shard_index, + self.shard_server.config, + self.shard_network_config, + shard_clients, + None, + ); + + futures::future::join( + server.start_on(&IpaRuntime::current(), self.mpc_server.socket.take(), ()), + shard_server.start_on(&IpaRuntime::current(), self.shard_server.socket.take(), ()), + ) + .await; + setup.connect(transport, shard_transport) + } +} + /// Uber container for test configuration. Provides access to a vec of MPC rings and 3 sharding /// networks (one for each Helper) pub struct TestConfig { diff --git a/ipa-core/src/net/transport.rs b/ipa-core/src/net/transport.rs index f77ca48d8..365c3a571 100644 --- a/ipa-core/src/net/transport.rs +++ b/ipa-core/src/net/transport.rs @@ -351,10 +351,7 @@ mod tests { use std::{iter::zip, task::Poll}; use bytes::Bytes; - use futures::{ - future::join, - stream::{poll_immediate, StreamExt}, - }; + use futures::stream::{poll_immediate, StreamExt}; use futures_util::future::{join_all, try_join_all}; use generic_array::GenericArray; use once_cell::sync::Lazy; @@ -371,11 +368,11 @@ mod tests { }, net::{ client::ClientIdentity, - test::{ClientIdentities, TestApp, TestConfig, TestConfigBuilder, TestServer}, + test::{TestConfig, TestConfigBuilder, TestServer}, }, secret_sharing::{replicated::semi_honest::AdditiveShare, IntoShares}, test_fixture::Reconstruct, - AppConfig, AppSetup, HelperApp, + HelperApp, }; static STEP: Lazy = Lazy::new(|| Gate::from("http-transport")); @@ -447,67 +444,13 @@ mod tests { ); } - async fn start_app(mut test_app: TestApp, disable_https: bool) -> HelperApp { - let (setup, mpc_handler, shard_handler) = AppSetup::new(AppConfig::default()); - let sid = test_app.mpc_server.id; - let identities = ClientIdentities::new(disable_https, sid); - - // Ring config - let clients = IpaHttpClient::from_conf( - &IpaRuntime::current(), - &test_app.mpc_network_config, - &identities.helper, - ); - let (transport, server) = MpcHttpTransport::new( - IpaRuntime::current(), - sid.helper_identity, - test_app.mpc_server.config, - test_app.mpc_network_config, - &clients, - Some(mpc_handler), - ); - - // Shard Config - let shard_clients = IpaHttpClient::::shards_from_conf( - &IpaRuntime::current(), - &test_app.shard_network_config, - &identities.shard, - ); - let (shard_transport, shard_server) = ShardHttpTransport::new( - IpaRuntime::current(), - Sharded { - shard_id: sid.shard_index, - shard_count: test_app.shard_network_config.shard_count(), - }, - test_app.shard_server.config, - test_app.shard_network_config, - shard_clients, - Some(shard_handler), - ); - - join( - server.start_on( - &IpaRuntime::current(), - test_app.mpc_server.socket.take(), - (), - ), - shard_server.start_on( - &IpaRuntime::current(), - test_app.shard_server.socket.take(), - (), - ), - ) - .await; - setup.connect(transport, shard_transport) - } - // TODO(651): write a test for an error while reading the body (after error handling is finalized) async fn make_helpers(conf: TestConfig) -> Vec { let disable_https = conf.disable_https; join_all( conf.into_apps() .into_iter() - .map(|a| start_app(a, disable_https)), + .map(|a| a.start_app(disable_https)), ) .await } From dff47a40dcc15eaadf15c8a9cb25fa4f101900b3 Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 11:18:02 -0700 Subject: [PATCH 4/7] Docs, clippy --- ipa-core/src/net/test.rs | 40 ++++++++++++++++++++--------------- ipa-core/src/net/transport.rs | 2 +- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 627c9ad20..9fe0422e7 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -250,6 +250,7 @@ pub struct TestApp { #[cfg(all(test, web_test, descriptive_gate))] impl TestApp { + /// Starts a new IPA app reading to be used in HTTP tests pub async fn start_app(mut self, disable_https: bool) -> crate::HelperApp { let (setup, mpc_handler) = crate::AppSetup::new(crate::AppConfig::default()); let sid = self.mpc_server.id; @@ -336,11 +337,11 @@ impl TestConfig { } } + /// Transforms this easy to modify configuration into an easy to run [`TestApp`]. #[must_use] pub fn into_apps(self) -> Vec { - let mut list = vec![]; let [s0, s1, s2] = self.shards; - // Transposing shards networks from + // Transposing shards networks to be per ring let shards_in_rings: Vec<_> = zip(zip(s2.servers, s1.servers), s0.servers) .map(|((ss2, ss1), ss0)| { [ @@ -350,21 +351,26 @@ impl TestConfig { ] }) .collect(); - for (shards_in_ring, ring_network) in zip(shards_in_rings, self.rings.into_iter()) { - for (mut option_mpc_server, (mut option_shard_server, shard_network_config)) in - zip(ring_network.servers.into_iter(), shards_in_ring) - { - let mpc_server = option_mpc_server.take().unwrap(); - let shard_server = option_shard_server.take().unwrap(); - list.push(TestApp { - mpc_server, - shard_server, - mpc_network_config: ring_network.network.clone(), - shard_network_config, - }); - } - } - list + + zip(shards_in_rings, self.rings) + .flat_map(|(shards_in_ring, ring_network)| { + zip(ring_network.servers, shards_in_ring).map( + move |( + mut option_mpc_server, + (mut option_shard_server, shard_network_config), + )| { + let mpc_server = option_mpc_server.take().unwrap(); + let shard_server = option_shard_server.take().unwrap(); + TestApp { + mpc_server, + shard_server, + mpc_network_config: ring_network.network.clone(), + shard_network_config, + } + }, + ) + }) + .collect() } } diff --git a/ipa-core/src/net/transport.rs b/ipa-core/src/net/transport.rs index 365c3a571..9afb78923 100644 --- a/ipa-core/src/net/transport.rs +++ b/ipa-core/src/net/transport.rs @@ -348,7 +348,7 @@ impl Transport for ShardHttpTransport { #[cfg(all(test, web_test, descriptive_gate))] mod tests { - use std::{iter::zip, task::Poll}; + use std::task::Poll; use bytes::Bytes; use futures::stream::{poll_immediate, StreamExt}; From f8fa81e7b8ee819c9ebd7844506296a893eca9ad Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 13:29:10 -0700 Subject: [PATCH 5/7] HTTP tests use OS assigned ports --- ipa-core/src/net/test.rs | 26 ++------------------------ ipa-core/src/net/transport.rs | 6 ------ 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 9fe0422e7..6748fafe0 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -46,20 +46,8 @@ pub const DEFAULT_TEST_PORTS: Ports = Ports { shards: [6000, 6001, 6002], }; -/// A network with two shards per helper. -pub const TWO_SHARDS: [Ports; 2] = [ - Ports { - ring: [3000, 3001, 3002], - shards: [6000, 6001, 6002], - }, - Ports { - ring: [3010, 3011, 3012], - shards: [6010, 6011, 6012], - }, -]; - /// A network with 4 shards per helper. -pub const FOUR_SHARDS: [Ports; 4] = [ +const FOUR_SHARDS: [Ports; 4] = [ Ports { ring: [10000, 10001, 10002], shards: [10005, 10006, 10007], @@ -446,16 +434,6 @@ impl TestConfigBuilder { self } - #[must_use] - pub fn four_shards(self) -> Self { - self.with_ports_by_ring(FOUR_SHARDS.to_vec()) - } - - #[must_use] - pub fn two_shards(self) -> Self { - self.with_ports_by_ring(TWO_SHARDS.to_vec()) - } - #[must_use] pub fn with_shard_count(mut self, value: u32) -> Self { self.shard_count = value; @@ -838,7 +816,7 @@ mod tests { // Providing ports and no https certs to keep this test fast let conf = TestConfigBuilder::default() .with_disable_https_option(true) - .four_shards() + .with_ports_by_ring(FOUR_SHARDS.to_vec()) .build(); assert!(conf.disable_https); diff --git a/ipa-core/src/net/transport.rs b/ipa-core/src/net/transport.rs index 9afb78923..d242d7a0a 100644 --- a/ipa-core/src/net/transport.rs +++ b/ipa-core/src/net/transport.rs @@ -535,12 +535,6 @@ mod tests { test_make_helpers(conf).await; } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn two_shards_https() { - let conf = TestConfigBuilder::default().two_shards().build(); - test_make_helpers(conf).await; - } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn four_shards_http() { let conf = TestConfigBuilder::default() From e4268dae4eb7b6858e8c26513944b09a56384738 Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 13:47:23 -0700 Subject: [PATCH 6/7] Moving four shards inside tests --- ipa-core/src/net/test.rs | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 6748fafe0..2d3e0f2ac 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -46,26 +46,6 @@ pub const DEFAULT_TEST_PORTS: Ports = Ports { shards: [6000, 6001, 6002], }; -/// A network with 4 shards per helper. -const FOUR_SHARDS: [Ports; 4] = [ - Ports { - ring: [10000, 10001, 10002], - shards: [10005, 10006, 10007], - }, - Ports { - ring: [10010, 10011, 10012], - shards: [10015, 10016, 10017], - }, - Ports { - ring: [10020, 10021, 10022], - shards: [10025, 10026, 10027], - }, - Ports { - ring: [10030, 10031, 10032], - shards: [10035, 10036, 10037], - }, -]; - /// Configuration of a server that can be reached via socket or port. pub struct AddressableTestServer { /// The identity of this server in the network. @@ -797,12 +777,32 @@ mod tests { config::NetworkConfig, helpers::HelperIdentity, net::{ - test::{Ports, FOUR_SHARDS, TEST_CERTS, TEST_KEYS}, + test::{Ports, TEST_CERTS, TEST_KEYS}, ConnectionFlavor, }, sharding::{ShardIndex, ShardedHelperIdentity}, }; + /// A network with 4 shards per helper. + const FOUR_SHARDS: [Ports; 4] = [ + Ports { + ring: [10000, 10001, 10002], + shards: [10005, 10006, 10007], + }, + Ports { + ring: [10010, 10011, 10012], + shards: [10015, 10016, 10017], + }, + Ports { + ring: [10020, 10021, 10022], + shards: [10025, 10026, 10027], + }, + Ports { + ring: [10030, 10031, 10032], + shards: [10035, 10036, 10037], + }, + ]; + fn assert_eq_configs(nc1: &NetworkConfig, nc2: &NetworkConfig) { let urls1: Vec<_> = nc1.vec_peers().into_iter().map(|p| p.url).collect(); let urls2: Vec<_> = nc2.vec_peers().into_iter().map(|p| p.url).collect(); From bf21d19c7a82fd7a90b8685c9ad559d95ee648cf Mon Sep 17 00:00:00 2001 From: Christian Berkhoff Date: Thu, 31 Oct 2024 14:29:24 -0700 Subject: [PATCH 7/7] Removing optional in servers --- ipa-core/src/net/test.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/ipa-core/src/net/test.rs b/ipa-core/src/net/test.rs index 2d3e0f2ac..602ab7410 100644 --- a/ipa-core/src/net/test.rs +++ b/ipa-core/src/net/test.rs @@ -88,18 +88,17 @@ impl AddressableTestServer { /// Either a single Ring on MPC connection or all of the shards in a Helper. pub struct TestNetwork { pub network: NetworkConfig, // Contains Clients config - pub servers: Vec>, + pub servers: Vec, } impl TestNetwork { /// Helper function that creates [`PeerConfig`] fn create_peers( - servers: &[Option], + servers: &[AddressableTestServer], conf: &TestConfigBuilder, ) -> Vec { servers .iter() - .flatten() .map(|addr_server| { let port = addr_server .config @@ -139,7 +138,7 @@ impl TestNetwork { .zip(ports) .map(|(ix, p)| { let sid = ShardedHelperIdentity::new(id, ix); - Some(AddressableTestServer::new(sid, p, conf)) + AddressableTestServer::new(sid, p, conf) }) .collect(); let peers = Self::create_peers(servers.as_slice(), conf); @@ -158,7 +157,7 @@ impl TestNetwork { .zip(ports) .map(|(id, p)| { let sid = ShardedHelperIdentity::new(id, ix); - Some(AddressableTestServer::new(sid, p, conf)) + AddressableTestServer::new(sid, p, conf) }) .collect(); let peers = Self::create_peers(servers.as_slice(), conf); @@ -323,18 +322,11 @@ impl TestConfig { zip(shards_in_rings, self.rings) .flat_map(|(shards_in_ring, ring_network)| { zip(ring_network.servers, shards_in_ring).map( - move |( - mut option_mpc_server, - (mut option_shard_server, shard_network_config), - )| { - let mpc_server = option_mpc_server.take().unwrap(); - let shard_server = option_shard_server.take().unwrap(); - TestApp { - mpc_server, - shard_server, - mpc_network_config: ring_network.network.clone(), - shard_network_config, - } + move |(mpc_server, (shard_server, shard_network_config))| TestApp { + mpc_server, + shard_server, + mpc_network_config: ring_network.network.clone(), + shard_network_config, }, ) }) @@ -550,7 +542,7 @@ impl TestServerBuilder { // TODO: add disble_matchkey here .build(); let leaders_ring = test_config.rings.pop().unwrap(); - let first_server = leaders_ring.servers.into_iter().next().unwrap().unwrap(); + let first_server = leaders_ring.servers.into_iter().next().unwrap(); let clients = IpaHttpClient::from_conf( &IpaRuntime::current(), &leaders_ring.network,