Files
Pulse/scripts/tests/test-common-lib.sh
rcourtman 0fcfad3dc5 feat: add shared script library system and refactor docker-agent installer
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.
2025-10-20 15:13:38 +00:00

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 "$@"