326 lines
8.4 KiB
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
|