1use crate::error::{CleanroomError, Result};
64use serde::{Deserialize, Serialize};
65use std::collections::HashMap;
66use std::time::Duration;
67
68#[derive(Debug, Clone, Default, Serialize, Deserialize)]
70pub struct Policy {
71 pub security: SecurityPolicy,
73 pub resources: ResourcePolicy,
75 pub execution: ExecutionPolicy,
77 pub compliance: CompliancePolicy,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct SecurityPolicy {
84 pub enable_network_isolation: bool,
86 pub enable_filesystem_isolation: bool,
88 pub enable_process_isolation: bool,
90 pub allowed_ports: Vec<u16>,
92 pub blocked_addresses: Vec<String>,
94 pub enable_data_redaction: bool,
96 pub redaction_patterns: Vec<String>,
98 pub enable_audit_logging: bool,
100 pub security_level: SecurityLevel,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct ResourcePolicy {
107 pub max_cpu_usage_percent: f64,
109 pub max_memory_usage_bytes: u64,
111 pub max_disk_usage_bytes: u64,
113 pub max_network_bandwidth_bytes_per_sec: u64,
115 pub max_container_count: u32,
117 pub max_test_execution_time: Duration,
119 pub enable_resource_monitoring: bool,
121 pub resource_cleanup_timeout: Duration,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct ExecutionPolicy {
128 pub enable_deterministic_execution: bool,
130 pub deterministic_seed: Option<u64>,
132 pub enable_parallel_execution: bool,
134 pub max_parallel_tasks: u32,
136 pub enable_test_isolation: bool,
138 pub test_timeout: Duration,
140 pub enable_retry_on_failure: bool,
142 pub max_retry_attempts: u32,
144 pub retry_delay: Duration,
146}
147
148#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct CompliancePolicy {
151 pub enable_compliance_reporting: bool,
153 pub compliance_standards: Vec<ComplianceStandard>,
155 pub enable_audit_trails: bool,
157 pub audit_retention_period: Duration,
159 pub enable_policy_validation: bool,
161 pub policy_validation_rules: Vec<PolicyValidationRule>,
163}
164
165#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
167pub enum SecurityLevel {
168 Low,
170 Medium,
172 High,
174 Maximum,
176 Standard,
178 Locked,
180}
181
182#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
184pub enum AuditLevel {
185 Debug,
187 Info,
189 Warn,
191 Error,
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
197pub enum ComplianceStandard {
198 Soc2,
200 Iso27001,
202 PciDss,
204 Hipaa,
206 Gdpr,
208 Custom(String),
210}
211
212#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct PolicyValidationRule {
215 pub name: String,
217 pub description: String,
219 pub condition: String,
221 pub action: PolicyValidationAction,
223 pub severity: PolicyValidationSeverity,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
229pub enum PolicyValidationAction {
230 Allow,
232 Deny,
234 Warn,
236 RequireApproval,
238}
239
240#[derive(Debug, Clone, Serialize, Deserialize)]
242pub enum PolicyValidationSeverity {
243 Low,
245 Medium,
247 High,
249 Critical,
251}
252
253impl SecurityPolicy {
254 pub fn new() -> Self {
256 Self::default()
257 }
258
259 pub fn with_security_level(security_level: SecurityLevel) -> Self {
261 let mut policy = Self {
262 security_level,
263 ..Default::default()
264 };
265
266 match security_level {
268 SecurityLevel::Low => {
269 policy.enable_network_isolation = false;
270 policy.enable_filesystem_isolation = false;
271 policy.enable_process_isolation = false;
272 policy.enable_data_redaction = false;
273 policy.enable_audit_logging = false;
274 }
275 SecurityLevel::Medium | SecurityLevel::Standard => {
276 }
278 SecurityLevel::High | SecurityLevel::Maximum | SecurityLevel::Locked => {
279 }
281 }
282
283 policy
284 }
285}
286
287impl Default for SecurityPolicy {
288 fn default() -> Self {
289 Self {
290 enable_network_isolation: true,
291 enable_filesystem_isolation: true,
292 enable_process_isolation: true,
293 allowed_ports: vec![5432, 6379, 8080, 9090],
294 blocked_addresses: vec!["127.0.0.1".to_string()],
295 enable_data_redaction: true,
296 redaction_patterns: vec![
297 r"password\s*=\s*[^\s]+".to_string(),
298 r"token\s*=\s*[^\s]+".to_string(),
299 r"key\s*=\s*[^\s]+".to_string(),
300 ],
301 enable_audit_logging: true,
302 security_level: SecurityLevel::Standard,
303 }
304 }
305}
306
307impl ResourcePolicy {
308 pub fn new() -> Self {
310 Self::default()
311 }
312}
313
314impl Default for ResourcePolicy {
315 fn default() -> Self {
316 Self {
317 max_cpu_usage_percent: 80.0,
318 max_memory_usage_bytes: 1024 * 1024 * 1024, max_disk_usage_bytes: 10 * 1024 * 1024 * 1024, max_network_bandwidth_bytes_per_sec: 100 * 1024 * 1024, max_container_count: 10,
322 max_test_execution_time: Duration::from_secs(300), enable_resource_monitoring: true,
324 resource_cleanup_timeout: Duration::from_secs(30),
325 }
326 }
327}
328
329impl ExecutionPolicy {
330 pub fn new() -> Self {
332 Self::default()
333 }
334}
335
336impl Default for ExecutionPolicy {
337 fn default() -> Self {
338 Self {
339 enable_deterministic_execution: true,
340 deterministic_seed: Some(42),
341 enable_parallel_execution: true,
342 max_parallel_tasks: 4,
343 enable_test_isolation: true,
344 test_timeout: Duration::from_secs(60),
345 enable_retry_on_failure: true,
346 max_retry_attempts: 3,
347 retry_delay: Duration::from_secs(1),
348 }
349 }
350}
351
352impl CompliancePolicy {
353 pub fn new() -> Self {
355 Self::default()
356 }
357}
358
359impl Default for CompliancePolicy {
360 fn default() -> Self {
361 Self {
362 enable_compliance_reporting: true,
363 compliance_standards: vec![ComplianceStandard::Soc2],
364 enable_audit_trails: true,
365 audit_retention_period: Duration::from_secs(30 * 24 * 60 * 60), enable_policy_validation: true,
367 policy_validation_rules: vec![],
368 }
369 }
370}
371
372impl Policy {
373 pub fn new() -> Self {
375 Self::default()
376 }
377
378 pub fn with_security_level(security_level: SecurityLevel) -> Self {
380 Self {
381 security: SecurityPolicy::with_security_level(security_level),
382 ..Default::default()
383 }
384 }
385
386 pub fn with_resource_limits(
388 max_cpu_percent: f64,
389 max_memory_bytes: u64,
390 max_disk_bytes: u64,
391 ) -> Self {
392 let mut policy = Self::default();
393 policy.resources.max_cpu_usage_percent = max_cpu_percent;
394 policy.resources.max_memory_usage_bytes = max_memory_bytes;
395 policy.resources.max_disk_usage_bytes = max_disk_bytes;
396 policy
397 }
398
399 pub fn locked() -> Self {
401 Self::with_security_level(SecurityLevel::Locked)
402 }
403
404 pub fn high_security() -> Self {
406 Self::with_security_level(SecurityLevel::High)
407 }
408
409 pub fn standard() -> Self {
411 Self::with_security_level(SecurityLevel::Standard)
412 }
413
414 pub fn low_security() -> Self {
416 Self::with_security_level(SecurityLevel::Low)
417 }
418
419 pub fn with_network_disabled(mut self) -> Self {
421 self.security.enable_network_isolation = true;
422 self
423 }
424
425 pub fn with_network_isolation(mut self, enable: bool) -> Self {
427 self.security.enable_network_isolation = enable;
428 self
429 }
430
431 pub fn allows_network(&self) -> bool {
433 !self.security.enable_network_isolation
434 }
435
436 pub fn validate(&self) -> Result<()> {
438 if self.security.allowed_ports.is_empty() {
440 return Err(CleanroomError::policy_violation_error(
441 "No allowed ports configured",
442 ));
443 }
444
445 if self.resources.max_cpu_usage_percent <= 0.0
447 || self.resources.max_cpu_usage_percent > 100.0
448 {
449 return Err(CleanroomError::policy_violation_error(
450 "Invalid CPU usage percentage",
451 ));
452 }
453
454 if self.resources.max_memory_usage_bytes == 0 {
455 return Err(CleanroomError::policy_violation_error(
456 "Invalid memory usage limit",
457 ));
458 }
459
460 if self.resources.max_disk_usage_bytes == 0 {
461 return Err(CleanroomError::policy_violation_error(
462 "Invalid disk usage limit",
463 ));
464 }
465
466 if self.execution.max_parallel_tasks == 0 {
468 return Err(CleanroomError::policy_violation_error(
469 "Invalid parallel task count",
470 ));
471 }
472
473 if self.execution.max_retry_attempts == 0 {
474 return Err(CleanroomError::policy_violation_error(
475 "Invalid retry attempt count",
476 ));
477 }
478
479 Ok(())
480 }
481
482 pub fn is_operation_allowed(
484 &self,
485 _operation: &str,
486 context: &HashMap<String, String>,
487 ) -> Result<bool> {
488 if self.security.enable_network_isolation {
490 if let Some(port) = context.get("port") {
491 if let Ok(port_num) = port.parse::<u16>() {
492 if !self.security.allowed_ports.contains(&port_num) {
493 return Ok(false);
494 }
495 }
496 }
497 }
498
499 if let Some(cpu_usage) = context.get("cpu_usage") {
501 if let Ok(cpu_percent) = cpu_usage.parse::<f64>() {
502 if cpu_percent > self.resources.max_cpu_usage_percent {
503 return Ok(false);
504 }
505 }
506 }
507
508 if let Some(memory_usage) = context.get("memory_usage") {
509 if let Ok(memory_bytes) = memory_usage.parse::<u64>() {
510 if memory_bytes > self.resources.max_memory_usage_bytes {
511 return Ok(false);
512 }
513 }
514 }
515
516 if let Some(parallel_tasks) = context.get("parallel_tasks") {
518 if let Ok(task_count) = parallel_tasks.parse::<u32>() {
519 if task_count > self.execution.max_parallel_tasks {
520 return Ok(false);
521 }
522 }
523 }
524
525 Ok(true)
526 }
527
528 pub fn to_env(&self) -> HashMap<String, String> {
530 let mut env = HashMap::new();
531
532 env.insert(
534 "CLEANROOM_SECURITY_LEVEL".to_string(),
535 format!("{:?}", self.security.security_level),
536 );
537 env.insert(
538 "CLEANROOM_NETWORK_ISOLATION".to_string(),
539 self.security.enable_network_isolation.to_string(),
540 );
541 env.insert(
542 "CLEANROOM_FILESYSTEM_ISOLATION".to_string(),
543 self.security.enable_filesystem_isolation.to_string(),
544 );
545 env.insert(
546 "CLEANROOM_PROCESS_ISOLATION".to_string(),
547 self.security.enable_process_isolation.to_string(),
548 );
549 env.insert(
550 "CLEANROOM_ALLOWED_PORTS".to_string(),
551 self.security
552 .allowed_ports
553 .iter()
554 .map(|p| p.to_string())
555 .collect::<Vec<_>>()
556 .join(","),
557 );
558
559 env.insert(
561 "CLEANROOM_MAX_CPU_PERCENT".to_string(),
562 self.resources.max_cpu_usage_percent.to_string(),
563 );
564 env.insert(
565 "CLEANROOM_MAX_MEMORY_BYTES".to_string(),
566 self.resources.max_memory_usage_bytes.to_string(),
567 );
568 env.insert(
569 "CLEANROOM_MAX_DISK_BYTES".to_string(),
570 self.resources.max_disk_usage_bytes.to_string(),
571 );
572 env.insert(
573 "CLEANROOM_MAX_CONTAINER_COUNT".to_string(),
574 self.resources.max_container_count.to_string(),
575 );
576
577 env.insert(
579 "CLEANROOM_DETERMINISTIC_EXECUTION".to_string(),
580 self.execution.enable_deterministic_execution.to_string(),
581 );
582 env.insert(
583 "CLEANROOM_PARALLEL_EXECUTION".to_string(),
584 self.execution.enable_parallel_execution.to_string(),
585 );
586 env.insert(
587 "CLEANROOM_MAX_PARALLEL_TASKS".to_string(),
588 self.execution.max_parallel_tasks.to_string(),
589 );
590 env.insert(
591 "CLEANROOM_TEST_ISOLATION".to_string(),
592 self.execution.enable_test_isolation.to_string(),
593 );
594
595 env
596 }
597
598 pub fn summary(&self) -> String {
600 format!(
601 "Policy Summary:\n\
602 Security Level: {:?}\n\
603 Network Isolation: {}\n\
604 Filesystem Isolation: {}\n\
605 Process Isolation: {}\n\
606 Max CPU Usage: {}%\n\
607 Max Memory Usage: {} bytes\n\
608 Max Disk Usage: {} bytes\n\
609 Max Container Count: {}\n\
610 Deterministic Execution: {}\n\
611 Parallel Execution: {}\n\
612 Max Parallel Tasks: {}\n\
613 Test Isolation: {}",
614 self.security.security_level,
615 self.security.enable_network_isolation,
616 self.security.enable_filesystem_isolation,
617 self.security.enable_process_isolation,
618 self.resources.max_cpu_usage_percent,
619 self.resources.max_memory_usage_bytes,
620 self.resources.max_disk_usage_bytes,
621 self.resources.max_container_count,
622 self.execution.enable_deterministic_execution,
623 self.execution.enable_parallel_execution,
624 self.execution.max_parallel_tasks,
625 self.execution.enable_test_isolation
626 )
627 }
628}
629
630#[cfg(test)]
631mod tests {
632 use super::*;
633
634 #[allow(
636 clippy::unwrap_used,
637 clippy::expect_used,
638 clippy::indexing_slicing,
639 clippy::panic
640 )]
641 #[test]
642 fn test_policy_creation() {
643 let policy = Policy::new();
644 assert!(policy.validate().is_ok());
645 }
646
647 #[test]
648 fn test_policy_with_security_level() {
649 let policy = Policy::with_security_level(SecurityLevel::High);
650 assert_eq!(policy.security.security_level, SecurityLevel::High);
651 }
652
653 #[test]
654 fn test_policy_with_resource_limits() {
655 let policy = Policy::with_resource_limits(50.0, 512 * 1024 * 1024, 5 * 1024 * 1024 * 1024);
656 assert_eq!(policy.resources.max_cpu_usage_percent, 50.0);
657 assert_eq!(policy.resources.max_memory_usage_bytes, 512 * 1024 * 1024);
658 assert_eq!(
659 policy.resources.max_disk_usage_bytes,
660 5 * 1024 * 1024 * 1024
661 );
662 }
663
664 #[test]
665 fn test_policy_validation() {
666 let policy = Policy::new();
667 assert!(policy.validate().is_ok());
668 }
669
670 #[test]
671 fn test_policy_operation_allowed() -> Result<()> {
672 let policy = Policy::new();
673 let mut context = HashMap::new();
674 context.insert("port".to_string(), "5432".to_string());
675 context.insert("cpu_usage".to_string(), "50.0".to_string());
676 context.insert("memory_usage".to_string(), "256000000".to_string());
677
678 assert!(policy.is_operation_allowed("test_operation", &context)?);
679 Ok(())
680 }
681
682 #[test]
683 fn test_policy_operation_denied() -> Result<()> {
684 let policy = Policy::new();
685 let mut context = HashMap::new();
686 context.insert("port".to_string(), "9999".to_string()); context.insert("cpu_usage".to_string(), "90.0".to_string()); assert!(!policy.is_operation_allowed("test_operation", &context)?);
690 Ok(())
691 }
692
693 #[test]
694 fn test_policy_env_variables() {
695 let policy = Policy::new();
696 let env = policy.to_env();
697
698 assert!(env.contains_key("CLEANROOM_SECURITY_LEVEL"));
699 assert!(env.contains_key("CLEANROOM_NETWORK_ISOLATION"));
700 assert!(env.contains_key("CLEANROOM_MAX_CPU_PERCENT"));
701 assert!(env.contains_key("CLEANROOM_MAX_MEMORY_BYTES"));
702 }
703
704 #[test]
705 fn test_policy_summary() {
706 let policy = Policy::new();
707 let summary = policy.summary();
708
709 assert!(summary.contains("Policy Summary"));
710 assert!(summary.contains("Security Level"));
711 assert!(summary.contains("Network Isolation"));
712 }
713
714 #[test]
715 fn test_policy_default() {
716 let policy = Policy::default();
717
718 assert_eq!(policy.security.security_level, SecurityLevel::Standard);
719 assert!(policy.security.enable_network_isolation);
720 assert!(policy.security.enable_filesystem_isolation);
721 assert!(policy.security.enable_process_isolation);
722 assert!(policy.security.enable_data_redaction);
723 assert!(policy.security.enable_audit_logging);
724 }
725
726 #[test]
727 fn test_policy_new() {
728 let policy = Policy::new();
729
730 assert_eq!(policy.security.security_level, SecurityLevel::Standard);
731 assert!(policy.security.enable_network_isolation);
732 assert!(policy.security.enable_filesystem_isolation);
733 assert!(policy.security.enable_process_isolation);
734 assert!(policy.security.enable_data_redaction);
735 assert!(policy.security.enable_audit_logging);
736 }
737
738 #[test]
739 fn test_policy_serialization() -> Result<()> {
740 let policy = Policy::new();
741
742 let json = serde_json::to_string(&policy)
743 .map_err(|e| CleanroomError::internal_error(format!("Serialization failed: {}", e)))?;
744 let deserialized: Policy = serde_json::from_str(&json).map_err(|e| {
745 CleanroomError::internal_error(format!("Deserialization failed: {}", e))
746 })?;
747
748 assert_eq!(
749 policy.security.security_level,
750 deserialized.security.security_level
751 );
752 assert_eq!(
753 policy.security.enable_network_isolation,
754 deserialized.security.enable_network_isolation
755 );
756 assert_eq!(
757 policy.security.enable_filesystem_isolation,
758 deserialized.security.enable_filesystem_isolation
759 );
760 Ok(())
761 }
762
763 #[test]
764 fn test_security_policy() {
765 let security = SecurityPolicy::new();
766
767 assert_eq!(security.security_level, SecurityLevel::Standard);
768 assert!(security.enable_network_isolation);
769 assert!(security.enable_filesystem_isolation);
770 assert!(security.enable_process_isolation);
771 assert!(security.enable_data_redaction);
772 assert!(security.enable_audit_logging);
773 assert!(security.allowed_ports.contains(&5432)); assert!(security.allowed_ports.contains(&6379)); }
776
777 #[test]
778 fn test_security_policy_with_level() {
779 let security = SecurityPolicy::with_security_level(SecurityLevel::High);
780
781 assert_eq!(security.security_level, SecurityLevel::High);
782 assert!(security.enable_network_isolation);
783 assert!(security.enable_filesystem_isolation);
784 assert!(security.enable_process_isolation);
785 assert!(security.enable_data_redaction);
786 assert!(security.enable_audit_logging);
787 }
788
789 #[test]
790 fn test_security_level_serialization() -> Result<()> {
791 let levels = vec![
792 SecurityLevel::Low,
793 SecurityLevel::Standard,
794 SecurityLevel::High,
795 SecurityLevel::Locked,
796 ];
797
798 for level in levels {
799 let json = serde_json::to_string(&level).map_err(|e| {
800 CleanroomError::internal_error(format!("Serialization failed: {}", e))
801 })?;
802 let deserialized: SecurityLevel = serde_json::from_str(&json).map_err(|e| {
803 CleanroomError::internal_error(format!("Deserialization failed: {}", e))
804 })?;
805 assert_eq!(level, deserialized);
806 }
807 Ok(())
808 }
809
810 #[test]
811 fn test_resource_policy() {
812 let resources = ResourcePolicy::new();
813
814 assert_eq!(resources.max_cpu_usage_percent, 80.0);
815 assert_eq!(resources.max_memory_usage_bytes, 1024 * 1024 * 1024); assert_eq!(resources.max_disk_usage_bytes, 10 * 1024 * 1024 * 1024); assert_eq!(
818 resources.max_network_bandwidth_bytes_per_sec,
819 100 * 1024 * 1024
820 ); assert_eq!(resources.max_container_count, 10);
822 assert_eq!(resources.max_test_execution_time, Duration::from_secs(300));
823 }
824
825 #[test]
826 fn test_execution_policy() {
827 let execution = ExecutionPolicy::new();
828
829 assert!(execution.enable_deterministic_execution);
830 assert!(execution.enable_parallel_execution);
831 assert!(execution.enable_test_isolation);
832 assert!(execution.enable_retry_on_failure);
833 assert_eq!(execution.max_parallel_tasks, 4);
834 assert_eq!(execution.max_retry_attempts, 3);
835 assert_eq!(execution.test_timeout, Duration::from_secs(60));
836 }
837
838 #[test]
839 fn test_compliance_policy() {
840 let compliance = CompliancePolicy::new();
841
842 assert!(compliance.enable_compliance_reporting);
843 assert!(compliance.enable_audit_trails);
844 assert!(compliance.enable_policy_validation);
845 assert_eq!(
846 compliance.audit_retention_period,
847 Duration::from_secs(30 * 24 * 60 * 60)
848 ); }
850
851 #[test]
852 fn test_audit_level_serialization() -> Result<()> {
853 let levels = vec![
854 AuditLevel::Debug,
855 AuditLevel::Info,
856 AuditLevel::Warn,
857 AuditLevel::Error,
858 ];
859
860 for level in levels {
861 let json = serde_json::to_string(&level).map_err(|e| {
862 CleanroomError::internal_error(format!("Serialization failed: {}", e))
863 })?;
864 let deserialized: AuditLevel = serde_json::from_str(&json).map_err(|e| {
865 CleanroomError::internal_error(format!("Deserialization failed: {}", e))
866 })?;
867 assert_eq!(level, deserialized);
868 }
869 Ok(())
870 }
871
872 #[test]
873 fn test_policy_locked() {
874 let policy = Policy::locked();
875
876 assert_eq!(policy.security.security_level, SecurityLevel::Locked);
877 assert!(policy.security.enable_network_isolation);
878 assert!(policy.security.enable_filesystem_isolation);
879 assert!(policy.security.enable_process_isolation);
880 assert!(policy.security.enable_data_redaction);
881 assert!(policy.security.enable_audit_logging);
882 }
883
884 #[test]
885 fn test_policy_high_security() {
886 let policy = Policy::high_security();
887
888 assert_eq!(policy.security.security_level, SecurityLevel::High);
889 assert!(policy.security.enable_network_isolation);
890 assert!(policy.security.enable_filesystem_isolation);
891 assert!(policy.security.enable_process_isolation);
892 assert!(policy.security.enable_data_redaction);
893 assert!(policy.security.enable_audit_logging);
894 }
895
896 #[test]
897 fn test_policy_standard() {
898 let policy = Policy::standard();
899
900 assert_eq!(policy.security.security_level, SecurityLevel::Standard);
901 assert!(policy.security.enable_network_isolation);
902 assert!(policy.security.enable_filesystem_isolation);
903 assert!(policy.security.enable_process_isolation);
904 assert!(policy.security.enable_data_redaction);
905 assert!(policy.security.enable_audit_logging);
906 }
907
908 #[test]
909 fn test_policy_low_security() {
910 let policy = Policy::low_security();
911
912 assert_eq!(policy.security.security_level, SecurityLevel::Low);
913 assert!(!policy.security.enable_network_isolation);
914 assert!(!policy.security.enable_filesystem_isolation);
915 assert!(!policy.security.enable_process_isolation);
916 assert!(!policy.security.enable_data_redaction);
917 assert!(!policy.security.enable_audit_logging);
918 }
919
920 #[test]
921 fn test_policy_operation_allowed_with_valid_context() -> Result<()> {
922 let policy = Policy::new();
923 let mut context = HashMap::new();
924 context.insert("port".to_string(), "5432".to_string());
925 context.insert("cpu_usage".to_string(), "50.0".to_string());
926 context.insert("memory_usage".to_string(), "256000000".to_string());
927
928 assert!(policy.is_operation_allowed("test_operation", &context)?);
929 Ok(())
930 }
931
932 #[test]
933 fn test_policy_operation_denied_with_invalid_port() -> Result<()> {
934 let policy = Policy::new();
935 let mut context = HashMap::new();
936 context.insert("port".to_string(), "9999".to_string()); context.insert("cpu_usage".to_string(), "50.0".to_string());
938 context.insert("memory_usage".to_string(), "256000000".to_string());
939
940 assert!(!policy.is_operation_allowed("test_operation", &context)?);
941 Ok(())
942 }
943
944 #[test]
945 fn test_policy_operation_denied_with_high_cpu() -> Result<()> {
946 let policy = Policy::new();
947 let mut context = HashMap::new();
948 context.insert("port".to_string(), "5432".to_string());
949 context.insert("cpu_usage".to_string(), "90.0".to_string()); context.insert("memory_usage".to_string(), "256000000".to_string());
951
952 assert!(!policy.is_operation_allowed("test_operation", &context)?);
953 Ok(())
954 }
955
956 #[test]
957 fn test_policy_operation_denied_with_high_memory() -> Result<()> {
958 let policy = Policy::new();
959 let mut context = HashMap::new();
960 context.insert("port".to_string(), "5432".to_string());
961 context.insert("cpu_usage".to_string(), "50.0".to_string());
962 context.insert("memory_usage".to_string(), "2000000000".to_string()); assert!(!policy.is_operation_allowed("test_operation", &context)?);
965 Ok(())
966 }
967
968 #[test]
969 fn test_policy_env_variables_values() {
970 let policy = Policy::new();
971 let env = policy.to_env();
972
973 assert_eq!(
974 env.get("CLEANROOM_SECURITY_LEVEL"),
975 Some(&"Standard".to_string())
976 );
977 assert_eq!(
978 env.get("CLEANROOM_NETWORK_ISOLATION"),
979 Some(&"true".to_string())
980 );
981 assert_eq!(
982 env.get("CLEANROOM_MAX_CPU_PERCENT"),
983 Some(&"80".to_string())
984 );
985 assert_eq!(
986 env.get("CLEANROOM_MAX_MEMORY_BYTES"),
987 Some(&"1073741824".to_string())
988 );
989 }
990}