#![cfg(all(not(feature = "std"), feature = "discovery"))]
use std::alloc::{GlobalAlloc, Layout, System};
use std::cell::Cell;
struct Counter;
thread_local! { static LARGE: Cell<Option<(usize,usize)>> = const { Cell::new(None) }; }
#[global_allocator]
static ALLOCATOR: Counter = Counter;
unsafe impl GlobalAlloc for Counter {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let _ = LARGE.try_with(|v| {
if let Some((threshold, count)) = v.get() {
if layout.size() >= threshold {
v.set(Some((threshold, count + 1)));
}
}
});
unsafe { System.alloc(layout) }
}
unsafe fn dealloc(&self, p: *mut u8, layout: Layout) {
unsafe { System.dealloc(p, layout) }
}
}
#[unsafe(no_mangle)]
extern "C" fn telemetry_lock() {}
#[unsafe(no_mangle)]
extern "C" fn telemetry_unlock() {}
#[test]
fn embedded_schema_encodes_directly_into_one_large_allocation() {
use sedsnet::discovery::{build_discovery_schema, decode_discovery_schema};
let ty = sedsnet::config::DataType::named("GPS_DATA");
let meta = sedsnet::config::data_type_definition(ty).unwrap();
let scalar =
sedsnet::packet::Packet::from_f32_slice(ty, &[1.0, 2.0, 3.0], &meta.endpoints, 123)
.unwrap();
let wire = sedsnet::wire_format::pack_packet(&scalar);
sedsnet::wire_format::unpack_packet(&wire).unwrap();
LARGE.with(|v| v.set(Some((0, 0))));
let decoded = sedsnet::wire_format::unpack_packet(&wire).unwrap();
let allocations = LARGE.with(|v| v.replace(None).unwrap().1);
assert_eq!(
allocations, 2,
"embedded small decoder allocated temporary metadata/payload storage"
);
assert_eq!(decoded.payload(), scalar.payload());
assert_eq!(decoded.packet_id(), scalar.packet_id());
let first = build_discovery_schema("GB", 1).unwrap();
let payload_len = first.payload().len();
assert!(payload_len > 256);
LARGE.with(|v| v.set(Some((payload_len, 0))));
let packet = build_discovery_schema("GB", 2).unwrap();
let large = LARGE.with(|v| v.replace(None).unwrap().1);
assert_eq!(
large, 1,
"schema retained duplicate full-size payload buffers"
);
assert_eq!(packet.payload(), first.payload());
let decoded = decode_discovery_schema(&packet).unwrap();
let expected = sedsnet::config::export_schema();
assert_eq!(decoded.endpoints.len(), expected.endpoints.len());
assert_eq!(decoded.types.len(), expected.types.len());
extern "C" fn deny(_: usize, _: usize) -> bool {
false
}
sedsnet::memory_admission::set_probe(Some(deny));
let rejected = build_discovery_schema("GB", 3);
sedsnet::memory_admission::set_probe(None);
assert!(matches!(
rejected,
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
assert_eq!(
build_discovery_schema("GB", 4).unwrap().payload(),
first.payload()
);
for ty in expected.types {
let actual = decoded
.types
.iter()
.find(|entry| entry.id == ty.id)
.unwrap();
assert_eq!(actual.name, ty.name);
assert_eq!(actual.element, ty.element);
assert_eq!(actual.endpoints, ty.endpoints);
assert_eq!(actual.reliable, ty.reliable);
}
static LARGE_ADMISSIONS: std::sync::atomic::AtomicUsize =
std::sync::atomic::AtomicUsize::new(0);
extern "C" fn control_only(additional: usize, _: usize) -> bool {
if additional > 1024 {
if additional > 8192 {
LARGE_ADMISSIONS.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
false
} else {
true
}
}
let router = sedsnet::router::Router::new_with_clock(
sedsnet::router::RouterConfig::new(vec![]),
Box::new(|| 0),
);
let router_side = router.add_side_packet("known-schema", |_| Ok(()));
let relay = sedsnet::relay::Relay::new(Box::new(|| 0));
let relay_side = relay.add_side_packet("known-schema", |_| Ok(()));
relay.rx_from_side(relay_side, first.clone()).unwrap();
sedsnet::memory_admission::set_probe(Some(control_only));
let router_result = router.rx_from_side(&first, router_side);
let relay_result = relay.process_rx_queue();
sedsnet::memory_admission::set_probe(None);
router_result.unwrap();
relay_result.unwrap();
assert_eq!(
LARGE_ADMISSIONS.load(std::sync::atomic::Ordering::Relaxed),
0,
"known schema unnecessarily required full decoder headroom"
);
let tuning = sedsnet::config::runtime_tuning_config();
sedsnet::config::set_runtime_tuning_config(sedsnet::config::RuntimeTuningConfig {
payload_compress_threshold: usize::MAX,
..tuning
})
.unwrap();
let raw = sedsnet::wire_format::pack_packet(&first);
let sequenced = sedsnet::wire_format::pack_packet_with_reliable(
&first,
sedsnet::wire_format::ReliableHeader {
flags: 0,
seq: 1,
ack: 0,
},
);
let piggyback = sedsnet::wire_format::pack_packet_with_reliable(
&first,
sedsnet::wire_format::ReliableHeader {
flags: sedsnet::wire_format::RELIABLE_FLAG_UNSEQUENCED,
seq: 0,
ack: 1,
},
);
let mut unknown_payload = first.payload().to_vec();
assert!(unknown_payload.len() > 12 && !expected.endpoints.is_empty());
unknown_payload[8..12].copy_from_slice(&(u32::MAX - 7).to_le_bytes());
let unknown = sedsnet::packet::Packet::new(
first.data_type(),
first.endpoints(),
"GB",
9,
std::sync::Arc::from(unknown_payload),
)
.unwrap();
let unknown = sedsnet::wire_format::pack_packet(&unknown);
sedsnet::config::set_runtime_tuning_config(tuning).unwrap();
let wrapped_router_side = router.add_side_packed_with_options(
"known-full-schema",
|_| Ok(()),
sedsnet::router::RouterSideOptions {
header_template_enabled: true,
..Default::default()
},
);
let wrapped_relay_side = relay.add_side_packed_with_options(
"known-full-schema",
|_| Ok(()),
sedsnet::relay::RelaySideOptions {
header_template_enabled: true,
..Default::default()
},
);
let mut full = b"SDT\x01\x01".to_vec();
full.extend_from_slice(&raw);
full.extend_from_slice(&crc32fast::hash(&full).to_le_bytes());
let mut corrupt = raw.to_vec();
*corrupt.last_mut().unwrap() ^= 1;
let mut truncated = raw[..raw.len() - 5].to_vec();
truncated.extend_from_slice(&crc32fast::hash(&truncated).to_le_bytes());
let mut compressed = raw[..raw.len() - 4].to_vec();
compressed[0] |= 1;
compressed.extend_from_slice(&crc32fast::hash(&compressed).to_le_bytes());
LARGE.with(|v| v.set(Some((payload_len, 0))));
sedsnet::memory_admission::set_probe(Some(control_only));
for frame in [&sequenced, &piggyback] {
assert!(matches!(
router.rx_packed_from_side(frame, router_side),
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
assert!(matches!(
relay.rx_packed_from_side(relay_side, frame),
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
}
let raw_router = router.rx_packed_from_side(&raw, router_side);
let raw_relay = relay.rx_packed_from_side(relay_side, &raw);
let full_router = router.rx_packed_from_side(&full, wrapped_router_side);
let full_relay = relay.rx_packed_from_side(wrapped_relay_side, &full);
assert!(router.rx_packed_from_side(&corrupt, router_side).is_err());
assert!(relay.rx_packed_from_side(relay_side, &corrupt).is_err());
assert!(router.rx_packed_from_side(&truncated, router_side).is_err());
assert!(relay.rx_packed_from_side(relay_side, &truncated).is_err());
assert!(matches!(
router.rx_packed_from_side(&compressed, router_side),
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
assert!(matches!(
relay.rx_packed_from_side(relay_side, &compressed),
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
assert!(matches!(
router.rx_packed_from_side(&unknown, router_side),
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
assert!(matches!(
relay.rx_packed_from_side(relay_side, &unknown),
Err(sedsnet::TelemetryError::Io("memory pressure"))
));
sedsnet::memory_admission::set_probe(None);
let packed_copies = LARGE.with(|v| v.replace(None).unwrap().1);
raw_router.unwrap();
raw_relay.unwrap();
full_router.unwrap();
full_relay.unwrap();
assert_eq!(
packed_copies, 0,
"known packed schema cloned its payload before admission"
);
let mut chunk = b"SDT\x03".to_vec();
chunk.extend_from_slice(&123u32.to_le_bytes());
chunk.extend_from_slice(&0u16.to_le_bytes());
chunk.extend_from_slice(&2u16.to_le_bytes());
chunk.extend_from_slice(&[0x5a; 128]);
chunk.extend_from_slice(&crc32fast::hash(&chunk).to_le_bytes());
router.rx_packed_from_side(&chunk, router_side).unwrap();
relay.rx_packed_from_side(relay_side, &chunk).unwrap();
LARGE.with(|v| v.set(Some((128, 0))));
let router_duplicate = router.rx_packed_from_side(&chunk, router_side);
let relay_duplicate = relay.rx_packed_from_side(relay_side, &chunk);
let copies = LARGE.with(|v| v.replace(None).unwrap().1);
router_duplicate.unwrap();
relay_duplicate.unwrap();
assert_eq!(copies, 0, "duplicate chunks allocated another payload copy");
}
#[test]
fn embedded_named_id_lookup_uses_retained_schema_storage() {
let schema = sedsnet::config::export_schema();
for def in &schema.endpoints {
assert!(
sedsnet::config::endpoint_exists(def.id),
"missing {}",
def.name
);
assert_eq!(sedsnet::config::endpoint_definition(def.id).unwrap(), *def);
}
for def in &schema.types {
assert!(
sedsnet::config::data_type_exists(def.id),
"missing {}",
def.name
);
assert_eq!(sedsnet::config::data_type_definition(def.id).unwrap(), *def);
}
assert!(!sedsnet::config::endpoint_exists(
sedsnet::config::DataEndpoint(u32::MAX)
));
assert!(!sedsnet::config::data_type_exists(
sedsnet::config::DataType(u32::MAX)
));
assert_eq!(
sedsnet::config::schema_bytes_used(),
0,
"flash schema must not consume the runtime RAM budget"
);
let ty = sedsnet::config::DataType::named("GPS_DATA");
let def = sedsnet::config::data_type_definition(ty).unwrap();
let ep = def.endpoints[0];
let endpoint = sedsnet::config::endpoint_definition(ep).unwrap();
LARGE.with(|v| v.set(Some((0, 0))));
for _ in 0..1000 {
assert_eq!(sedsnet::config::DataType::try_named("GPS_DATA"), Some(ty));
assert_eq!(
sedsnet::config::DataEndpoint::try_named(&endpoint.name),
Some(ep)
);
assert_eq!(
sedsnet::config::DataType::try_named("ID_LOOKUP_MISSING"),
None
);
}
let allocations = LARGE.with(|v| v.replace(None).unwrap().1);
assert_eq!(
allocations, 0,
"embedded ID lookup copied static schema definitions"
);
}