v0.3.14-pre.011
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs
|
||||
// version: 7
|
||||
// version: 8
|
||||
|
||||
fn network() -> std::option::Option<ksp_store_lib::RawNetworkId> {
|
||||
return match ksp_store_lib::RawNetworkId::new("mainnet") {
|
||||
@@ -62,6 +62,7 @@ fn gap(
|
||||
reason: super::RawTransactionIngestGapReason::WebSocketReconnect,
|
||||
source_key: [source_key_byte; 32],
|
||||
state,
|
||||
last_method: std::option::Option::None,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -647,3 +648,80 @@ fn pre_009_health_projection_rejects_duplicate_and_unknown_active_sources() {
|
||||
assert!(unknown_failed.context().iter().any(|context| return context.value() == "continuity.health_failed_source_unknown"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_011_gap_observability_projects_open_and_recent_repaired_entries() {
|
||||
let first = match capability(1, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, exact_scope("standard_logs", 7)) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => panic!("first capability fixture unavailable"),
|
||||
};
|
||||
let second = match capability(2, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, exact_scope("standard_logs", 7)) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => panic!("second capability fixture unavailable"),
|
||||
};
|
||||
let mut contracts = match crate::RawTransactionIngestContinuityContracts::new(std::vec![first, second]) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("continuity contracts fixture failed: {error}"),
|
||||
};
|
||||
assert!(contracts.record_source_loss_gap([1_u8; 32], 100, 110).is_ok());
|
||||
let pending = match contracts.observability_projection() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("pending observability projection failed: {error}"),
|
||||
};
|
||||
assert_eq!(pending.open_gap_count(), 1);
|
||||
assert_eq!(pending.repairing_gap_count(), 0);
|
||||
assert_eq!(pending.repaired_gap_total(), 0);
|
||||
assert_eq!(pending.unresolved_gap_total(), 0);
|
||||
assert_eq!(pending.oldest_open_gap_start_slot(), std::option::Option::Some(100));
|
||||
assert_eq!(pending.gaps().len(), 1);
|
||||
assert_eq!(pending.gaps()[0].start_slot(), 100);
|
||||
assert_eq!(pending.gaps()[0].end_slot(), 110);
|
||||
assert_eq!(pending.gaps()[0].state(), crate::RawTransactionIngestGapState::Pending);
|
||||
assert_eq!(pending.gaps()[0].reason(), crate::RawTransactionIngestGapReason::SourceFailure);
|
||||
assert_eq!(pending.gaps()[0].last_method(), std::option::Option::None);
|
||||
assert!(contracts.record_coverage_epoch([2_u8; 32], 90, 120).is_ok());
|
||||
let repaired = match contracts.observability_projection() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("repaired observability projection failed: {error}"),
|
||||
};
|
||||
assert_eq!(repaired.open_gap_count(), 0);
|
||||
assert_eq!(repaired.repaired_gap_total(), 1);
|
||||
assert_eq!(repaired.redundant_coverage_repair_total(), 1);
|
||||
assert_eq!(repaired.replay_repair_total(), 0);
|
||||
assert_eq!(repaired.http_scan_repair_total(), 0);
|
||||
assert_eq!(repaired.repair_block_fetch_total(), 0);
|
||||
assert_eq!(repaired.repair_transaction_hydration_total(), 0);
|
||||
assert_eq!(repaired.oldest_open_gap_start_slot(), std::option::Option::None);
|
||||
assert_eq!(repaired.gaps().len(), 1);
|
||||
assert_eq!(repaired.gaps()[0].state(), crate::RawTransactionIngestGapState::Repaired);
|
||||
assert_eq!(repaired.gaps()[0].last_method(), std::option::Option::Some(crate::RawTransactionIngestRepairMethod::RedundantCoverage));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_011_unresolved_gap_remains_visible_and_bounded() {
|
||||
let capability = match capability(1, ksp_onchain_transport_lib::SolanaCommitment::Confirmed, exact_scope("standard_logs", 7)) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => panic!("capability fixture unavailable"),
|
||||
};
|
||||
let mut contracts = match crate::RawTransactionIngestContinuityContracts::new(std::vec![capability]) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("continuity contracts fixture failed: {error}"),
|
||||
};
|
||||
let unresolved = match gap(1, 1, 200, 205, super::RawTransactionIngestGapState::Unresolved) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => panic!("unresolved gap fixture unavailable"),
|
||||
};
|
||||
contracts.gap_ledger.gaps.push(unresolved);
|
||||
contracts.gap_ledger.next_gap_id = 2;
|
||||
let projection = match contracts.observability_projection() {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("unresolved observability projection failed: {error}"),
|
||||
};
|
||||
assert_eq!(projection.open_gap_count(), 1);
|
||||
assert_eq!(projection.unresolved_gap_total(), 1);
|
||||
assert_eq!(projection.oldest_open_gap_start_slot(), std::option::Option::Some(200));
|
||||
assert!(projection.gaps().len() <= super::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS);
|
||||
assert_eq!(projection.gaps()[0].state(), crate::RawTransactionIngestGapState::Unresolved);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user