241 lines
7.8 KiB
Nim
241 lines
7.8 KiB
Nim
## 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..." |