v0.2.7-pre.002-fix.001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/tests/desktop_contract.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
//! Desktop build/shell contract audits for Config Desk.
|
||||
|
||||
@@ -26,6 +26,43 @@ fn read_json(path: &std::path::Path) -> serde_json::Value {
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_semver_core(value: &str) -> std::option::Option<(u64, u64, u64)> {
|
||||
let core = match value.split_once('-') {
|
||||
std::option::Option::Some((core, _)) => core,
|
||||
std::option::Option::None => value,
|
||||
};
|
||||
let mut parts = core.split('.');
|
||||
let major = match parts.next().and_then(|part| return part.parse::<u64>().ok()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let minor = match parts.next().and_then(|part| return part.parse::<u64>().ok()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let patch = match parts.next().and_then(|part| return part.parse::<u64>().ok()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
if parts.next().is_some() {
|
||||
return std::option::Option::None;
|
||||
}
|
||||
return std::option::Option::Some((major, minor, patch));
|
||||
}
|
||||
|
||||
fn assert_packaged_version_floor(value: std::option::Option<&str>, field: &str) {
|
||||
assert!(value.is_some(), "{field} packaged version must exist");
|
||||
let value = match value {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let parsed = parse_semver_core(value);
|
||||
assert!(parsed.is_some(), "{field} packaged version must be SemVer-like");
|
||||
if let std::option::Option::Some(parsed) = parsed {
|
||||
assert!(parsed >= (0, 2, 6), "{field} packaged version must be >= 0.2.6");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tauri_and_frontend_build_contracts_remain_explicit() {
|
||||
let root = app_root();
|
||||
@@ -103,11 +140,13 @@ fn pre_014_template_uses_sidebar_navigation_and_kbot_style_splash_contract() {
|
||||
#[test]
|
||||
fn pre_018_packaged_runtime_bundles_config_resources_and_activates_shared_writable_root() {
|
||||
let root = app_root();
|
||||
let expected_version = env!("CARGO_PKG_VERSION");
|
||||
let tauri = read_json(root.join("tauri.conf.json").as_path());
|
||||
assert_eq!(tauri.pointer("/version").and_then(serde_json::Value::as_str), std::option::Option::Some(expected_version));
|
||||
let tauri_version = tauri.pointer("/version").and_then(serde_json::Value::as_str);
|
||||
assert_packaged_version_floor(tauri_version, "tauri.conf.json");
|
||||
let package = read_json(root.join("package.json").as_path());
|
||||
assert_eq!(package.pointer("/version").and_then(serde_json::Value::as_str), std::option::Option::Some(expected_version));
|
||||
let package_version = package.pointer("/version").and_then(serde_json::Value::as_str);
|
||||
assert_packaged_version_floor(package_version, "package.json");
|
||||
assert_eq!(tauri_version, package_version, "desktop package metadata versions must remain synchronized");
|
||||
let resources = tauri.pointer("/bundle/resources").and_then(serde_json::Value::as_object);
|
||||
assert!(resources.is_some(), "packaged Config resources map must exist");
|
||||
if let std::option::Option::Some(resources) = resources {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-wallet-desk/tests/desktop_contract.rs
|
||||
// version: 21
|
||||
// version: 22
|
||||
|
||||
//! Desktop build, shell and Config-status contract audits for Wallet Desk.
|
||||
|
||||
@@ -31,6 +31,43 @@ fn read_json(path: &std::path::Path) -> serde_json::Value {
|
||||
};
|
||||
}
|
||||
|
||||
fn parse_semver_core(value: &str) -> std::option::Option<(u64, u64, u64)> {
|
||||
let core = match value.split_once('-') {
|
||||
std::option::Option::Some((core, _)) => core,
|
||||
std::option::Option::None => value,
|
||||
};
|
||||
let mut parts = core.split('.');
|
||||
let major = match parts.next().and_then(|part| return part.parse::<u64>().ok()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let minor = match parts.next().and_then(|part| return part.parse::<u64>().ok()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
let patch = match parts.next().and_then(|part| return part.parse::<u64>().ok()) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::option::Option::None,
|
||||
};
|
||||
if parts.next().is_some() {
|
||||
return std::option::Option::None;
|
||||
}
|
||||
return std::option::Option::Some((major, minor, patch));
|
||||
}
|
||||
|
||||
fn assert_packaged_version_floor(value: std::option::Option<&str>, field: &str) {
|
||||
assert!(value.is_some(), "{field} packaged version must exist");
|
||||
let value = match value {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let parsed = parse_semver_core(value);
|
||||
assert!(parsed.is_some(), "{field} packaged version must be SemVer-like");
|
||||
if let std::option::Option::Some(parsed) = parsed {
|
||||
assert!(parsed >= (0, 2, 6), "{field} packaged version must be >= 0.2.6");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tauri_shell_uses_reserved_wallet_desk_ports_and_template_windows() {
|
||||
let root = app_root();
|
||||
@@ -419,13 +456,19 @@ fn pre_017_wallet_desk_open_paths_remain_non_migrating() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_018_packaged_runtime_bundles_config_resources_and_keeps_wallet_desk_version_current() {
|
||||
fn pre_018_packaged_runtime_bundles_config_resources_and_keeps_wallet_desk_version_coherent() {
|
||||
let root = app_root();
|
||||
let expected_version = env!("CARGO_PKG_VERSION");
|
||||
let tauri = read_json(root.join("tauri.conf.json").as_path());
|
||||
assert_eq!(tauri.pointer("/version").and_then(serde_json::Value::as_str), std::option::Option::Some(expected_version));
|
||||
let tauri_version = tauri.pointer("/version").and_then(serde_json::Value::as_str);
|
||||
assert_packaged_version_floor(tauri_version, "tauri.conf.json");
|
||||
let package = read_json(root.join("package.json").as_path());
|
||||
assert_eq!(package.pointer("/version").and_then(serde_json::Value::as_str), std::option::Option::Some(expected_version));
|
||||
let package_version = package.pointer("/version").and_then(serde_json::Value::as_str);
|
||||
assert_packaged_version_floor(package_version, "package.json");
|
||||
assert_eq!(tauri_version, package_version, "desktop package metadata versions must remain synchronized");
|
||||
let packaged_version = match package_version {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return,
|
||||
};
|
||||
let resources = tauri.pointer("/bundle/resources").and_then(serde_json::Value::as_object);
|
||||
assert!(resources.is_some(), "packaged Wallet Desk Config resources map must exist");
|
||||
if let std::option::Option::Some(resources) = resources {
|
||||
@@ -440,7 +483,7 @@ fn pre_018_packaged_runtime_bundles_config_resources_and_keeps_wallet_desk_versi
|
||||
);
|
||||
}
|
||||
let main = read_text(root.join("frontend/main.html").as_path());
|
||||
assert!(main.contains(expected_version));
|
||||
assert!(main.contains(packaged_version));
|
||||
let tauri_source = read_text(root.join("src/tauri.rs").as_path());
|
||||
assert!(tauri_source.contains("ksp_config_lib::prepare_packaged_runtime"));
|
||||
assert!(tauri_source.contains("tauri::utils::platform::resource_dir"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/ws_lifecycle.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
/// Stable local identity assigned to one physical WebSocket session.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
@@ -104,7 +104,7 @@ impl WsSubscriptionKind {
|
||||
/// Returns the stable KSP descriptor for this standard subscription family.
|
||||
#[must_use]
|
||||
pub const fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
return match self {
|
||||
Self::Account => "account",
|
||||
Self::Block => "block",
|
||||
Self::Logs => "logs",
|
||||
@@ -114,7 +114,7 @@ impl WsSubscriptionKind {
|
||||
Self::Slot => "slot",
|
||||
Self::SlotsUpdates => "slots_updates",
|
||||
Self::Vote => "vote",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +130,7 @@ pub struct WsSubscriptionSnapshot {
|
||||
impl WsSubscriptionSnapshot {
|
||||
/// Creates one safe subscription lifecycle projection for Transport runtime internals.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
pub(crate) const fn new(id: crate::WsSubscriptionId, kind: crate::WsSubscriptionKind, state: crate::WsSubscriptionState, remote_bound: bool) -> Self {
|
||||
return Self { id, kind, state, remote_bound };
|
||||
}
|
||||
@@ -182,6 +183,7 @@ pub struct WsSessionSnapshot {
|
||||
impl WsSessionSnapshot {
|
||||
/// Creates one safe session projection for Transport runtime internals.
|
||||
#[must_use]
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
id: crate::WsSessionId,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-onchain-transport-lib/src/ws_settings.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
const DEFAULT_WS_CLOSE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
|
||||
const DEFAULT_WS_COMMAND_QUEUE_CAPACITY: usize = 128;
|
||||
@@ -132,9 +132,9 @@ impl WsProtocolKind {
|
||||
/// Returns the stable KSP descriptor for this protocol family.
|
||||
#[must_use]
|
||||
pub const fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
return match self {
|
||||
Self::SolanaStandard => "solana_standard",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,11 @@ impl WsReconnectSettings {
|
||||
|
||||
impl std::default::Default for WsReconnectSettings {
|
||||
fn default() -> Self {
|
||||
return Self::new(DEFAULT_WS_RECONNECT_MAX_RETRIES, DEFAULT_WS_RECONNECT_INITIAL_BACKOFF, DEFAULT_WS_RECONNECT_MAX_BACKOFF);
|
||||
return Self::new(
|
||||
DEFAULT_WS_RECONNECT_MAX_RETRIES,
|
||||
DEFAULT_WS_RECONNECT_INITIAL_BACKOFF,
|
||||
DEFAULT_WS_RECONNECT_MAX_BACKOFF,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,13 +327,27 @@ impl WsSessionSettings {
|
||||
"ws_session.reconnect.max_backoff",
|
||||
);
|
||||
}
|
||||
validate_non_zero_bound(self.command_queue_capacity, "ws_session.command_queue_capacity")?;
|
||||
validate_non_zero_bound(self.notification_queue_capacity, "ws_session.notification_queue_capacity")?;
|
||||
validate_non_zero_bound(self.max_active_subscriptions, "ws_session.max_active_subscriptions")?;
|
||||
validate_non_zero_bound(self.max_pending_requests, "ws_session.max_pending_requests")?;
|
||||
validate_non_zero_bound(self.max_message_size_bytes, "ws_session.max_message_size_bytes")?;
|
||||
validate_non_zero_bound(self.max_frame_size_bytes, "ws_session.max_frame_size_bytes")?;
|
||||
validate_non_zero_bound(self.max_write_buffer_size_bytes, "ws_session.max_write_buffer_size_bytes")?;
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.command_queue_capacity, "ws_session.command_queue_capacity") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.notification_queue_capacity, "ws_session.notification_queue_capacity") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.max_active_subscriptions, "ws_session.max_active_subscriptions") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.max_pending_requests, "ws_session.max_pending_requests") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.max_message_size_bytes, "ws_session.max_message_size_bytes") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.max_frame_size_bytes, "ws_session.max_frame_size_bytes") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = validate_non_zero_bound(self.max_write_buffer_size_bytes, "ws_session.max_write_buffer_size_bytes") {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
command_queue_capacity = self.command_queue_capacity,
|
||||
@@ -369,10 +387,10 @@ impl WsResubscribePolicy {
|
||||
/// Returns the stable KSP descriptor for this policy.
|
||||
#[must_use]
|
||||
pub const fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
return match self {
|
||||
Self::Never => "never",
|
||||
Self::ActiveSubscriptions => "active_subscriptions",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +491,9 @@ impl WsTransportSettings {
|
||||
}
|
||||
let mut enabled_endpoint_count = 0_usize;
|
||||
for (endpoint_index, endpoint) in self.endpoints.iter().enumerate() {
|
||||
validate_ws_endpoint(endpoint, endpoint_index)?;
|
||||
if let std::result::Result::Err(error) = validate_ws_endpoint(endpoint, endpoint_index) {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if endpoint.enabled() {
|
||||
enabled_endpoint_count += 1;
|
||||
}
|
||||
@@ -501,10 +521,21 @@ impl WsTransportSettings {
|
||||
}
|
||||
|
||||
fn validate_ws_endpoint(endpoint: &crate::WsEndpointSettings, endpoint_index: usize) -> ksp_core_lib::Result<()> {
|
||||
validate_ws_descriptor(endpoint.name(), format!("ws_endpoints[{endpoint_index}].name").as_str())?;
|
||||
validate_ws_descriptor(endpoint.provider().as_str(), format!("ws_endpoints[{endpoint_index}].provider").as_str())?;
|
||||
validate_ws_descriptor(endpoint.cluster().as_str(), format!("ws_endpoints[{endpoint_index}].cluster").as_str())?;
|
||||
endpoint.session().validate()?;
|
||||
let name_field = format!("ws_endpoints[{endpoint_index}].name");
|
||||
if let std::result::Result::Err(error) = validate_ws_descriptor(endpoint.name(), name_field.as_str()) {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let provider_field = format!("ws_endpoints[{endpoint_index}].provider");
|
||||
if let std::result::Result::Err(error) = validate_ws_descriptor(endpoint.provider().as_str(), provider_field.as_str()) {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let cluster_field = format!("ws_endpoints[{endpoint_index}].cluster");
|
||||
if let std::result::Result::Err(error) = validate_ws_descriptor(endpoint.cluster().as_str(), cluster_field.as_str()) {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
if let std::result::Result::Err(error) = endpoint.session().validate() {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
ksp_logging_lib::trace!(
|
||||
target: crate::TRACING_TARGET,
|
||||
endpoint_name = endpoint.name(),
|
||||
|
||||
Reference in New Issue
Block a user