#![cfg_attr(coverage_nightly, coverage(off))]
use super::*;
pub struct NetworkThrottle {
_limits: NetworkLimits,
}
impl NetworkThrottle {
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn new(limits: NetworkLimits) -> Result<Self, ResourceError> {
Ok(Self { _limits: limits })
}
}
impl ResourceController for NetworkThrottle {
fn apply_limits(&self, _limits: &ResourceLimits) -> Result<(), ResourceError> {
Ok(())
}
fn get_usage(&self) -> Result<ResourceUsage, ResourceError> {
Ok(ResourceUsage {
cpu_percent: 0.0,
memory_bytes: 0,
gpu_memory_bytes: None,
gpu_compute_percent: None,
network_ingress_bytes: 0,
network_egress_bytes: 0,
disk_read_bytes: 0,
disk_write_bytes: 0,
timestamp: std::time::SystemTime::now(),
})
}
fn release(&self) -> Result<(), ResourceError> {
Ok(())
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod coverage_tests {
use super::*;
fn create_test_network_limits() -> NetworkLimits {
NetworkLimits {
ingress_bytes_per_sec: 100 * 1024 * 1024, egress_bytes_per_sec: 50 * 1024 * 1024, max_connections: 10000,
burst_size: Some(10 * 1024 * 1024), }
}
fn create_test_resource_limits() -> ResourceLimits {
ResourceLimits::default()
}
#[test]
fn test_network_throttle_new_success() {
let limits = create_test_network_limits();
let result = NetworkThrottle::new(limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_new_without_burst() {
let limits = NetworkLimits {
ingress_bytes_per_sec: 10 * 1024 * 1024,
egress_bytes_per_sec: 10 * 1024 * 1024,
max_connections: 1000,
burst_size: None,
};
let result = NetworkThrottle::new(limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_new_with_zero_limits() {
let limits = NetworkLimits {
ingress_bytes_per_sec: 0,
egress_bytes_per_sec: 0,
max_connections: 0,
burst_size: None,
};
let result = NetworkThrottle::new(limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_new_with_max_limits() {
let limits = NetworkLimits {
ingress_bytes_per_sec: u64::MAX,
egress_bytes_per_sec: u64::MAX,
max_connections: usize::MAX,
burst_size: Some(u64::MAX),
};
let result = NetworkThrottle::new(limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_apply_limits() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
let resource_limits = create_test_resource_limits();
let result = throttle.apply_limits(&resource_limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_get_usage() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
let result = throttle.get_usage();
assert!(result.is_ok());
let usage = result.unwrap();
assert_eq!(usage.cpu_percent, 0.0);
assert_eq!(usage.memory_bytes, 0);
assert!(usage.gpu_memory_bytes.is_none());
assert!(usage.gpu_compute_percent.is_none());
assert_eq!(usage.network_ingress_bytes, 0);
assert_eq!(usage.network_egress_bytes, 0);
assert_eq!(usage.disk_read_bytes, 0);
assert_eq!(usage.disk_write_bytes, 0);
}
#[test]
fn test_network_throttle_get_usage_no_gpu_metrics() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
let usage = throttle.get_usage().unwrap();
assert!(usage.gpu_memory_bytes.is_none());
assert!(usage.gpu_compute_percent.is_none());
}
#[test]
fn test_network_throttle_get_usage_has_valid_timestamp() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
let before = std::time::SystemTime::now();
let usage = throttle.get_usage().unwrap();
let after = std::time::SystemTime::now();
assert!(usage.timestamp >= before);
assert!(usage.timestamp <= after);
}
#[test]
fn test_network_throttle_release() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
let result = throttle.release();
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_multiple_operations() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
for _ in 0..10 {
assert!(throttle.get_usage().is_ok());
}
}
#[test]
fn test_network_throttle_apply_different_limits() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
let mut resource_limits = create_test_resource_limits();
resource_limits.network.ingress_bytes_per_sec = 200 * 1024 * 1024;
resource_limits.network.egress_bytes_per_sec = 100 * 1024 * 1024;
let result = throttle.apply_limits(&resource_limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_release_then_get_usage() {
let limits = create_test_network_limits();
let throttle = NetworkThrottle::new(limits).unwrap();
assert!(throttle.release().is_ok());
assert!(throttle.get_usage().is_ok());
}
#[test]
fn test_network_throttle_asymmetric_bandwidth() {
let limits = NetworkLimits {
ingress_bytes_per_sec: 1000 * 1024 * 1024, egress_bytes_per_sec: 100 * 1024 * 1024, max_connections: 5000,
burst_size: Some(50 * 1024 * 1024),
};
let result = NetworkThrottle::new(limits);
assert!(result.is_ok());
}
#[test]
fn test_network_throttle_high_connection_limit() {
let limits = NetworkLimits {
ingress_bytes_per_sec: 10 * 1024 * 1024,
egress_bytes_per_sec: 10 * 1024 * 1024,
max_connections: 100000, burst_size: None,
};
let result = NetworkThrottle::new(limits);
assert!(result.is_ok());
}
}