clnrm_core/
policy.rs

1//! Policy enforcement for cleanroom testing
2//!
3//! This module provides comprehensive policy enforcement following core team best practices:
4//! - Security boundaries and isolation controls
5//! - Resource limits and constraints enforcement
6//! - Execution policies and compliance rules
7//! - Audit trails and compliance reporting
8//!
9//! ## Security Levels
10//!
11//! Cleanroom supports multiple security levels:
12//!
13//! - **Low**: Minimal isolation for development and debugging
14//! - **Medium**: Balanced security for most testing scenarios
15//! - **High**: Enhanced security for sensitive applications
16//! - **Maximum**: Maximum security with strict isolation
17//! - **Locked**: Maximum security with additional restrictions
18//!
19//! ## Usage Examples
20//!
21//! ### Basic Policy Creation
22//!
23//! ```no_run
24//! use clnrm::{Policy, SecurityLevel};
25//!
26//! // Create policy with specific security level
27//! let policy = Policy::with_security_level(SecurityLevel::High);
28//!
29//! // Create custom policy with resource limits
30//! let policy = Policy::with_resource_limits(
31//!     80.0,  // max CPU %
32//!     1024 * 1024 * 1024,  // max memory bytes (1GB)
33//!     10 * 1024 * 1024 * 1024,  // max disk bytes (10GB)
34//! );
35//! ```
36//!
37//! ### Security Policy Configuration
38//!
39//! ```no_run
40//! use clnrm::{Policy, SecurityPolicy};
41//!
42//! let mut policy = Policy::default();
43//! policy.security.enable_network_isolation = true;
44//! policy.security.enable_filesystem_isolation = true;
45//! policy.security.allowed_ports = vec![5432, 6379]; // PostgreSQL, Redis
46//! policy.security.blocked_addresses = vec!["127.0.0.1".to_string()];
47//! ```
48//!
49//! ### Policy Validation
50//!
51//! ```no_run
52//! use clnrm::Policy;
53//!
54//! let policy = Policy::locked();
55//!
56//! // Validate policy configuration
57//! if let Err(e) = policy.validate() {
58//!     eprintln!("Policy validation failed: {}", e);
59//!     // Handle validation errors
60//! }
61//! ```
62
63use crate::error::{CleanroomError, Result};
64use serde::{Deserialize, Serialize};
65use std::collections::HashMap;
66use std::time::Duration;
67
68/// Policy configuration for cleanroom testing
69#[derive(Debug, Clone, Default, Serialize, Deserialize)]
70pub struct Policy {
71    /// Security policy
72    pub security: SecurityPolicy,
73    /// Resource policy
74    pub resources: ResourcePolicy,
75    /// Execution policy
76    pub execution: ExecutionPolicy,
77    /// Compliance policy
78    pub compliance: CompliancePolicy,
79}
80
81/// Security policy configuration
82#[derive(Debug, Clone, Serialize, Deserialize)]
83pub struct SecurityPolicy {
84    /// Enable network isolation
85    pub enable_network_isolation: bool,
86    /// Enable filesystem isolation
87    pub enable_filesystem_isolation: bool,
88    /// Enable process isolation
89    pub enable_process_isolation: bool,
90    /// Allowed network ports
91    pub allowed_ports: Vec<u16>,
92    /// Blocked network addresses
93    pub blocked_addresses: Vec<String>,
94    /// Enable sensitive data redaction
95    pub enable_data_redaction: bool,
96    /// Redaction patterns
97    pub redaction_patterns: Vec<String>,
98    /// Enable audit logging
99    pub enable_audit_logging: bool,
100    /// Security level
101    pub security_level: SecurityLevel,
102}
103
104/// Resource policy configuration
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct ResourcePolicy {
107    /// Maximum CPU usage percentage
108    pub max_cpu_usage_percent: f64,
109    /// Maximum memory usage bytes
110    pub max_memory_usage_bytes: u64,
111    /// Maximum disk usage bytes
112    pub max_disk_usage_bytes: u64,
113    /// Maximum network bandwidth bytes per second
114    pub max_network_bandwidth_bytes_per_sec: u64,
115    /// Maximum container count
116    pub max_container_count: u32,
117    /// Maximum test execution time
118    pub max_test_execution_time: Duration,
119    /// Enable resource monitoring
120    pub enable_resource_monitoring: bool,
121    /// Resource cleanup timeout
122    pub resource_cleanup_timeout: Duration,
123}
124
125/// Execution policy configuration
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct ExecutionPolicy {
128    /// Enable deterministic execution
129    pub enable_deterministic_execution: bool,
130    /// Fixed seed for deterministic runs
131    pub deterministic_seed: Option<u64>,
132    /// Enable parallel execution
133    pub enable_parallel_execution: bool,
134    /// Maximum parallel tasks
135    pub max_parallel_tasks: u32,
136    /// Enable test isolation
137    pub enable_test_isolation: bool,
138    /// Test timeout
139    pub test_timeout: Duration,
140    /// Enable retry on failure
141    pub enable_retry_on_failure: bool,
142    /// Maximum retry attempts
143    pub max_retry_attempts: u32,
144    /// Retry delay
145    pub retry_delay: Duration,
146}
147
148/// Compliance policy configuration
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct CompliancePolicy {
151    /// Enable compliance reporting
152    pub enable_compliance_reporting: bool,
153    /// Compliance standards
154    pub compliance_standards: Vec<ComplianceStandard>,
155    /// Enable audit trails
156    pub enable_audit_trails: bool,
157    /// Audit retention period
158    pub audit_retention_period: Duration,
159    /// Enable policy validation
160    pub enable_policy_validation: bool,
161    /// Policy validation rules
162    pub policy_validation_rules: Vec<PolicyValidationRule>,
163}
164
165/// Security level enumeration
166#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
167pub enum SecurityLevel {
168    /// Low security level
169    Low,
170    /// Medium security level
171    Medium,
172    /// High security level
173    High,
174    /// Maximum security level
175    Maximum,
176    /// Standard security level
177    Standard,
178    /// Locked security level
179    Locked,
180}
181
182/// Audit level enumeration
183#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
184pub enum AuditLevel {
185    /// Debug audit level
186    Debug,
187    /// Info audit level
188    Info,
189    /// Warning audit level
190    Warn,
191    /// Error audit level
192    Error,
193}
194
195/// Compliance standard enumeration
196#[derive(Debug, Clone, Serialize, Deserialize)]
197pub enum ComplianceStandard {
198    /// SOC 2 compliance
199    Soc2,
200    /// ISO 27001 compliance
201    Iso27001,
202    /// PCI DSS compliance
203    PciDss,
204    /// HIPAA compliance
205    Hipaa,
206    /// GDPR compliance
207    Gdpr,
208    /// Custom compliance standard
209    Custom(String),
210}
211
212/// Policy validation rule
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct PolicyValidationRule {
215    /// Rule name
216    pub name: String,
217    /// Rule description
218    pub description: String,
219    /// Rule condition
220    pub condition: String,
221    /// Rule action
222    pub action: PolicyValidationAction,
223    /// Rule severity
224    pub severity: PolicyValidationSeverity,
225}
226
227/// Policy validation action
228#[derive(Debug, Clone, Serialize, Deserialize)]
229pub enum PolicyValidationAction {
230    /// Allow operation
231    Allow,
232    /// Deny operation
233    Deny,
234    /// Warn about operation
235    Warn,
236    /// Require approval
237    RequireApproval,
238}
239
240/// Policy validation severity
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub enum PolicyValidationSeverity {
243    /// Low severity
244    Low,
245    /// Medium severity
246    Medium,
247    /// High severity
248    High,
249    /// Critical severity
250    Critical,
251}
252
253impl SecurityPolicy {
254    /// Create a new security policy with default settings
255    pub fn new() -> Self {
256        Self::default()
257    }
258
259    /// Create a security policy with a specific security level
260    pub fn with_security_level(security_level: SecurityLevel) -> Self {
261        let mut policy = Self {
262            security_level,
263            ..Default::default()
264        };
265
266        // Adjust isolation settings based on security level
267        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                // Keep default settings
277            }
278            SecurityLevel::High | SecurityLevel::Maximum | SecurityLevel::Locked => {
279                // Keep all isolation enabled (default)
280            }
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    /// Create a new resource policy with default settings
309    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, // 1GB
319            max_disk_usage_bytes: 10 * 1024 * 1024 * 1024, // 10GB
320            max_network_bandwidth_bytes_per_sec: 100 * 1024 * 1024, // 100MB/s
321            max_container_count: 10,
322            max_test_execution_time: Duration::from_secs(300), // 5 minutes
323            enable_resource_monitoring: true,
324            resource_cleanup_timeout: Duration::from_secs(30),
325        }
326    }
327}
328
329impl ExecutionPolicy {
330    /// Create a new execution policy with default settings
331    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    /// Create a new compliance policy with default settings
354    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), // 30 days
366            enable_policy_validation: true,
367            policy_validation_rules: vec![],
368        }
369    }
370}
371
372impl Policy {
373    /// Create a new policy with default values
374    pub fn new() -> Self {
375        Self::default()
376    }
377
378    /// Create a policy with custom security level
379    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    /// Create a policy with custom resource limits
387    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    /// Create a locked-down policy with maximum security
400    pub fn locked() -> Self {
401        Self::with_security_level(SecurityLevel::Locked)
402    }
403
404    /// Create a high security policy
405    pub fn high_security() -> Self {
406        Self::with_security_level(SecurityLevel::High)
407    }
408
409    /// Create a standard security policy
410    pub fn standard() -> Self {
411        Self::with_security_level(SecurityLevel::Standard)
412    }
413
414    /// Create a low security policy
415    pub fn low_security() -> Self {
416        Self::with_security_level(SecurityLevel::Low)
417    }
418
419    /// Disable network access
420    pub fn with_network_disabled(mut self) -> Self {
421        self.security.enable_network_isolation = true;
422        self
423    }
424
425    /// Set network isolation
426    pub fn with_network_isolation(mut self, enable: bool) -> Self {
427        self.security.enable_network_isolation = enable;
428        self
429    }
430
431    /// Check if network access is allowed
432    pub fn allows_network(&self) -> bool {
433        !self.security.enable_network_isolation
434    }
435
436    /// Validate policy configuration
437    pub fn validate(&self) -> Result<()> {
438        // Validate security policy
439        if self.security.allowed_ports.is_empty() {
440            return Err(CleanroomError::policy_violation_error(
441                "No allowed ports configured",
442            ));
443        }
444
445        // Validate resource policy
446        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        // Validate execution policy
467        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    /// Check if operation is allowed by policy
483    pub fn is_operation_allowed(
484        &self,
485        _operation: &str,
486        context: &HashMap<String, String>,
487    ) -> Result<bool> {
488        // Check security policy
489        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        // Check resource policy
500        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        // Check execution policy
517        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    /// Get environment variables for policy enforcement
529    pub fn to_env(&self) -> HashMap<String, String> {
530        let mut env = HashMap::new();
531
532        // Security policy environment variables
533        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        // Resource policy environment variables
560        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        // Execution policy environment variables
578        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    /// Get policy summary
599    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 unwrap/expect in tests as they are expected to panic on failure
635    #[allow(clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing, clippy::panic)]
636
637    #[test]
638    fn test_policy_creation() {
639        let policy = Policy::new();
640        assert!(policy.validate().is_ok());
641    }
642
643    #[test]
644    fn test_policy_with_security_level() {
645        let policy = Policy::with_security_level(SecurityLevel::High);
646        assert_eq!(policy.security.security_level, SecurityLevel::High);
647    }
648
649    #[test]
650    fn test_policy_with_resource_limits() {
651        let policy = Policy::with_resource_limits(50.0, 512 * 1024 * 1024, 5 * 1024 * 1024 * 1024);
652        assert_eq!(policy.resources.max_cpu_usage_percent, 50.0);
653        assert_eq!(policy.resources.max_memory_usage_bytes, 512 * 1024 * 1024);
654        assert_eq!(
655            policy.resources.max_disk_usage_bytes,
656            5 * 1024 * 1024 * 1024
657        );
658    }
659
660    #[test]
661    fn test_policy_validation() {
662        let policy = Policy::new();
663        assert!(policy.validate().is_ok());
664    }
665
666    #[test]
667    fn test_policy_operation_allowed() {
668        let policy = Policy::new();
669        let mut context = HashMap::new();
670        context.insert("port".to_string(), "5432".to_string());
671        context.insert("cpu_usage".to_string(), "50.0".to_string());
672        context.insert("memory_usage".to_string(), "256000000".to_string());
673
674        assert!(policy
675            .is_operation_allowed("test_operation", &context)
676            .unwrap());
677    }
678
679    #[test]
680    fn test_policy_operation_denied() {
681        let policy = Policy::new();
682        let mut context = HashMap::new();
683        context.insert("port".to_string(), "9999".to_string()); // Not in allowed ports
684        context.insert("cpu_usage".to_string(), "90.0".to_string()); // Exceeds limit
685
686        assert!(!policy
687            .is_operation_allowed("test_operation", &context)
688            .unwrap());
689    }
690
691    #[test]
692    fn test_policy_env_variables() {
693        let policy = Policy::new();
694        let env = policy.to_env();
695
696        assert!(env.contains_key("CLEANROOM_SECURITY_LEVEL"));
697        assert!(env.contains_key("CLEANROOM_NETWORK_ISOLATION"));
698        assert!(env.contains_key("CLEANROOM_MAX_CPU_PERCENT"));
699        assert!(env.contains_key("CLEANROOM_MAX_MEMORY_BYTES"));
700    }
701
702    #[test]
703    fn test_policy_summary() {
704        let policy = Policy::new();
705        let summary = policy.summary();
706
707        assert!(summary.contains("Policy Summary"));
708        assert!(summary.contains("Security Level"));
709        assert!(summary.contains("Network Isolation"));
710    }
711
712    #[test]
713    fn test_policy_default() {
714        let policy = Policy::default();
715
716        assert_eq!(policy.security.security_level, SecurityLevel::Standard);
717        assert!(policy.security.enable_network_isolation);
718        assert!(policy.security.enable_filesystem_isolation);
719        assert!(policy.security.enable_process_isolation);
720        assert!(policy.security.enable_data_redaction);
721        assert!(policy.security.enable_audit_logging);
722    }
723
724    #[test]
725    fn test_policy_new() {
726        let policy = Policy::new();
727
728        assert_eq!(policy.security.security_level, SecurityLevel::Standard);
729        assert!(policy.security.enable_network_isolation);
730        assert!(policy.security.enable_filesystem_isolation);
731        assert!(policy.security.enable_process_isolation);
732        assert!(policy.security.enable_data_redaction);
733        assert!(policy.security.enable_audit_logging);
734    }
735
736    #[test]
737    fn test_policy_serialization() {
738        let policy = Policy::new();
739
740        let json = serde_json::to_string(&policy).unwrap();
741        let deserialized: Policy = serde_json::from_str(&json).unwrap();
742
743        assert_eq!(
744            policy.security.security_level,
745            deserialized.security.security_level
746        );
747        assert_eq!(
748            policy.security.enable_network_isolation,
749            deserialized.security.enable_network_isolation
750        );
751        assert_eq!(
752            policy.security.enable_filesystem_isolation,
753            deserialized.security.enable_filesystem_isolation
754        );
755    }
756
757    #[test]
758    fn test_security_policy() {
759        let security = SecurityPolicy::new();
760
761        assert_eq!(security.security_level, SecurityLevel::Standard);
762        assert!(security.enable_network_isolation);
763        assert!(security.enable_filesystem_isolation);
764        assert!(security.enable_process_isolation);
765        assert!(security.enable_data_redaction);
766        assert!(security.enable_audit_logging);
767        assert!(security.allowed_ports.contains(&5432)); // PostgreSQL
768        assert!(security.allowed_ports.contains(&6379)); // Redis
769    }
770
771    #[test]
772    fn test_security_policy_with_level() {
773        let security = SecurityPolicy::with_security_level(SecurityLevel::High);
774
775        assert_eq!(security.security_level, SecurityLevel::High);
776        assert!(security.enable_network_isolation);
777        assert!(security.enable_filesystem_isolation);
778        assert!(security.enable_process_isolation);
779        assert!(security.enable_data_redaction);
780        assert!(security.enable_audit_logging);
781    }
782
783    #[test]
784    fn test_security_level_serialization() {
785        let levels = vec![
786            SecurityLevel::Low,
787            SecurityLevel::Standard,
788            SecurityLevel::High,
789            SecurityLevel::Locked,
790        ];
791
792        for level in levels {
793            let json = serde_json::to_string(&level).unwrap();
794            let deserialized: SecurityLevel = serde_json::from_str(&json).unwrap();
795            assert_eq!(level, deserialized);
796        }
797    }
798
799    #[test]
800    fn test_resource_policy() {
801        let resources = ResourcePolicy::new();
802
803        assert_eq!(resources.max_cpu_usage_percent, 80.0);
804        assert_eq!(resources.max_memory_usage_bytes, 1024 * 1024 * 1024); // 1GB
805        assert_eq!(resources.max_disk_usage_bytes, 10 * 1024 * 1024 * 1024); // 10GB
806        assert_eq!(
807            resources.max_network_bandwidth_bytes_per_sec,
808            100 * 1024 * 1024
809        ); // 100MB/s
810        assert_eq!(resources.max_container_count, 10);
811        assert_eq!(resources.max_test_execution_time, Duration::from_secs(300));
812    }
813
814    #[test]
815    fn test_execution_policy() {
816        let execution = ExecutionPolicy::new();
817
818        assert!(execution.enable_deterministic_execution);
819        assert!(execution.enable_parallel_execution);
820        assert!(execution.enable_test_isolation);
821        assert!(execution.enable_retry_on_failure);
822        assert_eq!(execution.max_parallel_tasks, 4);
823        assert_eq!(execution.max_retry_attempts, 3);
824        assert_eq!(execution.test_timeout, Duration::from_secs(60));
825    }
826
827    #[test]
828    fn test_compliance_policy() {
829        let compliance = CompliancePolicy::new();
830
831        assert!(compliance.enable_compliance_reporting);
832        assert!(compliance.enable_audit_trails);
833        assert!(compliance.enable_policy_validation);
834        assert_eq!(
835            compliance.audit_retention_period,
836            Duration::from_secs(30 * 24 * 60 * 60)
837        ); // 30 days
838    }
839
840    #[test]
841    fn test_audit_level_serialization() {
842        let levels = vec![
843            AuditLevel::Debug,
844            AuditLevel::Info,
845            AuditLevel::Warn,
846            AuditLevel::Error,
847        ];
848
849        for level in levels {
850            let json = serde_json::to_string(&level).unwrap();
851            let deserialized: AuditLevel = serde_json::from_str(&json).unwrap();
852            assert_eq!(level, deserialized);
853        }
854    }
855
856    #[test]
857    fn test_policy_locked() {
858        let policy = Policy::locked();
859
860        assert_eq!(policy.security.security_level, SecurityLevel::Locked);
861        assert!(policy.security.enable_network_isolation);
862        assert!(policy.security.enable_filesystem_isolation);
863        assert!(policy.security.enable_process_isolation);
864        assert!(policy.security.enable_data_redaction);
865        assert!(policy.security.enable_audit_logging);
866    }
867
868    #[test]
869    fn test_policy_high_security() {
870        let policy = Policy::high_security();
871
872        assert_eq!(policy.security.security_level, SecurityLevel::High);
873        assert!(policy.security.enable_network_isolation);
874        assert!(policy.security.enable_filesystem_isolation);
875        assert!(policy.security.enable_process_isolation);
876        assert!(policy.security.enable_data_redaction);
877        assert!(policy.security.enable_audit_logging);
878    }
879
880    #[test]
881    fn test_policy_standard() {
882        let policy = Policy::standard();
883
884        assert_eq!(policy.security.security_level, SecurityLevel::Standard);
885        assert!(policy.security.enable_network_isolation);
886        assert!(policy.security.enable_filesystem_isolation);
887        assert!(policy.security.enable_process_isolation);
888        assert!(policy.security.enable_data_redaction);
889        assert!(policy.security.enable_audit_logging);
890    }
891
892    #[test]
893    fn test_policy_low_security() {
894        let policy = Policy::low_security();
895
896        assert_eq!(policy.security.security_level, SecurityLevel::Low);
897        assert!(!policy.security.enable_network_isolation);
898        assert!(!policy.security.enable_filesystem_isolation);
899        assert!(!policy.security.enable_process_isolation);
900        assert!(!policy.security.enable_data_redaction);
901        assert!(!policy.security.enable_audit_logging);
902    }
903
904    #[test]
905    fn test_policy_operation_allowed_with_valid_context() {
906        let policy = Policy::new();
907        let mut context = HashMap::new();
908        context.insert("port".to_string(), "5432".to_string());
909        context.insert("cpu_usage".to_string(), "50.0".to_string());
910        context.insert("memory_usage".to_string(), "256000000".to_string());
911
912        assert!(policy
913            .is_operation_allowed("test_operation", &context)
914            .unwrap());
915    }
916
917    #[test]
918    fn test_policy_operation_denied_with_invalid_port() {
919        let policy = Policy::new();
920        let mut context = HashMap::new();
921        context.insert("port".to_string(), "9999".to_string()); // Not in allowed ports
922        context.insert("cpu_usage".to_string(), "50.0".to_string());
923        context.insert("memory_usage".to_string(), "256000000".to_string());
924
925        assert!(!policy
926            .is_operation_allowed("test_operation", &context)
927            .unwrap());
928    }
929
930    #[test]
931    fn test_policy_operation_denied_with_high_cpu() {
932        let policy = Policy::new();
933        let mut context = HashMap::new();
934        context.insert("port".to_string(), "5432".to_string());
935        context.insert("cpu_usage".to_string(), "90.0".to_string()); // Exceeds limit
936        context.insert("memory_usage".to_string(), "256000000".to_string());
937
938        assert!(!policy
939            .is_operation_allowed("test_operation", &context)
940            .unwrap());
941    }
942
943    #[test]
944    fn test_policy_operation_denied_with_high_memory() {
945        let policy = Policy::new();
946        let mut context = HashMap::new();
947        context.insert("port".to_string(), "5432".to_string());
948        context.insert("cpu_usage".to_string(), "50.0".to_string());
949        context.insert("memory_usage".to_string(), "2000000000".to_string()); // Exceeds limit
950
951        assert!(!policy
952            .is_operation_allowed("test_operation", &context)
953            .unwrap());
954    }
955
956    #[test]
957    fn test_policy_env_variables_values() {
958        let policy = Policy::new();
959        let env = policy.to_env();
960
961        assert_eq!(
962            env.get("CLEANROOM_SECURITY_LEVEL"),
963            Some(&"Standard".to_string())
964        );
965        assert_eq!(
966            env.get("CLEANROOM_NETWORK_ISOLATION"),
967            Some(&"true".to_string())
968        );
969        assert_eq!(
970            env.get("CLEANROOM_MAX_CPU_PERCENT"),
971            Some(&"80".to_string())
972        );
973        assert_eq!(
974            env.get("CLEANROOM_MAX_MEMORY_BYTES"),
975            Some(&"1073741824".to_string())
976        );
977    }
978}