159 lines
4.8 KiB
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 |