# 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