ic-query 0.35.0

Internet Computer query library for CloudEngine, NNS, SNS, ICRC, system canisters, and public network metadata
Documentation
use super::{
    CloudEngineProviderInfoReport, CloudEngineProviderListReport, CloudEngineProviderLocation,
    CloudEngineProviderRow, cloud_engine_provider_info_report_text,
    cloud_engine_provider_list_report_text,
};
use crate::ic::IcDashboardReportProvenance;

const PROVIDER_A: &str = "2wxzd-qrbrs-ailta-kdtyb-ucg35-xcxd4-txevb-ot7hx-wiyus-szcca-nqe";
const PROVIDER_B: &str = "rbn2y-6vfsb-gv35j-4cyvy-pzbdu-e5aum-jzjg6-5b4n5-vuguf-ycubq-zae";

#[test]
fn text_keeps_dashboard_provenance_separate_from_provider_tables() {
    let provider = provider(PROVIDER_B, true);
    let list = CloudEngineProviderListReport {
        provenance: provenance(),
        source_node_provider_count: 2,
        cloud_engine_provider_count: 1,
        providers: vec![provider.clone()],
    };
    let info = CloudEngineProviderInfoReport {
        provenance: provenance(),
        cloud_engine_evidence_present: true,
        provider,
    };

    let list_text = cloud_engine_provider_list_report_text(&list);
    let info_text = cloud_engine_provider_info_report_text(&info);

    assert!(list_text.contains("point_in_time_guaranteed: no"));
    assert!(list_text.contains("cloud_engine_provider_count: 1\n\nCloudEngine providers\n"));
    assert!(info_text.contains("cloud_engine_evidence_present: yes"));
    assert!(info_text.contains("location_count: 1\n\nCloudEngine locations\n"));
    assert!(info_text.contains("Brussels"));
}

fn provenance() -> IcDashboardReportProvenance {
    IcDashboardReportProvenance {
        schema_version: 1,
        network: "ic".to_string(),
        authority: "official_ic_dashboard_api".to_string(),
        source_endpoint: "https://ic-api.internetcomputer.org/api/v3".to_string(),
        fetched_at: "2026-08-08T12:00:00Z".to_string(),
        fetched_by: "test".to_string(),
        certified: false,
        point_in_time_guaranteed: false,
    }
}

fn location() -> CloudEngineProviderLocation {
    CloudEngineProviderLocation {
        dc_key: "br1".to_string(),
        display_name: "Brussels".to_string(),
        latitude: 50.8386,
        longitude: 4.3475,
        owner: "Digital Realty".to_string(),
        region: "Europe,BE,Brussels Capital".to_string(),
    }
}

fn provider(principal_id: &str, cloud_engine: bool) -> CloudEngineProviderRow {
    let locations = vec![location()];
    CloudEngineProviderRow {
        principal_id: principal_id.to_string(),
        display_name: "Provider".to_string(),
        website: Some("example.com".to_string()),
        logo_url: None,
        location_count: locations.len(),
        locations: locations.clone(),
        cloud_engine_location_count: usize::from(cloud_engine),
        cloud_engine_locations: cloud_engine
            .then_some(locations[0].clone())
            .into_iter()
            .collect(),
        total_cloud_engine_nodes: if cloud_engine { 5 } else { 0 },
        total_cloud_engine_unassigned_nodes: if cloud_engine { 4 } else { 0 },
        total_cloud_engines: u64::from(cloud_engine),
        total_node_allowance: 7,
        total_nodes: 8,
        total_rewardable_nodes: 6,
        total_subnets: 2,
        total_unassigned_nodes: 3,
    }
}

#[cfg(feature = "dashboard-host")]
mod host {
    use super::*;
    use crate::{
        cloud_engine::{
            CloudEngineProviderInfoRequest, CloudEngineProviderInfoSourceData,
            CloudEngineProviderListRequest, CloudEngineProviderListSourceData,
            CloudEngineProviderSource, DEFAULT_CLOUD_ENGINE_DASHBOARD_SOURCE_ENDPOINT,
            build_cloud_engine_provider_info_report_with_source,
            build_cloud_engine_provider_list_report_with_source,
        },
        ic::{IcHostError, IcSourceRequest},
    };
    use std::cell::Cell;

    const NOW: u64 = 1_800_000_000;

    #[test]
    fn list_validates_complete_resource_then_filters_and_sorts_cloud_engine_rows() {
        let source = Fixture::default();
        let report = build_cloud_engine_provider_list_report_with_source(&list_request(), &source)
            .expect("CloudEngine providers");

        assert_eq!(source.list_calls.get(), 1);
        assert_eq!(source.info_calls.get(), 0);
        assert_eq!(report.source_node_provider_count, 3);
        assert_eq!(report.cloud_engine_provider_count, 2);
        assert_eq!(report.providers[0].principal_id, PROVIDER_A);
        assert_eq!(report.providers[1].principal_id, PROVIDER_B);
        assert_eq!(report.provenance.authority, "official_ic_dashboard_api");
        assert!(!report.provenance.certified);
        assert!(!report.provenance.point_in_time_guaranteed);
    }

    #[test]
    fn exact_info_preserves_zero_cloud_engine_evidence_without_hiding_the_provider() {
        let source = Fixture::default();
        let request = CloudEngineProviderInfoRequest::new(
            "ic",
            DEFAULT_CLOUD_ENGINE_DASHBOARD_SOURCE_ENDPOINT,
            NOW,
            PROVIDER_A,
        );
        source.info_cloud_engine.set(false);
        let report = build_cloud_engine_provider_info_report_with_source(&request, &source)
            .expect("exact provider");

        assert_eq!(source.info_calls.get(), 1);
        assert!(!report.cloud_engine_evidence_present);
        assert_eq!(report.provider.principal_id, PROVIDER_A);
    }

    #[test]
    fn cloud_engine_and_ordinary_location_scopes_are_independent() {
        let source = Fixture::default();
        source
            .mutation
            .set(Some(Mutation::IndependentCloudLocation));
        let report = build_cloud_engine_provider_list_report_with_source(&list_request(), &source)
            .expect("independent CloudEngine provider location");

        assert_eq!(report.providers[1].cloud_engine_locations[0].dc_key, "ce1");
        assert_eq!(report.providers[1].locations[0].dc_key, "br1");
    }

    #[test]
    fn requests_and_custom_source_contract_fail_closed() {
        let source = Fixture::default();
        let unsupported = CloudEngineProviderListRequest::new(
            "local",
            DEFAULT_CLOUD_ENGINE_DASHBOARD_SOURCE_ENDPOINT,
            NOW,
        );
        assert!(matches!(
            build_cloud_engine_provider_list_report_with_source(&unsupported, &source),
            Err(IcHostError::InvalidRequest {
                field: "network",
                ..
            })
        ));
        assert_eq!(source.list_calls.get(), 0);

        for mutation in [
            Mutation::WrongSource,
            Mutation::Empty,
            Mutation::DuplicateProvider,
            Mutation::BadLocationCount,
            Mutation::UnassignedOverflow,
        ] {
            source.mutation.set(Some(mutation));
            assert!(matches!(
                build_cloud_engine_provider_list_report_with_source(&list_request(), &source),
                Err(IcHostError::InvalidSourceData { .. })
            ));
        }
    }

    #[derive(Clone, Copy)]
    enum Mutation {
        WrongSource,
        Empty,
        DuplicateProvider,
        BadLocationCount,
        IndependentCloudLocation,
        UnassignedOverflow,
    }

    #[derive(Default)]
    struct Fixture {
        list_calls: Cell<usize>,
        info_calls: Cell<usize>,
        info_cloud_engine: Cell<bool>,
        mutation: Cell<Option<Mutation>>,
    }

    impl CloudEngineProviderSource for Fixture {
        fn fetch_cloud_engine_provider_list(
            &self,
            request: &IcSourceRequest,
        ) -> Result<CloudEngineProviderListSourceData, IcHostError> {
            self.list_calls.set(self.list_calls.get() + 1);
            let mut data = CloudEngineProviderListSourceData {
                source: request.clone(),
                providers: vec![
                    provider(PROVIDER_B, true),
                    provider(PROVIDER_A, true),
                    provider("aaaaa-aa", false),
                ],
            };
            match self.mutation.take() {
                Some(Mutation::WrongSource) => data.source.endpoint.push_str("/other"),
                Some(Mutation::Empty) => data.providers.clear(),
                Some(Mutation::DuplicateProvider) => {
                    data.providers[1].principal_id = data.providers[0].principal_id.clone();
                }
                Some(Mutation::BadLocationCount) => data.providers[0].location_count = 2,
                Some(Mutation::IndependentCloudLocation) => {
                    data.providers[0].cloud_engine_locations[0].dc_key = "ce1".to_string();
                    data.providers[0].cloud_engine_locations[0].owner = "Owner ".to_string();
                }
                Some(Mutation::UnassignedOverflow) => {
                    data.providers[0].total_cloud_engine_unassigned_nodes = 6;
                }
                None => {}
            }
            Ok(data)
        }

        fn fetch_cloud_engine_provider_info(
            &self,
            request: &IcSourceRequest,
            node_provider_id: &str,
        ) -> Result<CloudEngineProviderInfoSourceData, IcHostError> {
            self.info_calls.set(self.info_calls.get() + 1);
            Ok(CloudEngineProviderInfoSourceData {
                source: request.clone(),
                provider: provider(node_provider_id, self.info_cloud_engine.get()),
            })
        }
    }

    fn list_request() -> CloudEngineProviderListRequest {
        CloudEngineProviderListRequest::new(
            "ic",
            DEFAULT_CLOUD_ENGINE_DASHBOARD_SOURCE_ENDPOINT,
            NOW,
        )
    }
}