## Unit Tests for Resolver Cell Manager ## ## This module tests the cell management integration for the dependency resolver. ## ## **Requirements Tested:** ## - 10.3: Maintain separate dependency graphs per cell ## - 10.4: Support cell switching ## - 10.5: Clean up cell-specific packages import std/[unittest, options, tables, strutils] import ../src/nip/resolver/cell_manager import ../src/nip/resolver/nipcell_fallback import ../src/nip/resolver/dependency_graph import ../src/nip/resolver/variant_types # ============================================================================= # Test Helpers # ============================================================================= proc setupTestManager(): ResolverCellManager = ## Create a test cell manager with some pre-populated cells result = newResolverCellManager("/tmp/test-resolver-cells") # Create some test cells discard result.graphManager.createCell("dev-cell", "Development environment") discard result.graphManager.createCell("prod-cell", "Production environment") discard result.graphManager.createCell("test-cell", "Testing environment") # ============================================================================= # Cell Manager Construction Tests # ============================================================================= suite "Resolver Cell Manager - Construction": test "Create new cell manager": let manager = newResolverCellManager("/tmp/test-cells") check manager != nil check manager.graphManager != nil check manager.activeResolutions.len == 0 check manager.cellPackageCache.len == 0 # ============================================================================= # Cell Activation Tests # ============================================================================= suite "Resolver Cell Manager - Cell Activation": test "Activate existing cell": let manager = setupTestManager() let result = manager.activateCell("dev-cell") check result.success == true check result.cellName == "dev-cell" check result.error == "" check manager.getActiveCellName().isSome check manager.getActiveCellName().get() == "dev-cell" test "Cannot activate non-existent cell": let manager = setupTestManager() let result = manager.activateCell("non-existent") check result.success == false check result.error.contains("not found") test "Activation tracks previous cell": let manager = setupTestManager() discard manager.activateCell("dev-cell") let result = manager.activateCell("prod-cell") check result.success == true check result.previousCell.isSome check result.previousCell.get() == "dev-cell" test "Deactivate cell": let manager = setupTestManager() discard manager.activateCell("dev-cell") let success = manager.deactivateCell() check success == true check manager.getActiveCellName().isNone test "Cannot deactivate when no cell active": let manager = setupTestManager() let success = manager.deactivateCell() check success == false # ============================================================================= # Cell Switching Tests # ============================================================================= suite "Resolver Cell Manager - Cell Switching": test "Switch to different cell": let manager = setupTestManager() discard manager.activateCell("dev-cell") let result = manager.switchToCell("prod-cell") check result.success == true check result.cellName == "prod-cell" check result.previousCell.isSome check result.previousCell.get() == "dev-cell" check manager.getActiveCellName().get() == "prod-cell" test "Switch with resolution preservation": let manager = setupTestManager() discard manager.activateCell("dev-cell") let result = manager.switchToCell("prod-cell", preserveResolution = true) check result.success == true check result.cellName == "prod-cell" test "List available cells": let manager = setupTestManager() let cells = manager.listAvailableCells() check cells.len == 3 check "dev-cell" in cells check "prod-cell" in cells check "test-cell" in cells # ============================================================================= # Cell Removal Tests # ============================================================================= suite "Resolver Cell Manager - Cell Removal": test "Remove cell with package cleanup": let manager = setupTestManager() # Add some packages to the cell discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") discard manager.addPackageToActiveCell("openssl") let result = manager.removeCell("dev-cell", cleanupPackages = true) check result.success == true check result.cellName == "dev-cell" check result.packagesRemoved == 2 check "dev-cell" notin manager.listAvailableCells() test "Remove cell without package cleanup": let manager = setupTestManager() discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") let result = manager.removeCell("dev-cell", cleanupPackages = false) check result.success == true check result.packagesRemoved == 1 # Still counts packages test "Cannot remove non-existent cell": let manager = setupTestManager() let result = manager.removeCell("non-existent") check result.success == false check result.error.contains("not found") test "Removing active cell deactivates it": let manager = setupTestManager() discard manager.activateCell("dev-cell") discard manager.removeCell("dev-cell") check manager.getActiveCellName().isNone # ============================================================================= # Package Management Tests # ============================================================================= suite "Resolver Cell Manager - Package Management": test "Add package to active cell": let manager = setupTestManager() discard manager.activateCell("dev-cell") let success = manager.addPackageToActiveCell("nginx") check success == true check manager.isPackageInActiveCell("nginx") test "Cannot add package when no cell active": let manager = setupTestManager() let success = manager.addPackageToActiveCell("nginx") check success == false test "Remove package from active cell": let manager = setupTestManager() discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") let success = manager.removePackageFromActiveCell("nginx") check success == true check not manager.isPackageInActiveCell("nginx") test "Get active cell packages": let manager = setupTestManager() discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") discard manager.addPackageToActiveCell("openssl") discard manager.addPackageToActiveCell("zlib") let packages = manager.getActiveCellPackages() check packages.len == 3 check "nginx" in packages check "openssl" in packages check "zlib" in packages test "Packages are isolated between cells": let manager = setupTestManager() # Add packages to dev-cell discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") # Add different packages to prod-cell discard manager.activateCell("prod-cell") discard manager.addPackageToActiveCell("apache") # Verify isolation check manager.isPackageInActiveCell("apache") check not manager.isPackageInActiveCell("nginx") # Switch back to dev-cell discard manager.activateCell("dev-cell") check manager.isPackageInActiveCell("nginx") check not manager.isPackageInActiveCell("apache") # ============================================================================= # Resolution Integration Tests # ============================================================================= suite "Resolver Cell Manager - Resolution Integration": test "Save and retrieve resolution": let manager = setupTestManager() let graph = newDependencyGraph() manager.saveResolution("dev-cell", graph) let retrieved = manager.getResolution("dev-cell") check retrieved.isSome test "Get resolution for non-existent cell": let manager = setupTestManager() let retrieved = manager.getResolution("non-existent") check retrieved.isNone test "Resolve in cell context": let manager = setupTestManager() # This would integrate with actual resolver # For now, just test the interface let graphOpt = manager.resolveInCell("dev-cell", "nginx", VariantDemand()) # Should return the cell's graph (empty for now) check graphOpt.isSome # ============================================================================= # Cell Information Tests # ============================================================================= suite "Resolver Cell Manager - Cell Information": test "Get cell info": let manager = setupTestManager() let info = manager.getCellInfo("dev-cell") check info.isSome check info.get().cellName == "dev-cell" test "Get cell statistics": let manager = setupTestManager() discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") discard manager.addPackageToActiveCell("openssl") let stats = manager.getCellStatistics("dev-cell") check stats.packageCount == 2 test "Get statistics for non-existent cell": let manager = setupTestManager() let stats = manager.getCellStatistics("non-existent") check stats.packageCount == 0 # ============================================================================= # Cleanup Operations Tests # ============================================================================= suite "Resolver Cell Manager - Cleanup Operations": test "Cleanup unused packages in cell": let manager = setupTestManager() discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") discard manager.addPackageToActiveCell("unused-package") # In a real scenario, unused-package wouldn't be in the graph # For now, this tests the interface let removed = manager.cleanupUnusedPackages("dev-cell") check removed >= 0 test "Cleanup all cells": let manager = setupTestManager() # Add packages to multiple cells discard manager.activateCell("dev-cell") discard manager.addPackageToActiveCell("nginx") discard manager.activateCell("prod-cell") discard manager.addPackageToActiveCell("apache") let results = manager.cleanupAllCells() # Results map cell names to number of packages removed check results.len >= 0 # ============================================================================= # String Representation Tests # ============================================================================= suite "Resolver Cell Manager - String Representation": test "String representation": let manager = setupTestManager() discard manager.activateCell("dev-cell") let str = $manager check str.contains("ResolverCellManager") check str.contains("cells: 3") check str.contains("active: dev-cell") # ============================================================================= # Run Tests # ============================================================================= when isMainModule: echo "Running Resolver Cell Manager Tests..."