v0.1.4-pre.015-fix.002

This commit is contained in:
2026-08-16 18:20:32 +02:00
parent 05c65a12f4
commit 9ad61b40e1
25 changed files with 776 additions and 210 deletions

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-config-lib/tests/public_api.rs
// version: 15
// version: 16
//! Integration tests for the public `ksp-config-lib` bootstrap, registry, JSON/profile/composite, environment-resolution, sensitivity, Logging-adapter and
//! management contracts.
@@ -124,10 +124,13 @@ fn resolved_profile_contract_is_available_from_crate_root() {
assert!(file_id.is_ok(), "public Logging file_id should remain constructible: {file_id:?}");
if let (std::result::Result::Ok(bootstrap), std::result::Result::Ok(registry), std::result::Result::Ok(file_id)) = (bootstrap, registry, file_id) {
let engine = ksp_config_lib::ConfigDocumentEngine::new(bootstrap, registry);
let document = engine.load_validated_document(&file_id);
let resolved = engine.load_resolved_profile(&file_id, std::option::Option::None);
assert!(document.is_ok(), "public profile resolver should read committed source: {document:?}");
assert!(resolved.is_ok(), "public profile resolver should resolve committed default profile: {resolved:?}");
if let std::result::Result::Ok(resolved) = resolved {
assert_eq!(resolved.profile_id(), "local_dev");
if let (std::result::Result::Ok(document), std::result::Result::Ok(resolved)) = (document, resolved) {
let default_profile = document.value().get("default_profile").and_then(serde_json::Value::as_str);
assert_eq!(default_profile, std::option::Option::Some(resolved.profile_id()));
assert_eq!(resolved.selection_source(), ksp_config_lib::ConfigProfileSelectionSource::DefaultProfile);
assert_eq!(resolved.origin("logs_directory"), std::option::Option::Some(ksp_config_lib::ConfigValueOrigin::Global));
assert_eq!(resolved.origin("default_filter"), std::option::Option::Some(ksp_config_lib::ConfigValueOrigin::Profile));
@@ -212,13 +215,12 @@ fn management_contracts_are_available_from_crate_root() {
assert!(logging.is_ok(), "public typed Logging management contract should load committed source: {logging:?}");
if let std::result::Result::Ok(mut logging) = logging {
assert_eq!(logging.format_version(), 1);
assert_eq!(logging.default_profile(), "local_dev");
let default_profile = logging.default_profile().to_owned();
assert!(!default_profile.is_empty());
assert!(!logging.profiles().is_empty());
assert!(logging.profiles().iter().any(|profile| return profile.profile_id() == default_profile.as_str()));
logging.set_logs_directory("public-api-management-test");
assert_eq!(logging.logs_directory(), "public-api-management-test");
assert_eq!(logging.profiles().len(), 1);
assert_eq!(logging.profiles()[0].profile_id(), "local_dev");
assert_eq!(logging.profiles()[0].files().len(), 2);
assert!(!logging.profiles()[0].files()[0].ansi());
if let std::option::Option::Some(profile) = logging.profiles_mut().first_mut()
&& let std::option::Option::Some(file) = profile.files_mut().first_mut()
{

View File

@@ -1,18 +1,18 @@
// file: crates/ksp-config-lib/unit_tests/composite.rs
// version: 2
// version: 3
const TEST_COMPOSITE_FILE_ID: &str = "cfg.composite.test";
const TEST_COMPOSITE_FILENAME: &str = "examples/composite.example.json";
#[test]
fn committed_composite_example_resolves_default_document_profile() {
let engine = committed_engine();
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(), "committed composite example should resolve: {resolved:?}");
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);
@@ -20,7 +20,12 @@ fn committed_composite_example_resolves_default_document_profile() {
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);
assert_eq!(logging.resolved().profile_id(), "local_dev");
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));
}
@@ -30,7 +35,7 @@ fn committed_composite_example_resolves_default_document_profile() {
#[test]
fn composite_profile_override_marks_referenced_profile_selection_as_composite() {
let engine = committed_engine();
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:?}");
@@ -51,7 +56,7 @@ fn composite_profile_override_marks_referenced_profile_selection_as_composite()
#[test]
fn unknown_composite_profile_has_profile_not_found_error() {
let engine = committed_engine();
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:?}");
@@ -123,9 +128,10 @@ fn duplicate_component_ids_are_rejected_inside_one_composite_profile() {
cleanup_fixture(&fixture);
}
fn committed_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
fn fixture_example_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
let workspace = workspace_root();
let bootstrap = crate::ConfigBootstrapOptions::from_paths(workspace.join("config"), workspace.join("config/schemas"));
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),
@@ -205,7 +211,8 @@ fn prepare_fixture(fixture: &FixtureRoots, composite: &str) -> std::io::Result<(
return std::result::Result::Err(error);
}
let workspace = workspace_root();
let logging = std::fs::copy(workspace.join("config/std.logging.json"), fixture.config.join(crate::DEFAULT_STD_LOGGING_FILENAME));
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);
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-config-lib/unit_tests/document.rs
// version: 2
// version: 3
#[test]
fn committed_logging_document_passes_registered_schema_and_semantic_validation() {
@@ -17,10 +17,16 @@ fn committed_logging_document_passes_registered_schema_and_semantic_validation()
if let std::result::Result::Ok(document) = document {
assert_eq!(document.file_id(), &file_id);
assert_eq!(document.path(), workspace.join("config/std.logging.json").as_path());
let default_profile = document.value().get("default_profile");
let default_profile = document.value().get("default_profile").and_then(serde_json::Value::as_str);
assert!(default_profile.is_some(), "validated Logging document should retain default_profile");
if let std::option::Option::Some(default_profile) = default_profile {
assert_eq!(default_profile.as_str(), std::option::Option::Some("local_dev"));
let profiles = document.value().get("profiles").and_then(serde_json::Value::as_array);
assert!(profiles.is_some(), "validated Logging document should retain profiles");
if let std::option::Option::Some(profiles) = profiles {
assert!(profiles.iter().any(|profile| -> bool {
return profile.get("profile_id").and_then(serde_json::Value::as_str) == std::option::Option::Some(default_profile);
}));
}
}
}
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-config-lib/unit_tests/environment.rs
// version: 4
// version: 5
#[test]
fn process_environment_wins_over_dotenv_and_fallback_even_when_empty() {
@@ -174,9 +174,8 @@ fn fake_process_collection_filters_unrelated_names_without_mutating_real_environ
}
#[test]
fn committed_logging_profile_resolves_environment_fallback_without_changing_source_profile() {
let workspace = workspace_root();
let bootstrap = crate::ConfigBootstrapOptions::from_paths(workspace.join("config"), workspace.join("config/schemas"));
fn logging_fixture_profile_resolves_environment_fallback_without_changing_source_profile() {
let bootstrap = logging_fixture_bootstrap();
assert!(bootstrap.is_ok(), "bootstrap should resolve committed roots");
let bootstrap = match bootstrap {
std::result::Result::Ok(value) => value,
@@ -235,6 +234,12 @@ fn workspace_root() -> std::path::PathBuf {
return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
}
fn logging_fixture_bootstrap() -> ksp_core_lib::Result<crate::ConfigBootstrapOptions> {
let fixture_root = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("unit_tests/fixtures");
let workspace = workspace_root();
return crate::ConfigBootstrapOptions::from_paths(fixture_root, workspace.join("config/schemas"));
}
#[test]
fn secret_environment_value_keeps_real_value_but_redacts_safe_and_debug_views() {
let canary = "KSP_SECRET_CANARY_91b7c6";
@@ -322,9 +327,8 @@ fn detailed_json_preserves_safe_tree_sensitivity_and_pointer_provenance() {
}
#[test]
fn detailed_profile_environment_keeps_global_origin_and_adds_environment_provenance() {
let workspace = workspace_root();
let bootstrap = crate::ConfigBootstrapOptions::from_paths(workspace.join("config"), workspace.join("config/schemas"));
fn detailed_fixture_profile_environment_keeps_global_origin_and_adds_environment_provenance() {
let bootstrap = logging_fixture_bootstrap();
let bootstrap = match bootstrap {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,

View File

@@ -0,0 +1,25 @@
{
"format_version": 1,
"default_profile": "local_default",
"profiles": [
{
"profile_id": "local_default",
"documents": [
{
"component_id": "logging",
"file_id": "cfg.std.logging"
}
]
},
{
"profile_id": "local_explicit",
"documents": [
{
"component_id": "logging",
"file_id": "cfg.std.logging",
"profile_id": "local_dev"
}
]
}
]
}

View File

@@ -0,0 +1,77 @@
{
"format_version": 1,
"logs_directory": "${KSP_LOGS_DIRECTORY:-logs}",
"default_profile": "local_dev",
"profiles": [
{
"profile_id": "local_dev",
"default_filter": "warn",
"span_events": "new_and_close",
"console": {
"enabled": true,
"output": "stderr",
"ansi": true,
"format": "compact",
"filter": {
"level": "debug",
"targets": [
"*"
],
"domains": [
"*"
]
}
},
"files": [
{
"output_id": "file.all.debug",
"enabled": true,
"path": "debug/ksp-debug.log",
"rotation": "daily",
"format": "human",
"ansi": false,
"filter": {
"level": "debug",
"targets": [
"*"
],
"domains": [
"*"
]
}
},
{
"output_id": "file.config.error",
"enabled": true,
"path": "config/ksp-config-errors.jsonl",
"rotation": "daily",
"format": "json",
"ansi": false,
"filter": {
"level": "error",
"targets": [
"ksp-config-lib"
],
"domains": [
"config"
]
}
}
],
"target_filters": [
{
"target_prefix": "ksp-config-lib",
"level": "trace"
},
{
"target_prefix": "ksp-logging-lib",
"level": "debug"
},
{
"target_prefix": "ksp-app-config-desk",
"level": "debug"
}
]
}
]
}

View File

@@ -1,76 +1,145 @@
// file: crates/ksp-config-lib/unit_tests/logging.rs
// version: 2
// version: 3
#[test]
fn committed_logging_profile_maps_complete_runtime_contract() {
let engine = committed_engine();
fn fixture_logging_profile_maps_complete_runtime_contract() {
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let environment = crate::ConfigEnvironment::from_maps(std::collections::BTreeMap::new(), std::collections::BTreeMap::new());
let resolved = engine.load_resolved_logging_config(std::option::Option::None, &environment);
assert!(resolved.is_ok(), "committed Logging Config should map");
assert!(resolved.is_ok(), "fixture Logging Config should map");
let resolved = match resolved {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
assert_eq!(resolved.file_id().as_str(), crate::FILE_ID_STD_LOGGING);
assert_eq!(resolved.profile_id(), "local_dev");
assert_eq!(resolved.selection_source(), crate::ConfigProfileSelectionSource::DefaultProfile);
assert_eq!(resolved.logs_directory(), current_directory().join("logs").as_path());
assert_eq!(resolved.effective().value()["logs_directory"], serde_json::Value::String("logs".to_owned()));
let effective = resolved.effective().value();
let effective_logs_directory = effective.get("logs_directory").and_then(serde_json::Value::as_str);
assert!(effective_logs_directory.is_some(), "effective Logging Config should expose logs_directory");
if let std::option::Option::Some(effective_logs_directory) = effective_logs_directory {
let source_path = std::path::Path::new(effective_logs_directory);
let expected = if source_path.is_absolute() { source_path.to_path_buf() } else { current_directory().join(source_path) };
assert_eq!(resolved.logs_directory(), expected.as_path());
}
let settings = resolved.settings();
assert_eq!(settings.default_filter(), ksp_logging_lib::LogFilterLevel::Warn);
assert_eq!(settings.span_events(), ksp_logging_lib::SpanEvents::NewAndClose);
assert_eq!(settings.target_filters().len(), 3);
assert_eq!(settings.target_filters()[0].target_prefix(), "ksp-config-lib");
assert_eq!(settings.target_filters()[0].level(), ksp_logging_lib::LogFilterLevel::Trace);
assert_eq!(settings.target_filters()[1].target_prefix(), "ksp-logging-lib");
assert_eq!(settings.target_filters()[1].level(), ksp_logging_lib::LogFilterLevel::Debug);
assert_eq!(settings.target_filters()[2].target_prefix(), "ksp-app-config-desk");
assert_eq!(settings.target_filters()[2].level(), ksp_logging_lib::LogFilterLevel::Debug);
let default_filter = effective.get("default_filter").and_then(serde_json::Value::as_str);
let span_events = effective.get("span_events").and_then(serde_json::Value::as_str);
assert_eq!(default_filter.and_then(test_level), std::option::Option::Some(settings.default_filter()));
assert_eq!(span_events.and_then(test_span_events), std::option::Option::Some(settings.span_events()));
let source_target_filters = effective.get("target_filters").and_then(serde_json::Value::as_array);
assert!(source_target_filters.is_some(), "effective Logging Config should expose target_filters");
if let std::option::Option::Some(source_target_filters) = source_target_filters {
assert_eq!(settings.target_filters().len(), source_target_filters.len());
for (runtime, source) in settings.target_filters().iter().zip(source_target_filters) {
assert_eq!(source.get("target_prefix").and_then(serde_json::Value::as_str), std::option::Option::Some(runtime.target_prefix()));
assert_eq!(source.get("level").and_then(serde_json::Value::as_str).and_then(test_level), std::option::Option::Some(runtime.level()));
}
}
let console = settings.console();
assert!(console.is_some(), "committed Logging Config declares console settings");
let console = match console {
std::option::Option::Some(value) => value,
std::option::Option::None => return,
let source_console = effective.get("console");
assert!(console.is_some(), "effective Logging Config declares console settings");
assert!(source_console.is_some(), "effective Logging Config should expose console settings");
if let (std::option::Option::Some(console), std::option::Option::Some(source_console)) = (console, source_console) {
assert_eq!(source_console.get("enabled").and_then(serde_json::Value::as_bool), std::option::Option::Some(console.enabled()));
assert_eq!(source_console.get("ansi").and_then(serde_json::Value::as_bool), std::option::Option::Some(console.ansi()));
assert_eq!(source_console.get("output").and_then(serde_json::Value::as_str).and_then(test_console_output), std::option::Option::Some(console.output()));
assert_eq!(source_console.get("format").and_then(serde_json::Value::as_str).and_then(test_format), std::option::Option::Some(console.format()));
let filter = source_console.get("filter");
assert!(filter.is_some(), "effective console should expose filter");
if let std::option::Option::Some(filter) = filter {
assert_eq!(filter.get("level").and_then(serde_json::Value::as_str).and_then(test_level), std::option::Option::Some(console.filter().level()));
assert_eq!(json_string_array(filter.get("targets")), console.filter().targets().to_vec());
assert_eq!(json_string_array(filter.get("domains")), console.filter().domains().to_vec());
}
}
let source_files = effective.get("files").and_then(serde_json::Value::as_array);
assert!(source_files.is_some(), "effective Logging Config should expose files");
if let std::option::Option::Some(source_files) = source_files {
assert_eq!(settings.files().len(), source_files.len());
for (runtime, source) in settings.files().iter().zip(source_files) {
assert_eq!(source.get("output_id").and_then(serde_json::Value::as_str), std::option::Option::Some(runtime.output_id()));
assert_eq!(source.get("enabled").and_then(serde_json::Value::as_bool), std::option::Option::Some(runtime.enabled()));
assert_eq!(source.get("rotation").and_then(serde_json::Value::as_str).and_then(test_rotation), std::option::Option::Some(runtime.rotation()));
assert_eq!(source.get("format").and_then(serde_json::Value::as_str).and_then(test_format), std::option::Option::Some(runtime.format()));
assert_eq!(source.get("ansi").and_then(serde_json::Value::as_bool), std::option::Option::Some(runtime.ansi()));
let filter = source.get("filter");
assert!(filter.is_some(), "effective file should expose filter");
if let std::option::Option::Some(filter) = filter {
assert_eq!(filter.get("level").and_then(serde_json::Value::as_str).and_then(test_level), std::option::Option::Some(runtime.filter().level()));
assert_eq!(json_string_array(filter.get("targets")), runtime.filter().targets().to_vec());
assert_eq!(json_string_array(filter.get("domains")), runtime.filter().domains().to_vec());
}
}
}
}
fn test_level(value: &str) -> std::option::Option<ksp_logging_lib::LogFilterLevel> {
return match value {
"off" => std::option::Option::Some(ksp_logging_lib::LogFilterLevel::Off),
"error" => std::option::Option::Some(ksp_logging_lib::LogFilterLevel::Error),
"warn" => std::option::Option::Some(ksp_logging_lib::LogFilterLevel::Warn),
"info" => std::option::Option::Some(ksp_logging_lib::LogFilterLevel::Info),
"debug" => std::option::Option::Some(ksp_logging_lib::LogFilterLevel::Debug),
"trace" => std::option::Option::Some(ksp_logging_lib::LogFilterLevel::Trace),
_ => std::option::Option::None,
};
assert!(console.enabled());
assert_eq!(console.output(), ksp_logging_lib::ConsoleOutput::Stderr);
assert!(console.ansi());
assert_eq!(console.format(), ksp_logging_lib::LogFormat::Compact);
assert_eq!(console.filter().level(), ksp_logging_lib::LogFilterLevel::Debug);
assert_eq!(console.filter().targets(), &["*".to_owned()]);
assert_eq!(console.filter().domains(), &["*".to_owned()]);
assert_eq!(settings.files().len(), 2);
assert_file(
&settings.files()[0],
"file.all.debug",
current_directory().join("logs/debug").as_path(),
"ksp-debug.log",
ksp_logging_lib::FileRotation::Daily,
ksp_logging_lib::LogFormat::Human,
ksp_logging_lib::LogFilterLevel::Debug,
&["*"],
&["*"],
);
assert_file(
&settings.files()[1],
"file.config.error",
current_directory().join("logs/config").as_path(),
"ksp-config-errors.jsonl",
ksp_logging_lib::FileRotation::Daily,
ksp_logging_lib::LogFormat::Json,
ksp_logging_lib::LogFilterLevel::Error,
&["ksp-config-lib"],
&["config"],
);
}
fn test_span_events(value: &str) -> std::option::Option<ksp_logging_lib::SpanEvents> {
return match value {
"off" => std::option::Option::Some(ksp_logging_lib::SpanEvents::Off),
"new_and_close" => std::option::Option::Some(ksp_logging_lib::SpanEvents::NewAndClose),
"full" => std::option::Option::Some(ksp_logging_lib::SpanEvents::Full),
_ => std::option::Option::None,
};
}
fn test_console_output(value: &str) -> std::option::Option<ksp_logging_lib::ConsoleOutput> {
return match value {
"stdout" => std::option::Option::Some(ksp_logging_lib::ConsoleOutput::Stdout),
"stderr" => std::option::Option::Some(ksp_logging_lib::ConsoleOutput::Stderr),
_ => std::option::Option::None,
};
}
fn test_format(value: &str) -> std::option::Option<ksp_logging_lib::LogFormat> {
return match value {
"human" => std::option::Option::Some(ksp_logging_lib::LogFormat::Human),
"compact" => std::option::Option::Some(ksp_logging_lib::LogFormat::Compact),
"pretty" => std::option::Option::Some(ksp_logging_lib::LogFormat::Pretty),
"json" => std::option::Option::Some(ksp_logging_lib::LogFormat::Json),
_ => std::option::Option::None,
};
}
fn test_rotation(value: &str) -> std::option::Option<ksp_logging_lib::FileRotation> {
return match value {
"never" => std::option::Option::Some(ksp_logging_lib::FileRotation::Never),
"hourly" => std::option::Option::Some(ksp_logging_lib::FileRotation::Hourly),
"daily" => std::option::Option::Some(ksp_logging_lib::FileRotation::Daily),
_ => std::option::Option::None,
};
}
fn json_string_array(value: std::option::Option<&serde_json::Value>) -> std::vec::Vec<String> {
let mut result = std::vec::Vec::<String>::new();
if let std::option::Option::Some(values) = value.and_then(serde_json::Value::as_array) {
for value in values {
if let std::option::Option::Some(value) = value.as_str() {
result.push(value.to_owned());
}
}
}
return result;
}
#[test]
fn relative_logs_directory_is_anchored_to_process_current_directory() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -86,7 +155,7 @@ fn relative_logs_directory_is_anchored_to_process_current_directory() {
#[test]
fn absolute_logs_directory_is_preserved() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -111,7 +180,7 @@ fn effective_file_paths_cannot_escape_logging_root() {
#[test]
fn explicit_empty_logs_directory_is_invalid_instead_of_using_fallback() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -130,7 +199,7 @@ fn explicit_empty_logs_directory_is_invalid_instead_of_using_fallback() {
#[test]
fn existing_non_directory_logging_root_is_rejected_without_secret_leak() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -139,7 +208,7 @@ fn existing_non_directory_logging_root_is_rejected_without_secret_leak() {
let path = std::env::temp_dir().join(secret.as_str());
let write = std::fs::write(path.as_path(), b"not a directory");
assert!(write.is_ok(), "secret canary file should be created");
let profile = load_committed_profile(&engine);
let profile = load_fixture_profile(&engine);
let profile = match profile {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => {
@@ -161,12 +230,12 @@ fn existing_non_directory_logging_root_is_rejected_without_secret_leak() {
#[test]
fn logging_adapter_rejects_secret_effective_values_without_exposing_canary() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
};
let profile = load_committed_profile(&engine);
let profile = load_fixture_profile(&engine);
let profile = match profile {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -193,7 +262,7 @@ fn logging_adapter_rejects_secret_effective_values_without_exposing_canary() {
#[test]
fn mapped_logging_settings_can_initialize_and_reinitialize_runtime() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -231,7 +300,7 @@ fn mapped_logging_settings_can_initialize_and_reinitialize_runtime() {
#[test]
fn resolved_logging_debug_uses_safe_effective_view() {
let engine = committed_engine();
let engine = fixture_engine();
let engine = match engine {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => return,
@@ -270,9 +339,10 @@ fn assert_file(
assert_eq!(file.filter().domains().iter().map(String::as_str).collect::<std::vec::Vec<&str>>(), domains.to_vec());
}
fn committed_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
fn fixture_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
let workspace = workspace_root();
let bootstrap = crate::ConfigBootstrapOptions::from_paths(workspace.join("config"), workspace.join("config/schemas"));
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),
@@ -285,7 +355,7 @@ fn committed_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
return std::result::Result::Ok(crate::ConfigDocumentEngine::new(bootstrap, registry));
}
fn load_committed_profile(engine: &crate::ConfigDocumentEngine) -> ksp_core_lib::Result<crate::ResolvedConfigProfile> {
fn load_fixture_profile(engine: &crate::ConfigDocumentEngine) -> ksp_core_lib::Result<crate::ResolvedConfigProfile> {
let file_id = crate::ConfigFileId::new(crate::FILE_ID_STD_LOGGING);
let file_id = match file_id {
std::result::Result::Ok(value) => value,

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-config-lib/unit_tests/management.rs
// version: 4
// version: 5
static NEXT_FIXTURE_ID: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(1);
@@ -56,7 +56,7 @@ fn valid_raw_source_candidate_is_persisted_exactly_and_reports_reload() {
return;
},
};
let candidate = original.replace(" \"logs_directory\":", " \"logs_directory\":");
let candidate = format!("{original} \n");
assert_ne!(candidate, original, "raw source candidate fixture must change the persisted bytes");
let corrupt = std::fs::write(fixture.config_path.as_path(), b"{\n");
assert!(corrupt.is_ok(), "existing managed source should be corruptible for repair test");
@@ -165,7 +165,23 @@ fn semantic_invalid_source_candidate_is_rejected_without_modifying_existing_file
return;
},
};
let candidate = before.replace("\"default_profile\": \"local_dev\"", "\"default_profile\": \"missing\"");
let candidate_value = serde_json::from_str::<serde_json::Value>(before.as_str());
let mut candidate_value = match candidate_value {
std::result::Result::Ok(value) => value,
std::result::Result::Err(_) => {
cleanup_fixture(&fixture);
return;
},
};
candidate_value["default_profile"] = serde_json::Value::String("missing".to_owned());
let candidate = serde_json::to_string_pretty(&candidate_value);
let candidate = match candidate {
std::result::Result::Ok(value) => format!("{value}\n"),
std::result::Result::Err(_) => {
cleanup_fixture(&fixture);
return;
},
};
assert_ne!(candidate, before, "semantic-invalid fixture must alter the default profile");
let file_id = crate::ConfigFileId::new(crate::FILE_ID_STD_LOGGING);
let file_id = match file_id {
@@ -237,10 +253,8 @@ fn typed_logging_document_can_be_mutated_validated_and_persisted_atomically() {
},
};
assert_eq!(document.format_version(), 1);
assert_eq!(document.default_profile(), "local_dev");
assert_eq!(document.profiles().len(), 1);
assert_eq!(document.profiles()[0].files().len(), 2);
assert!(!document.profiles()[0].files()[0].ansi());
assert!(!document.default_profile().is_empty());
assert!(!document.profiles().is_empty());
document.set_logs_directory("managed-logs");
if let std::option::Option::Some(profile) = document.profiles_mut().first_mut() {
profile.set_default_filter("info");
@@ -496,7 +510,7 @@ fn management_fixture() -> ksp_core_lib::Result<ManagementFixture> {
);
}
let workspace = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
let source_config = workspace.join("config/std.logging.json");
let source_config = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("unit_tests/fixtures/std.logging.json");
let source_schema = workspace.join("config/schemas/std.logging.schema.json");
let config_path = config_root.join("std.logging.json");
let schema_path = schema_root.join("std.logging.schema.json");

View File

@@ -1,23 +1,27 @@
// file: crates/ksp-config-lib/unit_tests/profile.rs
// version: 1
// version: 2
#[test]
fn committed_default_profile_resolves_globals_profile_and_provenance() {
let engine = committed_engine();
fn fixture_default_profile_resolves_globals_profile_and_provenance() {
let engine = fixture_engine();
let file_id = crate::ConfigFileId::new(crate::FILE_ID_STD_LOGGING);
assert!(engine.is_ok(), "committed Config engine should be constructible: {engine:?}");
assert!(engine.is_ok(), "fixture Config engine should be constructible: {engine:?}");
assert!(file_id.is_ok(), "logging file_id should be valid: {file_id:?}");
if let (std::result::Result::Ok(engine), std::result::Result::Ok(file_id)) = (engine, file_id) {
let document = engine.load_validated_document(&file_id);
assert!(document.is_ok(), "committed Logging document should validate: {document:?}");
let resolved = engine.load_resolved_profile(&file_id, std::option::Option::None);
assert!(resolved.is_ok(), "default profile should resolve: {resolved:?}");
if let std::result::Result::Ok(resolved) = resolved {
assert_eq!(resolved.profile_id(), "local_dev");
if let (std::result::Result::Ok(document), std::result::Result::Ok(resolved)) = (document, resolved) {
let default_profile = document.value().get("default_profile").and_then(serde_json::Value::as_str);
assert_eq!(default_profile, std::option::Option::Some(resolved.profile_id()));
assert_eq!(resolved.selection_source(), super::ConfigProfileSelectionSource::DefaultProfile);
assert_eq!(resolved.globals().get("logs_directory").and_then(serde_json::Value::as_str), std::option::Option::Some("${KSP_LOGS_DIRECTORY:-logs}"));
assert_eq!(resolved.profile().get("default_filter").and_then(serde_json::Value::as_str), std::option::Option::Some("warn"));
assert_eq!(resolved.effective().get("default_filter").and_then(serde_json::Value::as_str), std::option::Option::Some("warn"));
assert_eq!(resolved.origin("logs_directory"), std::option::Option::Some(super::ConfigValueOrigin::Global));
assert_eq!(resolved.origin("default_filter"), std::option::Option::Some(super::ConfigValueOrigin::Profile));
assert_eq!(
resolved.profile().get("default_filter").and_then(serde_json::Value::as_str),
resolved.effective().get("default_filter").and_then(serde_json::Value::as_str),
);
assert!(!resolved.effective().contains_key("default_profile"));
assert!(!resolved.effective().contains_key("profiles"));
}
@@ -26,25 +30,33 @@ fn committed_default_profile_resolves_globals_profile_and_provenance() {
#[test]
fn explicit_profile_selection_is_distinct_from_default_selection() {
let engine = committed_engine();
let engine = fixture_engine();
let file_id = crate::ConfigFileId::new(crate::FILE_ID_STD_LOGGING);
assert!(engine.is_ok(), "committed Config engine should be constructible: {engine:?}");
assert!(engine.is_ok(), "fixture Config engine should be constructible: {engine:?}");
assert!(file_id.is_ok(), "logging 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_profile(&file_id, std::option::Option::Some("local_dev"));
assert!(resolved.is_ok(), "explicit committed profile should resolve: {resolved:?}");
if let std::result::Result::Ok(resolved) = resolved {
assert_eq!(resolved.profile_id(), "local_dev");
assert_eq!(resolved.selection_source(), super::ConfigProfileSelectionSource::Explicit);
let document = engine.load_validated_document(&file_id);
assert!(document.is_ok(), "committed Logging document should validate: {document:?}");
if let std::result::Result::Ok(document) = document {
let profile_id = document.value().get("default_profile").and_then(serde_json::Value::as_str);
assert!(profile_id.is_some(), "validated Logging document should expose default_profile");
if let std::option::Option::Some(profile_id) = profile_id {
let resolved = engine.load_resolved_profile(&file_id, std::option::Option::Some(profile_id));
assert!(resolved.is_ok(), "explicit committed profile should resolve: {resolved:?}");
if let std::result::Result::Ok(resolved) = resolved {
assert_eq!(resolved.profile_id(), profile_id);
assert_eq!(resolved.selection_source(), super::ConfigProfileSelectionSource::Explicit);
}
}
}
}
}
#[test]
fn unknown_explicit_profile_has_distinct_error_code() {
let engine = committed_engine();
let engine = fixture_engine();
let file_id = crate::ConfigFileId::new(crate::FILE_ID_STD_LOGGING);
assert!(engine.is_ok(), "committed Config engine should be constructible: {engine:?}");
assert!(engine.is_ok(), "fixture Config engine should be constructible: {engine:?}");
assert!(file_id.is_ok(), "logging 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_profile(&file_id, std::option::Option::Some("does-not-exist"));
@@ -55,9 +67,10 @@ fn unknown_explicit_profile_has_distinct_error_code() {
}
}
fn committed_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
fn fixture_engine() -> ksp_core_lib::Result<crate::ConfigDocumentEngine> {
let workspace = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
let bootstrap = crate::ConfigBootstrapOptions::from_paths(workspace.join("config"), workspace.join("config/schemas"));
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),