## Integration Tests for CAS Integration ## ## Tests for the CAS integration module which bridges build synthesis ## with the existing Content-Addressable Storage system. import std/[unittest, os, tempfiles, times, tables, options] import ../src/nip/resolver/build_synthesis import ../src/nip/resolver/variant_types import ../src/nip/resolver/cas_integration # Helper to count table entries proc tableLen[K, V](t: Table[K, V]): int = result = 0 for _ in t.keys: result += 1 suite "CAS Integration Tests": test "Create CAS integration manager": ## Test creating a CAS integration manager let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: let manager = newCASIntegrationManager(casRoot) check manager.casRoot == casRoot check tableLen(manager.references) == 0 check tableLen(manager.artifacts) == 0 finally: removeDir(casRoot) test "Store build in CAS": ## Test storing a synthesized build in the CAS let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create variant profile var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() # Synthesize build let buildResult = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile, sourceHash = "blake3-abc123" ) # Store in CAS let storeResult = manager.storeBuildInCAS(buildResult) check storeResult.isOk check tableLen(manager.references) == 1 check tableLen(manager.artifacts) == 1 finally: removeDir(casRoot) test "Retrieve build from CAS": ## Test retrieving a stored build from the CAS let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create and store build var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() let buildResult = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile, sourceHash = "blake3-abc123" ) let storeResult = manager.storeBuildInCAS(buildResult) check storeResult.isOk let casHash = storeResult.get() # Retrieve from CAS let retrieveResult = manager.retrieveBuildFromCAS(casHash) check retrieveResult.isOk let retrieved = retrieveResult.get() check retrieved.buildHash == buildResult.buildHash check retrieved.buildConfig.packageName == "nginx" check retrieved.buildConfig.packageVersion == "1.24.0" finally: removeDir(casRoot) test "Verify build in CAS": ## Test verifying that a build exists in the CAS let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create and store build var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() let buildResult = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile, sourceHash = "blake3-abc123" ) let storeResult = manager.storeBuildInCAS(buildResult) check storeResult.isOk # Verify build exists check manager.verifyBuildInCAS(buildResult.buildHash) == true # Verify non-existent build check manager.verifyBuildInCAS("xxh3-nonexistent") == false finally: removeDir(casRoot) test "Reference counting": ## Test reference counting for builds let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create and store build var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() let buildResult = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile, sourceHash = "blake3-abc123" ) let storeResult = manager.storeBuildInCAS(buildResult) check storeResult.isOk # Check initial reference count let initialCount = manager.getReferenceCount(buildResult.buildHash) var hasInitial = false if initialCount.isSome: hasInitial = true check hasInitial check initialCount.get() == 1 # Increment reference let incResult = manager.incrementReference(buildResult.buildHash) check incResult.isOk let newCount = manager.getReferenceCount(buildResult.buildHash) var hasNew = false if newCount.isSome: hasNew = true check hasNew check newCount.get() == 2 # Decrement reference let decResult = manager.decrementReference(buildResult.buildHash) check decResult.isOk check decResult.get() == 1 finally: removeDir(casRoot) test "List tracked builds": ## Test listing all tracked builds let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create and store multiple builds for i in 0..<3: var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() let buildResult = synthesizeBuild( packageName = "package" & $i, packageVersion = "1.0.0", variantProfile = profile, sourceHash = "blake3-" & $i ) discard manager.storeBuildInCAS(buildResult) # List tracked builds let tracked = manager.listTrackedBuilds() check tracked.len() == 3 finally: removeDir(casRoot) test "Get artifact metadata": ## Test retrieving artifact metadata let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create and store build var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() let buildResult = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile, sourceHash = "blake3-abc123" ) let storeResult = manager.storeBuildInCAS(buildResult) check storeResult.isOk # Get artifact metadata let metadata = manager.getArtifactMetadata(buildResult.buildHash) var hasMetadata = false if metadata.isSome: hasMetadata = true check hasMetadata let artifact = metadata.get() check artifact.buildHash == buildResult.buildHash check artifact.compressed == true check artifact.size > 0 finally: removeDir(casRoot) test "Calculate total tracked size": ## Test calculating total size of tracked builds let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create and store multiple builds for i in 0..<3: var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.calculateHash() let buildResult = synthesizeBuild( packageName = "package" & $i, packageVersion = "1.0.0", variantProfile = profile, sourceHash = "blake3-" & $i ) discard manager.storeBuildInCAS(buildResult) # Calculate total size let totalSize = manager.getTotalTrackedSize() check totalSize > 0 finally: removeDir(casRoot) test "Multiple builds with same package": ## Test storing multiple builds of the same package with different variants let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create two builds with different variants var profile1 = newVariantProfile() profile1.addFlag("optimization", "lto") profile1.calculateHash() var profile2 = newVariantProfile() profile2.addFlag("optimization", "o3") profile2.calculateHash() let build1 = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile1, sourceHash = "blake3-abc123" ) let build2 = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile2, sourceHash = "blake3-abc123" ) # Store both builds let store1 = manager.storeBuildInCAS(build1) let store2 = manager.storeBuildInCAS(build2) check store1.isOk check store2.isOk # Verify both are tracked check tableLen(manager.references) == 2 check tableLen(manager.artifacts) == 2 # Verify they have different hashes check build1.buildHash != build2.buildHash finally: removeDir(casRoot) test "Round-trip: store and retrieve": ## Test complete round-trip: store build, retrieve it, verify it matches let casRoot = getTempDir() / "test_cas_" & $getTime().toUnix() createDir(casRoot) try: var manager = newCASIntegrationManager(casRoot) # Create build with specific configuration var profile = newVariantProfile() profile.addFlag("optimization", "lto") profile.addFlag("security", "hardened") profile.calculateHash() let original = synthesizeBuild( packageName = "nginx", packageVersion = "1.24.0", variantProfile = profile, sourceHash = "blake3-abc123", compilerVersion = "gcc-13.2.0", compilerFlags = @["-O2", "-march=native"], configureFlags = @["--with-ssl", "--with-http2"], targetArchitecture = "x86_64", libc = "musl", allocator = "jemalloc" ) # Store in CAS let storeResult = manager.storeBuildInCAS(original) check storeResult.isOk let casHash = storeResult.get() # Retrieve from CAS let retrieveResult = manager.retrieveBuildFromCAS(casHash) check retrieveResult.isOk let retrieved = retrieveResult.get() # Verify all fields match check retrieved.buildHash == original.buildHash check retrieved.buildConfig.packageName == original.buildConfig.packageName check retrieved.buildConfig.packageVersion == original.buildConfig.packageVersion check retrieved.buildConfig.sourceHash == original.buildConfig.sourceHash check retrieved.buildConfig.compilerVersion == original.buildConfig.compilerVersion check retrieved.buildConfig.targetArchitecture == original.buildConfig.targetArchitecture check retrieved.buildConfig.libc == original.buildConfig.libc check retrieved.buildConfig.allocator == original.buildConfig.allocator finally: removeDir(casRoot)