mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
Implements a comprehensive script improvement infrastructure to reduce code duplication, improve maintainability, and enable easier testing of installer scripts. ## New Infrastructure ### Shared Library System (scripts/lib/) - common.sh: Core utilities (logging, sudo, dry-run, cleanup management) - systemd.sh: Service management helpers with container-safe systemctl - http.sh: HTTP/download helpers with curl/wget fallback and retry logic - README.md: Complete API documentation for all library functions ### Bundler System - scripts/bundle.sh: Concatenates library modules into single-file installers - scripts/bundle.manifest: Defines bundling configuration for distributables - Enables both modular development and curl|bash distribution ### Test Infrastructure - scripts/tests/run.sh: Test harness for running all smoke tests - scripts/tests/test-common-lib.sh: Common library validation (5 tests) - scripts/tests/test-docker-agent-v2.sh: Installer smoke tests (4 tests) - scripts/tests/integration/: Container-based integration tests (5 scenarios) - All tests passing ✓ ## Refactored Installer ### install-docker-agent-v2.sh - Reduced from 1098 to 563 lines (48% code reduction) - Uses shared libraries for all common operations - NEW: --dry-run flag support - Maintains 100% backward compatibility with original - Fully tested with smoke and integration tests ### Key Improvements - Sudo escalation: 100+ lines → 1 function call - Download logic: 51 lines → 1 function call - Service creation: 33 lines → 2 function calls - Logging: Standardized across all operations - Error handling: Improved with common library ## Documentation ### Rollout Strategy (docs/installer-v2-rollout.md) - 3-phase rollout plan (Alpha → Beta → GA) - Feature flag mechanism for gradual deployment - Testing checklist and success metrics - Rollback procedures and communication plan ### Developer Guides - docs/script-library-guide.md: Complete library usage guide - docs/CONTRIBUTING-SCRIPTS.md: Contribution workflow - docs/installer-v2-quickref.md: Quick reference for operators ## Metrics - Code reduction: 48% (1098 → 563 lines) - Reusable functions: 0 → 30+ - Test coverage: 0 → 8 test scenarios - Documentation: 0 → 5 comprehensive guides ## Testing All tests passing: - Smoke tests: 2/2 passed (8 test cases) - Integration tests: 5/5 scenarios passed - Bundled output: Syntax validated, dry-run tested ## Next Steps This lays the foundation for migrating other installers (install.sh, install-sensor-proxy.sh) to use the same pattern, reducing overall maintenance burden and improving code quality across the project.
119 lines
2.6 KiB
Bash
Executable File
119 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Smoke test for scripts/lib/common.sh functionality.
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
COMMON_LIB="${ROOT_DIR}/scripts/lib/common.sh"
|
|
|
|
if [[ ! -f "${COMMON_LIB}" ]]; then
|
|
echo "common.sh not found at ${COMMON_LIB}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC1090
|
|
source "${COMMON_LIB}"
|
|
|
|
export PULSE_NO_COLOR=1
|
|
common::init "$0"
|
|
|
|
failures=0
|
|
|
|
assert_success() {
|
|
local desc="$1"
|
|
shift
|
|
if "$@"; then
|
|
echo "[PASS] ${desc}"
|
|
return 0
|
|
else
|
|
echo "[FAIL] ${desc}" >&2
|
|
((failures++))
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
test_functions_exist() {
|
|
local missing=0
|
|
local fn
|
|
for fn in \
|
|
common::init \
|
|
common::log_info \
|
|
common::log_warn \
|
|
common::log_error \
|
|
common::log_debug \
|
|
common::fail \
|
|
common::require_command \
|
|
common::is_interactive \
|
|
common::ensure_root \
|
|
common::sudo_exec \
|
|
common::run \
|
|
common::run_capture \
|
|
common::temp_dir \
|
|
common::cleanup_push \
|
|
common::cleanup_run \
|
|
common::set_dry_run \
|
|
common::is_dry_run; do
|
|
if ! declare -F -- "${fn}" >/dev/null 2>&1; then
|
|
echo "Missing function definition: ${fn}" >&2
|
|
missing=1
|
|
fi
|
|
done
|
|
[[ "${missing}" -eq 0 ]]
|
|
}
|
|
|
|
test_logging() {
|
|
local info_output debug_output warn_output
|
|
info_output="$(common::log_info "common-log-info-test")"
|
|
[[ "${info_output}" == *"common-log-info-test"* ]] || return 1
|
|
|
|
debug_output="$(common::log_debug "common-log-debug-test" 2>&1)"
|
|
[[ -z "${debug_output}" ]] || return 1
|
|
|
|
warn_output="$(common::log_warn "common-log-warn-test" 2>&1)"
|
|
[[ "${warn_output}" == *"common-log-warn-test"* ]] || return 1
|
|
}
|
|
|
|
test_dry_run() {
|
|
local tmpfile
|
|
tmpfile="$(mktemp)"
|
|
rm -f "${tmpfile}"
|
|
common::set_dry_run true
|
|
common::run --label "dry-run-touch" touch "${tmpfile}"
|
|
common::set_dry_run false
|
|
[[ ! -e "${tmpfile}" ]]
|
|
}
|
|
|
|
test_interactive_detection() {
|
|
# Ensure the function returns success when forced.
|
|
if PULSE_FORCE_INTERACTIVE=1 common::is_interactive; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
test_temp_dir_cleanup() {
|
|
local tmp_dir=""
|
|
common::temp_dir tmp_dir --prefix pulse-test-common-
|
|
[[ -d "${tmp_dir}" ]] || return 1
|
|
common::cleanup_run
|
|
[[ ! -d "${tmp_dir}" ]]
|
|
}
|
|
|
|
main() {
|
|
assert_success "functions exist" test_functions_exist
|
|
assert_success "logging output" test_logging
|
|
assert_success "dry-run support" test_dry_run
|
|
assert_success "interactive detection" test_interactive_detection
|
|
assert_success "temp dir cleanup" test_temp_dir_cleanup
|
|
|
|
if (( failures > 0 )); then
|
|
echo "Total failures: ${failures}" >&2
|
|
return 1
|
|
fi
|
|
|
|
echo "All common.sh smoke tests passed."
|
|
}
|
|
|
|
main "$@"
|