nip/tests/test_cell_manager.nim

360 lines
12 KiB
Nim

## 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..."