505 lines
18 KiB
Bash
Executable File
505 lines
18 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -uo pipefail
|
|
|
|
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
run_test() {
|
|
local name="$1"
|
|
shift
|
|
if ("$@"); then
|
|
printf 'PASS %s\n' "$name"
|
|
PASS=$((PASS + 1))
|
|
else
|
|
printf 'FAIL %s\n' "$name"
|
|
FAIL=$((FAIL + 1))
|
|
fi
|
|
}
|
|
|
|
checksum_file() {
|
|
local file="$1"
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
sha256sum "$file"
|
|
else
|
|
shasum -a 256 "$file"
|
|
fi
|
|
}
|
|
|
|
test_erp_run_preserves_java_option_arguments() (
|
|
local tmp
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-run-test.XXXXXX")" || return 1
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
mkdir -p "$tmp/current/app" "$tmp/run"
|
|
: > "$tmp/current/app/kaidi-erp.jar"
|
|
: > "$tmp/-Dpattern=expanded"
|
|
printf '%s\n' \
|
|
'#!/usr/bin/env bash' \
|
|
'if [[ "${1:-}" == "-version" ]]; then' \
|
|
' printf '\''openjdk version "17.0.12"\n'\'' >&2' \
|
|
' exit 0' \
|
|
'fi' \
|
|
'printf '\''%s\n'\'' "$@"' > "$tmp/java"
|
|
chmod +x "$tmp/java"
|
|
{
|
|
printf 'ERP_JAVA_BIN=%q\n' "$tmp/java"
|
|
printf 'ERP_JAVA_OPTS=%q\n' '-Dpattern=* -Xmx1g'
|
|
printf 'ERP_RUN_DIR=%q\n' "$tmp/run"
|
|
} > "$tmp/erp.env"
|
|
|
|
local output
|
|
output="$(cd "$tmp" && ERP_INSTALL_ROOT="$tmp" ERP_CONFIG_FILE="$tmp/erp.env" \
|
|
"$PROJECT_ROOT/distribution/bin/erp-run")" || return 1
|
|
grep -Fqx -- '-Dpattern=*' <<< "$output" || return 1
|
|
grep -Fqx -- '-Xmx1g' <<< "$output" || return 1
|
|
grep -Fqx -- "$tmp/current/app/kaidi-erp.jar" <<< "$output"
|
|
)
|
|
|
|
prepare_signed_archive() {
|
|
local tmp="$1" unsafe="${2:-0}"
|
|
mkdir -p "$tmp/package/kaidi-erp-1.2.3/app"
|
|
printf 'jar\n' > "$tmp/package/kaidi-erp-1.2.3/app/kaidi-erp.jar"
|
|
if [[ "$unsafe" == "1" ]]; then
|
|
ln -s /etc/passwd "$tmp/package/kaidi-erp-1.2.3/unsafe-link"
|
|
fi
|
|
tar -czf "$tmp/kaidi-erp-1.2.3.tar.gz" -C "$tmp/package" kaidi-erp-1.2.3
|
|
(cd "$tmp" && checksum_file kaidi-erp-1.2.3.tar.gz) > "$tmp/SHA256SUMS"
|
|
openssl pkeyutl -sign -rawin -inkey "$tmp/private.pem" \
|
|
-in "$tmp/SHA256SUMS" -out "$tmp/SHA256SUMS.sig"
|
|
}
|
|
|
|
test_installer_verifies_signed_safe_archive() (
|
|
local tmp
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-signature-test.XXXXXX")" || return 1
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
openssl genpkey -algorithm ED25519 -out "$tmp/private.pem" >/dev/null 2>&1 || return 1
|
|
openssl pkey -in "$tmp/private.pem" -pubout -out "$tmp/public.pem" >/dev/null 2>&1 || return 1
|
|
prepare_signed_archive "$tmp" || return 1
|
|
|
|
source "$PROJECT_ROOT/install.sh"
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
TMP_DIR="$tmp"
|
|
PUBLIC_KEY="$(<"$tmp/public.pem")"
|
|
ARCHIVE_NAME=kaidi-erp-1.2.3.tar.gz
|
|
ARCHIVE_PATH="$tmp/$ARCHIVE_NAME"
|
|
verify_release
|
|
)
|
|
|
|
test_installer_rejects_archive_symlinks() (
|
|
local tmp
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-unsafe-test.XXXXXX")" || return 1
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
openssl genpkey -algorithm ED25519 -out "$tmp/private.pem" >/dev/null 2>&1 || return 1
|
|
openssl pkey -in "$tmp/private.pem" -pubout -out "$tmp/public.pem" >/dev/null 2>&1 || return 1
|
|
prepare_signed_archive "$tmp" 1 || return 1
|
|
|
|
source "$PROJECT_ROOT/install.sh"
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
TMP_DIR="$tmp"
|
|
PUBLIC_KEY="$(<"$tmp/public.pem")"
|
|
ARCHIVE_NAME=kaidi-erp-1.2.3.tar.gz
|
|
ARCHIVE_PATH="$tmp/$ARCHIVE_NAME"
|
|
! (verify_release) >/dev/null 2>&1
|
|
)
|
|
|
|
test_stable_channel_rejects_prerelease_tag() (
|
|
local tmp
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-prerelease-test.XXXXXX")" || return 1
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
printf 'OA_UPDATE_GITEA_BASE_URL=https://example.test\n' > "$tmp/erp.env"
|
|
ERP_INSTALL_ROOT="$tmp" ERP_CONFIG_FILE="$tmp/erp.env" source "$PROJECT_ROOT/distribution/bin/erp-update"
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
printf '%s\n' \
|
|
'{"tag_name":"v2.0.0-rc.1","draft":false,"prerelease":false,"assets":[' \
|
|
'{"name":"kaidi-erp-2.0.0-rc.1.tar.gz","browser_download_url":"https://example.test/app"},' \
|
|
'{"name":"SHA256SUMS","browser_download_url":"https://example.test/sums"},' \
|
|
'{"name":"SHA256SUMS.sig","browser_download_url":"https://example.test/sig"}]}' \
|
|
> "$tmp/release.json"
|
|
CHANNEL=stable
|
|
! select_release "$tmp/release.json" '' "$tmp/selection" >/dev/null 2>&1
|
|
)
|
|
|
|
prepare_update_release_archive() {
|
|
local tmp="$1" version="$2"
|
|
local root="$tmp/package/kaidi-erp-$version"
|
|
mkdir -p "$root/app" "$root/bin" "$root/config" "$tmp/assets"
|
|
printf 'mock jar %s\n' "$version" > "$root/app/kaidi-erp.jar"
|
|
cp "$PROJECT_ROOT/distribution/bin/erp-run" "$root/bin/erp-run"
|
|
cp "$PROJECT_ROOT/distribution/bin/erp-update" "$root/bin/erp-update"
|
|
chmod +x "$root/bin/erp-run" "$root/bin/erp-update"
|
|
printf '%s\n' "$version" > "$root/VERSION"
|
|
printf '{"version":"%s","database":"postgresql","rollbackCompatible":true}\n' \
|
|
"$version" > "$root/manifest.json"
|
|
|
|
local archive="kaidi-erp-$version.tar.gz"
|
|
tar -czf "$tmp/assets/$archive" -C "$tmp/package" "kaidi-erp-$version"
|
|
(cd "$tmp/assets" && checksum_file "$archive") > "$tmp/assets/SHA256SUMS"
|
|
: > "$tmp/assets/SHA256SUMS.sig"
|
|
}
|
|
|
|
test_installer_downloads_and_installs_signed_release() (
|
|
local version=3.0.0 tmp server_pid=""
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-install-e2e.XXXXXX")" || return 1
|
|
cleanup_install_scenario() {
|
|
[[ -z "$server_pid" ]] || kill "$server_pid" 2>/dev/null || true
|
|
[[ -z "$server_pid" ]] || wait "$server_pid" 2>/dev/null || true
|
|
rm -rf "$tmp"
|
|
}
|
|
trap cleanup_install_scenario EXIT
|
|
|
|
prepare_update_release_archive "$tmp" "$version" || return 1
|
|
openssl genpkey -algorithm ED25519 -out "$tmp/private.pem" >/dev/null 2>&1 || return 1
|
|
openssl pkey -in "$tmp/private.pem" -pubout -out "$tmp/public.pem" >/dev/null 2>&1 || return 1
|
|
openssl pkeyutl -sign -rawin -inkey "$tmp/private.pem" \
|
|
-in "$tmp/assets/SHA256SUMS" -out "$tmp/assets/SHA256SUMS.sig" || return 1
|
|
|
|
python3 - "$tmp" "$version" <<'PY' > "$tmp/server.log" 2>&1 &
|
|
import json
|
|
import os
|
|
import sys
|
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
|
|
root, version = sys.argv[1:]
|
|
assets = os.path.join(root, "assets")
|
|
archive = f"kaidi-erp-{version}.tar.gz"
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
def send_bytes(self, status, body, content_type="application/octet-stream"):
|
|
self.send_response(status)
|
|
self.send_header("Content-Type", content_type)
|
|
self.send_header("Content-Length", str(len(body)))
|
|
self.end_headers()
|
|
self.wfile.write(body)
|
|
|
|
def do_GET(self):
|
|
if self.path == "/api/v1/repos/awaioi/ERP/releases/latest":
|
|
base = f"http://127.0.0.1:{self.server.server_port}/assets"
|
|
payload = {
|
|
"tag_name": "v" + version,
|
|
"draft": False,
|
|
"prerelease": False,
|
|
"assets": [
|
|
{"name": archive, "browser_download_url": base + "/" + archive},
|
|
{"name": "SHA256SUMS", "browser_download_url": base + "/SHA256SUMS"},
|
|
{"name": "SHA256SUMS.sig", "browser_download_url": base + "/SHA256SUMS.sig"},
|
|
],
|
|
}
|
|
self.send_bytes(200, json.dumps(payload).encode(), "application/json")
|
|
return
|
|
if self.path.startswith("/assets/"):
|
|
name = self.path.removeprefix("/assets/")
|
|
if name not in {archive, "SHA256SUMS", "SHA256SUMS.sig"}:
|
|
self.send_bytes(404, b"not found", "text/plain")
|
|
return
|
|
with open(os.path.join(assets, name), "rb") as handle:
|
|
self.send_bytes(200, handle.read())
|
|
return
|
|
self.send_bytes(404, b"not found", "text/plain")
|
|
|
|
def log_message(self, *_):
|
|
pass
|
|
|
|
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
|
|
with open(os.path.join(root, "server.port"), "w", encoding="ascii") as handle:
|
|
handle.write(str(server.server_port))
|
|
server.serve_forever()
|
|
PY
|
|
server_pid=$!
|
|
|
|
local attempt=0
|
|
while [[ ! -s "$tmp/server.port" && "$attempt" -lt 100 ]]; do
|
|
sleep 0.02
|
|
attempt=$((attempt + 1))
|
|
done
|
|
[[ -s "$tmp/server.port" ]] || return 1
|
|
local port
|
|
port="$(<"$tmp/server.port")"
|
|
|
|
source "$PROJECT_ROOT/install.sh"
|
|
trap cleanup_install_scenario EXIT
|
|
GITEA_BASE_URL="http://127.0.0.1:$port"
|
|
REPOSITORY=awaioi/ERP
|
|
ALLOW_INSECURE=1
|
|
INSTALL_ROOT="$tmp/install"
|
|
ERP_CONFIG_ROOT="$tmp/config"
|
|
ERP_STATE_ROOT="$tmp/state"
|
|
ERP_LOG_ROOT="$tmp/log"
|
|
DB_MODE=existing
|
|
NO_SERVICE=0
|
|
PUBLIC_KEY="$(<"$tmp/public.pem")"
|
|
|
|
detect_platform() { PLATFORM=darwin; }
|
|
install_dependencies() { return 0; }
|
|
configure_existing_postgres() {
|
|
DB_HOST=127.0.0.1
|
|
DB_PORT=5432
|
|
DB_NAME=kaidi_erp
|
|
DB_USER=kaidi_erp
|
|
DB_PASSWORD=test-password
|
|
DB_SSLMODE=require
|
|
}
|
|
validate_postgres() { return 0; }
|
|
install_service() { return 0; }
|
|
wait_for_health() { return 0; }
|
|
|
|
main > "$tmp/install.log" 2>&1 || return 1
|
|
|
|
[[ "$(readlink "$INSTALL_ROOT/current")" == "releases/$version" ]] || return 1
|
|
[[ -r "$INSTALL_ROOT/current/app/kaidi-erp.jar" ]] || return 1
|
|
(
|
|
source "$ERP_CONFIG_ROOT/erp.env"
|
|
[[ "$SPRING_PROFILES_ACTIVE" == "postgres" ]]
|
|
[[ "$OA_UPDATE_ENABLED" == "true" ]]
|
|
[[ "$OA_UPDATE_GITEA_BASE_URL" == "http://127.0.0.1:$port" ]]
|
|
[[ "$OA_DB_URL" == "jdbc:postgresql://127.0.0.1:5432/kaidi_erp?sslmode=require" ]]
|
|
[[ "$ERP_PGSSLMODE" == "require" ]]
|
|
)
|
|
)
|
|
|
|
run_update_scenario() (
|
|
local mode="$1" version=2.0.0
|
|
local tmp server_pid="" supervisor_pid=""
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-update-e2e.XXXXXX")" || return 1
|
|
cleanup_scenario() {
|
|
[[ -z "$supervisor_pid" ]] || kill "$supervisor_pid" 2>/dev/null || true
|
|
[[ -z "$server_pid" ]] || kill "$server_pid" 2>/dev/null || true
|
|
[[ -z "$supervisor_pid" ]] || wait "$supervisor_pid" 2>/dev/null || true
|
|
[[ -z "$server_pid" ]] || wait "$server_pid" 2>/dev/null || true
|
|
rm -rf "$tmp"
|
|
}
|
|
trap cleanup_scenario EXIT
|
|
|
|
prepare_update_release_archive "$tmp" "$version" || return 1
|
|
mkdir -p "$tmp/releases/1.0.0" "$tmp/run" "$tmp/state"
|
|
printf '1.0.0\n' > "$tmp/releases/1.0.0/VERSION"
|
|
ln -s releases/1.0.0 "$tmp/current"
|
|
|
|
python3 - "$tmp" "$mode" <<'PY' > "$tmp/server.log" 2>&1 &
|
|
import json
|
|
import os
|
|
import sys
|
|
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
|
|
root, mode = sys.argv[1:]
|
|
assets = os.path.join(root, "assets")
|
|
|
|
class Handler(BaseHTTPRequestHandler):
|
|
def send_bytes(self, status, body, content_type="application/octet-stream"):
|
|
self.send_response(status)
|
|
self.send_header("Content-Type", content_type)
|
|
self.send_header("Content-Length", str(len(body)))
|
|
self.end_headers()
|
|
self.wfile.write(body)
|
|
|
|
def do_GET(self):
|
|
if self.path == "/api/v1/repos/awaioi/ERP/releases/latest":
|
|
base = f"http://127.0.0.1:{self.server.server_port}"
|
|
payload = {
|
|
"tag_name": "v2.0.0",
|
|
"draft": False,
|
|
"prerelease": False,
|
|
"assets": [
|
|
{"name": "kaidi-erp-2.0.0.tar.gz", "browser_download_url": base + "/assets/kaidi-erp-2.0.0.tar.gz"},
|
|
{"name": "SHA256SUMS", "browser_download_url": base + "/assets/SHA256SUMS"},
|
|
{"name": "SHA256SUMS.sig", "browser_download_url": base + "/assets/SHA256SUMS.sig"},
|
|
],
|
|
}
|
|
self.send_bytes(200, json.dumps(payload).encode(), "application/json")
|
|
return
|
|
if self.path == "/health":
|
|
current = os.path.basename(os.path.realpath(os.path.join(root, "current")))
|
|
healthy = current == "2.0.0" if mode == "success" else current == "1.0.0"
|
|
self.send_bytes(200 if healthy else 503, b'{"status":"UP"}' if healthy else b'{"status":"DOWN"}', "application/json")
|
|
return
|
|
if self.path.startswith("/assets/"):
|
|
name = self.path.removeprefix("/assets/")
|
|
if name not in {"kaidi-erp-2.0.0.tar.gz", "SHA256SUMS", "SHA256SUMS.sig"}:
|
|
self.send_bytes(404, b"not found", "text/plain")
|
|
return
|
|
with open(os.path.join(assets, name), "rb") as handle:
|
|
self.send_bytes(200, handle.read())
|
|
return
|
|
self.send_bytes(404, b"not found", "text/plain")
|
|
|
|
def log_message(self, *_):
|
|
pass
|
|
|
|
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
|
|
with open(os.path.join(root, "server.port"), "w", encoding="ascii") as handle:
|
|
handle.write(str(server.server_port))
|
|
server.serve_forever()
|
|
PY
|
|
server_pid=$!
|
|
|
|
local attempt=0
|
|
while [[ ! -s "$tmp/server.port" && "$attempt" -lt 100 ]]; do
|
|
sleep 0.02
|
|
attempt=$((attempt + 1))
|
|
done
|
|
[[ -s "$tmp/server.port" ]] || return 1
|
|
local port
|
|
port="$(<"$tmp/server.port")"
|
|
|
|
(
|
|
child=""
|
|
trap '[[ -z "$child" ]] || kill "$child" 2>/dev/null || true' EXIT
|
|
trap 'exit 0' TERM INT
|
|
while :; do
|
|
sleep 300 &
|
|
child=$!
|
|
printf '%s\n' "$child" > "$tmp/run/app.pid"
|
|
wait "$child" 2>/dev/null || true
|
|
child=""
|
|
sleep 0.05
|
|
done
|
|
) &
|
|
supervisor_pid=$!
|
|
|
|
attempt=0
|
|
while [[ ! -s "$tmp/run/app.pid" && "$attempt" -lt 100 ]]; do
|
|
sleep 0.02
|
|
attempt=$((attempt + 1))
|
|
done
|
|
[[ -s "$tmp/run/app.pid" ]] || return 1
|
|
|
|
{
|
|
printf 'ERP_RUN_DIR=%q\n' "$tmp/run"
|
|
printf 'OA_UPDATE_STATE_FILE=%q\n' "$tmp/state/update.json"
|
|
printf 'OA_UPDATE_GITEA_BASE_URL=http://127.0.0.1:%s\n' "$port"
|
|
printf 'OA_UPDATE_ALLOW_INSECURE_HTTP=true\n'
|
|
printf 'OA_UPDATE_REPOSITORY=awaioi/ERP\n'
|
|
printf 'ERP_HEALTH_URL=http://127.0.0.1:%s/health\n' "$port"
|
|
printf 'ERP_UPDATE_REQUIRE_SIGNATURE=false\n'
|
|
printf 'ERP_UPDATE_BACKUP_MODE=none\n'
|
|
printf 'ERP_UPDATE_HEALTH_TIMEOUT_SECONDS=3\n'
|
|
printf 'ERP_UPDATE_HEALTH_POLL_SECONDS=1\n'
|
|
} > "$tmp/erp.env"
|
|
|
|
local status=0 phase current
|
|
ERP_INSTALL_ROOT="$tmp" ERP_CONFIG_FILE="$tmp/erp.env" \
|
|
"$PROJECT_ROOT/distribution/bin/erp-update" install "$version" \
|
|
> "$tmp/update.log" 2>&1 || status=$?
|
|
phase="$(python3 -c 'import json,sys; print(json.load(open(sys.argv[1]))["phase"])' "$tmp/state/update.json")" \
|
|
|| return 1
|
|
current="$(readlink "$tmp/current")"
|
|
|
|
if [[ "$mode" == "success" ]]; then
|
|
[[ "$status" == "0" && "$phase" == "SUCCEEDED" && "$current" == "releases/2.0.0" ]]
|
|
else
|
|
[[ "$status" != "0" && "$phase" == "ROLLED_BACK" && "$current" == "releases/1.0.0" ]]
|
|
fi
|
|
)
|
|
|
|
test_update_helper_installs_healthy_release() (
|
|
run_update_scenario success
|
|
)
|
|
|
|
test_update_helper_rolls_back_unhealthy_release() (
|
|
run_update_scenario rollback
|
|
)
|
|
|
|
test_update_lock_rejects_concurrent_process() (
|
|
local tmp
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-lock-test.XXXXXX")" || return 1
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
mkdir -p "$tmp/bin" "$tmp/run" "$tmp/state"
|
|
printf '%s\n' \
|
|
'#!/usr/bin/env bash' \
|
|
'printf '\''%s\n'\'' "$$" > "$MOCK_CURL_PID_FILE"' \
|
|
'trap '\''exit 1'\'' TERM INT' \
|
|
'sleep 30' \
|
|
'exit 1' > "$tmp/bin/curl"
|
|
chmod +x "$tmp/bin/curl"
|
|
{
|
|
printf 'ERP_RUN_DIR=%q\n' "$tmp/run"
|
|
printf 'OA_UPDATE_STATE_FILE=%q\n' "$tmp/state/update.json"
|
|
printf 'OA_UPDATE_GITEA_BASE_URL=%q\n' 'http://127.0.0.1:1'
|
|
printf 'OA_UPDATE_ALLOW_INSECURE_HTTP=true\n'
|
|
printf 'OA_UPDATE_REPOSITORY=awaioi/ERP\n'
|
|
} > "$tmp/erp.env"
|
|
|
|
PATH="$tmp/bin:$PATH" MOCK_CURL_PID_FILE="$tmp/curl.pid" \
|
|
ERP_INSTALL_ROOT="$tmp" ERP_CONFIG_FILE="$tmp/erp.env" \
|
|
"$PROJECT_ROOT/distribution/bin/erp-update" install > "$tmp/first.log" 2>&1 &
|
|
local first=$! attempt=0
|
|
while [[ ! -s "$tmp/run/update.lock" && "$attempt" -lt 100 ]]; do
|
|
sleep 0.02
|
|
attempt=$((attempt + 1))
|
|
done
|
|
[[ -s "$tmp/run/update.lock" ]] || { kill "$first" 2>/dev/null || true; return 1; }
|
|
|
|
local output status=0 rejected=0
|
|
output="$(PATH="$tmp/bin:$PATH" MOCK_CURL_PID_FILE="$tmp/curl-2.pid" \
|
|
ERP_INSTALL_ROOT="$tmp" ERP_CONFIG_FILE="$tmp/erp.env" \
|
|
"$PROJECT_ROOT/distribution/bin/erp-update" install 2>&1)" || status=$?
|
|
[[ "$status" -ne 0 && "$output" == *'已有更新任务正在执行'* ]] && rejected=1
|
|
|
|
[[ ! -r "$tmp/curl.pid" ]] || kill "$(<"$tmp/curl.pid")" 2>/dev/null || true
|
|
kill "$first" 2>/dev/null || true
|
|
wait "$first" 2>/dev/null || true
|
|
[[ "$rejected" == "1" ]]
|
|
)
|
|
|
|
test_noninteractive_installer_reports_missing_password() (
|
|
local output status=0
|
|
output="$(ERP_INSTALL_NON_INTERACTIVE=1 bash -c '
|
|
root="$1"
|
|
set --
|
|
source "$root/install.sh"
|
|
unset ERP_DB_PASSWORD DB_PASSWORD
|
|
configure_existing_postgres
|
|
' _ "$PROJECT_ROOT" 2>&1)" || status=$?
|
|
[[ "$status" -ne 0 && "$output" == *'database password is required'* ]]
|
|
)
|
|
|
|
test_installer_requires_explicit_gitea_url() (
|
|
local output status=0
|
|
output="$(ERP_GITEA_BASE_URL= bash -c '
|
|
root="$1"
|
|
set --
|
|
source "$root/install.sh"
|
|
GITEA_BASE_URL=
|
|
main
|
|
' _ "$PROJECT_ROOT" 2>&1)" || status=$?
|
|
[[ "$status" -ne 0 && "$output" == *'Gitea URL is required'* ]]
|
|
)
|
|
|
|
test_no_service_install_disables_online_update() (
|
|
local tmp
|
|
tmp="$(mktemp -d "${TMPDIR:-/tmp}/erp-no-service-test.XXXXXX")" || return 1
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
source "$PROJECT_ROOT/install.sh"
|
|
trap 'rm -rf "$tmp"' EXIT
|
|
CONFIG_ROOT="$tmp/config"
|
|
STATE_ROOT="$tmp/state"
|
|
INSTALL_ROOT="$tmp/install"
|
|
PLATFORM=darwin
|
|
NO_SERVICE=1
|
|
DB_HOST=127.0.0.1
|
|
DB_PORT=5432
|
|
DB_NAME=kaidi_erp
|
|
DB_USER=kaidi_erp
|
|
DB_PASSWORD=test-password
|
|
DB_SSLMODE=require
|
|
mkdir -p "$CONFIG_ROOT" "$STATE_ROOT" "$INSTALL_ROOT"
|
|
|
|
write_configuration || return 1
|
|
|
|
grep -Fqx 'OA_UPDATE_ENABLED=false' "$CONFIG_ROOT/erp.env"
|
|
)
|
|
|
|
run_test 'erp-run preserves Java option arguments' test_erp_run_preserves_java_option_arguments
|
|
run_test 'installer accepts a correctly signed archive' test_installer_verifies_signed_safe_archive
|
|
run_test 'installer rejects symlinks in release archives' test_installer_rejects_archive_symlinks
|
|
run_test 'stable update channel rejects prerelease tags' test_stable_channel_rejects_prerelease_tag
|
|
run_test 'installer downloads and installs a signed release end to end' test_installer_downloads_and_installs_signed_release
|
|
run_test 'update helper installs a healthy release end to end' test_update_helper_installs_healthy_release
|
|
run_test 'update helper rolls back an unhealthy release end to end' test_update_helper_rolls_back_unhealthy_release
|
|
run_test 'update helper rejects a concurrent process' test_update_lock_rejects_concurrent_process
|
|
run_test 'noninteractive install reports a missing database password' test_noninteractive_installer_reports_missing_password
|
|
run_test 'installer requires an explicit Gitea URL' test_installer_requires_explicit_gitea_url
|
|
run_test 'no-service install disables online update' test_no_service_install_disables_online_update
|
|
|
|
printf 'RESULT pass=%s fail=%s\n' "$PASS" "$FAIL"
|
|
[[ "$FAIL" -eq 0 ]]
|