use std::{str::FromStr, time::SystemTime};
use anyhow::Context;
use endhost_api_client::client::{CrpcEndhostApiClient, EndhostApiClient};
use ntest::timeout;
use pocketscion::{
self,
network::scion::topology::{ScionAs, ScionTopology},
runtime::PocketScionRuntimeBuilder,
state::SharedPocketScionState,
};
use rand::SeedableRng;
use rand_chacha::ChaCha8Rng;
use scion_proto::address::IsdAsn;
use url::Url;
#[test_log::test(tokio::test)]
#[timeout(10_000)]
async fn should_have_working_eh_api() -> anyhow::Result<()> {
let mut state = SharedPocketScionState::new(SystemTime::now());
let ia1 = IsdAsn::from_str("1-1")?;
let ia2 = IsdAsn::from_str("2-3")?;
let mut topo = ScionTopology::new();
topo.add_as(ScionAs::new_core("1-1".parse()?))?
.add_as(ScionAs::new_core("1-2".parse()?))?
.add_as(ScionAs::new("1-3".parse()?))?
.add_as(ScionAs::new_core("2-1".parse()?))?
.add_as(ScionAs::new("2-2".parse()?))?
.add_as(ScionAs::new("2-3".parse()?))?
.add_link("1-1#1 core 1-2#2".parse()?)?
.add_link("1-2#1 down_to 1-3#1".parse()?)?
.add_link("1-1#2 down_to 1-3#2".parse()?)?
.add_link("1-1#3 core 2-1#1".parse()?)?
.add_link("2-1#2 down_to 2-2#1".parse()?)?
.add_link("2-2#2 down_to 2-3#1".parse()?)?;
state.set_topology(topo);
let ia1_snap = state.add_snap();
state.add_snap_data_plane(
ia1_snap,
ia1,
vec!["10.0.0.1/30".parse()?],
ChaCha8Rng::seed_from_u64(1),
);
let eh_api_id = state.add_endhost_api(vec![ia1]);
let ps_rt = PocketScionRuntimeBuilder::new()
.with_system_state(state.into_state())
.start()
.await
.context("error starting runtime")?;
tracing::info!("Runtime started");
let ps_api = ps_rt.api_client().get_io_config().await?;
let eh_addr = ps_api
.endhost_apis
.get(&eh_api_id)
.expect("missing addr for endhost api");
tracing::info!(%eh_addr, "Got endhost api addr");
let eh_client = CrpcEndhostApiClient::new(&Url::parse(&format!("http://{eh_addr}"))?)?;
let underlays = eh_client
.list_underlays(ia1)
.await
.context("endhost api client failed")?;
println!("{underlays:?}");
assert_eq!(underlays.snap_underlay.len(), 1);
let segments = eh_client
.list_segments(ia1, ia2, 256, "".to_string())
.await
.context("error listing segments")?;
assert_eq!(segments.down_segments.len(), 1);
assert_eq!(segments.core_segments.len(), 1);
Ok(())
}