## Tests for platform detection and isolation strategy selection ## ## Property-Based Tests: ## - Property 14: Platform Detection Accuracy ## - Property 15: Strategy Selection Correctness ## - Property 16: Mode Selection Logic import std/[unittest, options] import ../src/nip/platform suite "Platform Detection": test "detectOSType returns valid OS type": ## Test that OS type detection returns a valid value let osType = detectOSType() check osType in [Linux, FreeBSD, OpenBSD, NetBSD, macOS, Embedded] test "getOSTypeString returns non-empty string": ## Test that OS type string conversion works let osType = detectOSType() let osStr = getOSTypeString(osType) check osStr.len > 0 test "getKernelVersion returns non-empty string": ## Test that kernel version detection works let version = getKernelVersion() check version.len > 0 check version != "unknown" or true # May be unknown on some systems test "parseKernelVersion handles valid version strings": ## Test kernel version parsing let (major, minor, patch) = parseKernelVersion("5.10.0") check major == 5 check minor == 10 check patch == 0 test "parseKernelVersion handles version with suffix": ## Test kernel version parsing with suffix let (major, minor, patch) = parseKernelVersion("5.10.0-generic") check major == 5 check minor == 10 check patch == 0 test "parseKernelVersion handles incomplete versions": ## Test kernel version parsing with incomplete version let (major, minor, patch) = parseKernelVersion("5.10") check major == 5 check minor == 10 check patch == 0 test "getMemoryTotal returns positive value": ## Test that memory detection returns a positive value let memory = getMemoryTotal() check memory >= 0 # May be 0 on some systems test "getCPUCount returns positive value": ## Test that CPU count detection returns a positive value let cpuCount = getCPUCount() check cpuCount > 0 test "detectEmbeddedDevice returns boolean": ## Test that embedded device detection returns a boolean let isEmbedded = detectEmbeddedDevice() check isEmbedded in [true, false] suite "Platform Capabilities": test "detectPlatform returns valid capabilities": ## Property 14: Platform Detection Accuracy ## For any platform, detectPlatform() SHALL return accurate capabilities let caps = detectPlatform() # Verify OS type is valid check caps.osType in [Linux, FreeBSD, OpenBSD, NetBSD, macOS, Embedded] # Verify kernel version is non-empty check caps.kernelVersion.len >= 0 # Verify memory and CPU are non-negative check caps.memoryTotal >= 0 check caps.cpuCount > 0 test "detectPlatform consistency": ## Test that multiple calls return consistent results let caps1 = detectPlatform() let caps2 = detectPlatform() check caps1.osType == caps2.osType check caps1.isRoot == caps2.isRoot check caps1.isEmbedded == caps2.isEmbedded test "detectPlatform Linux capabilities": ## Test Linux-specific capability detection when defined(linux): let caps = detectPlatform() check caps.osType == Linux check caps.hasJails == false check caps.hasUnveil == false test "detectPlatform FreeBSD capabilities": ## Test FreeBSD-specific capability detection when defined(freebsd): let caps = detectPlatform() check caps.osType == FreeBSD check caps.hasUserNamespaces == false check caps.hasUnveil == false test "detectPlatform OpenBSD capabilities": ## Test OpenBSD-specific capability detection when defined(openbsd): let caps = detectPlatform() check caps.osType == OpenBSD check caps.hasUserNamespaces == false check caps.hasJails == false suite "Isolation Strategy Selection": test "selectStrategy returns valid strategy": ## Property 15: Strategy Selection Correctness ## For any platform capabilities, selectStrategy() SHALL return a valid strategy let caps = detectPlatform() let strategy = selectStrategy(caps) check strategy in [LinuxNamespace, FreeBSDJail, OpenBSDUnveil, POSIXFallback] test "selectStrategy Linux with namespaces": ## Test strategy selection for Linux with namespace support var caps = PlatformCapabilities( osType: Linux, hasUserNamespaces: true, hasJails: false, hasUnveil: false, isRoot: false, kernelVersion: "5.10.0", isEmbedded: false, memoryTotal: 8 * 1024 * 1024 * 1024, cpuCount: 4 ) let strategy = selectStrategy(caps) check strategy == LinuxNamespace test "selectStrategy Linux without namespaces": ## Test strategy selection for Linux without namespace support var caps = PlatformCapabilities( osType: Linux, hasUserNamespaces: false, hasJails: false, hasUnveil: false, isRoot: false, kernelVersion: "4.4.0", isEmbedded: false, memoryTotal: 8 * 1024 * 1024 * 1024, cpuCount: 4 ) let strategy = selectStrategy(caps) check strategy == POSIXFallback test "selectStrategy FreeBSD with jails": ## Test strategy selection for FreeBSD with jail support var caps = PlatformCapabilities( osType: FreeBSD, hasUserNamespaces: false, hasJails: true, hasUnveil: false, isRoot: true, kernelVersion: "11.0", isEmbedded: false, memoryTotal: 8 * 1024 * 1024 * 1024, cpuCount: 4 ) let strategy = selectStrategy(caps) check strategy == FreeBSDJail test "selectStrategy FreeBSD without jails": ## Test strategy selection for FreeBSD without jail support var caps = PlatformCapabilities( osType: FreeBSD, hasUserNamespaces: false, hasJails: false, hasUnveil: false, isRoot: false, kernelVersion: "10.0", isEmbedded: false, memoryTotal: 8 * 1024 * 1024 * 1024, cpuCount: 4 ) let strategy = selectStrategy(caps) check strategy == POSIXFallback test "selectStrategy OpenBSD with unveil": ## Test strategy selection for OpenBSD with unveil support var caps = PlatformCapabilities( osType: OpenBSD, hasUserNamespaces: false, hasJails: false, hasUnveil: true, isRoot: true, kernelVersion: "6.4", isEmbedded: false, memoryTotal: 8 * 1024 * 1024 * 1024, cpuCount: 4 ) let strategy = selectStrategy(caps) check strategy == OpenBSDUnveil test "selectStrategy OpenBSD without unveil": ## Test strategy selection for OpenBSD without unveil support var caps = PlatformCapabilities( osType: OpenBSD, hasUserNamespaces: false, hasJails: false, hasUnveil: false, isRoot: false, kernelVersion: "6.3", isEmbedded: false, memoryTotal: 8 * 1024 * 1024 * 1024, cpuCount: 4 ) let strategy = selectStrategy(caps) check strategy == POSIXFallback test "selectStrategy embedded device": ## Test strategy selection for embedded device var caps = PlatformCapabilities( osType: Linux, hasUserNamespaces: false, hasJails: false, hasUnveil: false, isRoot: false, kernelVersion: "4.14.0", isEmbedded: true, memoryTotal: 256 * 1024 * 1024, cpuCount: 1 ) let strategy = selectStrategy(caps) check strategy == POSIXFallback suite "Installation Mode Selection": test "selectMode returns valid mode": ## Property 16: Mode Selection Logic ## For any strategy, selectMode() SHALL return a valid mode let caps = detectPlatform() let strategy = selectStrategy(caps) let mode = selectMode(strategy, none(InstallMode)) check mode in [UserMode, SystemMode] test "selectMode Linux namespace prefers user mode": ## Test that Linux namespace strategy prefers user mode let strategy = LinuxNamespace let mode = selectMode(strategy, none(InstallMode)) check mode == UserMode test "selectMode FreeBSD jail requires system mode": ## Test that FreeBSD jail strategy requires system mode let strategy = FreeBSDJail let mode = selectMode(strategy, none(InstallMode)) check mode == SystemMode test "selectMode OpenBSD unveil requires system mode": ## Test that OpenBSD unveil strategy requires system mode let strategy = OpenBSDUnveil let mode = selectMode(strategy, none(InstallMode)) check mode == SystemMode test "selectMode POSIX fallback as root": ## Test POSIX fallback mode selection as root let strategy = POSIXFallback let mode = selectMode(strategy, none(InstallMode)) # Mode depends on whether running as root check mode in [UserMode, SystemMode] test "selectMode respects user request for valid strategy": ## Test that user request is respected when valid let strategy = LinuxNamespace let mode = selectMode(strategy, some(UserMode)) check mode == UserMode test "selectMode falls back on invalid user request": ## Test that invalid user request falls back gracefully let strategy = FreeBSDJail let mode = selectMode(strategy, some(UserMode)) # Should fall back to SystemMode since FreeBSD jail doesn't support user mode check mode == SystemMode suite "Strategy Information": test "getStrategyDescription returns non-empty string": ## Test that strategy descriptions are available for strategy in [LinuxNamespace, FreeBSDJail, OpenBSDUnveil, POSIXFallback]: let desc = getStrategyDescription(strategy) check desc.len > 0 test "getSecurityLevel returns valid level": ## Test that security levels are valid (1-5) for strategy in [LinuxNamespace, FreeBSDJail, OpenBSDUnveil, POSIXFallback]: let level = getSecurityLevel(strategy) check level >= 1 and level <= 5 test "getStrategyInfo returns non-empty string": ## Test that strategy info is available for strategy in [LinuxNamespace, FreeBSDJail, OpenBSDUnveil, POSIXFallback]: let info = getStrategyInfo(strategy) check info.len > 0 test "security levels are reasonable": ## Test that security levels make sense check getSecurityLevel(LinuxNamespace) == 5 check getSecurityLevel(FreeBSDJail) == 5 check getSecurityLevel(OpenBSDUnveil) == 4 check getSecurityLevel(POSIXFallback) == 1 suite "Embedded Device Constraints": test "getEmbeddedConstraints returns valid constraints": ## Test that embedded constraints are valid let constraints = getEmbeddedConstraints() check constraints.maxConcurrentDownloads > 0 check constraints.maxConcurrentBuilds > 0 check constraints.maxCacheSize > 0 test "embedded constraints are reasonable": ## Test that embedded constraints are reasonable let constraints = getEmbeddedConstraints() # Downloads should be limited check constraints.maxConcurrentDownloads <= 4 # Builds should be single-threaded check constraints.maxConcurrentBuilds == 1 # Cache should be limited check constraints.maxCacheSize <= 1024 * 1024 * 1024 # Max 1GB test "embedded constraints enable compression": ## Test that compression is enabled for embedded let constraints = getEmbeddedConstraints() check constraints.enableCompression == true test "embedded constraints enable deduplication": ## Test that deduplication is enabled for embedded let constraints = getEmbeddedConstraints() check constraints.enableDeduplication == true suite "Byte Formatting": test "formatBytes handles bytes": ## Test byte formatting for small sizes check formatBytes(512) == "512B" test "formatBytes handles kilobytes": ## Test byte formatting for kilobytes check formatBytes(1024) == "1KB" check formatBytes(2048) == "2KB" test "formatBytes handles megabytes": ## Test byte formatting for megabytes check formatBytes(1024 * 1024) == "1MB" check formatBytes(512 * 1024 * 1024) == "512MB" test "formatBytes handles gigabytes": ## Test byte formatting for gigabytes check formatBytes(1024 * 1024 * 1024) == "1GB" check formatBytes(8 * 1024 * 1024 * 1024) == "8GB" suite "Platform Summary": test "printPlatformInfo does not crash": ## Test that platform info printing works let caps = detectPlatform() # This should not crash or raise an exception printPlatformInfo(caps) test "printEmbeddedConstraints does not crash": ## Test that embedded constraints printing works let constraints = getEmbeddedConstraints() # This should not crash or raise an exception printEmbeddedConstraints(constraints)