nip/tests/test_cas_integration.nim

391 lines
11 KiB
Nim

## 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)