Files
khadhroony-solana-project/crates/ksp-onchain-transport-lib/tests/release_completeness.rs
2026-08-18 09:48:11 +02:00

197 lines
9.0 KiB
Rust

// file: crates/ksp-onchain-transport-lib/tests/release_completeness.rs
// version: 6
//! Release-level completeness canaries for the `0.2.1` HTTP foundation contract.
#[test]
fn release_registry_partition_matches_the_audited_http_plan() {
let mut foundation = 0_usize;
let mut accounts_tokens_cluster = 0_usize;
let mut transactions = 0_usize;
let mut blocks_economics = 0_usize;
let mut historical_in_current = 0_usize;
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
match descriptor.coverage_release() {
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_1 => foundation += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2 => accounts_tokens_cluster += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_3 => transactions += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_4 => blocks_economics += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::Historical => historical_in_current += 1,
}
}
assert_eq!(ksp_onchain_transport_lib::current_http_rpc_methods().len(), 52);
assert_eq!(ksp_onchain_transport_lib::historical_http_rpc_methods().len(), 14);
assert_eq!(foundation, 4);
assert_eq!(accounts_tokens_cluster, 22);
assert_eq!(transactions, 11);
assert_eq!(blocks_economics, 15);
assert_eq!(historical_in_current, 0);
}
#[test]
fn release_foundation_canaries_and_historical_statuses_are_exact() {
let mut foundation_names = std::vec::Vec::<&str>::new();
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
if descriptor.coverage_release() == ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_1 {
foundation_names.push(descriptor.method());
assert_eq!(descriptor.runtime_status(), ksp_onchain_transport_lib::RpcRuntimeStatus::Supported);
}
}
foundation_names.sort_unstable();
assert_eq!(foundation_names, std::vec!["getBalance", "getGenesisHash", "getHealth", "getVersion"]);
for descriptor in ksp_onchain_transport_lib::historical_http_rpc_methods() {
assert_eq!(descriptor.documentation_status(), ksp_onchain_transport_lib::RpcDocumentationStatus::Deprecated);
assert_eq!(descriptor.runtime_status(), ksp_onchain_transport_lib::RpcRuntimeStatus::Removed);
assert_eq!(descriptor.coverage_release(), ksp_onchain_transport_lib::HttpRpcCoverageRelease::Historical);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::NotApplicable);
}
}
#[test]
fn release_pre_003_accounts_subset_is_exact_without_advancing_other_v0_2_2_families() {
let mut account_names = std::vec::Vec::<&str>::new();
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
if descriptor.coverage_release() == ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2
&& descriptor.category() == ksp_onchain_transport_lib::HttpRpcCategory::Accounts
{
account_names.push(descriptor.method());
assert_eq!(descriptor.operation_kind(), ksp_onchain_transport_lib::RpcOperationKind::Read);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
}
}
account_names.sort_unstable();
assert_eq!(
account_names,
std::vec!["getAccountInfo", "getLargestAccounts", "getMinimumBalanceForRentExemption", "getMultipleAccounts", "getProgramAccounts",],
);
}
#[test]
fn release_pre_004_tokens_subset_is_exact_and_retry_safe() {
let mut token_names = std::vec::Vec::<&str>::new();
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
if descriptor.coverage_release() == ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2
&& descriptor.category() == ksp_onchain_transport_lib::HttpRpcCategory::Tokens
{
token_names.push(descriptor.method());
assert_eq!(descriptor.operation_kind(), ksp_onchain_transport_lib::RpcOperationKind::Read);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
}
}
token_names.sort_unstable();
assert_eq!(
token_names,
std::vec!["getTokenAccountBalance", "getTokenAccountsByDelegate", "getTokenAccountsByOwner", "getTokenLargestAccounts", "getTokenSupply",],
);
}
#[test]
fn release_pre_005_simple_cluster_subset_is_exact_and_retry_safe() {
let expected = std::vec![
"getClusterNodes",
"getEpochInfo",
"getEpochSchedule",
"getHighestSnapshotSlot",
"getIdentity",
"getMaxRetransmitSlot",
"getMaxShredInsertSlot",
];
let deferred = std::vec!["getLeaderSchedule", "getSlot", "getSlotLeader", "getSlotLeaders", "getVoteAccounts"];
for method_name in &expected {
let descriptor = ksp_onchain_transport_lib::find_http_rpc_method(method_name).expect("pre.005 cluster descriptor must exist");
assert_eq!(descriptor.category(), ksp_onchain_transport_lib::HttpRpcCategory::Cluster);
assert_eq!(descriptor.coverage_release(), ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2);
assert_eq!(descriptor.operation_kind(), ksp_onchain_transport_lib::RpcOperationKind::Read);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
}
for method_name in &deferred {
let descriptor = ksp_onchain_transport_lib::find_http_rpc_method(method_name).expect("pre.006 cluster descriptor must remain registered");
assert_eq!(descriptor.coverage_release(), ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2);
}
assert_eq!(expected.len(), 7);
assert_eq!(deferred.len(), 5);
}
#[test]
fn release_pre_006_completes_cluster_subset_exactly_and_retry_safe() {
let mut expected = std::vec![
"getClusterNodes",
"getEpochInfo",
"getEpochSchedule",
"getHighestSnapshotSlot",
"getIdentity",
"getLeaderSchedule",
"getMaxRetransmitSlot",
"getMaxShredInsertSlot",
"getSlot",
"getSlotLeader",
"getSlotLeaders",
"getVoteAccounts",
];
let mut actual = std::vec::Vec::new();
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
if descriptor.coverage_release() == ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2
&& descriptor.category() == ksp_onchain_transport_lib::HttpRpcCategory::Cluster
{
actual.push(descriptor.method());
assert_eq!(descriptor.operation_kind(), ksp_onchain_transport_lib::RpcOperationKind::Read);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
}
}
actual.sort_unstable();
expected.sort_unstable();
assert_eq!(actual, expected);
assert_eq!(actual.len(), 12);
}
#[test]
fn release_pre_007_v0_2_2_exact_set_is_complete_without_advancing_future_releases() {
let mut expected = std::vec![
"getAccountInfo",
"getClusterNodes",
"getEpochInfo",
"getEpochSchedule",
"getHighestSnapshotSlot",
"getIdentity",
"getLargestAccounts",
"getLeaderSchedule",
"getMaxRetransmitSlot",
"getMaxShredInsertSlot",
"getMinimumBalanceForRentExemption",
"getMultipleAccounts",
"getProgramAccounts",
"getSlot",
"getSlotLeader",
"getSlotLeaders",
"getTokenAccountBalance",
"getTokenAccountsByDelegate",
"getTokenAccountsByOwner",
"getTokenLargestAccounts",
"getTokenSupply",
"getVoteAccounts",
];
let mut actual = std::vec::Vec::new();
let mut future_transactions = 0_usize;
let mut future_blocks_economics = 0_usize;
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
match descriptor.coverage_release() {
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2 => {
actual.push(descriptor.method());
assert_eq!(descriptor.documentation_status(), ksp_onchain_transport_lib::RpcDocumentationStatus::Stable);
assert_eq!(descriptor.runtime_status(), ksp_onchain_transport_lib::RpcRuntimeStatus::Supported);
assert_eq!(descriptor.operation_kind(), ksp_onchain_transport_lib::RpcOperationKind::Read);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
},
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_3 => future_transactions += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_4 => future_blocks_economics += 1,
_ => {},
}
}
actual.sort_unstable();
expected.sort_unstable();
assert_eq!(actual, expected);
assert_eq!(actual.len(), 22);
assert_eq!(future_transactions, 11);
assert_eq!(future_blocks_economics, 15);
}