nip/tests/test_build_system.nim

264 lines
7.6 KiB
Nim

## tests/test_build_system.nim
## Unit tests for the Nimplate build system
##
## Tests type-safe build templates, build execution, caching,
## and environment isolation for all supported build systems.
import std/[unittest, os, times, strutils]
import ../src/nimpak/build_system
import ../src/nimpak/recipes
suite "Nimplate Build System Tests":
setup:
# Create temporary test directory
let testDir = getTempDir() / "nip_test_build"
createDir(testDir)
teardown:
# Clean up test directory
let testDir = getTempDir() / "nip_test_build"
if dirExists(testDir):
removeDir(testDir)
test "Build environment creation":
let sourceDir = getTempDir() / "test_source"
createDir(sourceDir)
let env = newBuildEnvironment(sourceDir, isolated = true)
check env.sourceDir == sourceDir
check env.isolated == true
check env.environment.hasKey("PREFIX")
check env.environment.hasKey("MAKEFLAGS")
check env.workDir.contains("nimpak_build_")
test "Nimplate executor creation":
let sourceDir = getTempDir() / "test_source"
createDir(sourceDir)
let buildTmpl = getBuildSystemDefaults(CMake)
let executor = newNimplateExecutor(buildTmpl, sourceDir)
check executor.buildTemplate.system == CMake
check executor.cacheEnabled == true
check executor.sandboxed == true
check executor.environment.sourceDir == sourceDir
test "CMake build template defaults":
let buildTmpl = getBuildSystemDefaults(CMake)
check buildTmpl.system == CMake
check "-DCMAKE_BUILD_TYPE=Release" in buildTmpl.configureArgs
check "--parallel" in buildTmpl.buildArgs
test "Autotools build template defaults":
let buildTmpl = getBuildSystemDefaults(Autotools)
check buildTmpl.system == Autotools
check "--prefix=/usr" in buildTmpl.configureArgs
check "-j" in buildTmpl.buildArgs[0] # Should contain -j for parallel make
test "Meson build template defaults":
let buildTmpl = getBuildSystemDefaults(Meson)
check buildTmpl.system == Meson
check "setup" in buildTmpl.configureArgs
check "--buildtype=release" in buildTmpl.configureArgs
test "Cargo build template defaults":
let buildTmpl = getBuildSystemDefaults(Cargo)
check buildTmpl.system == Cargo
check "--release" in buildTmpl.buildArgs
test "Nim build template defaults":
let buildTmpl = getBuildSystemDefaults(NimBuild)
check buildTmpl.system == NimBuild
check "-d:release" in buildTmpl.buildArgs
test "Build hash calculation":
let sourceDir = getTempDir() / "test_source"
createDir(sourceDir)
let buildTmpl = getBuildSystemDefaults(CMake)
let hash1 = calculateBuildHash(sourceDir, buildTmpl)
let hash2 = calculateBuildHash(sourceDir, buildTmpl)
check hash1 == hash2 # Same source and template should produce same hash
check hash1.startsWith("build-")
test "Build cache detection":
let cacheDir = getTempDir() / "build_cache"
createDir(cacheDir)
let buildHash = "test-build-hash"
# Initially not cached
check isBuildCached(buildHash, cacheDir) == false
# Create cache file
let cacheFile = cacheDir / buildHash & ".cache"
writeFile(cacheFile, "cached build result")
# Now should be cached
check isBuildCached(buildHash, cacheDir) == true
test "Build environment isolation setup":
let sourceDir = getTempDir() / "test_source"
var env = newBuildEnvironment(sourceDir, isolated = true)
setupSandbox(env)
check env.environment.hasKey("SANDBOX")
check env.environment["SANDBOX"] == "true"
check env.environment.hasKey("HOME")
check env.environment.hasKey("TMPDIR")
suite "Nimplate Build Execution Tests":
test "Mock CMake build execution":
# Create a mock CMake project
let sourceDir = getTempDir() / "cmake_project"
createDir(sourceDir)
# Create a minimal CMakeLists.txt
writeFile(sourceDir / "CMakeLists.txt", """
cmake_minimum_required(VERSION 3.10)
project(TestProject)
add_executable(test main.cpp)
""")
# Create a minimal main.cpp
writeFile(sourceDir / "main.cpp", """
#include <iostream>
int main() { std::cout << "Hello World!" << std::endl; return 0; }
""")
let buildTmpl = getBuildSystemDefaults(CMake)
let executor = newNimplateExecutor(buildTmpl, sourceDir)
# This will fail in CI without CMake, but we can test the setup
check executor.buildTemplate.system == CMake
check executor.environment.sourceDir == sourceDir
test "Mock Nim build execution":
# Create a mock Nim project
let sourceDir = getTempDir() / "nim_project"
createDir(sourceDir)
# Create a minimal nim file
writeFile(sourceDir / "main.nim", """
echo "Hello from Nim!"
""")
let buildTmpl = getBuildSystemDefaults(NimBuild)
let executor = newNimplateExecutor(buildTmpl, sourceDir)
check executor.buildTemplate.system == NimBuild
check executor.environment.sourceDir == sourceDir
test "Build result structure":
# Test BuildResult type
var result = BuildResult(
success: true,
buildTime: 1.5,
outputSize: 1024,
buildLog: "Build completed successfully",
artifacts: @["/path/to/binary"],
phase: PhaseInstall,
exitCode: 0
)
check result.success == true
check result.buildTime == 1.5
check result.outputSize == 1024
check result.phase == PhaseInstall
check result.artifacts.len == 1
suite "Build System Integration Tests":
test "Build template validation":
let buildTmpl = getBuildSystemDefaults(CMake)
let warnings = validateBuildInstructions(buildTmpl)
# CMake template should be valid
check warnings.len == 0
test "Custom build template creation":
let customTmpl = createBuildTemplate(
system = Custom,
configureArgs = @["./configure", "--enable-feature"],
buildArgs = @["make", "-j4"],
installArgs = @["make", "install"]
)
check customTmpl.system == Custom
check customTmpl.configureArgs.len == 2
check customTmpl.buildArgs.len == 2
check customTmpl.installArgs.len == 2
test "Build environment cleanup":
let sourceDir = getTempDir() / "test_source"
createDir(sourceDir)
let env = newBuildEnvironment(sourceDir, isolated = true)
let workDir = env.workDir
# Work directory should exist
check dirExists(workDir)
# Clean up
cleanupBuildEnvironment(env)
# Work directory should be removed (if isolated)
# Note: This might not work in all test environments
# check not dirExists(workDir)
test "Build cache save and load":
let cacheDir = getTempDir() / "build_cache_test"
let buildHash = "test-hash-123"
let result = BuildResult(
success: true,
buildTime: 2.0,
buildLog: "Test build log",
phase: PhaseInstall
)
# Save to cache
saveBuildCache(result, buildHash, cacheDir)
# Check cache exists
check isBuildCached(buildHash, cacheDir) == true
suite "Build System Error Handling":
test "Invalid source directory handling":
let invalidDir = "/nonexistent/directory"
let buildTmpl = getBuildSystemDefaults(CMake)
# Should handle gracefully
let executor = newNimplateExecutor(buildTmpl, invalidDir)
check executor.environment.sourceDir == invalidDir
test "Build failure handling":
# Test that build failures are properly captured
var result = BuildResult(
success: false,
exitCode: 1,
buildLog: "Build failed with error",
phase: PhaseBuild
)
check result.success == false
check result.exitCode == 1
check "failed" in result.buildLog
when isMainModule:
echo "🧪 Running Build System Tests..."
echo "Testing Nimplate build templates and execution..."
# This will run all the test suites
discard