nip/tests/test_install.nim

159 lines
4.8 KiB
Nim

# tests/test_install.nim
# Unit tests for installation orchestrator
import unittest, tables
import ../src/nimpak/[install, dependency, types, errors, transactions, filesystem, cas]
suite "Installation Orchestrator Tests":
setup:
# Create test fragments
let pkgA = PackageId(name: "pkgA", version: "1.0", stream: Stable)
let pkgB = PackageId(name: "pkgB", version: "1.0", stream: Stable)
let fragmentA = Fragment(
id: pkgA,
dependencies: @[pkgB],
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
buildSystem: CMake,
metadata: PackageMetadata(description: "Test package A"),
acul: AculCompliance(required: false)
)
let fragmentB = Fragment(
id: pkgB,
dependencies: @[],
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
buildSystem: CMake,
metadata: PackageMetadata(description: "Test package B"),
acul: AculCompliance(required: false)
)
var fragments = initTable[PackageId, Fragment]()
fragments[pkgA] = fragmentA
fragments[pkgB] = fragmentB
let fsManager = FilesystemManager(
programsRoot: "/tmp/test/Programs",
indexRoot: "/tmp/test/Index"
)
let casManager = CasManager(
userCasPath: "/tmp/test/.nip/cas",
systemCasPath: "/tmp/test/var/lib/nip/cas",
compression: true,
compressionLevel: 3
)
test "Create installation plan":
let planResult = createInstallPlan(@[pkgA], fragments)
check planResult.isOk
let plan = planResult.get()
check plan.steps.len == 2 # pkgA and pkgB
# Check step ordering (dependencies first)
check plan.steps[0].package.name == "pkgB"
check plan.steps[1].package.name == "pkgA"
# Check step numbering
check plan.steps[0].stepNumber == 1
check plan.steps[1].stepNumber == 2
check plan.steps[0].totalSteps == 2
check plan.steps[1].totalSteps == 2
test "Installation plan validation":
let planResult = createInstallPlan(@[pkgA], fragments)
check planResult.isOk
let plan = planResult.get()
let validationResult = validateInstallPlan(plan)
check validationResult.isOk
test "Empty installation plan validation":
let emptyPlan = InstallPlan(
steps: @[],
transaction: Transaction(),
rollbackData: @[]
)
let validationResult = validateInstallPlan(emptyPlan)
check validationResult.isErr
check validationResult.error.code == InvalidOperation
test "Installation progress tracking":
let planResult = createInstallPlan(@[pkgA], fragments)
check planResult.isOk
let plan = planResult.get()
# Test progress at different steps
let progress1 = getInstallProgress(plan, 1)
check progress1.currentStep == 1
check progress1.totalSteps == 2
check progress1.currentPackage.name == "pkgB"
check progress1.status == Installing
let progress2 = getInstallProgress(plan, 2)
check progress2.currentStep == 2
check progress2.totalSteps == 2
check progress2.currentPackage.name == "pkgA"
check progress2.status == Completed
test "Progress formatting":
let progress = InstallProgress(
currentStep: 1,
totalSteps: 3,
currentPackage: pkgA,
status: Installing
)
let formatted = formatInstallProgress(progress)
check "33%" in formatted
check "pkgA" in formatted
check "(1/3)" in formatted
test "Installation summary generation":
let planResult = createInstallPlan(@[pkgA], fragments)
check planResult.isOk
let plan = planResult.get()
let summary = getInstallSummary(plan)
check "Installation Plan Summary" in summary
check "Total packages: 2" in summary
check "pkgA" in summary
check "pkgB" in summary
test "Multiple package installation plan":
let pkgC = PackageId(name: "pkgC", version: "1.0", stream: Stable)
let fragmentC = Fragment(
id: pkgC,
dependencies: @[],
source: Source(url: "test", hash: "test", hashAlgorithm: "blake2b", method: Http),
buildSystem: CMake,
metadata: PackageMetadata(description: "Test package C"),
acul: AculCompliance(required: false)
)
var testFragments = fragments
testFragments[pkgC] = fragmentC
let planResult = createInstallPlan(@[pkgA, pkgC], testFragments)
check planResult.isOk
let plan = planResult.get()
check plan.steps.len == 3 # pkgA, pkgB, pkgC
# Check that dependencies are handled correctly
let packageNames = plan.steps.mapIt(it.package.name)
check "pkgA" in packageNames
check "pkgB" in packageNames
check "pkgC" in packageNames
test "Installation plan with missing dependencies":
let pkgMissing = PackageId(name: "missing", version: "1.0", stream: Stable)
let planResult = createInstallPlan(@[pkgMissing], fragments)
check planResult.isErr
check planResult.error.code == PackageNotFound