#!/bin/bash # Particle-OS System Testing Script # Comprehensive testing of all Particle-OS tools and components set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Test results TESTS_PASSED=0 TESTS_FAILED=0 TESTS_SKIPPED=0 # Logging functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } # Test function run_test() { local test_name="$1" local test_command="$2" local description="${3:-}" echo log_info "Running test: $test_name" if [[ -n "$description" ]]; then log_info "Description: $description" fi if eval "$test_command" >/dev/null 2>&1; then log_success "Test PASSED: $test_name" ((TESTS_PASSED++)) return 0 else log_error "Test FAILED: $test_name" ((TESTS_FAILED++)) return 1 fi } # Skip test function skip_test() { local test_name="$1" local reason="${2:-Not applicable}" echo log_warning "Test SKIPPED: $test_name" log_warning "Reason: $reason" ((TESTS_SKIPPED++)) } # Test system permissions test_system_permissions() { log_info "=== Testing System Permissions ===" # Test directory permissions run_test "Particle-OS workspace directory" \ "[[ -d /var/lib/particle-os && -r /var/lib/particle-os && -w /var/lib/particle-os ]]" \ "Check if workspace directory exists and is writable" run_test "Particle-OS log directory" \ "[[ -d /var/log/particle-os && -r /var/log/particle-os && -w /var/log/particle-os ]]" \ "Check if log directory exists and is writable" run_test "Particle-OS cache directory" \ "[[ -d /var/cache/particle-os && -r /var/cache/particle-os && -w /var/cache/particle-os ]]" \ "Check if cache directory exists and is writable" run_test "Particle-OS config directory" \ "[[ -d /usr/local/etc/particle-os && -r /usr/local/etc/particle-os ]]" \ "Check if config directory exists and is readable" # Test file permissions run_test "Particle-OS configuration file" \ "[[ -f /usr/local/etc/particle-config.sh && -r /usr/local/etc/particle-config.sh ]]" \ "Check if configuration file exists and is readable" run_test "Deployment database file" \ "[[ -f /var/lib/particle-os/deployments.json && -r /var/lib/particle-os/deployments.json && -w /var/lib/particle-os/deployments.json ]]" \ "Check if deployment database exists and is writable" run_test "Current deployment file" \ "[[ -f /var/lib/particle-os/current-deployment && -r /var/lib/particle-os/current-deployment && -w /var/lib/particle-os/current-deployment ]]" \ "Check if current deployment file exists and is writable" } # Test tool availability test_tool_availability() { log_info "=== Testing Tool Availability ===" # Test if tools are in PATH run_test "apt-layer tool availability" \ "command -v apt-layer >/dev/null 2>&1" \ "Check if apt-layer is available in PATH" run_test "composefs tool availability" \ "command -v composefs >/dev/null 2>&1" \ "Check if composefs is available in PATH" run_test "bootc tool availability" \ "command -v bootc >/dev/null 2>&1" \ "Check if bootc is available in PATH" run_test "bootupd tool availability" \ "command -v bootupd >/dev/null 2>&1" \ "Check if bootupd is available in PATH" run_test "particle-orchestrator tool availability" \ "command -v particle-orchestrator >/dev/null 2>&1" \ "Check if particle-orchestrator is available in PATH" # Test if tools are executable run_test "apt-layer executable" \ "[[ -x /usr/local/bin/apt-layer ]]" \ "Check if apt-layer is executable" run_test "composefs executable" \ "[[ -x /usr/local/bin/composefs ]]" \ "Check if composefs is executable" run_test "bootc executable" \ "[[ -x /usr/local/bin/bootc ]]" \ "Check if bootc is executable" run_test "bootupd executable" \ "[[ -x /usr/local/bin/bootupd ]]" \ "Check if bootupd is executable" run_test "particle-orchestrator executable" \ "[[ -x /usr/local/bin/particle-orchestrator ]]" \ "Check if particle-orchestrator is executable" } # Test tool functionality test_tool_functionality() { log_info "=== Testing Tool Functionality ===" # Test help commands (should work without root) run_test "apt-layer help" \ "apt-layer --help >/dev/null 2>&1" \ "Check if apt-layer shows help without errors" run_test "composefs help" \ "composefs --help >/dev/null 2>&1" \ "Check if composefs shows help without errors" run_test "bootc help" \ "bootc --help >/dev/null 2>&1" \ "Check if bootc shows help without errors" run_test "bootupd help" \ "bootupd --help >/dev/null 2>&1" \ "Check if bootupd shows help without errors" run_test "particle-orchestrator help" \ "particle-orchestrator help >/dev/null 2>&1" \ "Check if particle-orchestrator shows help without errors" # Test status commands (should work without root) run_test "apt-layer status" \ "apt-layer status >/dev/null 2>&1" \ "Check if apt-layer status works without errors" run_test "composefs status" \ "composefs status >/dev/null 2>&1" \ "Check if composefs status works without errors" run_test "bootc status" \ "bootc status >/dev/null 2>&1" \ "Check if bootc status works without errors" run_test "bootupd status" \ "bootupd status >/dev/null 2>&1" \ "Check if bootupd status works without errors" } # Test system dependencies test_system_dependencies() { log_info "=== Testing System Dependencies ===" # Test essential system packages run_test "squashfs-tools package" \ "dpkg -l | grep -q '^ii squashfs-tools '" \ "Check if squashfs-tools is installed" run_test "jq package" \ "dpkg -l | grep -q '^ii jq '" \ "Check if jq is installed" run_test "podman package" \ "dpkg -l | grep -q '^ii podman '" \ "Check if podman is installed" run_test "skopeo package" \ "dpkg -l | grep -q '^ii skopeo '" \ "Check if skopeo is installed" # Test kernel modules run_test "overlay kernel module" \ "lsmod | grep -q '^overlay '" \ "Check if overlay kernel module is loaded" run_test "squashfs kernel module" \ "lsmod | grep -q '^squashfs '" \ "Check if squashfs kernel module is loaded" # Test essential commands run_test "jq command" \ "command -v jq >/dev/null 2>&1" \ "Check if jq command is available" run_test "podman command" \ "command -v podman >/dev/null 2>&1" \ "Check if podman command is available" run_test "skopeo command" \ "command -v skopeo >/dev/null 2>&1" \ "Check if skopeo command is available" run_test "mksquashfs command" \ "command -v mksquashfs >/dev/null 2>&1" \ "Check if mksquashfs command is available" run_test "unsquashfs command" \ "command -v unsquashfs >/dev/null 2>&1" \ "Check if unsquashfs command is available" } # Test configuration loading test_configuration_loading() { log_info "=== Testing Configuration Loading ===" # Test configuration file loading run_test "Configuration file loading" \ "source /usr/local/etc/particle-config.sh && [[ -n \"\$PARTICLE_WORKSPACE\" ]]" \ "Check if configuration file can be loaded and variables are set" run_test "PARTICLE_WORKSPACE variable" \ "source /usr/local/etc/particle-config.sh && [[ \"\$PARTICLE_WORKSPACE\" == \"/var/lib/particle-os\" ]]" \ "Check if PARTICLE_WORKSPACE variable is set correctly" run_test "PARTICLE_LOG_DIR variable" \ "source /usr/local/etc/particle-config.sh && [[ \"\$PARTICLE_LOG_DIR\" == \"/var/log/particle-os\" ]]" \ "Check if PARTICLE_LOG_DIR variable is set correctly" run_test "PARTICLE_CONFIG_LOADED variable" \ "source /usr/local/etc/particle-config.sh && [[ \"\$PARTICLE_CONFIG_LOADED\" == \"true\" ]]" \ "Check if PARTICLE_CONFIG_LOADED variable is set correctly" } # Test log file creation test_log_file_creation() { log_info "=== Testing Log File Creation ===" # Test if tools can write to log files run_test "apt-layer log file writable" \ "touch /var/log/particle-os/apt-layer.log && [[ -w /var/log/particle-os/apt-layer.log ]]" \ "Check if apt-layer log file is writable" run_test "composefs log file writable" \ "touch /var/log/particle-os/composefs.log && [[ -w /var/log/particle-os/composefs.log ]]" \ "Check if composefs log file is writable" run_test "bootc log file writable" \ "touch /var/log/particle-os/bootc.log && [[ -w /var/log/particle-os/bootc.log ]]" \ "Check if bootc log file is writable" run_test "bootupd log file writable" \ "touch /var/log/particle-os/bootupd.log && [[ -w /var/log/particle-os/bootupd.log ]]" \ "Check if bootupd log file is writable" run_test "orchestrator log file writable" \ "touch /var/log/particle-os/orchestrator.log && [[ -w /var/log/particle-os/orchestrator.log ]]" \ "Check if orchestrator log file is writable" } # Test basic operations (as regular user) test_basic_operations() { log_info "=== Testing Basic Operations (as regular user) ===" # Test list commands run_test "apt-layer list branches" \ "apt-layer --list >/dev/null 2>&1" \ "Check if apt-layer can list branches" run_test "composefs list images" \ "composefs list-images >/dev/null 2>&1" \ "Check if composefs can list images" # Test info commands run_test "apt-layer info command" \ "apt-layer --info test-image >/dev/null 2>&1 || true" \ "Check if apt-layer info command works (may fail for non-existent image)" # Test query commands run_test "apt-layer query audit" \ "apt-layer --query-audit >/dev/null 2>&1" \ "Check if apt-layer can query audit logs" } # Test root operations (skip if not root) test_root_operations() { log_info "=== Testing Root Operations ===" if [[ $EUID -eq 0 ]]; then # Test initialization run_test "apt-layer initialization" \ "apt-layer --init >/dev/null 2>&1" \ "Check if apt-layer can initialize system" # Test basic package operations run_test "apt-layer install (dry run)" \ "apt-layer install --dry-run test-package >/dev/null 2>&1 || true" \ "Check if apt-layer install command works (may fail for non-existent package)" # Test composefs operations run_test "composefs create (test)" \ "mkdir -p /tmp/test-composefs && composefs create test-image /tmp/test-composefs >/dev/null 2>&1 || true" \ "Check if composefs can create images (may fail for missing dependencies)" # Cleanup rm -rf /tmp/test-composefs 2>/dev/null || true else skip_test "Root operations" "Not running as root" fi } # Generate test report generate_report() { echo log_info "=== Test Report ===" log_info "Tests passed: $TESTS_PASSED" log_info "Tests failed: $TESTS_FAILED" log_info "Tests skipped: $TESTS_SKIPPED" local total_tests=$((TESTS_PASSED + TESTS_FAILED + TESTS_SKIPPED)) local success_rate=0 if [[ $total_tests -gt 0 ]]; then success_rate=$((TESTS_PASSED * 100 / total_tests)) fi log_info "Total tests: $total_tests" log_info "Success rate: ${success_rate}%" if [[ $TESTS_FAILED -eq 0 ]]; then log_success "All tests passed! Particle-OS system is working correctly." return 0 else log_error "Some tests failed. Please review the issues above." return 1 fi } # Main function main() { log_info "Starting Particle-OS system testing..." # Run all test suites test_system_permissions test_tool_availability test_system_dependencies test_configuration_loading test_log_file_creation test_tool_functionality test_basic_operations test_root_operations # Generate report generate_report } # Run main function main "$@"