// file: crates/ksp-config-lib/unit_tests/composite.rs // version: 6 const TEST_COMPOSITE_FILENAME: &str = "examples/composite.example.json"; const TEST_COMPOSITE_FILE_ID: &str = "cfg.composite.test"; #[test] fn fixture_composite_example_resolves_default_document_profile() { let engine = fixture_example_engine(); let file_id = crate::ConfigFileId::new(TEST_COMPOSITE_FILE_ID); assert!(engine.is_ok(), "composite test engine should be constructible: {engine:?}"); assert!(file_id.is_ok(), "composite test file_id should be valid: {file_id:?}"); if let (std::result::Result::Ok(engine), std::result::Result::Ok(file_id)) = (engine, file_id) { let resolved = engine.load_resolved_composite(&file_id, std::option::Option::None); assert!(resolved.is_ok(), "fixture composite example should resolve: {resolved:?}"); if let std::result::Result::Ok(resolved) = resolved { assert_eq!(resolved.profile_id(), "local_default"); assert_eq!(resolved.selection_source(), crate::ConfigProfileSelectionSource::DefaultProfile); let logging = resolved.component("logging"); assert!(logging.is_some(), "logging component should be resolved"); if let std::option::Option::Some(logging) = logging { assert_eq!(logging.resolved().file_id().as_str(), crate::FILE_ID_STD_LOGGING); let logging_document = engine.load_validated_document(logging.resolved().file_id()); assert!(logging_document.is_ok(), "referenced Logging document should validate: {logging_document:?}"); if let std::result::Result::Ok(logging_document) = logging_document { let default_profile = logging_document.value().get("default_profile").and_then(serde_json::Value::as_str); assert_eq!(default_profile, std::option::Option::Some(logging.resolved().profile_id())); } assert_eq!(logging.resolved().selection_source(), crate::ConfigProfileSelectionSource::DefaultProfile); assert_eq!(logging.resolved().origin("logs_directory"), std::option::Option::Some(crate::ConfigValueOrigin::Global)); } } } } #[test] fn composite_profile_override_marks_referenced_profile_selection_as_composite() { let engine = fixture_example_engine(); let file_id = crate::ConfigFileId::new(TEST_COMPOSITE_FILE_ID); assert!(engine.is_ok(), "composite test engine should be constructible: {engine:?}"); assert!(file_id.is_ok(), "composite test file_id should be valid: {file_id:?}"); if let (std::result::Result::Ok(engine), std::result::Result::Ok(file_id)) = (engine, file_id) { let resolved = engine.load_resolved_composite(&file_id, std::option::Option::Some("local_explicit")); assert!(resolved.is_ok(), "explicit composite profile should resolve: {resolved:?}"); if let std::result::Result::Ok(resolved) = resolved { assert_eq!(resolved.selection_source(), crate::ConfigProfileSelectionSource::Explicit); let logging = resolved.component("logging"); assert!(logging.is_some(), "logging component should be resolved"); if let std::option::Option::Some(logging) = logging { assert_eq!(logging.resolved().profile_id(), "local_dev"); assert_eq!(logging.resolved().selection_source(), crate::ConfigProfileSelectionSource::Composite); } } } } #[test] fn unknown_composite_profile_has_profile_not_found_error() { let engine = fixture_example_engine(); let file_id = crate::ConfigFileId::new(TEST_COMPOSITE_FILE_ID); assert!(engine.is_ok(), "composite test engine should be constructible: {engine:?}"); assert!(file_id.is_ok(), "composite test file_id should be valid: {file_id:?}"); if let (std::result::Result::Ok(engine), std::result::Result::Ok(file_id)) = (engine, file_id) { let result = engine.load_resolved_composite(&file_id, std::option::Option::Some("missing")); assert!(result.is_err(), "unknown composite profile must be rejected: {result:?}"); if let std::result::Result::Err(error) = result { assert_eq!(error.code(), crate::ERROR_CODE_PROFILE_NOT_FOUND); } } } #[test] fn unknown_referenced_file_id_is_rejected_during_composite_validation() { let fixture = fixture_roots("unknown-reference"); let composite = r#"{ "format_version": 1, "default_profile": "test", "profiles": [{ "profile_id": "test", "documents": [{"component_id": "missing", "file_id": "cfg.std.missing"}] }] }"#; let prepared = prepare_fixture(&fixture, composite); assert!(prepared.is_ok(), "composite fixture should be writable: {prepared:?}"); if prepared.is_ok() { let engine = fixture_engine(&fixture); let file_id = crate::ConfigFileId::new(TEST_COMPOSITE_FILE_ID); assert!(engine.is_ok(), "fixture engine should be constructible: {engine:?}"); if let (std::result::Result::Ok(engine), std::result::Result::Ok(file_id)) = (engine, file_id) { let result = engine.load_validated_document(&file_id); assert!(result.is_err(), "unknown composite reference must be rejected: {result:?}"); if let std::result::Result::Err(error) = result { assert_eq!(error.code(), crate::ERROR_CODE_COMPOSITE_REFERENCE_INVALID); } } } cleanup_fixture(&fixture); } #[test] fn duplicate_component_ids_are_rejected_inside_one_composite_profile() { let fixture = fixture_roots("duplicate-component"); let composite = r#"{ "format_version": 1, "default_profile": "test", "profiles": [{ "profile_id": "test", "documents": [ {"component_id": "logging", "file_id": "cfg.std.logging"}, {"component_id": "logging", "file_id": "cfg.std.logging"} ] }] }"#; let prepared = prepare_fixture(&fixture, composite); assert!(prepared.is_ok(), "composite fixture should be writable: {prepared:?}"); if prepared.is_ok() { let engine = fixture_engine(&fixture); let file_id = crate::ConfigFileId::new(TEST_COMPOSITE_FILE_ID); assert!(engine.is_ok(), "fixture engine should be constructible: {engine:?}"); if let (std::result::Result::Ok(engine), std::result::Result::Ok(file_id)) = (engine, file_id) { let result = engine.load_validated_document(&file_id); assert!(result.is_err(), "duplicate component_id must be rejected: {result:?}"); if let std::result::Result::Err(error) = result { assert_eq!(error.code(), crate::ERROR_CODE_DOCUMENT_SEMANTIC_INVALID); } } } cleanup_fixture(&fixture); } #[test] fn v0_3_15_pre_006_fix_001_raw_ingest_composite_is_network_centric_and_keeps_all_transport_sources_coherent() { let workspace = workspace_root(); let bootstrap = crate::ConfigBootstrapOptions::from_paths(workspace.join("config"), workspace.join("config/schemas")); assert!(bootstrap.is_ok(), "committed Config roots should be valid: {bootstrap:?}"); let registry = crate::ConfigFileRegistry::defaults(); assert!(registry.is_ok(), "default Config registry should be valid: {registry:?}"); let file_id = crate::ConfigFileId::new(crate::FILE_ID_COMPOSITE_KSP_APP_RAW_TRANSACTION_INGEST_DESK); assert!(file_id.is_ok(), "Raw Transaction Ingest Desk composite file_id should be valid: {file_id:?}"); let (bootstrap, registry, file_id) = match (bootstrap, registry, file_id) { (std::result::Result::Ok(bootstrap), std::result::Result::Ok(registry), std::result::Result::Ok(file_id)) => (bootstrap, registry, file_id), _ => return, }; let engine = crate::ConfigDocumentEngine::new(bootstrap, registry); let mut process = std::collections::BTreeMap::::new(); process.insert("KSP_SECRET_HELIUS_API_KEY".to_owned(), "helius-composite-canary".to_owned()); process.insert("KSP_SECRET_ORBITFLARE_DEVNET_GRPC_X_TOKEN".to_owned(), "orbitflare-composite-canary".to_owned()); process.insert("KSP_SECRET_PUBLICNODE_MAINNET_GRPC_X_TOKEN".to_owned(), "publicnode-mainnet-composite-canary".to_owned()); process.insert("KSP_SECRET_PUBLICNODE_TESTNET_GRPC_X_TOKEN".to_owned(), "publicnode-testnet-composite-canary".to_owned()); let environment = crate::ConfigEnvironment::from_maps(process, std::collections::BTreeMap::new()); for (profile_id, expected_network, expected_transport_profiles) in [ ("devnet", "devnet", vec!["devnet_public", "helius_devnet", "orbitflare_devnet"]), ("mainnet", "mainnet", vec!["mainnet_public", "helius_mainnet", "publicnode_mainnet"]), ("testnet", "testnet", vec!["testnet_public", "publicnode_testnet"]), ] { let composite = engine.load_resolved_composite(&file_id, std::option::Option::Some(profile_id)); assert!(composite.is_ok(), "Raw Ingest network profile {profile_id} should resolve: {composite:?}"); let composite = match composite { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => continue, }; assert_eq!(composite.profile_id(), profile_id); let store_component = composite.component("store"); assert!(store_component.is_some(), "profile {profile_id} should contain Store"); let store_component = match store_component { std::option::Option::Some(value) => value, std::option::Option::None => continue, }; assert_eq!(store_component.resolved().profile_id(), expected_network); let store = engine.resolve_store_config_profile(store_component.resolved(), &environment); assert!(store.is_ok(), "Store profile {expected_network} should map: {store:?}"); if let std::result::Result::Ok(store) = store { assert_eq!(store.settings().network().as_str(), expected_network); } let transport_components = composite .components() .iter() .filter(|(component_id, component)| { return component_id.starts_with("transport") && component.resolved().file_id().as_str() == crate::FILE_ID_STD_TRANSPORT; }) .map(|(_, component)| return component) .collect::>(); assert_eq!(transport_components.len(), expected_transport_profiles.len()); let actual_profiles = transport_components.iter().map(|component| return component.resolved().profile_id()).collect::>(); for expected_transport_profile in expected_transport_profiles { assert!( actual_profiles.contains(&expected_transport_profile), "network profile {profile_id} should include Transport source {expected_transport_profile}" ); } for component in transport_components { let transport = engine.resolve_transport_config_profile(component.resolved(), &environment); assert!(transport.is_ok(), "Transport source {} should map: {transport:?}", component.resolved().profile_id()); if let std::result::Result::Ok(transport) = transport { assert!(transport.http_settings().endpoints().iter().all(|endpoint| return endpoint.cluster().as_str() == expected_network)); if let std::option::Option::Some(ws) = transport.ws_settings() { assert!(ws.endpoints().iter().all(|endpoint| return endpoint.cluster().as_str() == expected_network)); } if let std::option::Option::Some(grpc) = transport.grpc_settings() { assert!(grpc.endpoints().iter().all(|endpoint| return endpoint.cluster().as_str() == expected_network)); } } } } } fn fixture_example_engine() -> ksp_core_lib::Result { let workspace = workspace_root(); let fixture_root = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("unit_tests/fixtures"); let bootstrap = crate::ConfigBootstrapOptions::from_paths(fixture_root, workspace.join("config/schemas")); let bootstrap = match bootstrap { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let registry = test_registry(TEST_COMPOSITE_FILENAME); return match registry { std::result::Result::Ok(value) => std::result::Result::Ok(crate::ConfigDocumentEngine::new(bootstrap, value)), std::result::Result::Err(error) => std::result::Result::Err(error), }; } fn fixture_engine(fixture: &FixtureRoots) -> ksp_core_lib::Result { let bootstrap = crate::ConfigBootstrapOptions::from_paths(fixture.config.as_path(), fixture.schemas.as_path()); let bootstrap = match bootstrap { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let registry = test_registry("composite.test.json"); return match registry { std::result::Result::Ok(value) => std::result::Result::Ok(crate::ConfigDocumentEngine::new(bootstrap, value)), std::result::Result::Err(error) => std::result::Result::Err(error), }; } fn test_registry(composite_filename: &'static str) -> ksp_core_lib::Result { let logging = crate::registry::ConfigFileDescriptor::new( crate::FILE_ID_STD_LOGGING, crate::ConfigFileKind::Config, crate::DEFAULT_STD_LOGGING_FILENAME, std::option::Option::Some(crate::FILE_ID_SCHEMA_STD_LOGGING), ); let logging = match logging { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let logging_schema = crate::registry::ConfigFileDescriptor::new( crate::FILE_ID_SCHEMA_STD_LOGGING, crate::ConfigFileKind::Schema, crate::DEFAULT_STD_LOGGING_SCHEMA_FILENAME, std::option::Option::None, ); let logging_schema = match logging_schema { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let composite_schema = crate::registry::ConfigFileDescriptor::new( crate::FILE_ID_SCHEMA_COMPOSITE, crate::ConfigFileKind::Schema, crate::DEFAULT_COMPOSITE_SCHEMA_FILENAME, std::option::Option::None, ); let composite_schema = match composite_schema { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; let composite = crate::registry::ConfigFileDescriptor::new( TEST_COMPOSITE_FILE_ID, crate::ConfigFileKind::Config, composite_filename, std::option::Option::Some(crate::FILE_ID_SCHEMA_COMPOSITE), ); let composite = match composite { std::result::Result::Ok(value) => value, std::result::Result::Err(error) => return std::result::Result::Err(error), }; return crate::build_registry([logging, logging_schema, composite_schema, composite]); } fn prepare_fixture(fixture: &FixtureRoots, composite: &str) -> std::io::Result<()> { cleanup_fixture(fixture); let config = std::fs::create_dir_all(fixture.config.as_path()); if let std::result::Result::Err(error) = config { return std::result::Result::Err(error); } let schemas = std::fs::create_dir_all(fixture.schemas.as_path()); if let std::result::Result::Err(error) = schemas { return std::result::Result::Err(error); } let workspace = workspace_root(); let stable_logging = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("unit_tests/fixtures/std.logging.json"); let logging = std::fs::copy(stable_logging, fixture.config.join(crate::DEFAULT_STD_LOGGING_FILENAME)); if let std::result::Result::Err(error) = logging { return std::result::Result::Err(error); } let logging_schema = std::fs::copy(workspace.join("config/schemas/std.logging.schema.json"), fixture.schemas.join(crate::DEFAULT_STD_LOGGING_SCHEMA_FILENAME)); if let std::result::Result::Err(error) = logging_schema { return std::result::Result::Err(error); } let composite_schema = std::fs::copy(workspace.join("config/schemas/composite.schema.json"), fixture.schemas.join(crate::DEFAULT_COMPOSITE_SCHEMA_FILENAME)); if let std::result::Result::Err(error) = composite_schema { return std::result::Result::Err(error); } return std::fs::write(fixture.config.join("composite.test.json"), composite); } fn workspace_root() -> std::path::PathBuf { return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../.."); } struct FixtureRoots { root: std::path::PathBuf, config: std::path::PathBuf, schemas: std::path::PathBuf, } fn fixture_roots(name: &str) -> FixtureRoots { let root = std::env::temp_dir().join(format!("ksp-config-composite-{name}-{}", std::process::id())); return FixtureRoots { config: root.join("config"), schemas: root.join("schemas"), root }; } fn cleanup_fixture(fixture: &FixtureRoots) { let removal = std::fs::remove_dir_all(fixture.root.as_path()); if let std::result::Result::Err(error) = removal && error.kind() != std::io::ErrorKind::NotFound { eprintln!("unable to cleanup Config composite fixture {}: {error}", fixture.root.display()); } }