diff --git a/protocol/agent/v1/fixtures/heartbeat/MANIFEST.sha256 b/protocol/agent/v1/fixtures/heartbeat/MANIFEST.sha256 index fa096e9e7..9de2fce00 100644 --- a/protocol/agent/v1/fixtures/heartbeat/MANIFEST.sha256 +++ b/protocol/agent/v1/fixtures/heartbeat/MANIFEST.sha256 @@ -1,5 +1,6 @@ 975c1ca53eefeef6766a6fc0b3d3281f7408255342b0686e5e2aee5ad055414c duplicate.json 963529a38a02849c6c2acc6d72668dca9f63218b49c89fae41a451b584850411 overflow.json +d8cf9de12c459aff83736d761ba003ca2544e45477fbbc5d1c6ae43a1e78a482 producer-capabilities.json e3adeee1c8a19aa17e70894896fb79c072e3785bea3611b93c11e79f039ed5af stale.json 22cc7337f545271ebf11ca6b76e7e479d62c51278ac001a8d870b07d0fa9884e unknown.json b06a72ff1d964efe65e996797705ec2ef72574a813aec5d8e9aff26c899f1352 valid.json diff --git a/protocol/agent/v1/fixtures/heartbeat/producer-capabilities.json b/protocol/agent/v1/fixtures/heartbeat/producer-capabilities.json new file mode 100644 index 000000000..6b9c1033c --- /dev/null +++ b/protocol/agent/v1/fixtures/heartbeat/producer-capabilities.json @@ -0,0 +1,52 @@ +{ + "protocolVersion": "v1", + "fixtureSet": "heartbeat", + "fixture": "producer-capabilities", + "description": "The exact base and diagnostic capability tokens published by a RustFS agent heartbeat.", + "baseCapabilities": [ + "heartbeat", + "diagnostics.policy.v1", + "inventory.environment@1" + ], + "producerCapabilities": [ + "performance.client@1", + "performance.drive@1", + "performance.object@1", + "performance.siteReplication@1", + "logs.capture@1", + "profile.cpu@1", + "profile.memory@1", + "profile.threads@1", + "telemetry.record@1", + "telemetry.otlp@1", + "telemetry.replay@1", + "top.api@1", + "top.disk@1", + "top.locks@1", + "top.net@1", + "top.rpc@1", + "inspect.object@1" + ], + "heartbeatCapabilities": [ + "heartbeat", + "diagnostics.policy.v1", + "inventory.environment@1", + "performance.client@1", + "performance.drive@1", + "performance.object@1", + "performance.siteReplication@1", + "logs.capture@1", + "profile.cpu@1", + "profile.memory@1", + "profile.threads@1", + "telemetry.record@1", + "telemetry.otlp@1", + "telemetry.replay@1", + "top.api@1", + "top.disk@1", + "top.locks@1", + "top.net@1", + "top.rpc@1", + "inspect.object@1" + ] +} diff --git a/protocol/agent/v1/fixtures/manifest.sha256 b/protocol/agent/v1/fixtures/manifest.sha256 index 152bdd0c8..cd0e69cb2 100644 --- a/protocol/agent/v1/fixtures/manifest.sha256 +++ b/protocol/agent/v1/fixtures/manifest.sha256 @@ -1,7 +1,7 @@ a499742c06046e9cf2f781fc17d8b4cf95e018ab45fa41ee5944ba15b0e2902c auth 9b54e39584a442270ae486e8378df1d6f168c45d0c59baba9459b46bb212d2df version 159d116e965b51771f1687fc6ec9bdfbf2a4a0e6d6aa26d3f1046b3dac2697dd registration -f707b09b257c7d652eff2a3f680ecb0c8c45ebb4c2defa8dc07f9dd7ee46ca04 heartbeat +5905ef6b39f02d5846912878c2762537e54875ef1a8666a2ee2be17b489e9f68 heartbeat cc6c3f3bf5e6a938f2e00b8ce42d8fa7bfb974f4eb2927101d4ede4ebdc10dd5 inventory 0207458ec9b97b368e2f347da112511a3aabd27d752890cacda4fa2408e7f19e object-performance a464d4c695d76dd985c0f2abf68c2135c080221098ad2427022f85243a7bf6ae network-performance diff --git a/rustfs/tests/agent_protocol_fixtures.rs b/rustfs/tests/agent_protocol_fixtures.rs index 0cee61d08..882f1f204 100644 --- a/rustfs/tests/agent_protocol_fixtures.rs +++ b/rustfs/tests/agent_protocol_fixtures.rs @@ -24,6 +24,7 @@ use std::fs; use std::path::PathBuf; +use rustfs::connect::CONNECT_DIAGNOSTIC_CAPABILITIES; use sha2::{Digest as _, Sha256}; fn fixture_root() -> PathBuf { @@ -34,6 +35,31 @@ fn sha256_hex(bytes: &[u8]) -> String { Sha256::digest(bytes).iter().map(|byte| format!("{byte:02x}")).collect() } +#[test] +fn heartbeat_producer_capabilities_match_the_frozen_contract() { + let fixture: serde_json::Value = serde_json::from_slice( + &fs::read(fixture_root().join("heartbeat/producer-capabilities.json")).expect("read producer capabilities fixture"), + ) + .expect("producer capabilities fixture parses"); + let producer = fixture["producerCapabilities"] + .as_array() + .expect("producerCapabilities is an array") + .iter() + .map(|value| value.as_str().expect("producer capability is a string")) + .collect::>(); + assert_eq!(producer, CONNECT_DIAGNOSTIC_CAPABILITIES); + + let mut expected_heartbeat = vec!["heartbeat", "diagnostics.policy.v1", "inventory.environment@1"]; + expected_heartbeat.extend(producer); + let heartbeat = fixture["heartbeatCapabilities"] + .as_array() + .expect("heartbeatCapabilities is an array") + .iter() + .map(|value| value.as_str().expect("heartbeat capability is a string")) + .collect::>(); + assert_eq!(heartbeat, expected_heartbeat); +} + /// The registry is closed; adding another set is a protocol change, not a /// fixture change. Mirrors `EXPECTED_SETS` in Connect's checker. const EXPECTED_SETS: [&str; 13] = [