nip/tests/test_flexible_adapter.nim

340 lines
9.4 KiB
Nim

## Unit Tests for Flexible Adapter
##
## Tests for the flexible adapter implementation which handles
## source-based builds like Gentoo and NPK.
import std/[unittest, options, tables, strutils]
import ../src/nip/resolver/flexible_adapter
import ../src/nip/resolver/source_adapter
import ../src/nip/resolver/variant_types
suite "Flexible Adapter Tests":
test "Create flexible adapter":
## Test basic adapter creation
let adapter = newFlexibleAdapter("test-flexible", priority = 30)
check adapter.name == "test-flexible"
check adapter.class == Flexible
check adapter.priority == 30
test "Add package to flexible adapter":
## Test adding buildable packages
let adapter = newFlexibleAdapter("test-flexible")
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[profile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300 # 5 minutes
)
adapter.addPackage(metadata)
check adapter.availablePackages.hasKey("nginx")
check adapter.availablePackages["nginx"].name == "nginx"
check adapter.availablePackages["nginx"].buildTime == 300
test "canSatisfy: Package available":
## Test that available packages are detected
let adapter = newFlexibleAdapter("test-flexible")
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[profile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300
)
adapter.addPackage(metadata)
let demand = VariantDemand(
packageName: "nginx",
variantProfile: profile,
optional: false
)
let availability = adapter.canSatisfy(demand)
check availability == Available
test "canSatisfy: Package unavailable":
## Test that unavailable packages are detected
let adapter = newFlexibleAdapter("test-flexible")
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let demand = VariantDemand(
packageName: "nonexistent",
variantProfile: profile,
optional: false
)
let availability = adapter.canSatisfy(demand)
check availability == Unavailable
test "canSatisfy: Any variant is acceptable":
## Test that flexible sources accept any variant
## (they can build with any configuration)
let adapter = newFlexibleAdapter("test-flexible")
var availableProfile = newVariantProfile()
availableProfile.addFlag("optimization", "lto")
availableProfile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[availableProfile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300
)
adapter.addPackage(metadata)
# Request different variant
var demandProfile = newVariantProfile()
demandProfile.addFlag("optimization", "pgo")
demandProfile.addFlag("graphics", "wayland")
demandProfile.calculateHash()
let demand = VariantDemand(
packageName: "nginx",
variantProfile: demandProfile,
optional: false
)
let availability = adapter.canSatisfy(demand)
# Flexible sources can build any variant
check availability == Available
test "getVariant: Returns metadata with requested variant":
## Test that getVariant returns metadata for any variant
let adapter = newFlexibleAdapter("test-flexible")
var baseProfile = newVariantProfile()
baseProfile.addFlag("optimization", "lto")
baseProfile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[baseProfile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300
)
adapter.addPackage(metadata)
# Request different variant
var demandProfile = newVariantProfile()
demandProfile.addFlag("optimization", "pgo")
demandProfile.calculateHash()
let demand = VariantDemand(
packageName: "nginx",
variantProfile: demandProfile,
optional: false
)
let result = adapter.getVariant(demand)
check result.isSome
check result.get.name == "nginx"
check result.get.availableVariants[0] == demandProfile
test "getVariant: Returns none for unavailable package":
## Test that getVariant returns none for missing packages
let adapter = newFlexibleAdapter("test-flexible")
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let demand = VariantDemand(
packageName: "nonexistent",
variantProfile: profile,
optional: false
)
let result = adapter.getVariant(demand)
check result.isNone
test "synthesize: Successful build with mock function":
## Test successful package synthesis
let mockBuild = mockBuildSuccess("nginx", "cas-nginx-abc123")
let adapter = newFlexibleAdapter("test-flexible", buildFunc = mockBuild)
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[profile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300
)
adapter.addPackage(metadata)
let demand = VariantDemand(
packageName: "nginx",
variantProfile: profile,
optional: false
)
let result = adapter.synthesize(demand)
check result.isOk
check $result.value == "cas-nginx-abc123"
test "synthesize: Build failure with mock function":
## Test build failure handling
let mockBuild = mockBuildFailure("Compilation failed", exitCode = 2)
let adapter = newFlexibleAdapter("test-flexible", buildFunc = mockBuild)
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[profile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300
)
adapter.addPackage(metadata)
let demand = VariantDemand(
packageName: "nginx",
variantProfile: profile,
optional: false
)
let result = adapter.synthesize(demand)
check not result.isOk
check result.error.exitCode == 2
check "Compilation failed" in result.error.message
test "synthesize: Package not found":
## Test synthesis of non-existent package
let adapter = newFlexibleAdapter("test-flexible")
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let demand = VariantDemand(
packageName: "nonexistent",
variantProfile: profile,
optional: false
)
let result = adapter.synthesize(demand)
check not result.isOk
check "not found" in result.error.message.toLowerAscii()
test "synthesize: Default implementation generates CAS ID":
## Test that default synthesis generates valid CAS ID
let adapter = newFlexibleAdapter("test-flexible")
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.calculateHash()
let metadata = PackageMetadata(
name: "nginx",
version: "1.24.0",
availableVariants: @[profile],
sourceHash: "https://nginx.org/download/nginx-1.24.0.tar.gz",
buildTime: 300
)
adapter.addPackage(metadata)
let demand = VariantDemand(
packageName: "nginx",
variantProfile: profile,
optional: false
)
let result = adapter.synthesize(demand)
check result.isOk
# CAS ID should contain package name and variant hash
let casIdStr = $result.value
check "nginx" in casIdStr
check profile.hash in casIdStr
test "synthesize: Variant profile is passed correctly":
## Test that the requested variant profile is used in synthesis
var capturedProfile: VariantProfile
let mockBuild = proc(demand: VariantDemand): Result[CasId, BuildError] =
capturedProfile = demand.variantProfile
return ok[CasId, BuildError](newCasId("test-cas-id"))
let adapter = newFlexibleAdapter("test-flexible", buildFunc = mockBuild)
var profile = newVariantProfile()
profile.addFlag("optimization", "lto")
profile.addFlag("graphics", "wayland")
profile.calculateHash()
let metadata = PackageMetadata(
name: "firefox",
version: "120.0",
availableVariants: @[profile],
sourceHash: "https://mozilla.org/firefox-120.0.tar.gz",
buildTime: 600
)
adapter.addPackage(metadata)
let demand = VariantDemand(
packageName: "firefox",
variantProfile: profile,
optional: false
)
let result = adapter.synthesize(demand)
check result.isOk
check capturedProfile == profile
check capturedProfile.hasDomain("optimization")
check capturedProfile.hasDomain("graphics")