nip/tests/test_variant_coexistence.nim

326 lines
8.4 KiB
Nim

## test_variant_coexistence.nim
## Tests for variant coexistence guarantees (Task 14)
import std/[unittest, tables, os, strutils]
import ../src/nimpak/variant_types
import ../src/nimpak/variant_manager
import ../src/nimpak/variant_database
import ../src/nimpak/config
suite "Variant Coexistence and Conflict Detection":
setup:
let testDbPath = getTempDir() / "nip-test-coexistence"
if dirExists(testDbPath):
removeDir(testDbPath)
createDir(testDbPath)
let vm = newVariantManager(testDbPath)
let compilerFlags = CompilerFlags(
cflags: "-O2",
cxxflags: "-O2",
ldflags: "",
makeflags: ""
)
teardown:
if dirExists(testDbPath):
removeDir(testDbPath)
test "Conflict detection - no conflict for new variant":
let domains = {
"init": @["dinit"],
"graphics": @["wayland"]
}.toTable
let result = vm.createVariant(
"firefox",
"118.0",
domains,
compilerFlags
)
check result.success == true
check result.reusedExisting == false
test "Conflict detection - reuse existing variant with same fingerprint":
let domains = {
"init": @["dinit"],
"graphics": @["wayland"]
}.toTable
# Create first variant
let result1 = vm.createVariant(
"firefox",
"118.0",
domains,
compilerFlags
)
check result1.success == true
check result1.reusedExisting == false
# Try to create same variant again
let result2 = vm.createVariant(
"firefox",
"118.0",
domains,
compilerFlags
)
check result2.success == true
check result2.reusedExisting == true
# Fingerprints should match
check result1.fingerprint.hash == result2.fingerprint.hash
test "Query variant by path":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"nginx",
"1.24.0",
domains,
compilerFlags
)
check result.success == true
# Query by path
let installPath = result.fingerprint.hash # Simplified for test
let query = vm.db.queryVariantByPath(result.fingerprint.hash)
# Note: This will fail because we're not actually creating the path
# In real usage, the path would be created during installation
check query.found == false or query.record.packageName == "nginx"
test "Variant reference tracking - add reference":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add reference from nginx to libssl variant
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
# Check reference was added
let refs = vm.db.getVariantReferences(result.fingerprint.hash)
check refs.len == 1
check "nginx" in refs
test "Variant reference tracking - multiple references":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add multiple references
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
vm.db.addVariantReference(result.fingerprint.hash, "curl")
vm.db.addVariantReference(result.fingerprint.hash, "wget")
# Check all references
let refs = vm.db.getVariantReferences(result.fingerprint.hash)
check refs.len == 3
check "nginx" in refs
check "curl" in refs
check "wget" in refs
test "Variant reference tracking - remove reference":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add and remove reference
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
check vm.db.getVariantReferences(result.fingerprint.hash).len == 1
let removed = vm.db.removeVariantReference(result.fingerprint.hash, "nginx")
check removed == true
check vm.db.getVariantReferences(result.fingerprint.hash).len == 0
test "Variant reference tracking - prevent deletion of referenced variant":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add reference
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
# Try to delete - should fail
let canDelete = vm.db.canDeleteVariant(result.fingerprint.hash)
check canDelete == false
let deleteResult = vm.db.deleteVariantWithReferences(result.fingerprint.hash, force = false)
check deleteResult.success == false
check "referenced" in deleteResult.message.toLower()
test "Variant reference tracking - allow deletion when no references":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# No references - should be deletable
let canDelete = vm.db.canDeleteVariant(result.fingerprint.hash)
check canDelete == true
let deleteResult = vm.db.deleteVariantWithReferences(result.fingerprint.hash, force = false)
check deleteResult.success == true
test "Variant reference tracking - force delete referenced variant":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add reference
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
# Force delete
let deleteResult = vm.db.deleteVariantWithReferences(result.fingerprint.hash, force = true)
check deleteResult.success == true
check "forced" in deleteResult.message.toLower()
test "Variant reference info":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add references
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
vm.db.addVariantReference(result.fingerprint.hash, "curl")
# Get reference info
let refInfo = vm.db.getVariantReferenceInfo(result.fingerprint.hash)
check refInfo.fingerprint == result.fingerprint.hash
check refInfo.referencedBy.len == 2
check refInfo.canDelete == false
test "List variants referenced by package":
let domains1 = {
"init": @["dinit"]
}.toTable
let domains2 = {
"init": @["systemd"]
}.toTable
# Create two variants
let result1 = vm.createVariant("libssl", "3.0.0", domains1, compilerFlags)
let result2 = vm.createVariant("zlib", "1.2.13", domains2, compilerFlags)
check result1.success == true
check result2.success == true
# Add references from nginx to both
vm.db.addVariantReference(result1.fingerprint.hash, "nginx")
vm.db.addVariantReference(result2.fingerprint.hash, "nginx")
# List variants referenced by nginx
let nginxRefs = vm.db.listReferencedVariants("nginx")
check nginxRefs.len == 2
check result1.fingerprint.hash in nginxRefs
check result2.fingerprint.hash in nginxRefs
test "Reference persistence - save and load":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add references
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
vm.db.addVariantReference(result.fingerprint.hash, "curl")
# Save
vm.db.saveVariants()
# Create new database instance and load
let vm2 = newVariantManager(testDbPath)
# Check references were loaded
let refs = vm2.db.getVariantReferences(result.fingerprint.hash)
check refs.len == 2
check "nginx" in refs
check "curl" in refs
test "Duplicate reference prevention":
let domains = {
"init": @["dinit"]
}.toTable
let result = vm.createVariant(
"libssl",
"3.0.0",
domains,
compilerFlags
)
check result.success == true
# Add same reference twice
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
vm.db.addVariantReference(result.fingerprint.hash, "nginx")
# Should only have one reference
let refs = vm.db.getVariantReferences(result.fingerprint.hash)
check refs.len == 1