128 lines
5.0 KiB
Rust
128 lines
5.0 KiB
Rust
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime.rs
|
|
// version: 1
|
|
|
|
fn settings(network: &str) -> std::option::Option<crate::RawTransactionIngestSettings> {
|
|
let network = match ksp_store_lib::RawNetworkId::new(network) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
let worker_id = match ksp_worker_api::WorkerId::new("raw-ingest-runtime-001") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return std::option::Option::None,
|
|
};
|
|
return std::option::Option::Some(crate::RawTransactionIngestSettings::with_defaults(network, worker_id));
|
|
}
|
|
|
|
#[test]
|
|
fn pre_004_current_runtime_is_required_before_spawn() {
|
|
let result = super::current_runtime_handle();
|
|
assert!(result.is_err());
|
|
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_RUNTIME_INVALID);
|
|
assert_eq!(error.context().len(), 1);
|
|
assert_eq!(error.context()[0].value(), "start.runtime_unavailable");
|
|
return;
|
|
}
|
|
|
|
#[test]
|
|
fn pre_004_store_network_mismatch_is_rejected_without_echoing_network_values() {
|
|
let settings = match settings("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let other = match ksp_store_lib::RawNetworkId::new("devnet") {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let result = super::validate_store_network(&settings, &other);
|
|
assert!(result.is_err());
|
|
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_RUNTIME_INVALID);
|
|
let rendered = std::format!("{error:?}");
|
|
assert!(!rendered.contains("mainnet"));
|
|
assert!(!rendered.contains("devnet"));
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_004_immediate_stop_is_idempotent_and_reaches_stopped_terminal() {
|
|
let settings = match settings("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let handle = match super::start_foundation(settings, tokio::runtime::Handle::current(), std::option::Option::None) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
assert_eq!(*handle.terminal_receiver.borrow(), ksp_worker_api::WorkerState::Starting);
|
|
assert!(handle.request_stop());
|
|
assert!(!handle.request_stop());
|
|
let terminal = handle.wait_terminal().await;
|
|
assert!(terminal.is_ok());
|
|
let terminal = match terminal {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
assert_eq!(terminal, ksp_worker_api::WorkerState::Stopped);
|
|
assert!(terminal.is_terminal());
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_004_running_lifecycle_stops_through_cloned_handle() {
|
|
let settings = match settings("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let handle = match super::start_foundation(settings, tokio::runtime::Handle::current(), std::option::Option::None) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
tokio::task::yield_now().await;
|
|
assert_eq!(*handle.terminal_receiver.borrow(), ksp_worker_api::WorkerState::Running);
|
|
let clone = handle.clone();
|
|
assert!(clone.request_stop());
|
|
assert!(!handle.request_stop());
|
|
let terminal = handle.wait_terminal().await;
|
|
let terminal = match terminal {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
assert_eq!(terminal, ksp_worker_api::WorkerState::Stopped);
|
|
return;
|
|
}
|
|
|
|
#[tokio::test(flavor = "current_thread")]
|
|
async fn pre_004_dropping_last_control_handle_causes_private_runtime_exit() {
|
|
let settings = match settings("mainnet") {
|
|
std::option::Option::Some(value) => value,
|
|
std::option::Option::None => return,
|
|
};
|
|
let handle = match super::start_foundation(settings, tokio::runtime::Handle::current(), std::option::Option::None) {
|
|
std::result::Result::Ok(value) => value,
|
|
std::result::Result::Err(_) => return,
|
|
};
|
|
let mut observer = handle.terminal_receiver.clone();
|
|
std::mem::drop(handle);
|
|
loop {
|
|
let current = *observer.borrow();
|
|
if current.is_terminal() {
|
|
let closed = observer.changed().await;
|
|
assert!(closed.is_err());
|
|
assert_eq!(current, ksp_worker_api::WorkerState::Stopped);
|
|
return;
|
|
}
|
|
let changed = observer.changed().await;
|
|
assert!(changed.is_ok(), "runtime closed before publishing terminal state");
|
|
if changed.is_err() {
|
|
return;
|
|
}
|
|
}
|
|
}
|