v0.3.6-pre.010
This commit is contained in:
350
crates/ksp-job-backfill-lib/tests/hardening.rs
Normal file
350
crates/ksp-job-backfill-lib/tests/hardening.rs
Normal file
@@ -0,0 +1,350 @@
|
||||
// file: crates/ksp-job-backfill-lib/tests/hardening.rs
|
||||
// version: 4
|
||||
|
||||
//! Adversarial, security, visibility and external-boundary hardening canaries for `pre.010`.
|
||||
|
||||
fn signature_text() -> std::string::String {
|
||||
return "2".repeat(ksp_job_backfill_lib::MIN_BACKFILL_SIGNATURE_TEXT_BYTES);
|
||||
}
|
||||
|
||||
fn signature() -> std::option::Option<ksp_job_backfill_lib::BackfillSignature> {
|
||||
let result = ksp_job_backfill_lib::BackfillSignature::new(signature_text());
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
||||
std::result::Result::Err(error) => {
|
||||
assert_eq!(error.code(), ksp_job_backfill_lib::ERROR_CODE_BACKFILL_SIGNATURE_INVALID);
|
||||
std::option::Option::None
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn network(value: &'static str) -> std::option::Option<ksp_store_lib::RawNetworkId> {
|
||||
let result = ksp_store_lib::RawNetworkId::new(value);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
||||
std::result::Result::Err(error) => {
|
||||
assert_eq!(error.code().domain(), "store_api");
|
||||
std::option::Option::None
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn job_id(value: &'static str) -> std::option::Option<ksp_job_api::JobId> {
|
||||
let result = ksp_job_api::JobId::new(value);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
||||
std::result::Result::Err(error) => {
|
||||
assert_eq!(error.code().domain(), "job_api");
|
||||
std::option::Option::None
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn explicit_scope() -> std::option::Option<ksp_job_backfill_lib::BackfillScope> {
|
||||
let signature = match signature() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let result = ksp_job_backfill_lib::BackfillScope::explicit_signatures(vec![signature]);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
||||
std::result::Result::Err(error) => {
|
||||
assert_eq!(error.code(), ksp_job_backfill_lib::ERROR_CODE_BACKFILL_REQUEST_INVALID);
|
||||
std::option::Option::None
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn request(
|
||||
id: &'static str,
|
||||
network_name: &'static str,
|
||||
role_name: &'static str,
|
||||
scope: ksp_job_backfill_lib::BackfillScope,
|
||||
) -> std::option::Option<ksp_job_backfill_lib::BackfillRequest> {
|
||||
let id = match job_id(id) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let network = match network(network_name) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let result = ksp_job_backfill_lib::BackfillRequest::new(
|
||||
id,
|
||||
network,
|
||||
ksp_onchain_transport_lib::HttpRoleName::new(role_name),
|
||||
ksp_job_backfill_lib::BackfillCommitment::Confirmed,
|
||||
scope,
|
||||
100,
|
||||
10,
|
||||
500,
|
||||
8,
|
||||
std::option::Option::None,
|
||||
);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::option::Option::Some(value),
|
||||
std::result::Result::Err(error) => {
|
||||
assert_eq!(error.code(), ksp_job_backfill_lib::ERROR_CODE_BACKFILL_REQUEST_INVALID);
|
||||
std::option::Option::None
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_external_error_codes_are_stable_unique_and_domain_scoped() {
|
||||
let codes = [
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_CHECKPOINT_INVALID, "checkpoint_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_DISCOVERY_INVALID, "discovery_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_DISCOVERY_STALLED, "discovery_stalled"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_EXECUTION_INVALID, "execution_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_PERSISTENCE_INVALID, "persistence_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_RAW_CONVERSION_INVALID, "raw_conversion_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_REQUEST_INVALID, "request_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_RUNTIME_INVALID, "runtime_invalid"),
|
||||
(ksp_job_backfill_lib::ERROR_CODE_BACKFILL_SIGNATURE_INVALID, "signature_invalid"),
|
||||
];
|
||||
for (index, (code, expected)) in codes.iter().enumerate() {
|
||||
assert_eq!(code.domain(), "job_backfill");
|
||||
assert_eq!(code.code(), *expected);
|
||||
for (other_index, (other, _)) in codes.iter().enumerate() {
|
||||
if index != other_index {
|
||||
assert_ne!(code, other);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_external_request_adversarial_bounds_return_stable_codes() {
|
||||
let invalid_signature = ksp_job_backfill_lib::BackfillSignature::new("0".repeat(ksp_job_backfill_lib::MIN_BACKFILL_SIGNATURE_TEXT_BYTES));
|
||||
let error = match invalid_signature {
|
||||
std::result::Result::Ok(_) => return,
|
||||
std::result::Result::Err(error) => error,
|
||||
};
|
||||
assert_eq!(error.code(), ksp_job_backfill_lib::ERROR_CODE_BACKFILL_SIGNATURE_INVALID);
|
||||
let id = match job_id("backfill:hardening:bounds") {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let network = match network("devnet") {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let scope = match explicit_scope() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let result = ksp_job_backfill_lib::BackfillRequest::new(
|
||||
id,
|
||||
network,
|
||||
ksp_onchain_transport_lib::HttpRoleName::new("history"),
|
||||
ksp_job_backfill_lib::BackfillCommitment::Finalized,
|
||||
scope,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
std::option::Option::None,
|
||||
);
|
||||
let error = match result {
|
||||
std::result::Result::Ok(_) => return,
|
||||
std::result::Result::Err(error) => error,
|
||||
};
|
||||
assert_eq!(error.code(), ksp_job_backfill_lib::ERROR_CODE_BACKFILL_REQUEST_INVALID);
|
||||
assert!(error.context().iter().any(|context| return context.key() == "field" && context.value() == "page_size"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_scope_fingerprint_is_network_sensitive_and_transport_source_independent() {
|
||||
let scope = match explicit_scope() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let first = match request("backfill:hardening:fingerprint:a", "devnet", "history-primary", scope.clone()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let second = match request("backfill:hardening:fingerprint:b", "devnet", "history-secondary", scope.clone()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let other_network = match request("backfill:hardening:fingerprint:c", "mainnet", "history-primary", scope) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
assert_eq!(first.scope_fingerprint(), second.scope_fingerprint());
|
||||
assert_ne!(first.scope_fingerprint(), other_network.scope_fingerprint());
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_debug_surfaces_redact_signature_fingerprint_and_runtime_snapshot_payloads() {
|
||||
let raw_signature = signature_text();
|
||||
let scope = match explicit_scope() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let backfill_request = match request("backfill:hardening:debug", "devnet", "history", scope) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let request_debug = format!("{backfill_request:?}");
|
||||
assert!(!request_debug.contains(raw_signature.as_str()));
|
||||
assert!(request_debug.contains("BackfillScopeFingerprint(..)"));
|
||||
assert!(request_debug.contains("signature_count"));
|
||||
let fingerprint_debug = format!("{:?}", backfill_request.scope_fingerprint());
|
||||
assert_eq!(fingerprint_debug, "BackfillScopeFingerprint(..)");
|
||||
let runtime = ksp_job_backfill_lib::BackfillJobRuntime::new(backfill_request);
|
||||
let runtime = match runtime {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let handle_debug = format!("{:?}", runtime.handle());
|
||||
assert!(!handle_debug.contains(raw_signature.as_str()));
|
||||
assert!(handle_debug.contains("snapshot"));
|
||||
assert!(handle_debug.contains("<redacted>"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_external_runtime_handle_starts_created_and_cancellation_is_idempotent() {
|
||||
let scope = match explicit_scope() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let backfill_request = match request("backfill:hardening:control", "devnet", "history", scope) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let runtime = ksp_job_backfill_lib::BackfillJobRuntime::new(backfill_request);
|
||||
let runtime = match runtime {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let handle = runtime.handle();
|
||||
let source = handle.snapshots();
|
||||
let current = <ksp_job_backfill_lib::BackfillSnapshotSource as ksp_job_api::JobSnapshotSource>::current(&source);
|
||||
assert_eq!(current.state(), ksp_job_api::JobState::Created);
|
||||
assert_eq!(current.snapshot().phase(), ksp_job_backfill_lib::BackfillJobPhase::Created);
|
||||
assert!(!handle.is_cancellation_requested());
|
||||
assert!(handle.cancel());
|
||||
assert!(handle.is_cancellation_requested());
|
||||
assert!(!handle.cancel());
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_manifest_dependency_surface_is_exact_and_backend_neutral() {
|
||||
let manifest = include_str!("../Cargo.toml");
|
||||
let mut section = "";
|
||||
let mut normal = std::collections::BTreeSet::new();
|
||||
let mut dev = std::collections::BTreeSet::new();
|
||||
for line in manifest.lines() {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.starts_with('[') && trimmed.ends_with(']') {
|
||||
section = trimmed;
|
||||
continue;
|
||||
}
|
||||
if trimmed.is_empty() || trimmed.starts_with('#') {
|
||||
continue;
|
||||
}
|
||||
let name = match trimmed.split_once('=') {
|
||||
std::option::Option::Some((name, _)) => name.trim(),
|
||||
std::option::Option::None => continue,
|
||||
};
|
||||
if section == "[dependencies]" {
|
||||
normal.insert(name);
|
||||
} else if section == "[dev-dependencies]" {
|
||||
dev.insert(name);
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
normal,
|
||||
std::collections::BTreeSet::from([
|
||||
"futures-util",
|
||||
"ksp-core-lib",
|
||||
"ksp-job-api",
|
||||
"ksp-logging-lib",
|
||||
"ksp-onchain-transport-lib",
|
||||
"ksp-store-lib",
|
||||
"serde_json.workspace",
|
||||
"sha2.workspace",
|
||||
"tokio",
|
||||
])
|
||||
);
|
||||
assert_eq!(dev, std::collections::BTreeSet::from(["tokio"]));
|
||||
assert!(manifest.contains("ksp-store-lib = { path = \"../ksp-store-lib\", default-features = false }"));
|
||||
assert!(manifest.contains("tokio = { workspace = true, features = [\"macros\", \"sync\"] }"));
|
||||
assert!(!manifest.contains("ksp-store-postgres-lib"));
|
||||
assert!(!manifest.contains("ksp-store-api"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_source_visibility_contract_uses_crate_root_for_shared_items() {
|
||||
let root = include_str!("../src/lib.rs");
|
||||
assert!(!root.contains("BackfillRuntimeControl"));
|
||||
assert!(!root.contains("TerminalClaim"));
|
||||
let source_contracts: [(&str, &[&str]); 3] = [
|
||||
(include_str!("../src/checkpoint.rs"), &["BackfillCheckpoint", "CompletionFrontier"]),
|
||||
(
|
||||
include_str!("../src/request.rs"),
|
||||
&["BackfillCommitment", "BackfillSignature", "BackfillScopeKind", "BackfillScope", "BackfillScopeFingerprint", "BackfillRequest"],
|
||||
),
|
||||
(include_str!("../src/runtime.rs"), &["BackfillJobPhase", "BackfillJobSnapshot", "BackfillJobHandle", "BackfillJobRuntime"]),
|
||||
];
|
||||
for (source, symbols) in source_contracts {
|
||||
for symbol in symbols {
|
||||
let required = format!("impl crate::{symbol}");
|
||||
assert!(source.contains(required.as_str()), "shared item must use crate-root impl path: {symbol}");
|
||||
let forbidden = format!("impl {symbol}");
|
||||
assert!(!source.contains(forbidden.as_str()), "shared item must not use bare impl path: {symbol}");
|
||||
}
|
||||
}
|
||||
let request = include_str!("../src/request.rs");
|
||||
assert!(request.contains("crate::BackfillScopeFingerprint::from_bytes(bytes)"));
|
||||
assert!(!request.contains("crate::BackfillScopeFingerprint(bytes)"));
|
||||
assert!(!request.contains("return BackfillScopeFingerprint(bytes)"));
|
||||
for (module, source) in [
|
||||
("checkpoint", include_str!("../src/checkpoint.rs")),
|
||||
("conversion", include_str!("../src/conversion.rs")),
|
||||
("discovery", include_str!("../src/discovery.rs")),
|
||||
("execution", include_str!("../src/execution.rs")),
|
||||
("persistence", include_str!("../src/persistence.rs")),
|
||||
("request", include_str!("../src/request.rs")),
|
||||
("runtime", include_str!("../src/runtime.rs")),
|
||||
] {
|
||||
let forbidden = format!("crate::{module}::");
|
||||
assert!(!source.contains(forbidden.as_str()), "internal module path bypasses crate-root façade: {forbidden}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_lower_layers_have_no_dependency_return_to_job() {
|
||||
for manifest in [
|
||||
include_str!("../../ksp-core-lib/Cargo.toml"),
|
||||
include_str!("../../ksp-logging-lib/Cargo.toml"),
|
||||
include_str!("../../ksp-onchain-transport-lib/Cargo.toml"),
|
||||
include_str!("../../ksp-store-api/Cargo.toml"),
|
||||
include_str!("../../ksp-store-lib/Cargo.toml"),
|
||||
include_str!("../../ksp-store-postgres-lib/Cargo.toml"),
|
||||
] {
|
||||
assert!(!manifest.contains("ksp-job-api"));
|
||||
assert!(!manifest.contains("ksp-job-backfill-lib"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_public_root_exposes_no_runtime_or_backend_implementation_types() {
|
||||
let root = include_str!("../src/lib.rs");
|
||||
for forbidden in
|
||||
["pub mod ", "tokio::", "FuturesUnordered", "serde_json::", "sha2::", "ksp_store_api::", "ksp_store_postgres_lib::", "reqwest::", "tonic::"]
|
||||
{
|
||||
assert!(!root.contains(forbidden), "implementation/backend detail leaked into public root: {forbidden}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
// file: crates/ksp-job-backfill-lib/tests/release_completeness.rs
|
||||
// version: 7
|
||||
// version: 9
|
||||
|
||||
//! Completeness canaries through the `pre.009` concrete cancellation and latest-value runtime tranche.
|
||||
//! Completeness canaries through the `pre.010` hardening and external-canary tranche.
|
||||
|
||||
#[test]
|
||||
fn pre_009_production_module_inventory_is_exact() -> std::io::Result<()> {
|
||||
fn pre_010_production_module_inventory_is_exact() -> std::io::Result<()> {
|
||||
let source_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
|
||||
let entries = match std::fs::read_dir(source_root) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -51,7 +51,7 @@ fn pre_009_production_module_inventory_is_exact() -> std::io::Result<()> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_009_surface_closes_concrete_cancellation_and_latest_value_runtime() {
|
||||
fn pre_010_surface_closes_concrete_cancellation_and_latest_value_runtime() {
|
||||
let root = include_str!("../src/lib.rs");
|
||||
for required in [
|
||||
"BackfillCandidate",
|
||||
@@ -84,7 +84,7 @@ fn pre_009_surface_closes_concrete_cancellation_and_latest_value_runtime() {
|
||||
"BACKFILL_JOB_KIND_CODE",
|
||||
"ERROR_CODE_BACKFILL_RUNTIME_INVALID",
|
||||
] {
|
||||
assert!(root.contains(required), "required pre.009 public contract missing: {required}");
|
||||
assert!(root.contains(required), "required pre.010 public contract missing: {required}");
|
||||
}
|
||||
for forbidden in ["tokio::", "FuturesUnordered", "watch::Receiver", "watch::Sender"] {
|
||||
assert!(!root.contains(forbidden), "runtime implementation detail leaked into public root: {forbidden}");
|
||||
@@ -92,3 +92,22 @@ fn pre_009_surface_closes_concrete_cancellation_and_latest_value_runtime() {
|
||||
assert!(!root.contains("pub mod "));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_external_hardening_suite_is_present_and_scoped() {
|
||||
let hardening = include_str!("hardening.rs");
|
||||
for required in [
|
||||
"pre_010_external_error_codes_are_stable_unique_and_domain_scoped",
|
||||
"pre_010_external_request_adversarial_bounds_return_stable_codes",
|
||||
"pre_010_scope_fingerprint_is_network_sensitive_and_transport_source_independent",
|
||||
"pre_010_debug_surfaces_redact_signature_fingerprint_and_runtime_snapshot_payloads",
|
||||
"pre_010_external_runtime_handle_starts_created_and_cancellation_is_idempotent",
|
||||
"pre_010_manifest_dependency_surface_is_exact_and_backend_neutral",
|
||||
"pre_010_source_visibility_contract_uses_crate_root_for_shared_items",
|
||||
"pre_010_lower_layers_have_no_dependency_return_to_job",
|
||||
"pre_010_public_root_exposes_no_runtime_or_backend_implementation_types",
|
||||
] {
|
||||
assert!(hardening.contains(required), "required pre.010 hardening canary missing: {required}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user