nip/tests/test_variant_profiles.nim

195 lines
6.3 KiB
Nim

## test_variant_profiles.nim
## Tests for variant profile system
import std/[unittest, tables, options, os, strutils]
import ../src/nimpak/variant_profiles
import ../src/nimpak/variant_types
import ../src/nimpak/config
suite "Variant Profile System":
test "Load fleet-node profile from KDL":
let profilePath = ".kiro/nip/profiles/fleet-node.kdl"
if not fileExists(profilePath):
skip()
let profile = loadProfile(profilePath)
check profile.name == "fleet-node"
check profile.description.len > 0
check profile.domains.len > 0
# Check specific domains
check profile.hasDomain("init")
check profile.getDomainValues("init") == @["dinit"]
check profile.hasDomain("security")
let securityFlags = profile.getDomainValues("security")
check "pie" in securityFlags
check "relro" in securityFlags
# Check compiler flags
check profile.compilerFlags.cflags.len > 0
check "-Os" in profile.compilerFlags.cflags
test "Load gaming-rig profile from KDL":
let profilePath = ".kiro/nip/profiles/gaming-rig.kdl"
if not fileExists(profilePath):
skip()
let profile = loadProfile(profilePath)
check profile.name == "gaming-rig"
check profile.hasDomain("graphics")
let graphicsFlags = profile.getDomainValues("graphics")
check "vulkan" in graphicsFlags
check "wayland" in graphicsFlags
# Check optimization
check profile.hasDomain("optimization")
let optFlags = profile.getDomainValues("optimization")
check "lto" in optFlags
check "march-native" in optFlags
test "Load ml-workstation profile from KDL":
let profilePath = ".kiro/nip/profiles/ml-workstation.kdl"
if not fileExists(profilePath):
skip()
let profile = loadProfile(profilePath)
check profile.name == "ml-workstation"
check profile.hasDomain("runtime")
let runtimeFlags = profile.getDomainValues("runtime")
check "python" in runtimeFlags
check profile.hasDomain("developer")
let devFlags = profile.getDomainValues("developer")
check "debugger" in devFlags
check "lsp" in devFlags
test "Merge profile with domain overrides":
var baseProfile = newVariantProfile("base", "Base profile")
baseProfile.domains["init"] = @["systemd"]
baseProfile.domains["graphics"] = @["X"]
baseProfile.compilerFlags.cflags = "-O2"
var overrides = initTable[string, seq[string]]()
overrides["init"] = @["dinit"] # Override init
overrides["audio"] = @["pipewire"] # Add new domain
let merged = mergeProfileWithOverrides(baseProfile, overrides)
check merged.getDomainValues("init") == @["dinit"] # Overridden
check merged.getDomainValues("graphics") == @["X"] # Preserved
check merged.getDomainValues("audio") == @["pipewire"] # Added
check merged.compilerFlags.cflags == "-O2" # Preserved
test "Merge profile with compiler flag overrides":
var baseProfile = newVariantProfile("base", "Base profile")
baseProfile.compilerFlags.cflags = "-O2"
baseProfile.compilerFlags.ldflags = "-Wl,-O1"
var overrideFlags = CompilerFlags(
cflags: "-O3 -march=native",
ldflags: "", # Empty, should not override
makeflags: "-j16" # New flag
)
let merged = mergeProfileWithOverrides(
baseProfile,
initTable[string, seq[string]](),
some(overrideFlags)
)
check merged.compilerFlags.cflags == "-O3 -march=native" # Overridden
check merged.compilerFlags.ldflags == "-Wl,-O1" # Preserved (empty override)
check merged.compilerFlags.makeflags == "-j16" # Added
test "Merge two profiles":
var baseProfile = newVariantProfile("base", "Base profile")
baseProfile.domains["init"] = @["systemd"]
baseProfile.domains["graphics"] = @["X"]
baseProfile.compilerFlags.cflags = "-O2"
var overlayProfile = newVariantProfile("overlay", "Overlay profile")
overlayProfile.domains["init"] = @["dinit"] # Override
overlayProfile.domains["audio"] = @["pipewire"] # Add
overlayProfile.compilerFlags.cflags = "-O3" # Override
overlayProfile.compilerFlags.ldflags = "-Wl,-O1" # Add
let merged = mergeProfiles(baseProfile, overlayProfile)
check merged.name == "overlay" # Takes overlay name
check merged.getDomainValues("init") == @["dinit"] # Overridden
check merged.getDomainValues("graphics") == @["X"] # Preserved from base
check merged.getDomainValues("audio") == @["pipewire"] # Added from overlay
check merged.compilerFlags.cflags == "-O3" # Overridden
check merged.compilerFlags.ldflags == "-Wl,-O1" # Added
test "Profile string representation":
var profile = newVariantProfile("test", "Test profile")
profile.domains["init"] = @["dinit"]
profile.domains["graphics"] = @["wayland", "vulkan"]
profile.compilerFlags.cflags = "-O3"
profile.compilerFlags.makeflags = "-j8"
let str = $profile
check "test" in str
check "Test profile" in str
check "init" in str
check "dinit" in str
check "graphics" in str
check "wayland" in str
check "CFLAGS" in str
check "-O3" in str
test "List domains in profile":
var profile = newVariantProfile("test", "Test profile")
profile.domains["init"] = @["dinit"]
profile.domains["graphics"] = @["wayland"]
profile.domains["audio"] = @["pipewire"]
let domains = profile.listDomains()
check domains.len == 3
check "init" in domains
check "graphics" in domains
check "audio" in domains
test "Profile error handling - missing file":
expect ProfileParseError:
discard loadProfile("nonexistent.kdl")
test "Profile error handling - invalid KDL":
# Create a temporary invalid KDL file
let tempPath = "/tmp/test_invalid_profile.kdl"
writeFile(tempPath, "invalid { kdl syntax")
try:
expect CatchableError: # KDL parse errors are caught as ProfileParseError
discard loadProfile(tempPath)
finally:
removeFile(tempPath)
test "Profile error handling - missing profile node":
# Create a KDL file without a profile node
let tempPath = "/tmp/test_no_profile.kdl"
writeFile(tempPath, """
config {
value "test"
}
""")
try:
expect ProfileParseError:
discard loadProfile(tempPath)
finally:
removeFile(tempPath)
when isMainModule:
echo "Running variant profile tests..."