diff --git a/Project-Tests/run-tests.sh b/Project-Tests/run-tests.sh index 6a34df0..f0190ba 100755 --- a/Project-Tests/run-tests.sh +++ b/Project-Tests/run-tests.sh @@ -5,10 +5,19 @@ set -euo pipefail -# Source framework includes -PROJECT_ROOT="$(dirname "$(realpath "${BASH_SOURCE[0]}")")/.." -source "$PROJECT_ROOT/Framework-Includes/Logging.sh" -source "$PROJECT_ROOT/Framework-Includes/PrettyPrint.sh" +# Resolve repository root from this script's location (Project-Tests/ -> repo root) +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +# The KNELShellFramework is vendored under vendor/ +FRAMEWORK_INCLUDES="$PROJECT_ROOT/vendor/git@git.knownelement.com/29418/KNEL/KNELShellFramework/Framework-Includes" +source "$FRAMEWORK_INCLUDES/Logging.sh" +source "$FRAMEWORK_INCLUDES/PrettyPrint.sh" + +# The vendored PrettyPrint only defines print_info/print_error; provide the +# additional output helpers the test suite relies on. +function print_header() { echo ""; echo "=== $1 ==="; } +function print_success() { echo "✅ $1"; } +function print_warning() { echo "⚠️ $1"; } # Test configuration TEST_LOG_DIR="$PROJECT_ROOT/logs/tests" diff --git a/Project-Tests/security/2fa-validation.sh b/Project-Tests/security/2fa-validation.sh index 443c2d6..f1b9b78 100755 --- a/Project-Tests/security/2fa-validation.sh +++ b/Project-Tests/security/2fa-validation.sh @@ -18,7 +18,7 @@ function test_2fa_packages() { echo "✅ Package installed: $package" else echo "❌ Package missing: $package" - ((failed++)) + ((++failed)) fi done @@ -27,7 +27,7 @@ function test_2fa_packages() { echo "✅ Google Authenticator command available" else echo "❌ Google Authenticator command not found" - ((failed++)) + ((++failed)) fi return $failed @@ -44,21 +44,21 @@ function test_ssh_2fa_config() { echo "✅ ChallengeResponseAuthentication enabled" else echo "❌ ChallengeResponseAuthentication not enabled" - ((failed++)) + ((++failed)) fi if grep -q "^UsePAM yes" "$ssh_config"; then echo "✅ UsePAM enabled" else echo "❌ UsePAM not enabled" - ((failed++)) + ((++failed)) fi if grep -q "^AuthenticationMethods publickey,keyboard-interactive" "$ssh_config"; then echo "✅ AuthenticationMethods configured for 2FA" else echo "❌ AuthenticationMethods not configured for 2FA" - ((failed++)) + ((++failed)) fi return $failed @@ -75,7 +75,7 @@ function test_pam_2fa_config() { echo "✅ PAM Google Authenticator module configured" else echo "❌ PAM Google Authenticator module not configured" - ((failed++)) + ((++failed)) fi # Check if nullok is present (allows users without 2FA setup) @@ -106,7 +106,7 @@ function test_cockpit_2fa_config() { echo "✅ Cockpit configuration file exists" else echo "❌ Cockpit configuration file missing" - ((failed++)) + ((++failed)) fi # Check Cockpit PAM configuration @@ -114,7 +114,7 @@ function test_cockpit_2fa_config() { echo "✅ Cockpit PAM 2FA configured" else echo "❌ Cockpit PAM 2FA not configured" - ((failed++)) + ((++failed)) fi return $failed @@ -137,14 +137,14 @@ function test_webmin_2fa_config() { echo "✅ Webmin TOTP provider configured" else echo "❌ Webmin TOTP provider not configured" - ((failed++)) + ((++failed)) fi if grep -q "^twofactor=1" "$webmin_config"; then echo "✅ Webmin 2FA enabled" else echo "❌ Webmin 2FA not enabled" - ((failed++)) + ((++failed)) fi return $failed @@ -163,7 +163,7 @@ function test_user_2fa_setup() { echo "✅ 2FA setup script exists for user: $user" else echo "❌ 2FA setup script missing for user: $user" - ((failed++)) + ((++failed)) fi # Check if instructions exist @@ -171,7 +171,7 @@ function test_user_2fa_setup() { echo "✅ 2FA instructions exist for user: $user" else echo "❌ 2FA instructions missing for user: $user" - ((failed++)) + ((++failed)) fi else echo "⚠️ User $user not found, skipping" @@ -191,7 +191,7 @@ function test_service_status() { echo "✅ SSH service is running" else echo "❌ SSH service is not running" - ((failed++)) + ((++failed)) fi # Test SSH configuration @@ -199,7 +199,7 @@ function test_service_status() { echo "✅ SSH configuration is valid" else echo "❌ SSH configuration is invalid" - ((failed++)) + ((++failed)) fi # Test Cockpit service if installed @@ -208,7 +208,7 @@ function test_service_status() { echo "✅ Cockpit service is running" else echo "❌ Cockpit service is not running" - ((failed++)) + ((++failed)) fi fi @@ -218,7 +218,7 @@ function test_service_status() { echo "✅ Webmin service is running" else echo "❌ Webmin service is not running" - ((failed++)) + ((++failed)) fi fi @@ -242,7 +242,7 @@ function test_backup_existence() { fi else echo "❌ Backup directory does not exist" - ((failed++)) + ((++failed)) fi return $failed diff --git a/Project-Tests/security/https-enforcement.sh b/Project-Tests/security/https-enforcement.sh index 9263afd..08f1073 100755 --- a/Project-Tests/security/https-enforcement.sh +++ b/Project-Tests/security/https-enforcement.sh @@ -5,23 +5,24 @@ set -euo pipefail -PROJECT_ROOT="$(dirname "$(realpath "${BASH_SOURCE[0]}")")/../.." +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +FRAMEWORK_INCLUDES="$PROJECT_ROOT/vendor/git@git.knownelement.com/29418/KNEL/KNELShellFramework/Framework-Includes" function test_no_http_urls() { echo "🔍 Checking for HTTP URLs in scripts..." local http_violations=0 - local script_dirs=("ProjectCode" "Framework-Includes" "Project-Includes") - + local script_dirs=("$PROJECT_ROOT/ProjectCode" "$FRAMEWORK_INCLUDES" "$PROJECT_ROOT/Project-Includes") + for dir in "${script_dirs[@]}"; do - if [[ -d "$PROJECT_ROOT/$dir" ]]; then + if [[ -d "$dir" ]]; then # Find HTTP URLs in shell scripts (excluding comments) while IFS= read -r -d '' file; do if grep -n "http://" "$file" | grep -v "^[[:space:]]*#" | grep -v "schema.org" | grep -v "xmlns"; then echo "❌ HTTP URL found in: $file" - ((http_violations++)) + ((++http_violations)) fi - done < <(find "$PROJECT_ROOT/$dir" -name "*.sh" -type f -print0) + done < <(find "$dir" -name "*.sh" -type f -print0) fi done @@ -37,12 +38,12 @@ function test_no_http_urls() { function test_https_urls_valid() { echo "🔍 Validating HTTPS URLs are accessible..." - local script_dirs=("ProjectCode" "Framework-Includes" "Project-Includes") + local script_dirs=("$PROJECT_ROOT/ProjectCode" "$FRAMEWORK_INCLUDES" "$PROJECT_ROOT/Project-Includes") local https_failures=0 - + # Extract HTTPS URLs from scripts for dir in "${script_dirs[@]}"; do - if [[ -d "$PROJECT_ROOT/$dir" ]]; then + if [[ -d "$dir" ]]; then while IFS= read -r -d '' file; do # Extract HTTPS URLs from non-comment lines grep -o "https://[^[:space:]\"']*" "$file" | grep -v "schema.org" | while read -r url; do @@ -51,10 +52,10 @@ function test_https_urls_valid() { echo "✅ HTTPS URL accessible: $url" else echo "❌ HTTPS URL not accessible: $url" - ((https_failures++)) + ((++https_failures)) fi done - done < <(find "$PROJECT_ROOT/$dir" -name "*.sh" -type f -print0) + done < <(find "$dir" -name "*.sh" -type f -print0) fi done @@ -78,7 +79,7 @@ function test_ssl_certificate_validation() { echo "✅ SSL certificate valid: $url" else echo "❌ SSL certificate validation failed: $url" - ((ssl_failures++)) + ((++ssl_failures)) fi done diff --git a/Project-Tests/unit/framework-functions.sh b/Project-Tests/unit/framework-functions.sh index 5ffe5f4..affd68e 100755 --- a/Project-Tests/unit/framework-functions.sh +++ b/Project-Tests/unit/framework-functions.sh @@ -5,37 +5,31 @@ set -euo pipefail -PROJECT_ROOT="$(dirname "$(realpath "${BASH_SOURCE[0]}")")/../.." +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -# Source framework functions -source "$PROJECT_ROOT/Framework-Includes/Logging.sh" 2>/dev/null || echo "Warning: Logging.sh not found" -source "$PROJECT_ROOT/Framework-Includes/PrettyPrint.sh" 2>/dev/null || echo "Warning: PrettyPrint.sh not found" -source "$PROJECT_ROOT/Framework-Includes/ErrorHandling.sh" 2>/dev/null || echo "Warning: ErrorHandling.sh not found" +# Source framework functions from the vendored KNELShellFramework +FRAMEWORK_INCLUDES="$PROJECT_ROOT/vendor/git@git.knownelement.com/29418/KNEL/KNELShellFramework/Framework-Includes" +source "$FRAMEWORK_INCLUDES/Logging.sh" 2>/dev/null || echo "Warning: Logging.sh not found" +source "$FRAMEWORK_INCLUDES/PrettyPrint.sh" 2>/dev/null || echo "Warning: PrettyPrint.sh not found" +source "$FRAMEWORK_INCLUDES/ErrorHandling.sh" 2>/dev/null || echo "Warning: ErrorHandling.sh not found" -function test_logging_functions() { - echo "🔍 Testing logging functions..." - - local test_log="/tmp/test-log-$$" - - # Test if logging functions exist and work - if command -v log_info >/dev/null 2>&1; then - log_info "Test info message" 2>/dev/null || true - echo "✅ log_info function exists" +function test_logging_variables() { + echo "🔍 Testing logging variables..." + + if [[ -n "${CURRENT_TIMESTAMP:-}" ]]; then + echo "✅ CURRENT_TIMESTAMP is set" else - echo "❌ log_info function missing" + echo "❌ CURRENT_TIMESTAMP is not set" return 1 fi - - if command -v log_error >/dev/null 2>&1; then - log_error "Test error message" 2>/dev/null || true - echo "✅ log_error function exists" + + if [[ -n "${LOGFILENAME:-}" ]]; then + echo "✅ LOGFILENAME is set" else - echo "❌ log_error function missing" + echo "❌ LOGFILENAME is not set" return 1 fi - - # Cleanup - rm -f "$test_log" + return 0 } @@ -59,14 +53,6 @@ function test_pretty_print_functions() { return 1 fi - if command -v print_success >/dev/null 2>&1; then - print_success "Test success message" >/dev/null 2>&1 || true - echo "✅ print_success function exists" - else - echo "❌ print_success function missing" - return 1 - fi - return 0 } @@ -74,10 +60,17 @@ function test_error_handling() { echo "🔍 Testing error handling..." # Test if error handling functions exist - if command -v handle_error >/dev/null 2>&1; then - echo "✅ handle_error function exists" + if command -v error_out >/dev/null 2>&1; then + echo "✅ error_out function exists" else - echo "❌ handle_error function missing" + echo "❌ error_out function missing" + return 1 + fi + + if command -v handle_failure >/dev/null 2>&1; then + echo "✅ handle_failure function exists" + else + echo "❌ handle_failure function missing" return 1 fi @@ -112,11 +105,11 @@ function test_framework_includes_exist() { local missing_files=0 for include_file in "${required_includes[@]}"; do - if [[ -f "$PROJECT_ROOT/Framework-Includes/$include_file" ]]; then + if [[ -f "$FRAMEWORK_INCLUDES/$include_file" ]]; then echo "✅ Framework include exists: $include_file" else echo "❌ Framework include missing: $include_file" - ((missing_files++)) + ((++missing_files)) fi done @@ -127,18 +120,28 @@ function test_syntax_validation() { echo "🔍 Testing script syntax validation..." local syntax_errors=0 - local script_dirs=("Framework-Includes" "Project-Includes" "ProjectCode") - + local script_dirs=( + "$FRAMEWORK_INCLUDES" + "$PROJECT_ROOT/Project-Includes" + "$PROJECT_ROOT/ProjectCode" + ) + for dir in "${script_dirs[@]}"; do - if [[ -d "$PROJECT_ROOT/$dir" ]]; then + if [[ -d "$dir" ]]; then while IFS= read -r -d '' file; do + # Skip files that aren't bash scripts despite a .sh extension (e.g. PHP agents) + local shebang + shebang="$(head -c 32 "$file" 2>/dev/null)" + case "$shebang" in + *php*|*python*|*perl*) continue ;; + esac if bash -n "$file" 2>/dev/null; then echo "✅ Syntax valid: $(basename "$file")" else echo "❌ Syntax error in: $(basename "$file")" - ((syntax_errors++)) + ((++syntax_errors)) fi - done < <(find "$PROJECT_ROOT/$dir" -name "*.sh" -type f -print0) + done < <(find "$dir" -name "*.sh" -type f -print0) fi done @@ -154,7 +157,7 @@ function main() { # Run all unit tests test_framework_includes_exist || ((total_failures++)) - test_logging_functions || ((total_failures++)) + test_logging_variables || ((total_failures++)) test_pretty_print_functions || ((total_failures++)) test_error_handling || ((total_failures++)) test_syntax_validation || ((total_failures++)) diff --git a/Project-Tests/unit/safe-download.sh b/Project-Tests/unit/safe-download.sh index c20a3ee..f441227 100755 --- a/Project-Tests/unit/safe-download.sh +++ b/Project-Tests/unit/safe-download.sh @@ -5,15 +5,22 @@ set -euo pipefail -PROJECT_ROOT="$(dirname "$(realpath "${BASH_SOURCE[0]}")")/../.." +PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -# Source framework functions -source "$PROJECT_ROOT/Framework-Includes/SafeDownload.sh" +# Source framework functions from the vendored KNELShellFramework +FRAMEWORK_INCLUDES="$PROJECT_ROOT/vendor/git@git.knownelement.com/29418/KNEL/KNELShellFramework/Framework-Includes" + +# The vendored PrettyPrint only defines print_info/print_error, but SafeDownload.sh +# calls print_success/print_warning; define lightweight shims before sourcing. +function print_success() { echo "✅ $1"; } +function print_warning() { echo "⚠️ $1"; } + +source "$FRAMEWORK_INCLUDES/SafeDownload.sh" function test_network_connectivity() { echo "🔍 Testing network connectivity..." - - if test_network_connectivity; then + + if check_url_accessibility "https://github.com"; then echo "✅ Network connectivity test passed" return 0 else @@ -37,7 +44,7 @@ function test_url_accessibility() { echo "✅ URL accessible: $url" else echo "❌ URL not accessible: $url" - ((failed++)) + ((++failed)) fi done @@ -60,20 +67,20 @@ function test_safe_download() { echo "✅ Downloaded file exists and has content" else echo "❌ Downloaded file is missing or empty" - ((failed++)) + ((++failed)) fi # Cleanup rm -f "$test_dest" else echo "❌ Safe download failed" - ((failed++)) + ((++failed)) fi # Test download with invalid URL if safe_download "https://invalid.example.com/nonexistent" "/tmp/test-invalid-$$" 2>/dev/null; then echo "❌ Invalid URL download should have failed" - ((failed++)) + ((++failed)) else echo "✅ Invalid URL download failed as expected" fi @@ -97,13 +104,13 @@ function test_checksum_verification() { echo "✅ Correct checksum verification passed" else echo "❌ Correct checksum verification failed" - ((failed++)) + ((++failed)) fi # Test incorrect checksum if verify_checksum "$test_file" "invalid_checksum" 2>/dev/null; then echo "❌ Incorrect checksum should have failed" - ((failed++)) + ((++failed)) else echo "✅ Incorrect checksum verification failed as expected" fi @@ -111,7 +118,7 @@ function test_checksum_verification() { # Test missing file if verify_checksum "/tmp/nonexistent-file-$$" "$expected_checksum" 2>/dev/null; then echo "❌ Missing file checksum should have failed" - ((failed++)) + ((++failed)) else echo "✅ Missing file checksum verification failed as expected" fi @@ -143,7 +150,7 @@ function test_batch_download() { echo "✅ Batch file downloaded: $(basename "$file")" else echo "❌ Batch file missing: $(basename "$file")" - ((failed++)) + ((++failed)) fi done @@ -153,7 +160,7 @@ function test_batch_download() { done else echo "❌ Batch download failed" - ((failed++)) + ((++failed)) fi return $failed @@ -172,7 +179,7 @@ function test_config_backup_and_restore() { # Test safe config download (this will fail with invalid URL, triggering restore) if safe_config_download "https://invalid.example.com/config" "$test_config" ".test-backup" 2>/dev/null; then echo "❌ Invalid config download should have failed" - ((failed++)) + ((++failed)) else echo "✅ Invalid config download failed as expected" @@ -181,7 +188,7 @@ function test_config_backup_and_restore() { echo "✅ Original config was restored after failed download" else echo "❌ Original config was not restored properly" - ((failed++)) + ((++failed)) fi fi @@ -199,14 +206,14 @@ function test_download_error_handling() { # Test download with missing parameters if safe_download "" "/tmp/test" 2>/dev/null; then echo "❌ Download with empty URL should have failed" - ((failed++)) + ((++failed)) else echo "✅ Download with empty URL failed as expected" fi if safe_download "https://example.com" "" 2>/dev/null; then echo "❌ Download with empty destination should have failed" - ((failed++)) + ((++failed)) else echo "✅ Download with empty destination failed as expected" fi @@ -214,7 +221,7 @@ function test_download_error_handling() { # Test download to read-only location (should fail) if safe_download "https://github.com" "/test-readonly-$$" 2>/dev/null; then echo "❌ Download to read-only location should have failed" - ((failed++)) + ((++failed)) else echo "✅ Download to read-only location failed as expected" fi diff --git a/Project-Tests/validation/system-requirements.sh b/Project-Tests/validation/system-requirements.sh index 8cbf22a..c0d3a63 100755 --- a/Project-Tests/validation/system-requirements.sh +++ b/Project-Tests/validation/system-requirements.sh @@ -44,7 +44,7 @@ function test_required_commands() { echo "✅ Required command available: $cmd" else echo "❌ Required command missing: $cmd" - ((failed++)) + ((++failed)) fi done @@ -87,7 +87,7 @@ function test_network_connectivity() { echo "✅ Network connectivity: $url" else echo "❌ Network connectivity failed: $url" - ((failed++)) + ((++failed)) fi done @@ -103,7 +103,7 @@ function test_permissions() { echo "✅ Write permission: $dir" else echo "❌ Write permission denied: $dir" - ((failed++)) + ((++failed)) fi done