Addresses Hadolint DL3008 warnings and ensures reproducible Docker builds by pinning all apt packages to specific Debian 13 (trixie) versions. Changes: - Dockerfile: Pin 21 packages with version constraints - tests/unit/build-iso_comprehensive_test.bats: Add 22 version pinning tests Pinned versions from Debian 13 candidate: - Base: ca-certificates, gnupg, curl, wget, git - Build: live-build, debootstrap, squashfs-tools, xorriso, grub-* - Testing: bats, shellcheck (bats-* helpers not versioned in Debian) - Security: nftables, iptables, auditd, rsyslog Fixes: FINDING-006 (Docker package versions not pinned) Reference: Hadolint DL3008, reproducible builds best practice 💘 Generated with Crush Assisted-by: Claude via Crush <crush@charm.land>
387 lines
10 KiB
Bash
387 lines
10 KiB
Bash
#!/usr/bin/env bats
|
|
# KNEL-Football Unit Tests - ISO Build Process
|
|
# Reference: PRD.md FR-010 (ISO Build Process)
|
|
# Copyright © 2026 Known Element Enterprises LLC
|
|
# License: GNU Affero General Public License v3.0 only
|
|
|
|
# =============================================================================
|
|
# Build Script Existence
|
|
# =============================================================================
|
|
|
|
@test "run.sh exists for ISO build" {
|
|
[ -f "/workspace/run.sh" ]
|
|
}
|
|
|
|
@test "run.sh is executable" {
|
|
[ -x "/workspace/run.sh" ]
|
|
}
|
|
|
|
@test "Dockerfile exists for build environment" {
|
|
[ -f "/workspace/Dockerfile" ]
|
|
}
|
|
|
|
# =============================================================================
|
|
# Docker Build Environment
|
|
# =============================================================================
|
|
|
|
@test "Dockerfile uses Debian base" {
|
|
grep -q "FROM debian" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile installs live-build" {
|
|
grep -q "live-build" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile installs debootstrap" {
|
|
grep -q "debootstrap" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile installs xorriso for ISO creation" {
|
|
grep -q "xorriso" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile installs grub for UEFI support" {
|
|
grep -q "grub-efi" /workspace/Dockerfile || grep -q "grub-pc" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile installs bats for testing" {
|
|
grep -q "bats" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile installs shellcheck for linting" {
|
|
grep -q "shellcheck" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile creates workspace directory" {
|
|
grep -q "/workspace" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile creates build directory" {
|
|
grep -q "/build" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile creates output directory" {
|
|
grep -q "/output" /workspace/Dockerfile
|
|
}
|
|
|
|
# =============================================================================
|
|
# Live-Build Configuration (run.sh iso command)
|
|
# =============================================================================
|
|
|
|
@test "run.sh configures Debian trixie distribution" {
|
|
grep -q "\-\-distribution trixie" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh configures AMD64 architecture" {
|
|
grep -q "\-\-architectures amd64" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh configures main contrib non-free archives" {
|
|
grep -q "\-\-archive-areas.*main.*contrib.*non-free" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh configures Debian mode" {
|
|
grep -q "\-\-mode debian" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh configures squashfs chroot filesystem" {
|
|
grep -q "\-\-chroot-filesystem squashfs" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh configures ISO hybrid binary image" {
|
|
grep -q "\-\-binary-images iso-hybrid" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh sets ISO application name" {
|
|
grep -q "\-\-iso-application" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh sets ISO publisher" {
|
|
grep -q "\-\-iso-publisher" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh sets ISO volume name" {
|
|
grep -q "\-\-iso-volume" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh enables netinst Debian installer" {
|
|
grep -q "\-\-debian-installer netinst" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh enables Debian installer GUI" {
|
|
grep -q "\-\-debian-installer-gui true" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh disables source packages" {
|
|
grep -q "\-\-source false" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh disables apt indices" {
|
|
grep -q "\-\-apt-indices false" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh disables apt source archives" {
|
|
grep -q "\-\-apt-source-archives false" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Configuration Copying
|
|
# =============================================================================
|
|
|
|
@test "run.sh copies config directory to build" {
|
|
grep -q "cp -r.*config" /workspace/run.sh
|
|
}
|
|
|
|
@test "config directory exists" {
|
|
[ -d "/workspace/config" ]
|
|
}
|
|
|
|
@test "config/preseed.cfg exists" {
|
|
[ -f "/workspace/config/includes.installer/preseed.cfg" ]
|
|
}
|
|
|
|
@test "config/hooks directory exists" {
|
|
[ -d "/workspace/config/hooks" ]
|
|
}
|
|
|
|
@test "config/hooks/live directory exists" {
|
|
[ -d "/workspace/config/hooks/live" ]
|
|
}
|
|
|
|
@test "config/hooks/installed directory exists" {
|
|
[ -d "/workspace/config/hooks/installed" ]
|
|
}
|
|
|
|
@test "config/package-lists directory exists" {
|
|
[ -d "/workspace/config/package-lists" ]
|
|
}
|
|
|
|
# =============================================================================
|
|
# Build Timeout and Safety
|
|
# =============================================================================
|
|
|
|
@test "run.sh has build timeout" {
|
|
grep -q "timeout" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh build timeout is reasonable (1 hour max)" {
|
|
grep -q "timeout 3600" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Checksum Generation
|
|
# =============================================================================
|
|
|
|
@test "run.sh generates SHA256 checksum" {
|
|
grep -q "sha256sum" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh generates MD5 checksum" {
|
|
grep -q "md5sum" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh creates .sha256 file" {
|
|
grep -q "\.sha256" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh creates .md5 file" {
|
|
grep -q "\.md5" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Output Handling
|
|
# =============================================================================
|
|
|
|
@test "run.sh defines output directory" {
|
|
grep -q "OUTPUT_DIR=" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh names final ISO knel-football-secure.iso" {
|
|
grep -q "knel-football-secure.iso" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh copies ISO to output directory" {
|
|
grep -q "cp.*output" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh sets correct ownership on output files" {
|
|
grep -q "chown" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Build Logging
|
|
# =============================================================================
|
|
|
|
@test "run.sh defines build log path" {
|
|
grep -q "BUILD_LOG=" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh logs build output to file" {
|
|
grep -q "tee.*BUILD_LOG" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh has monitor command" {
|
|
grep -q "monitor_build" /workspace/run.sh
|
|
}
|
|
|
|
@test "monitor function checks for build completion" {
|
|
grep -q "ISO build completed" /workspace/run.sh
|
|
}
|
|
|
|
@test "monitor function checks for build failure" {
|
|
grep -q "ISO build failed" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Docker Integration for Build
|
|
# =============================================================================
|
|
|
|
@test "run.sh iso uses docker run" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "docker run"
|
|
}
|
|
|
|
@test "run.sh iso runs as root in container" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "\-\-user root"
|
|
}
|
|
|
|
@test "run.sh iso uses privileged mode for loop devices" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "\-\-privileged"
|
|
}
|
|
|
|
@test "run.sh iso mounts workspace read-only" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "/workspace:ro"
|
|
}
|
|
|
|
@test "run.sh iso mounts output directory" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "/output"
|
|
}
|
|
|
|
@test "run.sh iso sets timezone" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "TZ="
|
|
}
|
|
|
|
@test "run.sh iso sets noninteractive frontend" {
|
|
grep -A 100 'iso)' /workspace/run.sh | grep -q "DEBIAN_FRONTEND"
|
|
}
|
|
|
|
# =============================================================================
|
|
# Error Handling
|
|
# =============================================================================
|
|
|
|
@test "run.sh checks for ISO creation success" {
|
|
grep -q "ISO_FILE=" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh handles ISO creation failure" {
|
|
grep -q "exit 1" /workspace/run.sh
|
|
}
|
|
|
|
@test "run.sh lists output on success" {
|
|
grep -q "ls -lh.*output" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Host FDE Requirement (FR-011)
|
|
# =============================================================================
|
|
|
|
@test "run.sh iso checks host FDE before building" {
|
|
grep -B 2 'iso)' /workspace/run.sh | grep -A 10 'iso)' /workspace/run.sh | grep -q "check_host_fde"
|
|
}
|
|
|
|
@test "run.sh exits if host FDE check fails" {
|
|
grep -q "check_host_fde || exit 1" /workspace/run.sh
|
|
}
|
|
|
|
# =============================================================================
|
|
# Package Version Pinning (FINDING-006 - Reproducible Builds)
|
|
# =============================================================================
|
|
|
|
@test "Dockerfile pins ca-certificates version" {
|
|
grep -q "ca-certificates=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins gnupg version" {
|
|
grep -q "gnupg=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins curl version" {
|
|
grep -q "curl=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins wget version" {
|
|
grep -q "wget=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins git version" {
|
|
grep -q "git=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins live-build version" {
|
|
grep -q "live-build=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins debootstrap version" {
|
|
grep -q "debootstrap=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins squashfs-tools version" {
|
|
grep -q "squashfs-tools=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins xorriso version" {
|
|
grep -q "xorriso=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins grub-pc-bin version" {
|
|
grep -q "grub-pc-bin=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins grub-efi-amd64-bin version" {
|
|
grep -q "grub-efi-amd64-bin=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins mtools version" {
|
|
grep -q "mtools=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins dosfstools version" {
|
|
grep -q "dosfstools=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins syslinux-utils version" {
|
|
grep -q "syslinux-utils=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins isolinux version" {
|
|
grep -q "isolinux=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins bats version" {
|
|
grep -q "bats=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins shellcheck version" {
|
|
grep -q "shellcheck=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins nftables version" {
|
|
grep -q "nftables=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins iptables version" {
|
|
grep -q "iptables=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins auditd version" {
|
|
grep -q "auditd=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile pins rsyslog version" {
|
|
grep -q "rsyslog=" /workspace/Dockerfile
|
|
}
|
|
|
|
@test "Dockerfile has at least 20 pinned packages" {
|
|
pinned=$(grep -c "=[0-9]" /workspace/Dockerfile || echo 0)
|
|
[ "$pinned" -ge 20 ]
|
|
}
|