244 lines
6.6 KiB
Bash
Executable File
244 lines
6.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
SCRIPT_PATH="${ROOT_DIR}/scripts/github-actions/deploy-native-binary.sh"
|
|
EXPECTED_COMMIT="425a38f"
|
|
|
|
fail() {
|
|
printf 'FAIL: %s\n' "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
assert_contains() {
|
|
local haystack="$1"
|
|
local needle="$2"
|
|
if [[ "${haystack}" != *"${needle}"* ]]; then
|
|
fail "expected output to contain: ${needle}"
|
|
fi
|
|
}
|
|
|
|
assert_file_contains() {
|
|
local file="$1"
|
|
local needle="$2"
|
|
if [[ ! -f "${file}" ]]; then
|
|
fail "expected file to exist: ${file}"
|
|
fi
|
|
if ! grep -qF -- "${needle}" "${file}"; then
|
|
fail "expected ${file} to contain: ${needle}"
|
|
fi
|
|
}
|
|
|
|
build_fake_bin_dir() {
|
|
local bin_dir="$1"
|
|
|
|
cat >"${bin_dir}/scp" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
src="$2"
|
|
dest="$3"
|
|
printf 'scp %s\n' "${dest}" >>"${FAKE_DEPLOY_LOG}"
|
|
dest_path="${dest#*:}"
|
|
cp "${src}" "${dest_path}"
|
|
EOF
|
|
|
|
cat >"${bin_dir}/ssh" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
while [[ "${1:-}" == -* ]]; do
|
|
case "${1}" in
|
|
-o|-i|-p|-l)
|
|
shift 2
|
|
;;
|
|
*)
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
target="$1"
|
|
shift
|
|
printf 'ssh %s\n' "${target}" >>"${FAKE_DEPLOY_LOG}"
|
|
cmd="$*"
|
|
case "${cmd}" in
|
|
cat\ *)
|
|
path="${cmd#cat }"
|
|
path="${path%% 2>/dev/null*}"
|
|
path="${path%% || true*}"
|
|
path="${path%\'}"
|
|
path="${path#\'}"
|
|
cat "${path}" 2>/dev/null || true
|
|
;;
|
|
*)
|
|
bash -c "${cmd}"
|
|
;;
|
|
esac
|
|
EOF
|
|
|
|
cat >"${bin_dir}/systemctl" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
printf 'systemctl %s\n' "$*" >>"${FAKE_DEPLOY_LOG}"
|
|
if [[ "${1:-}" == "is-active" ]]; then
|
|
exit 1
|
|
fi
|
|
if [[ "${1:-}" == "--user" && "${2:-}" == "show" ]]; then
|
|
printf '1\n'
|
|
exit 0
|
|
fi
|
|
exit 0
|
|
EOF
|
|
|
|
cat >"${bin_dir}/readlink" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
if [[ "${1:-}" == "-f" && "${2:-}" == /proc/*/exe ]]; then
|
|
printf '%s\n' "${REMOTE_BINARY}"
|
|
exit 0
|
|
fi
|
|
/usr/bin/readlink "$@"
|
|
EOF
|
|
|
|
cat >"${bin_dir}/sleep" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
exit 0
|
|
EOF
|
|
|
|
chmod +x "${bin_dir}/"*
|
|
}
|
|
|
|
create_fake_binary() {
|
|
local path="$1"
|
|
cat >"${path}" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
if [[ "${1:-}" == "version" ]]; then
|
|
printf '{"commit":"425a38f","version":"test"}\n'
|
|
exit 0
|
|
fi
|
|
sleep 3600
|
|
EOF
|
|
chmod +x "${path}"
|
|
}
|
|
|
|
setup_test_env() {
|
|
local label="$1"
|
|
local tmp_dir
|
|
tmp_dir="$(mktemp -d)"
|
|
local bin_dir="${tmp_dir}/bin"
|
|
local remote_dir="${tmp_dir}/remote"
|
|
mkdir -p "${bin_dir}" "${remote_dir}/tmp" "${remote_dir}/opt/cloud-neutral/xworkmate-bridge"
|
|
|
|
create_fake_binary "${tmp_dir}/xworkmate-bridge"
|
|
build_fake_bin_dir "${bin_dir}"
|
|
|
|
printf '%s\n' "${label}" >&2
|
|
echo "${tmp_dir}"
|
|
}
|
|
|
|
run_deploy() {
|
|
local bin_dir="$1"
|
|
local log_file="$2"
|
|
shift 2
|
|
env \
|
|
PATH="${bin_dir}:${PATH}" \
|
|
FAKE_DEPLOY_LOG="${log_file}" \
|
|
"$@" \
|
|
bash "${SCRIPT_PATH}" "example.test" "${bin_dir}/../xworkmate-bridge" "${EXPECTED_COMMIT}"
|
|
}
|
|
|
|
run_env_token_case() {
|
|
local tmp_dir
|
|
tmp_dir="$(setup_test_env "case: BRIDGE_AUTH_TOKEN env var drives the unit file")"
|
|
|
|
local log_file="${tmp_dir}/deploy.log"
|
|
local unit_file="${tmp_dir}/remote/home/ubuntu/.config/systemd/user/xworkmate-bridge.service"
|
|
run_deploy "${tmp_dir}/bin" "${log_file}" \
|
|
REMOTE_TMP="${tmp_dir}/remote/tmp/xworkmate-bridge-${EXPECTED_COMMIT}" \
|
|
REMOTE_BINARY="${tmp_dir}/remote/home/ubuntu/.local/bin/xworkmate-go-core" \
|
|
REMOTE_WORKING_DIR="${tmp_dir}/remote/opt/cloud-neutral/xworkmate-bridge" \
|
|
BRIDGE_CONFIG_PATH="${tmp_dir}/remote/opt/cloud-neutral/xworkmate-bridge/config.yaml" \
|
|
USER_SYSTEMD_DIR="${tmp_dir}/remote/home/ubuntu/.config/systemd/user" \
|
|
DEPLOY_NATIVE_SKIP_PROC_CHECK=true \
|
|
BRIDGE_AUTH_TOKEN="test-token"
|
|
|
|
local log_output
|
|
log_output="$(cat "${log_file}")"
|
|
assert_contains "${log_output}" "ssh root@example.test"
|
|
assert_contains "${log_output}" "scp ubuntu@example.test:"
|
|
assert_contains "${log_output}" "ssh ubuntu@example.test"
|
|
assert_contains "${log_output}" "systemctl --user restart xworkmate-bridge.service"
|
|
assert_file_contains "${unit_file}" 'Environment="BRIDGE_AUTH_TOKEN=test-token"'
|
|
assert_file_contains "${unit_file}" "WantedBy=default.target"
|
|
|
|
rm -rf "${tmp_dir}"
|
|
}
|
|
|
|
run_unit_fallback_case() {
|
|
local tmp_dir
|
|
tmp_dir="$(setup_test_env "case: BRIDGE_AUTH_TOKEN recovered from system service unit file")"
|
|
|
|
local system_unit_dir="${tmp_dir}/remote/etc/systemd/system"
|
|
mkdir -p "${system_unit_dir}"
|
|
local system_unit_file="${system_unit_dir}/xworkmate-bridge.service"
|
|
cat >"${system_unit_file}" <<'EOF'
|
|
[Unit]
|
|
Description=Stale system service
|
|
[Service]
|
|
Environment="BRIDGE_AUTH_TOKEN=recovered-from-systemd"
|
|
Environment="BRIDGE_REVIEW_AUTH_TOKEN=recovered-review-token"
|
|
ExecStart=/bin/true
|
|
EOF
|
|
|
|
local log_file="${tmp_dir}/deploy.log"
|
|
local unit_file="${tmp_dir}/remote/home/ubuntu/.config/systemd/user/xworkmate-bridge.service"
|
|
run_deploy "${tmp_dir}/bin" "${log_file}" \
|
|
REMOTE_TMP="${tmp_dir}/remote/tmp/xworkmate-bridge-${EXPECTED_COMMIT}" \
|
|
REMOTE_BINARY="${tmp_dir}/remote/home/ubuntu/.local/bin/xworkmate-go-core" \
|
|
REMOTE_WORKING_DIR="${tmp_dir}/remote/opt/cloud-neutral/xworkmate-bridge" \
|
|
BRIDGE_CONFIG_PATH="${tmp_dir}/remote/opt/cloud-neutral/xworkmate-bridge/config.yaml" \
|
|
USER_SYSTEMD_DIR="${tmp_dir}/remote/home/ubuntu/.config/systemd/user" \
|
|
SYSTEM_SERVICE_UNIT_PATH="${system_unit_file}" \
|
|
DEPLOY_NATIVE_SKIP_PROC_CHECK=true
|
|
|
|
assert_file_contains "${unit_file}" 'Environment="BRIDGE_AUTH_TOKEN=recovered-from-systemd"'
|
|
assert_file_contains "${unit_file}" 'Environment="BRIDGE_REVIEW_AUTH_TOKEN=recovered-review-token"'
|
|
|
|
rm -rf "${tmp_dir}"
|
|
}
|
|
|
|
run_fail_fast_case() {
|
|
local tmp_dir
|
|
tmp_dir="$(setup_test_env "case: missing BRIDGE_AUTH_TOKEN fails fast with clear error")"
|
|
|
|
local log_file="${tmp_dir}/deploy.log"
|
|
local stderr_file="${tmp_dir}/deploy.stderr"
|
|
set +e
|
|
run_deploy "${tmp_dir}/bin" "${log_file}" \
|
|
REMOTE_TMP="${tmp_dir}/remote/tmp/xworkmate-bridge-${EXPECTED_COMMIT}" \
|
|
REMOTE_BINARY="${tmp_dir}/remote/home/ubuntu/.local/bin/xworkmate-go-core" \
|
|
REMOTE_WORKING_DIR="${tmp_dir}/remote/opt/cloud-neutral/xworkmate-bridge" \
|
|
BRIDGE_CONFIG_PATH="${tmp_dir}/remote/opt/cloud-neutral/xworkmate-bridge/config.yaml" \
|
|
USER_SYSTEMD_DIR="${tmp_dir}/remote/home/ubuntu/.config/systemd/user" \
|
|
DEPLOY_NATIVE_SKIP_PROC_CHECK=true \
|
|
2>"${stderr_file}"
|
|
local exit_code=$?
|
|
set -e
|
|
|
|
if [[ "${exit_code}" == "0" ]]; then
|
|
fail "expected deploy to fail when BRIDGE_AUTH_TOKEN is empty and no system service unit exists"
|
|
fi
|
|
assert_contains "$(cat "${stderr_file}")" "BRIDGE_AUTH_TOKEN is required"
|
|
|
|
rm -rf "${tmp_dir}"
|
|
}
|
|
|
|
main() {
|
|
run_env_token_case
|
|
run_unit_fallback_case
|
|
run_fail_fast_case
|
|
printf 'deploy-native-binary regression tests passed\n'
|
|
}
|
|
|
|
main "$@"
|