mirror of
https://github.com/DictXiong/dotfiles.git
synced 2026-09-14 02:06:51 +08:00
84 lines
2.6 KiB
Bash
Executable File
84 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
THIS_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
SCF="$THIS_DIR/../scripts/scf"
|
|
TEST_DIR=$(mktemp -d /tmp/scf.XXXXXX)
|
|
trap 'rm -rf "$TEST_DIR"' EXIT
|
|
|
|
MOCK_BIN="$TEST_DIR/bin"
|
|
DATA_DIR="$TEST_DIR/data"
|
|
MOCK_SYSTEMCTL_LOG="$TEST_DIR/systemctl.log"
|
|
MOCK_MAIN="$DATA_DIR/main.yaml"
|
|
MOCK_CHILD="$DATA_DIR/child.conf"
|
|
MOCK_NOTE="$DATA_DIR/notes.txt"
|
|
mkdir -p "$MOCK_BIN" "$DATA_DIR"
|
|
export MOCK_SYSTEMCTL_LOG MOCK_MAIN MOCK_CHILD MOCK_NOTE
|
|
|
|
printf 'include %s\n' "$MOCK_CHILD" > "$MOCK_MAIN"
|
|
printf 'child configuration\n' > "$MOCK_CHILD"
|
|
printf 'not a configuration candidate\n' > "$MOCK_NOTE"
|
|
|
|
cat > "$MOCK_BIN/systemctl" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
printf '%s\n' "$*" >> "$MOCK_SYSTEMCTL_LOG"
|
|
service=${@: -1}
|
|
case "$service" in
|
|
demo.service)
|
|
printf 'path=/usr/bin/demo ; argv[0]=demo ; argv[1]=%s ; argv[2]=%s ;\n' \
|
|
"$MOCK_MAIN" "$MOCK_NOTE"
|
|
;;
|
|
empty.service)
|
|
printf 'path=/usr/bin/empty ; argv[0]=empty ;\n'
|
|
;;
|
|
*)
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "$MOCK_BIN/systemctl"
|
|
|
|
run_scf() {
|
|
PATH="$MOCK_BIN:$PATH" "$SCF" "$@"
|
|
}
|
|
|
|
# A service name without .service is accepted, and non-interactive mode prints
|
|
# the only configuration candidate instead of opening an editor.
|
|
output=$(run_scf demo 2> "$TEST_DIR/stderr")
|
|
grep -Fxq 'include '"$MOCK_CHILD" <<< "$output"
|
|
grep -Fq -- '--property=ExecStart --value demo.service' "$MOCK_SYSTEMCTL_LOG"
|
|
|
|
# Recursive mode discovers configuration files referenced by the first one.
|
|
output=$(run_scf -r -n 2 demo)
|
|
grep -Fxq 'child configuration' <<< "$output"
|
|
|
|
# Decimal values with a leading zero must not be treated as invalid octal.
|
|
output=$(SCF_MAX_DEPTH=08 SCF_MAX_CANDIDATES=08 run_scf demo)
|
|
grep -Fxq 'include '"$MOCK_CHILD" <<< "$output"
|
|
if run_scf -n 08 demo > "$TEST_DIR/out" 2> "$TEST_DIR/stderr"; then
|
|
echo 'expected scf -n 08 to fail because only one candidate exists' >&2
|
|
exit 1
|
|
fi
|
|
grep -Fq 'candidate number 8 is out of range' "$TEST_DIR/stderr"
|
|
|
|
# Invalid service names are rejected before systemctl is invoked.
|
|
before=$(wc -l < "$MOCK_SYSTEMCTL_LOG")
|
|
if run_scf 'demo; touch /tmp/unexpected' > "$TEST_DIR/out" 2> "$TEST_DIR/stderr"; then
|
|
echo 'expected an invalid service name to fail' >&2
|
|
exit 1
|
|
fi
|
|
grep -Fq 'invalid service name' "$TEST_DIR/stderr"
|
|
after=$(wc -l < "$MOCK_SYSTEMCTL_LOG")
|
|
test "$before" -eq "$after"
|
|
|
|
# A service without a referenced file reports a useful failure.
|
|
if run_scf empty > "$TEST_DIR/out" 2> "$TEST_DIR/stderr"; then
|
|
echo 'expected a service without a config path to fail' >&2
|
|
exit 1
|
|
fi
|
|
grep -Fq 'no existing configuration path found' "$TEST_DIR/stderr"
|
|
|
|
echo 'scf tests passed'
|