124 lines
3.5 KiB
Bash
124 lines
3.5 KiB
Bash
#!/bin/bash
|
|||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
||
|
|
TMP=$(mktemp -d)
|
||
|
|
trap 'rm -rf -- "$TMP"' EXIT
|
||
|
|
|
||
|
|
BIN="$TMP/bin"
|
||
|
|
LOG="$TMP/calls.log"
|
||
|
|
STATUS="$TMP/update.status"
|
||
|
|
TEST_HOME="$TMP/home"
|
||
|
|
PLUGINS="$TEST_HOME/.config/omarchy/plugins"
|
||
|
|
mkdir -p -- "$BIN" "$PLUGINS"
|
||
|
|
|
||
|
|
make_plugin() {
|
||
|
|
local id="$1"
|
||
|
|
local dir="$PLUGINS/$id"
|
||
|
|
git init -q -b main "$dir"
|
||
|
|
git -C "$dir" config user.name "Omaplug Tests"
|
||
|
|
git -C "$dir" config user.email "omaplug-tests@example.invalid"
|
||
|
|
printf '{"id":"%s"}\n' "$id" > "$dir/manifest.json"
|
||
|
|
git -C "$dir" add manifest.json
|
||
|
|
git -C "$dir" commit -qm "fixture"
|
||
|
|
}
|
||
|
|
|
||
|
|
for id in good fail slow dirty detached; do make_plugin "$id"; done
|
||
|
|
printf '\n' >> "$PLUGINS/dirty/manifest.json"
|
||
|
|
git -C "$PLUGINS/detached" checkout -q --detach
|
||
|
|
ln -s -- "$PLUGINS/good" "$PLUGINS/linked"
|
||
|
|
|
||
|
|
cat > "$BIN/omarchy" <<'EOF'
|
||
|
|
#!/bin/bash
|
||
|
|
printf '%s\n' "$*" >> "$OMAPLUG_TEST_LOG"
|
||
|
|
case "${3:-}" in
|
||
|
|
slow) sleep 0.4 ;;
|
||
|
|
esac
|
||
|
|
if [[ ${3:-} == fail ]]; then
|
||
|
|
printf 'could not update %s\n' "$3" >&2
|
||
|
|
exit 7
|
||
|
|
fi
|
||
|
|
printf 'updated %s\n' "${3:-}"
|
||
|
|
EOF
|
||
|
|
chmod +x "$BIN/omarchy"
|
||
|
|
|
||
|
|
export PATH="$BIN:$PATH"
|
||
|
|
export OMAPLUG_TEST_LOG="$LOG"
|
||
|
|
export HOME="$TEST_HOME"
|
||
|
|
|
||
|
|
# A prior run may have left a status file created under a permissive umask.
|
||
|
|
# The helper must tighten it before writing any job details.
|
||
|
|
: > "$STATUS"
|
||
|
|
chmod 0644 "$STATUS"
|
||
|
|
|
||
|
|
assert_line() {
|
||
|
|
local line="$1"
|
||
|
|
local file="$2"
|
||
|
|
grep -Fqx -- "$line" "$file" || {
|
||
|
|
printf 'FAIL: missing line %q in %s\n' "$line" "$file" >&2
|
||
|
|
cat "$file" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if "$ROOT/update-helper.sh" "$STATUS" job-direct good fail dirty detached linked 'bad/id'; then
|
||
|
|
printf 'FAIL: a partially failed update job returned success\n' >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_line $'job\tjob-direct' "$STATUS"
|
||
|
|
assert_line $'start\tgood' "$STATUS"
|
||
|
|
assert_line $'ok\tgood\tupdated good' "$STATUS"
|
||
|
|
assert_line $'start\tfail' "$STATUS"
|
||
|
|
assert_line $'failed\tfail\tcould not update fail' "$STATUS"
|
||
|
|
assert_line $'failed\tdirty\tplugin gained local changes after the update check' "$STATUS"
|
||
|
|
assert_line $'failed\tdetached\tplugin is on a detached HEAD' "$STATUS"
|
||
|
|
assert_line $'failed\tlinked\tplugin became a symlink after the update check' "$STATUS"
|
||
|
|
assert_line $'failed\tbad/id\tinvalid plugin id' "$STATUS"
|
||
|
|
assert_line $'done\t1\t5' "$STATUS"
|
||
|
|
[[ $(stat -c '%a' "$STATUS") == 600 ]] || {
|
||
|
|
printf 'FAIL: status file mode is %s instead of 600\n' "$(stat -c '%a' "$STATUS")" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
[[ $(tail -n 1 "$STATUS") == $'done\t1\t5' ]] || {
|
||
|
|
printf 'FAIL: done is not the final status record\n' >&2
|
||
|
|
cat "$STATUS" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
assert_line 'plugin update good --yes' "$LOG"
|
||
|
|
assert_line 'plugin update fail --yes' "$LOG"
|
||
|
|
[[ $(wc -l < "$LOG") -eq 2 ]] || {
|
||
|
|
printf 'FAIL: invalid plugin id reached omarchy\n' >&2
|
||
|
|
cat "$LOG" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
# A live runner owns the stable status path. A second runner must fail without
|
||
|
|
# replacing or appending to that job's status stream.
|
||
|
|
: > "$LOG"
|
||
|
|
"$ROOT/update-helper.sh" "$STATUS" job-first slow &
|
||
|
|
first_pid=$!
|
||
|
|
for _ in {1..100}; do
|
||
|
|
[[ -f $STATUS.flock ]] && break
|
||
|
|
sleep 0.01
|
||
|
|
done
|
||
|
|
sleep 0.05
|
||
|
|
if "$ROOT/update-helper.sh" "$STATUS" job-second good; then
|
||
|
|
printf 'FAIL: a concurrent update runner acquired the same lock\n' >&2
|
||
|
|
exit 1
|
||
|
|
else
|
||
|
|
second_rc=$?
|
||
|
|
fi
|
||
|
|
[[ $second_rc -eq 3 ]] || {
|
||
|
|
printf 'FAIL: concurrent runner returned %s instead of 3\n' "$second_rc" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
wait "$first_pid"
|
||
|
|
assert_line $'job\tjob-first' "$STATUS"
|
||
|
|
if grep -Fq $'job\tjob-second' "$STATUS"; then
|
||
|
|
printf 'FAIL: concurrent runner clobbered the active status\n' >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
printf 'update-helper-test: ok\n'
|