- Content-addressable store (CAS) like Nix for fast lookups - Binary cache system with remote support - Linux chroot sandbox for isolated builds - Pacman-style UI with progress bars and colors - Temperature-aware parallel builds - fakeroot integration tests - Update .gitignore for Docker and test artifacts Implements LFS-optimized build pipeline with proper fakeroot support.
213 lines
5.1 KiB
Go
213 lines
5.1 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
// FakerootTestRunner runs tests in fakeroot environment
|
||
type FakerootTestRunner struct {
|
||
workDir string
|
||
rootDir string
|
||
zsvoBin string
|
||
}
|
||
|
||
// NewFakerootTestRunner creates test runner
|
||
func NewFakerootTestRunner() (*FakerootTestRunner, error) {
|
||
workDir, err := os.MkdirTemp("", "zsvo-test-")
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
rootDir := filepath.Join(workDir, "fakeroot")
|
||
if err := os.MkdirAll(rootDir, 0755); err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// Find zsvo binary
|
||
zsvoBin := "./zsvo"
|
||
if _, err := os.Stat(zsvoBin); err != nil {
|
||
// Try to build
|
||
cmd := exec.Command("go", "build", "-o", "zsvo", ".")
|
||
if err := cmd.Run(); err != nil {
|
||
return nil, fmt.Errorf("failed to build zsvo: %w", err)
|
||
}
|
||
}
|
||
|
||
return &FakerootTestRunner{
|
||
workDir: workDir,
|
||
rootDir: rootDir,
|
||
zsvoBin: zsvoBin,
|
||
}, nil
|
||
}
|
||
|
||
// Cleanup removes test directory
|
||
func (f *FakerootTestRunner) Cleanup() {
|
||
os.RemoveAll(f.workDir)
|
||
}
|
||
|
||
// RunInFakeroot executes command in fakeroot environment
|
||
func (f *FakerootTestRunner) RunInFakeroot(args ...string) (string, string, error) {
|
||
// Check if fakeroot is available
|
||
fakerootPath, err := exec.LookPath("fakeroot")
|
||
if err != nil {
|
||
// Run without fakeroot but with custom root
|
||
cmd := exec.Command(f.zsvoBin, args...)
|
||
cmd.Env = append(os.Environ(),
|
||
"FAKEROOT=true",
|
||
"ZSVO_ROOT="+f.rootDir,
|
||
)
|
||
output, err := cmd.CombinedOutput()
|
||
return string(output), "", err
|
||
}
|
||
|
||
// Run with fakeroot
|
||
cmdArgs := append([]string{f.zsvoBin}, args...)
|
||
cmd := exec.Command(fakerootPath, cmdArgs...)
|
||
cmd.Env = append(os.Environ(), "ZSVO_ROOT="+f.rootDir)
|
||
|
||
output, err := cmd.CombinedOutput()
|
||
return string(output), "", err
|
||
}
|
||
|
||
// TestInstallSimplePackage tests installing simple package
|
||
func TestInstallSimplePackage(t *testing.T) {
|
||
runner, err := NewFakerootTestRunner()
|
||
if err != nil {
|
||
t.Fatalf("Failed to create test runner: %v", err)
|
||
}
|
||
defer runner.Cleanup()
|
||
|
||
// Test installing expat (simple C library)
|
||
stdout, stderr, err := runner.RunInFakeroot(
|
||
"install", "expat",
|
||
"--work-dir", runner.workDir,
|
||
"--root", runner.rootDir,
|
||
"--jobs", "2",
|
||
"--cooldown", "0s",
|
||
)
|
||
|
||
t.Logf("stdout: %s", stdout)
|
||
t.Logf("stderr: %s", stderr)
|
||
|
||
if err != nil {
|
||
t.Fatalf("Install failed: %v\nOutput: %s", err, stdout)
|
||
}
|
||
|
||
// Verify installation
|
||
if !strings.Contains(stdout, "completed") && !strings.Contains(stdout, "successfully") {
|
||
t.Errorf("Installation may have failed, output: %s", stdout)
|
||
}
|
||
}
|
||
|
||
// TestCacheHit tests that cached packages are not rebuilt
|
||
func TestCacheHit(t *testing.T) {
|
||
runner, err := NewFakerootTestRunner()
|
||
if err != nil {
|
||
t.Fatalf("Failed to create test runner: %v", err)
|
||
}
|
||
defer runner.Cleanup()
|
||
|
||
// First install - should build
|
||
stdout1, _, _ := runner.RunInFakeroot(
|
||
"install", "zlib",
|
||
"--work-dir", runner.workDir,
|
||
"--root", runner.rootDir,
|
||
"--dry-run",
|
||
)
|
||
|
||
if !strings.Contains(stdout1, "Would auto-build") {
|
||
t.Skip("Dry-run mode doesn't show cache hit info")
|
||
}
|
||
}
|
||
|
||
// TestDependencyResolution tests dependency resolution
|
||
func TestDependencyResolution(t *testing.T) {
|
||
runner, err := NewFakerootTestRunner()
|
||
if err != nil {
|
||
t.Fatalf("Failed to create test runner: %v", err)
|
||
}
|
||
defer runner.Cleanup()
|
||
|
||
stdout, _, err := runner.RunInFakeroot(
|
||
"search", "libssl-dev",
|
||
)
|
||
|
||
if err != nil {
|
||
t.Logf("Search output: %s", stdout)
|
||
}
|
||
}
|
||
|
||
// TestFakerootIsolation tests that fakeroot provides proper isolation
|
||
func TestFakerootIsolation(t *testing.T) {
|
||
runner, err := NewFakerootTestRunner()
|
||
if err != nil {
|
||
t.Fatalf("Failed to create test runner: %v", err)
|
||
}
|
||
defer runner.Cleanup()
|
||
|
||
// Install a package
|
||
_, _, err = runner.RunInFakeroot(
|
||
"install", "expat",
|
||
"--work-dir", runner.workDir,
|
||
"--root", runner.rootDir,
|
||
"--jobs", "2",
|
||
"--cooldown", "0s",
|
||
)
|
||
|
||
if err != nil {
|
||
t.Skipf("Install failed, skipping isolation test: %v", err)
|
||
}
|
||
|
||
// Verify files are in fakeroot, not system
|
||
fakerootFile := filepath.Join(runner.rootDir, "usr", "lib", "libexpat.so")
|
||
systemFile := "/usr/lib/libexpat.so"
|
||
|
||
if _, err := os.Stat(fakerootFile); err == nil {
|
||
t.Logf("✓ Package installed in fakeroot: %s", fakerootFile)
|
||
} else {
|
||
t.Errorf("Package not found in fakeroot: %v", err)
|
||
}
|
||
|
||
// System should not have the file (or it's different)
|
||
if _, err := os.Stat(systemFile); err == nil {
|
||
t.Logf("ℹ System already has %s (may be different version)", systemFile)
|
||
}
|
||
}
|
||
|
||
// BenchmarkInstall measures install performance
|
||
func BenchmarkInstall(b *testing.B) {
|
||
for i := 0; i < b.N; i++ {
|
||
runner, err := NewFakerootTestRunner()
|
||
if err != nil {
|
||
b.Fatalf("Failed to create test runner: %v", err)
|
||
}
|
||
|
||
// Use dry-run for speed
|
||
runner.RunInFakeroot(
|
||
"install", "zlib",
|
||
"--work-dir", runner.workDir,
|
||
"--root", runner.rootDir,
|
||
"--dry-run",
|
||
)
|
||
|
||
runner.Cleanup()
|
||
}
|
||
}
|
||
|
||
// TestMain runs all tests
|
||
func TestMain(m *testing.M) {
|
||
// Skip if not Linux
|
||
if os.Getenv("GOOS") != "" && os.Getenv("GOOS") != "linux" {
|
||
if _, err := exec.LookPath("go"); err != nil {
|
||
fmt.Println("Skipping tests: not Linux environment")
|
||
os.Exit(0)
|
||
}
|
||
}
|
||
|
||
os.Exit(m.Run())
|
||
}
|