#!/bin/sh # $KAPPA integration test suite # Run: docker run --rm -v $(pwd):/opt/$KAPPA kappa-test ./test.sh set -e KAPPA="${KAPPA_BIN:-./build/kappa}" PASS=0 FAIL=0 check() { local desc="$1" cmd="$2" expect="$3" local out out=$(eval "$cmd" 2>&1) || true if echo "$out" | grep -q "$expect"; then echo " ✓ $desc" PASS=$((PASS + 1)) else echo " ✗ $desc" echo " expected: $expect" echo " got: $(echo "$out" | head -3)" FAIL=$((FAIL + 1)) fi } echo "" echo "=== Package DSL tests ===" echo "" check "parse foo.kap" \ "$KAPPA parse-package examples/foo.kap" \ 'package "foo" 1.2.3 — valid' check "parse postgres.kap (multi-service)" \ "$KAPPA parse-package examples/postgres.kap" \ 'package "postgresql" 16.3 — valid' check "format foo.kap round-trips service block" \ "$KAPPA format examples/foo.kap" \ 'service {' check "format postgres.kap shows named services" \ "$KAPPA format examples/postgres.kap" \ 'service checkpointer {' echo "" echo "=== Config DSL tests ===" echo "" check "parse config.kap" \ "$KAPPA parse-config examples/config.kap" \ 'system config — valid' check "config.kap shows init description" \ "$KAPPA parse-config examples/config.kap" \ 's6 — s6 supervision suite' check "config.kap shows bootloader description" \ "$KAPPA parse-config examples/config.kap" \ 'Limine — modern multiprotocol bootloader' echo "" echo "=== Doctor tests ===" echo "" check "doctor foo.kap" \ "$KAPPA doctor examples/foo.kap" \ 'no issues found' echo "" echo "=== Validate tests ===" echo "" check "validate foo.kap" \ "$KAPPA validate examples/foo.kap" \ 'valid package' echo "" echo "=== Rebuild tests ===" echo "" check "rebuild detects new packages" \ "$KAPPA rebuild examples/config.kap" \ 'packages to rebuild' echo "" echo "=== Init system recognition tests ===" echo "" # Create temp config with each init system for init in systemd openrc s6 runit dinit; do cat > /tmp/test_init.kap << KAPEOF system { hostname = "test" } packages {} services {} boot { kernel = "linux" init = "$init" root = "/dev/sda1" bootloader = "limine" } users { root { shell = "/bin/sh" } } KAPEOF check "recognizes init=$init" \ "$KAPPA parse-config /tmp/test_init.kap" \ "$init" check "doctor accepts init=$init" \ "$KAPPA doctor /tmp/test_init.kap 2>&1" \ "" done # Test unknown init cat > /tmp/test_badinit.kap << 'KAPEOF' system { hostname = "test" } packages {} services {} boot { kernel = "linux" init = "fakething" root = "/dev/sda1" bootloader = "limine" } users { root { shell = "/bin/sh" } } KAPEOF check "warns on unknown init" \ "$KAPPA doctor /tmp/test_badinit.kap 2>&1" \ 'not a recognized init system' echo "" echo "=== Bootloader recognition tests ===" echo "" for bl in grub limine; do cat > /tmp/test_bl.kap << KAPEOF system { hostname = "test" } packages {} services {} boot { kernel = "linux" init = "s6" root = "/dev/sda1" bootloader = "$bl" } users { root { shell = "/bin/sh" } } KAPEOF check "recognizes bootloader=$bl" \ "$KAPPA parse-config /tmp/test_bl.kap" \ "$bl" done echo "" echo "=== Service generation tests ===" echo "" # Test that format output contains service fields for each backend type hint check "service format includes type field" \ "$KAPPA format examples/foo.kap" \ 'type = "forking"' check "service format includes ports" \ "$KAPPA format examples/foo.kap" \ 'ports = \[' check "service format includes description" \ "$KAPPA format examples/foo.kap" \ 'description = "Foo web server"' echo "" echo "=== Groups DSL tests ===" echo "" cat > /tmp/test_groups.kap << 'KAPEOF' system { hostname = "test" } packages {} services {} boot { kernel = "linux" init = "s6" root = "/dev/sda1" bootloader = "limine" } groups { wheel { gid = 998 } audio {} docker { gid = 995 } } users { root { shell = "/bin/sh" } } KAPEOF check "parse groups block" \ "$KAPPA parse-config /tmp/test_groups.kap" \ 'valid' check "format groups round-trips" \ "$KAPPA format /tmp/test_groups.kap" \ 'wheel {' echo "" echo "=== Conflicts tests ===" echo "" cat > /tmp/test_conflict.kap << 'KAPEOF' package "systemd" { version = "255" source = "https://example.com/systemd-255.tar.gz" provides = ["udev", "logind"] conflicts = ["eudev", "elogind"] build { make } install { make install } } KAPEOF check "parse conflicts in package def" \ "$KAPPA parse-package /tmp/test_conflict.kap" \ 'valid' check "format shows conflicts" \ "$KAPPA format /tmp/test_conflict.kap" \ 'conflicts =' echo "" echo "==========================================" echo " Results: $PASS passed, $FAIL failed" echo "==========================================" [ "$FAIL" -eq 0 ] || exit 1