v0.3.14-pre.012
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
||||
// version: 33
|
||||
// version: 34
|
||||
|
||||
fn grpc_endpoint(cluster: &str) -> std::option::Option<ksp_onchain_transport_lib::YellowstoneGrpcEndpointSettings> {
|
||||
return grpc_endpoint_with_identity(cluster, "yellowstone-fixture", "fixture-provider");
|
||||
@@ -1155,6 +1155,7 @@ async fn v0_3_13_pre_007_source_supervisor_joins_all_children_on_stop() {
|
||||
contracts,
|
||||
inventory,
|
||||
tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty()).0,
|
||||
std::time::Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
@@ -1223,6 +1224,7 @@ async fn v0_3_13_pre_007_source_failure_stops_and_joins_sibling_sources() {
|
||||
contracts,
|
||||
inventory,
|
||||
tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty()).0,
|
||||
std::time::Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
assert!(result.is_err());
|
||||
@@ -3838,6 +3840,7 @@ async fn v0_3_13_pre_011_aborting_outer_source_supervisor_aborts_nested_source_t
|
||||
contracts,
|
||||
inventory,
|
||||
tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty()).0,
|
||||
std::time::Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
@@ -3905,6 +3908,7 @@ async fn v0_3_13_pre_011_stop_racing_ready_source_fault_preserves_fault_and_join
|
||||
contracts,
|
||||
inventory,
|
||||
tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty()).0,
|
||||
std::time::Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
@@ -3930,6 +3934,110 @@ async fn v0_3_13_pre_011_stop_racing_ready_source_fault_preserves_fault_and_join
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_012_source_fault_preserves_first_fault_and_aborts_non_cooperative_sibling() {
|
||||
let active = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0));
|
||||
let barrier = std::sync::Arc::new(tokio::sync::Barrier::new(2));
|
||||
let (_stop_sender, stop_receiver) = tokio::sync::watch::channel(false);
|
||||
let (source_stop_sender, _source_stop_receiver) = tokio::sync::watch::channel(false);
|
||||
let contracts = match supervisor_contracts(&[(1, "fixture-a", 1), (2, "fixture-b", 2)]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let inventory = match supervisor_inventory(
|
||||
std::vec![[1_u8; 32], [2_u8; 32]],
|
||||
&[
|
||||
std::option::Option::Some(crate::RawTransactionIngestSourceState::Failed),
|
||||
std::option::Option::Some(crate::RawTransactionIngestSourceState::Active),
|
||||
],
|
||||
) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let mut children = tokio::task::JoinSet::new();
|
||||
let failing_barrier = std::sync::Arc::clone(&barrier);
|
||||
let _failing_abort_handle = children.spawn(async move {
|
||||
let _barrier_wait = failing_barrier.wait().await;
|
||||
return ([1_u8; 32], std::result::Result::Err(crate::runtime_error("test.pre_012_source_fault")));
|
||||
});
|
||||
let sibling_barrier = std::sync::Arc::clone(&barrier);
|
||||
let sibling_active = std::sync::Arc::clone(&active);
|
||||
let _sibling_abort_handle = children.spawn(async move {
|
||||
let _guard = Pre011SourceActiveGuard::new(sibling_active);
|
||||
let _barrier_wait = sibling_barrier.wait().await;
|
||||
return std::future::pending::<([u8; 32], ksp_core_lib::Result<()>)>().await;
|
||||
});
|
||||
let result = super::supervise_live_source_tasks(
|
||||
stop_receiver,
|
||||
source_stop_sender,
|
||||
children,
|
||||
contracts,
|
||||
inventory,
|
||||
tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty()).0,
|
||||
std::time::Duration::from_millis(5),
|
||||
)
|
||||
.await;
|
||||
let error = match result {
|
||||
std::result::Result::Ok(()) => return,
|
||||
std::result::Result::Err(value) => value,
|
||||
};
|
||||
assert_eq!(error.context()[0].value(), "test.pre_012_source_fault");
|
||||
assert_eq!(active.load(std::sync::atomic::Ordering::Acquire), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_012_stop_aborts_non_cooperative_source_after_bounded_drain() {
|
||||
let active = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0));
|
||||
let (stop_sender, stop_receiver) = tokio::sync::watch::channel(false);
|
||||
let (source_stop_sender, _source_stop_receiver) = tokio::sync::watch::channel(false);
|
||||
let contracts = match supervisor_contracts(&[(1, "fixture-a", 1)]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let inventory = match supervisor_inventory(std::vec![[1_u8; 32]], &[std::option::Option::Some(crate::RawTransactionIngestSourceState::Active)]) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let mut children = tokio::task::JoinSet::new();
|
||||
let source_active = std::sync::Arc::clone(&active);
|
||||
let _abort_handle = children.spawn(async move {
|
||||
let _guard = Pre011SourceActiveGuard::new(source_active);
|
||||
return std::future::pending::<([u8; 32], ksp_core_lib::Result<()>)>().await;
|
||||
});
|
||||
let supervisor = tokio::spawn(async move {
|
||||
return super::supervise_live_source_tasks(
|
||||
stop_receiver,
|
||||
source_stop_sender,
|
||||
children,
|
||||
contracts,
|
||||
inventory,
|
||||
tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty()).0,
|
||||
std::time::Duration::from_millis(5),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
for _ in 0..64 {
|
||||
if active.load(std::sync::atomic::Ordering::Acquire) == 1 {
|
||||
break;
|
||||
}
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
assert_eq!(active.load(std::sync::atomic::Ordering::Acquire), 1);
|
||||
stop_sender.send_replace(true);
|
||||
let result = match supervisor.await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let error = match result {
|
||||
std::result::Result::Ok(()) => return,
|
||||
std::result::Result::Err(value) => value,
|
||||
};
|
||||
assert_eq!(error.code(), crate::ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT);
|
||||
assert_eq!(active.load(std::sync::atomic::Ordering::Acquire), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "current_thread")]
|
||||
async fn v0_3_14_pre_008_proven_full_ledger_epoch_survives_filtered_peer_loss_without_worker_respawn() {
|
||||
let sibling_active = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
|
||||
@@ -3974,7 +4082,16 @@ async fn v0_3_14_pre_008_proven_full_ledger_epoch_survives_filtered_peer_loss_wi
|
||||
});
|
||||
let (health_sender, health_receiver) = tokio::sync::watch::channel(crate::RawTransactionIngestProcessingFrontierProjection::empty());
|
||||
let supervisor = tokio::spawn(async move {
|
||||
return super::supervise_live_source_tasks(stop_receiver, source_stop_sender, children, contracts, inventory, health_sender).await;
|
||||
return super::supervise_live_source_tasks(
|
||||
stop_receiver,
|
||||
source_stop_sender,
|
||||
children,
|
||||
contracts,
|
||||
inventory,
|
||||
health_sender,
|
||||
std::time::Duration::from_secs(5),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
for _ in 0..64 {
|
||||
if sibling_active.load(std::sync::atomic::Ordering::Acquire) && health_receiver.borrow().failed_source_losses_reconciled() {
|
||||
|
||||
Reference in New Issue
Block a user