## tests/test_integrity_monitoring.nim ## Tests for integrity monitoring and health checks implementation ## ## This module tests the enhanced integrity monitoring system including: ## - nip verify command with --all support ## - nip doctor --integrity health checks ## - Periodic integrity scanning ## - Real-time filesystem monitoring ## - Integration with runHealthChecks() framework import std/[unittest, os, times, json, asyncdispatch] import ../src/nimpak/security/[integrity_monitor, periodic_scanner] import ../src/nimpak/cli/verify_commands suite "Integrity Monitoring Tests": setup: # Create test environment if not dirExists("/tmp/test_programs"): createDir("/tmp/test_programs") if not dirExists("/tmp/test_programs/TestPackage"): createDir("/tmp/test_programs/TestPackage") if not dirExists("/tmp/test_programs/TestPackage/1.0.0"): createDir("/tmp/test_programs/TestPackage/1.0.0") # Create a test package file writeFile("/tmp/test_programs/TestPackage/1.0.0/TestPackage.npk", "test package content") writeFile("/tmp/test_programs/TestPackage/1.0.0/TestPackage.manifest.json", """ { "package_hash": "blake2b-test123456789abcdef", "version": "1.0.0", "files": ["TestPackage.npk"] } """) teardown: # Clean up test environment if dirExists("/tmp/test_programs"): removeDir("/tmp/test_programs") test "Integrity Monitor Initialization": let config = getDefaultIntegrityConfig() let monitor = newIntegrityMonitor(config) check monitor.monitoringEnabled == true check monitor.config.enableRealtimeWatcher == true check monitor.config.scanInterval == 3600 check monitor.violationCount == 0 test "Package Integrity Verification": let result = verifyPackageIntegrity("TestPackage", "/tmp/test_programs/TestPackage/1.0.0/TestPackage.npk") check result.packageName == "TestPackage" check result.checkType == CheckFileIntegrity check result.duration >= 0.0 # Note: This test may fail due to hash mismatch, which is expected for test data test "Health Check Registration": registerIntegrityHealthChecks() # Check that health checks were registered check registeredHealthChecks.len > 0 # Find integrity-related health checks var foundIntegrityCheck = false for healthCheck in registeredHealthChecks: if healthCheck.name == "package-integrity": foundIntegrityCheck = true break check foundIntegrityCheck == true test "Verify Command Options Parsing": let options1 = parseVerifyCommandOptions(@["--all", "--verbose", "--auto-repair"]) check options1.target == "--all" check options1.verbose == true check options1.autoRepair == true check options1.checkSignatures == true check options1.checkHashes == true let options2 = parseVerifyCommandOptions(@["TestPackage", "--no-signatures", "--hashes-only"]) check options2.target == "TestPackage" check options2.checkSignatures == false check options2.checkHashes == true test "Doctor Integrity Options Parsing": let options1 = parseDoctorIntegrityOptions(@["--auto-repair", "--verbose"]) check options1.autoRepair == true check options1.verbose == true check options1.showRecommendations == true let options2 = parseDoctorIntegrityOptions(@["--no-recommendations"]) check options2.showRecommendations == false test "Periodic Scanner Configuration": let schedule = getDefaultScanSchedule() check schedule.enabled == true check schedule.fullScanInterval == 24 check schedule.incrementalInterval == 15 check schedule.fullScanHour == 2 let config = getDefaultIntegrityConfig() let monitor = newIntegrityMonitor(config) let scanner = newPeriodicScanner(schedule, monitor) check scanner.schedule.enabled == true check scanner.isRunning == false check scanner.scanHistory.len == 0 test "Scan ID Generation": let scanId1 = generateScanId("full") let scanId2 = generateScanId("incremental") check scanId1.startsWith("scan_full_") check scanId2.startsWith("scan_incremental_") check scanId1 != scanId2 test "Integrity Alert Generation": var reporter = newIntegrityReporter(5) let violation = IntegrityViolation( violationType: "file_modified", packageName: "TestPackage", filePath: "/tmp/test_programs/TestPackage/1.0.0/TestPackage.npk", expectedHash: "blake2b-expected123", actualHash: "blake2b-actual456", detectedAt: now(), severity: SeverityCritical ) let alert = reporter.generateAlert(violation) check alert.packageName == "TestPackage" check alert.severity == SeverityCritical check alert.acknowledged == false check reporter.alertHistory.len == 1 test "Alert Summary Generation": var reporter = newIntegrityReporter(3) # Generate multiple alerts for i in 1..5: let violation = IntegrityViolation( violationType: "test_violation", packageName: fmt"Package{i}", filePath: fmt"/tmp/package{i}", expectedHash: "hash1", actualHash: "hash2", detectedAt: now(), severity: if i <= 2: SeverityCritical else: SeverityWarning ) discard reporter.generateAlert(violation) let summary = reporter.getAlertSummary() check summary["total_alerts"].getInt() == 5 check summary["active_alerts"].getInt() == 5 check summary["severity_breakdown"]["critical"].getInt() == 2 check summary["severity_breakdown"]["warning"].getInt() == 3 check summary["threshold_exceeded"].getBool() == true test "Scan Statistics Calculation": let schedule = getDefaultScanSchedule() let config = getDefaultIntegrityConfig() let monitor = newIntegrityMonitor(config) var scanner = newPeriodicScanner(schedule, monitor) # Add some mock scan results let mockResult1 = ScanResult( scanId: "test1", scanType: "full", startTime: now(), endTime: now(), duration: 10.5, packagesScanned: 100, issuesFound: 0, results: @[], success: true ) let mockResult2 = ScanResult( scanId: "test2", scanType: "incremental", startTime: now(), endTime: now(), duration: 2.3, packagesScanned: 5, issuesFound: 1, results: @[], success: false ) scanner.scanHistory.add(mockResult1) scanner.scanHistory.add(mockResult2) let stats = scanner.getScanStatistics() check stats["total_scans"].getInt() == 2 check stats["successful_scans"].getInt() == 1 check stats["failed_scans"].getInt() == 1 check stats["success_rate"].getFloat() == 0.5 check stats["total_packages_scanned"].getInt() == 105 check stats["total_issues_found"].getInt() == 1 suite "Async Integrity Monitoring Tests": test "Periodic Scanner Scheduling Logic": let schedule = ScanSchedule( enabled: true, fullScanInterval: 24, incrementalInterval: 15, fullScanHour: 2, maxConcurrentScans: 2, scanTimeout: 3600 ) let config = getDefaultIntegrityConfig() let monitor = newIntegrityMonitor(config) var scanner = newPeriodicScanner(schedule, monitor) # Test when no previous scans # Note: This test depends on current time, so we'll just check the logic exists let shouldRunFull = scanner.shouldRunFullScan() let shouldRunIncremental = scanner.shouldRunIncrementalScan() # These are time-dependent, so we just verify they return boolean values check shouldRunFull is bool check shouldRunIncremental is bool test "Health Check Framework Integration": # Initialize health checks registerIntegrityHealthChecks() # Run health checks let results = runHealthChecks() # Verify that health checks were executed # Note: Results may vary based on system state check results is seq[IntegrityCheckResult] echo "Running integrity monitoring tests..."