147 lines
7.1 KiB
Rust
147 lines
7.1 KiB
Rust
// file: crates/ksp-job-backfill-lib/tests/dependency_boundary.rs
|
|
// version: 9
|
|
|
|
//! Dependency firewall canaries through the concrete cancellation and latest-value runtime tranche.
|
|
|
|
#[test]
|
|
fn pre_003_manifest_adds_common_raw_edge_without_crossing_store_or_runtime_boundaries() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
let production_manifest = match manifest.split_once("[dev-dependencies]") {
|
|
std::option::Option::Some((production, _)) => production,
|
|
std::option::Option::None => manifest,
|
|
};
|
|
for required in [
|
|
"futures-util = { workspace = true, features = [\"std\"] }",
|
|
"ksp-core-lib = { path = \"../ksp-core-lib\" }",
|
|
"ksp-job-api = { path = \"../ksp-job-api\" }",
|
|
"ksp-logging-lib = { path = \"../ksp-logging-lib\" }",
|
|
"ksp-onchain-transport-lib = { path = \"../ksp-onchain-transport-lib\" }",
|
|
"ksp-raw-transaction-lib = { path = \"../ksp-raw-transaction-lib\" }",
|
|
"ksp-store-lib = { path = \"../ksp-store-lib\", default-features = false }",
|
|
"serde_json.workspace = true",
|
|
"sha2.workspace = true",
|
|
"tokio = { workspace = true, features = [\"macros\", \"sync\"] }",
|
|
] {
|
|
assert!(production_manifest.contains(required), "required Backfill dependency missing: {required}");
|
|
}
|
|
for forbidden in [
|
|
"ksp-config-lib",
|
|
"ksp-interface-lib",
|
|
"ksp-program-api",
|
|
"ksp-store-api",
|
|
"ksp-store-postgres-lib",
|
|
"ksp-wallet-lib",
|
|
"solana-",
|
|
"reqwest",
|
|
"serde.workspace = true",
|
|
"serde = {",
|
|
"tonic",
|
|
] {
|
|
assert!(!production_manifest.contains(forbidden), "forbidden Backfill dependency present: {forbidden}");
|
|
}
|
|
let root = include_str!("../src/lib.rs");
|
|
assert!(!root.contains("tokio::"), "Tokio implementation types must not leak through the public crate root");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_005_websocket_parity_dependency_stays_test_only() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
let parts = manifest.splitn(2, "[dev-dependencies]").collect::<std::vec::Vec<_>>();
|
|
let (dependencies, dev_dependencies) = match parts.as_slice() {
|
|
[dependencies, dev_dependencies] => (*dependencies, *dev_dependencies),
|
|
_ => {
|
|
assert_eq!(parts.len(), 2, "Backfill manifest must retain exactly one dev-dependencies section");
|
|
return;
|
|
},
|
|
};
|
|
assert!(!dependencies.contains("tokio-tungstenite"), "WebSocket parity client must not become a production Backfill dependency");
|
|
assert!(
|
|
dev_dependencies.contains("tokio-tungstenite = { workspace = true, features = [\"handshake\"] }"),
|
|
"WebSocket parity client must remain an explicit test-only dependency",
|
|
);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_006_yellowstone_parity_dependencies_stay_test_only() {
|
|
let manifest = include_str!("../Cargo.toml");
|
|
let parts = manifest.splitn(2, "[dev-dependencies]").collect::<std::vec::Vec<_>>();
|
|
let (dependencies, dev_dependencies) = match parts.as_slice() {
|
|
[dependencies, dev_dependencies] => (*dependencies, *dev_dependencies),
|
|
_ => {
|
|
assert_eq!(parts.len(), 2, "Backfill manifest must retain exactly one dev-dependencies section");
|
|
return;
|
|
},
|
|
};
|
|
assert!(!dependencies.contains("tonic"), "Yellowstone parity server must not become a production Backfill dependency");
|
|
assert!(!dependencies.contains("yellowstone-grpc-proto"), "Yellowstone protobuf must not become a production Backfill dependency");
|
|
assert!(
|
|
dev_dependencies.contains("tonic = { workspace = true, features = [\"codegen\", \"server\"] }"),
|
|
"Yellowstone parity server must remain an explicit test-only dependency",
|
|
);
|
|
assert!(
|
|
dev_dependencies.contains("yellowstone-grpc-proto = { workspace = true, features = [\"tonic\"] }"),
|
|
"Yellowstone protobuf must remain an explicit test-only dependency",
|
|
);
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_009_production_sources_keep_transport_store_and_scheduler_ownership_separate() {
|
|
let neutral_sources = [
|
|
include_str!("../src/checkpoint.rs"),
|
|
include_str!("../src/constants.rs"),
|
|
include_str!("../src/discovery.rs"),
|
|
include_str!("../src/error.rs"),
|
|
include_str!("../src/lib.rs"),
|
|
include_str!("../src/request.rs"),
|
|
include_str!("../src/runtime.rs"),
|
|
];
|
|
for source in neutral_sources {
|
|
for forbidden in ["ksp_config_lib::", "ksp_interface_lib::", "ksp_store_api::", "ksp_store_postgres_lib::", "reqwest::", "std::env", "tonic::"] {
|
|
assert!(!source.contains(forbidden), "forbidden concrete Backfill path detected: {forbidden}");
|
|
}
|
|
}
|
|
let conversion = include_str!("../src/conversion.rs");
|
|
assert!(conversion.contains("ksp_raw_transaction_lib::canonicalize_raw_transaction"));
|
|
assert!(conversion.contains("ksp_raw_transaction_lib::assemble_raw_transaction_acquisition"));
|
|
assert!(conversion.contains("ksp_raw_transaction_lib::parse_raw_transaction_signature"));
|
|
assert!(!conversion.contains("fn append_canonical_json"));
|
|
assert!(!conversion.contains("fn base58_digit"));
|
|
assert!(!conversion.contains("RawPayload::try_new"));
|
|
assert!(conversion.contains("get_transaction_observed"));
|
|
assert!(conversion.contains("SolanaTransactionEncoding::Base64"));
|
|
assert!(conversion.contains("std::option::Option::Some(0)"));
|
|
assert!(conversion.contains("BackfillHydrationOutcome::Missing(reference)"));
|
|
assert!(!conversion.contains("execute_standard_rpc"));
|
|
assert!(!conversion.contains("persist_raw_transaction_acquisition"));
|
|
let persistence = include_str!("../src/persistence.rs");
|
|
assert!(persistence.contains("persist_raw_transaction_acquisition"));
|
|
assert!(persistence.contains("RawTransactionAcquisitionMode::Normal"));
|
|
assert!(persistence.contains("ERROR_CODE_RAW_CONFLICT"));
|
|
assert!(!persistence.contains("record_raw_transaction_observation"));
|
|
assert!(!persistence.contains("RawTransactionAcquisitionMode::ForceRehydrate"));
|
|
let discovery = include_str!("../src/discovery.rs");
|
|
assert!(discovery.contains("get_signatures_for_address"));
|
|
assert!(!discovery.contains("execute_standard_rpc"));
|
|
assert!(!discovery.contains("retry"));
|
|
assert!(!discovery.contains("endpoint_name"));
|
|
let execution = include_str!("../src/execution.rs");
|
|
assert!(execution.contains("FuturesUnordered"));
|
|
assert!(execution.contains("hydrate_backfill_candidate"));
|
|
assert!(execution.contains("persist_backfill_hydration"));
|
|
assert!(execution.contains("request.hydration_concurrency()"));
|
|
for forbidden in ["tokio::spawn", "tokio::time", "retry", "endpoint_name", "provider()", "ForceRehydrate", "get_raw_transaction"] {
|
|
assert!(!execution.contains(forbidden), "forbidden scheduler/policy ownership detected: {forbidden}");
|
|
}
|
|
let runtime = include_str!("../src/runtime.rs");
|
|
assert!(runtime.contains("tokio::sync::watch"));
|
|
assert!(runtime.contains("JobSnapshotSource"));
|
|
assert!(runtime.contains("JobCancellationToken"));
|
|
assert!(!runtime.contains("tokio::spawn"));
|
|
assert!(!runtime.contains("tokio::time"));
|
|
assert!(!runtime.contains("reqwest::"));
|
|
return;
|
|
}
|