first commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
make_working_copy
|
||||
stub make
|
||||
# Fails on any file that contains BAD, as if it had a warning
|
||||
stub shellcheck 'for f in "$@"; do [ -f "$f" ] && grep -q BAD "$f" && exit 1; done; exit 0'
|
||||
stub bats 'echo 7'
|
||||
}
|
||||
|
||||
@test "check runs make lint and make test, and shellcheck on untracked scripts" {
|
||||
printf '%s\n' '#!/bin/bash' 'echo fine' > "$WC/new-script"
|
||||
printf '%s\n' 'echo fine' > "$WC/new-hook.sh"
|
||||
echo "not a script" > "$WC/notes.txt"
|
||||
|
||||
run cdd check
|
||||
[ "$status" -eq 0 ]
|
||||
called make --no-print-directory lint
|
||||
called make --no-print-directory test
|
||||
grep -q "^shellcheck --severity=warning .*new-script" "$STUB_LOG"
|
||||
grep -q "^shellcheck --severity=warning .*new-hook.sh" "$STUB_LOG"
|
||||
[[ "$output" == *"shellcheck: ok ("*" files, 2 untracked) bats: ok (7 tests)"* ]]
|
||||
run grep -q "^shellcheck .*notes.txt" "$STUB_LOG"
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "check fails on a warning in an untracked script" {
|
||||
printf '%s\n' '#!/bin/bash' 'BAD' > "$WC/new-script"
|
||||
|
||||
run cdd check
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"shellcheck: FAILED"* ]]
|
||||
}
|
||||
|
||||
@test "check skips ignored files" {
|
||||
echo "ignored-script" > "$WC/.gitignore"
|
||||
printf '%s\n' '#!/bin/bash' 'BAD' > "$WC/ignored-script"
|
||||
|
||||
run cdd check
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "check --fast runs only the shellcheck steps" {
|
||||
run cdd check --fast
|
||||
[ "$status" -eq 0 ]
|
||||
called make --no-print-directory lint
|
||||
uncalled make --no-print-directory test
|
||||
[[ "$output" == *"bats: skipped (--fast)"* ]]
|
||||
}
|
||||
|
||||
@test "check fails when make test fails" {
|
||||
stub make '[ "$2" != test ]'
|
||||
run cdd check
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"bats: FAILED"* ]]
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "deployed status shows the commit, how far behind, and local changes" {
|
||||
make_working_copy
|
||||
git -C "$WC" commit -q --allow-empty -m "new"
|
||||
git -C "$WC" push -q origin main
|
||||
echo "# edited" >> "$DEPLOYED/update"
|
||||
|
||||
run cdd deployed
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Branch: main"* ]]
|
||||
[[ "$output" == *"CoreDesktop"* ]]
|
||||
[[ "$output" == *"Behind: 1 commits"* ]]
|
||||
[[ "$output" == *"M update"* ]]
|
||||
}
|
||||
|
||||
@test "deployed restore asks first, and changes nothing on no" {
|
||||
echo "# edited" >> "$DEPLOYED/update"
|
||||
|
||||
run cdd deployed restore <<< n
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"Nothing changed."* ]]
|
||||
grep -q "# edited" "$DEPLOYED/update"
|
||||
}
|
||||
|
||||
@test "deployed restore puts back tracked files and leaves untracked ones" {
|
||||
echo "# edited" >> "$DEPLOYED/update"
|
||||
rm "$DEPLOYED/utils.sh"
|
||||
echo "mine" > "$DEPLOYED/untracked-file"
|
||||
|
||||
run cdd deployed restore <<< y
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"untracked-file"* ]]
|
||||
[ -f "$DEPLOYED/utils.sh" ]
|
||||
[ "$(cat "$DEPLOYED/untracked-file")" = mine ]
|
||||
[ -z "$(git -C "$DEPLOYED" status --porcelain --untracked-files=no)" ]
|
||||
run grep -q "# edited" "$DEPLOYED/update"
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "deployed restore puts back staged changes too" {
|
||||
echo "# edited" >> "$DEPLOYED/update"
|
||||
git -C "$DEPLOYED" add update
|
||||
|
||||
run cdd deployed restore <<< y
|
||||
[ "$status" -eq 0 ]
|
||||
[ -z "$(git -C "$DEPLOYED" status --porcelain --untracked-files=no)" ]
|
||||
}
|
||||
|
||||
@test "deployed restore with nothing to restore doesn't ask" {
|
||||
run cdd deployed restore < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"no local changes"* ]]
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
@test "doctor reports local changes in the deployed copy and how to fix them" {
|
||||
make_working_copy
|
||||
echo "# edited" >> "$DEPLOYED/update"
|
||||
|
||||
run cdd doctor
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"PROBLEM the deployed copy has local changes"* ]]
|
||||
[[ "$output" == *"M update"* ]]
|
||||
[[ "$output" == *"coredesktop-dev deployed restore"* ]]
|
||||
}
|
||||
|
||||
@test "doctor is happy with a clean deployed copy that can fast-forward" {
|
||||
make_working_copy
|
||||
# Upstream moves on; the deployed copy is behind, which is fine
|
||||
git -C "$WC" commit -q --allow-empty -m "new"
|
||||
git -C "$WC" push -q origin main
|
||||
|
||||
run cdd doctor
|
||||
[[ "$output" == *"ok the deployed copy has no local changes"* ]]
|
||||
[[ "$output" == *"ok the deployed copy can fast-forward to its upstream"* ]]
|
||||
[[ "$output" == *"ok working copy: $WC"* ]]
|
||||
}
|
||||
|
||||
@test "doctor reports a deployed copy with commits upstream doesn't have" {
|
||||
make_working_copy
|
||||
git -C "$DEPLOYED" commit -q --allow-empty -m "local commit"
|
||||
|
||||
run cdd doctor
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"has commits its upstream doesn't"* ]]
|
||||
}
|
||||
|
||||
@test "doctor reports a missing working copy" {
|
||||
run cdd doctor
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"PROBLEM no working copy is set"* ]]
|
||||
}
|
||||
|
||||
@test "doctor reports when it was run from a Flatpak" {
|
||||
make_working_copy
|
||||
COREDESKTOP_DEV_VIA_FLATPAK=1 run cdd doctor
|
||||
[[ "$output" == *"note you ran this in a Flatpak"* ]]
|
||||
}
|
||||
|
||||
@test "doctor reports the pre-push hook" {
|
||||
make_working_copy
|
||||
run cdd doctor
|
||||
[[ "$output" == *"the pre-push hook isn't installed"* ]]
|
||||
|
||||
cdd hooks install
|
||||
run cdd doctor
|
||||
[[ "$output" == *"ok the pre-push hook is installed"* ]]
|
||||
}
|
||||
|
||||
@test "in a Flatpak, coredesktop-dev re-runs itself on the host" {
|
||||
stub flatpak-spawn
|
||||
FLATPAK_ID=com.vscodium.codium run cdd doctor
|
||||
[ "$status" -eq 0 ]
|
||||
called flatpak-spawn --host --env=COREDESKTOP_DEV_VIA_FLATPAK=1 \
|
||||
"$(readlink -f "$PROJECT/bin/coredesktop-dev")" doctor
|
||||
}
|
||||
|
||||
@test "--help works in a Flatpak without going to the host" {
|
||||
stub flatpak-spawn
|
||||
FLATPAK_ID=com.vscodium.codium run cdd doctor --help
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Usage: coredesktop-dev doctor"* ]]
|
||||
not_called flatpak-spawn
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
make_working_copy
|
||||
HOOK="$WC/.git/hooks/pre-push"
|
||||
}
|
||||
|
||||
@test "hooks install installs the pre-push hook" {
|
||||
run cdd hooks install
|
||||
[ "$status" -eq 0 ]
|
||||
[ -x "$HOOK" ]
|
||||
cmp "$PROJECT/hooks/pre-push" "$HOOK"
|
||||
|
||||
run cdd hooks
|
||||
[[ "$output" == *"The pre-push hook is installed"* ]]
|
||||
}
|
||||
|
||||
@test "hooks install won't overwrite someone else's hook" {
|
||||
printf '%s\n' '#!/bin/bash' 'mine' > "$HOOK"
|
||||
|
||||
run cdd hooks install
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"didn't write it"* ]]
|
||||
[ "$(tail -n 1 "$HOOK")" = mine ]
|
||||
}
|
||||
|
||||
@test "hooks remove removes only our hook" {
|
||||
cdd hooks install
|
||||
run cdd hooks remove
|
||||
[ "$status" -eq 0 ]
|
||||
[ ! -e "$HOOK" ]
|
||||
|
||||
printf '%s\n' '#!/bin/bash' 'mine' > "$HOOK"
|
||||
run cdd hooks remove
|
||||
[ "$status" -eq 1 ]
|
||||
[ -e "$HOOK" ]
|
||||
}
|
||||
|
||||
@test "hooks follows core.hooksPath" {
|
||||
git -C "$WC" config core.hooksPath .githooks
|
||||
run cdd hooks install
|
||||
[ "$status" -eq 0 ]
|
||||
[ -x "$WC/.githooks/pre-push" ]
|
||||
}
|
||||
|
||||
@test "the hook stops a push when check fails, and says how to skip it" {
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
printf '%s\n' '#!/bin/bash' 'exit 1' > "$HOME/.local/bin/coredesktop-dev"
|
||||
chmod +x "$HOME/.local/bin/coredesktop-dev"
|
||||
|
||||
run bash "$PROJECT/hooks/pre-push"
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"git push --no-verify"* ]]
|
||||
}
|
||||
|
||||
@test "the hook lets a push through when check passes" {
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
printf '%s\n' '#!/bin/bash' 'exit 0' > "$HOME/.local/bin/coredesktop-dev"
|
||||
chmod +x "$HOME/.local/bin/coredesktop-dev"
|
||||
|
||||
run bash "$PROJECT/hooks/pre-push"
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
config() {
|
||||
cat "$HOME/.config/coredesktop-dev/config"
|
||||
}
|
||||
|
||||
@test "install refuses the deployed copy, then takes a working copy" {
|
||||
git clone -q "$UPSTREAM" "$WC"
|
||||
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' "$DEPLOYED" "$WC" n)"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"is the deployed copy"* ]]
|
||||
[ "$(config)" = "WORKING_COPY=$(printf '%q' "$WC")" ]
|
||||
[ "$(readlink "$HOME/.local/bin/coredesktop-dev")" = "$PROJECT/bin/coredesktop-dev" ]
|
||||
called install_packages shellcheck bats tea qemu-base libisoburn
|
||||
}
|
||||
|
||||
@test "install refuses the deployed copy however it's spelled" {
|
||||
git clone -q "$UPSTREAM" "$WC"
|
||||
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' '~/.local/share/coredesktop/' "$WC" n)"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"is the deployed copy"* ]]
|
||||
[ "$(config)" = "WORKING_COPY=$(printf '%q' "$WC")" ]
|
||||
}
|
||||
|
||||
@test "install offers to clone the working copy from the deployed copy's origin" {
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' "" y n)"
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(git -C "$WC" remote get-url origin)" = "$UPSTREAM" ]
|
||||
[ "$(config)" = "WORKING_COPY=$(printf '%q' "$WC")" ]
|
||||
}
|
||||
|
||||
@test "install won't use a folder that isn't a clone and isn't empty" {
|
||||
mkdir -p "$HOME/other"
|
||||
touch "$HOME/other/file"
|
||||
git clone -q "$UPSTREAM" "$WC"
|
||||
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' "$HOME/other" "$WC" n)"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"isn't a clone of CoreDesktop, and isn't empty"* ]]
|
||||
[ "$(config)" = "WORKING_COPY=$(printf '%q' "$WC")" ]
|
||||
}
|
||||
|
||||
@test "install is safe to re-run, and Enter keeps the saved working copy" {
|
||||
# Somewhere other than the default, ~/Projects/coredesktop
|
||||
other="$HOME/work/coredesktop"
|
||||
git clone -q "$UPSTREAM" "$other"
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' "$other" n)"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' "" n)"
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(config)" = "WORKING_COPY=$(printf '%q' "$other")" ]
|
||||
[ ! -e "$WC" ]
|
||||
}
|
||||
|
||||
@test "install stops without an answer instead of looping" {
|
||||
run bash "$PROJECT/install.sh" < /dev/null
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"No answer"* ]]
|
||||
[ ! -f "$HOME/.config/coredesktop-dev/config" ]
|
||||
}
|
||||
|
||||
@test "install offers the pre-push hook, and installs it on yes" {
|
||||
git clone -q "$UPSTREAM" "$WC"
|
||||
|
||||
run bash "$PROJECT/install.sh" <<< "$(printf '%s\n' "$WC" y)"
|
||||
[ "$status" -eq 0 ]
|
||||
grep -qxF "# Installed by coredesktop-dev; remove with: coredesktop-dev hooks remove" \
|
||||
"$WC/.git/hooks/pre-push"
|
||||
}
|
||||
|
||||
@test "install stops if CoreDesktop isn't installed" {
|
||||
rm -rf "$DEPLOYED"
|
||||
run bash "$PROJECT/install.sh" <<< ""
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"CoreDesktop isn't installed"* ]]
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
# The driver with fake QEMU: "VMs" are sleep processes, and ssh runs its command
|
||||
# right here. The working copy has a small fake smoketest of its own.
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
make_working_copy
|
||||
|
||||
export KVM_DEVICE="$BATS_TEST_TMPDIR/kvm"
|
||||
touch "$KVM_DEVICE"
|
||||
export SMOKETEST_DESKTOP_TIMEOUT=0 SMOKETEST_SSH_TIMEOUT=5
|
||||
STATE="$HOME/.cache/coredesktop-dev/smoketest"
|
||||
mkdir -p "$STATE/images"
|
||||
touch "$STATE/images/base.qcow2" "$STATE/images/installed.qcow2"
|
||||
git -C "$WC" rev-parse HEAD > "$STATE/images/installed.ref"
|
||||
|
||||
# A VM is a sleep that lets go of bats' output pipes
|
||||
stub qemu-system-x86_64 'while [ $# -gt 0 ]; do [ "$1" = -pidfile ] && pidfile="$2"; shift; done
|
||||
/usr/bin/sleep 300 > /dev/null 2>&1 3>&- &
|
||||
echo $! > "$pidfile"'
|
||||
stub qemu-img 'touch "${@: -1}"'
|
||||
stub xorriso
|
||||
stub curl
|
||||
stub ss
|
||||
stub ssh-keygen 'touch "${@: -1}" "${@: -1}.pub"'
|
||||
stub systemctl
|
||||
stub ssh 'while [ $# -gt 0 ]; do
|
||||
case "$1" in -i | -o | -p) shift 2 ;; *@*) shift; break ;; *) shift ;; esac
|
||||
done
|
||||
[ $# -gt 0 ] || exit 0
|
||||
cd "$HOME" && exec bash -c "$*"'
|
||||
stub scp 'dest="${*: -1}"; cp "${@: -2:1}" "${dest#*:}"'
|
||||
|
||||
SC="$WC/smoketest/scenarios"
|
||||
mkdir -p "$SC" "$WC/smoketest/lib"
|
||||
cat > "$WC/smoketest/lib/scenario.sh" << 'EOF'
|
||||
SKIP_STATUS=3
|
||||
smoketest_prepare() { echo "prepare $IMAGE $SMOKETEST_REF $IMAGE_REF"; }
|
||||
fail() { echo "FAIL: $*"; exit 1; }
|
||||
skip() { echo "SKIP: $*"; exit 3; }
|
||||
EOF
|
||||
scenario_file 10-passes pr installed 'vm_exec "echo in the vm"; echo "ref=$SMOKETEST_REF"'
|
||||
scenario_file 20-fails pr base 'false; echo "still going"'
|
||||
scenario_file 30-variants nightly base 'echo "variant $VARIANT"' 'VARIANTS=(one two)'
|
||||
scenario_file 40-skips pr base 'skip "not today"'
|
||||
}
|
||||
|
||||
# scenario_file NAME TIER IMAGE BODY [EXTRA]
|
||||
scenario_file() {
|
||||
printf '%s\n' "DESCRIPTION=\"$1 does things\"" "TIER=$2" "IMAGE=$3" "${5:-}" \
|
||||
"scenario() {" "$4" "}" > "$SC/$1.sh"
|
||||
}
|
||||
|
||||
last_run() {
|
||||
ls -d "$STATE/runs/"* | tail -n 1
|
||||
}
|
||||
|
||||
@test "list shows each scenario's tier, image and description" {
|
||||
run cdd smoketest list
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"10-passes"*"pr"*"installed"*"10-passes does things"* ]]
|
||||
[[ "$output" == *"30-variants"*"nightly"*"base"*"(2 variants)"* ]]
|
||||
}
|
||||
|
||||
@test "run runs the pr scenarios against HEAD and reports each" {
|
||||
run cdd smoketest run
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"PASS 10-passes"* ]]
|
||||
[[ "$output" == *"FAIL 20-fails"* ]]
|
||||
[[ "$output" == *"SKIP 40-skips"* ]]
|
||||
[[ "$output" != *"30-variants"* ]]
|
||||
[[ "$output" == *"in the vm"* ]]
|
||||
[[ "$output" == *"ref=$(git -C "$WC" rev-parse HEAD)"* ]]
|
||||
[ -f "$(last_run)/summary" ]
|
||||
}
|
||||
|
||||
@test "a scenario stops at its first failing command" {
|
||||
run cdd smoketest run 20
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" != *"still going"* ]]
|
||||
}
|
||||
|
||||
@test "run picks scenarios by name or number" {
|
||||
run cdd smoketest run 10 40-skips
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"PASS 10-passes"* ]]
|
||||
[[ "$output" == *"SKIP 40-skips"* ]]
|
||||
[[ "$output" != *"20-fails"* ]]
|
||||
}
|
||||
|
||||
@test "run stops on an unknown scenario before starting any VM" {
|
||||
run cdd smoketest run 10 nosuch
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"No scenario called nosuch"* ]]
|
||||
not_called qemu-system-x86_64
|
||||
}
|
||||
|
||||
@test "each variant runs in its own VM" {
|
||||
run cdd smoketest run 30
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"PASS 30-variants @ one"* ]]
|
||||
[[ "$output" == *"PASS 30-variants @ two"* ]]
|
||||
[ "$(grep -c '^qemu-system-x86_64 ' "$STUB_LOG")" -eq 2 ]
|
||||
grep -q "variant two" "$(last_run)/30-variants@two/scenario.log"
|
||||
}
|
||||
|
||||
@test "--tier all runs every scenario" {
|
||||
run cdd smoketest run --tier all
|
||||
[[ "$output" == *"30-variants @ one"* ]]
|
||||
[[ "$output" == *"10-passes"* ]]
|
||||
}
|
||||
|
||||
@test "the scenario boots a copy of its image, and gets the installed image's commit" {
|
||||
run cdd smoketest run 10
|
||||
[ "$status" -eq 0 ]
|
||||
grep -q "^qemu-img create -q -f qcow2 -b $STATE/images/installed.qcow2 " "$STUB_LOG"
|
||||
[[ "$output" == *"prepare installed $(git -C "$WC" rev-parse HEAD) $(cat "$STATE/images/installed.ref")"* ]]
|
||||
}
|
||||
|
||||
@test "the VM is stopped and its disk deleted after each scenario" {
|
||||
run cdd smoketest run 10 20
|
||||
for dir in "$(last_run)"/*/; do
|
||||
[ ! -e "$dir/qemu.pid" ]
|
||||
[ ! -e "$dir/disk.qcow2" ]
|
||||
done
|
||||
}
|
||||
|
||||
@test "--keep leaves a failed scenario's VM running, and stops the run" {
|
||||
run cdd smoketest run --keep 20 10
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"The VM is still running"* ]]
|
||||
[[ "$output" != *"PASS 10-passes"* ]]
|
||||
pid="$(cat "$(last_run)/20-fails/qemu.pid")"
|
||||
kill -0 "$pid"
|
||||
kill "$pid"
|
||||
}
|
||||
|
||||
@test "run --ref tests another commit" {
|
||||
first="$(git -C "$WC" rev-parse HEAD)"
|
||||
git -C "$WC" commit -q --allow-empty -m second
|
||||
run cdd smoketest run --ref "$first" 10
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"ref=$first"* ]]
|
||||
}
|
||||
|
||||
@test "run stops without KVM" {
|
||||
rm "$KVM_DEVICE"
|
||||
run cdd smoketest run 10
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"Can't use $KVM_DEVICE"* ]]
|
||||
}
|
||||
|
||||
@test "smoketest needs a working copy with a smoketest folder" {
|
||||
rm -rf "$WC/smoketest"
|
||||
run cdd smoketest list
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" == *"has no smoketest/scenarios"* ]]
|
||||
}
|
||||
|
||||
@test "images shows what's built" {
|
||||
rm "$STATE/images/installed.qcow2"
|
||||
run cdd smoketest images
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"base built"* ]]
|
||||
[[ "$output" == *"installed not built"* ]]
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Shared setup for the bats tests, after CoreDesktop's: each test gets its own
|
||||
# HOME and a bin dir at the front of PATH for fake commands. On top of that,
|
||||
# HOME holds a fake CoreDesktop: an upstream repo, the deployed copy cloned
|
||||
# from it, and a working copy at ~/Projects/coredesktop.
|
||||
|
||||
# Used by the .bats files that load this one
|
||||
# shellcheck disable=SC2034
|
||||
PROJECT="$(cd "$BATS_TEST_DIRNAME/.." && pwd)"
|
||||
|
||||
common_setup() {
|
||||
export HOME="$BATS_TEST_TMPDIR/home"
|
||||
export STUB_BIN="$BATS_TEST_TMPDIR/bin"
|
||||
export STUB_LOG="$BATS_TEST_TMPDIR/stub.log"
|
||||
export TMPDIR="$BATS_TEST_TMPDIR/tmp"
|
||||
mkdir -p "$HOME" "$STUB_BIN" "$TMPDIR"
|
||||
: > "$STUB_LOG"
|
||||
export PATH="$STUB_BIN:$PATH"
|
||||
unset XDG_CONFIG_HOME XDG_CACHE_HOME FLATPAK_ID COREDESKTOP_DEV_VIA_FLATPAK
|
||||
export GIT_AUTHOR_NAME=Test GIT_AUTHOR_EMAIL=test@localhost
|
||||
export GIT_COMMITTER_NAME=Test GIT_COMMITTER_EMAIL=test@localhost
|
||||
export GIT_CONFIG_NOSYSTEM=1
|
||||
|
||||
UPSTREAM="$BATS_TEST_TMPDIR/upstream.git"
|
||||
DEPLOYED="$HOME/.local/share/coredesktop"
|
||||
WC="$HOME/Projects/coredesktop"
|
||||
make_coredesktop
|
||||
}
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
}
|
||||
|
||||
# A CoreDesktop upstream with one commit, and the deployed copy cloned from it.
|
||||
# The fake utils.sh logs install_packages instead of installing anything.
|
||||
make_coredesktop() {
|
||||
local src="$BATS_TEST_TMPDIR/src"
|
||||
git init -q --initial-branch=main "$src"
|
||||
mkdir -p "$src/updates.d"
|
||||
printf '%s\n' '#!/bin/bash' 'echo update' > "$src/update"
|
||||
chmod +x "$src/update"
|
||||
touch "$src/updates.d/.keep"
|
||||
printf '%s\n' '#!/bin/bash' 'install_packages() { echo "install_packages $*" >> "$STUB_LOG"; }' \
|
||||
> "$src/utils.sh"
|
||||
printf 'check:\n\ttrue\n' > "$src/Makefile"
|
||||
git -C "$src" add -A
|
||||
git -C "$src" commit -qm "CoreDesktop"
|
||||
git clone -q --bare "$src" "$UPSTREAM"
|
||||
rm -rf "$src"
|
||||
git clone -q "$UPSTREAM" "$DEPLOYED"
|
||||
}
|
||||
|
||||
# Clone the working copy and point the settings at it
|
||||
make_working_copy() {
|
||||
git clone -q "$UPSTREAM" "$WC"
|
||||
mkdir -p "$HOME/.config/coredesktop-dev"
|
||||
printf 'WORKING_COPY=%q\n' "$WC" > "$HOME/.config/coredesktop-dev/config"
|
||||
}
|
||||
|
||||
# Run the coredesktop-dev command
|
||||
cdd() {
|
||||
"$PROJECT/bin/coredesktop-dev" "$@"
|
||||
}
|
||||
|
||||
# stub NAME [BODY]: put a fake NAME on PATH that appends "NAME args..." to
|
||||
# $STUB_LOG and then runs BODY, a bash snippet that sees the args as "$@"
|
||||
stub() {
|
||||
local name="$1" body="${2:-}"
|
||||
cat > "$STUB_BIN/$name" << EOF
|
||||
#!/bin/bash
|
||||
echo "$name \$*" >> "\$STUB_LOG"
|
||||
$body
|
||||
EOF
|
||||
chmod +x "$STUB_BIN/$name"
|
||||
}
|
||||
|
||||
# called NAME ARGS...: true if the stub log has exactly the line "NAME ARGS..."
|
||||
called() {
|
||||
grep -qxF "$*" "$STUB_LOG"
|
||||
}
|
||||
|
||||
# not_called NAME: true if the stub NAME never ran
|
||||
not_called() {
|
||||
! grep -q "^$1 " "$STUB_LOG"
|
||||
}
|
||||
|
||||
# uncalled NAME ARGS...: the opposite of called. (A bare "! called ..." would
|
||||
# not fail the test: bats, like set -e, ignores the status of a ! command.)
|
||||
uncalled() {
|
||||
! called "$@"
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
setup() {
|
||||
common_setup
|
||||
make_working_copy
|
||||
stub dbus-run-session '[ "$1" = -- ] && shift; exec "$@"'
|
||||
export DISPLAY=:0 WAYLAND_DISPLAY=wayland-0 DBUS_SESSION_BUS_ADDRESS=unix:path=/nowhere SSH_AUTH_SOCK=/nowhere
|
||||
}
|
||||
|
||||
@test "try runs the command in a throwaway home with the working copy as CoreDesktop" {
|
||||
run cdd try bash -c 'echo "home=$HOME"
|
||||
echo "runtime=$XDG_RUNTIME_DIR $(stat -c %a "$XDG_RUNTIME_DIR")"
|
||||
echo "display=${DISPLAY-unset} ${WAYLAND_DISPLAY-unset} ${DBUS_SESSION_BUS_ADDRESS-unset} ${SSH_AUTH_SOCK-unset}"
|
||||
echo "coredesktop=$(readlink ~/.local/share/coredesktop)"
|
||||
echo "update=$(readlink "$(command -v update)")"
|
||||
echo "config=$XDG_CONFIG_HOME"'
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"home=$TMPDIR/coredesktop-dev-try."*"/home"* ]]
|
||||
[[ "$output" == *"runtime=$TMPDIR/coredesktop-dev-try."*"/runtime 700"* ]]
|
||||
[[ "$output" == *"display=unset unset unset unset"* ]]
|
||||
[[ "$output" == *"coredesktop=$WC"* ]]
|
||||
[[ "$output" == *"update=$WC/update"* ]]
|
||||
[[ "$output" == *"config=$TMPDIR/coredesktop-dev-try."*"/home/.config"* ]]
|
||||
[[ "$output" == *"still change this machine"* ]]
|
||||
grep -q "^dbus-run-session -- bash" "$STUB_LOG"
|
||||
}
|
||||
|
||||
@test "try cleans up afterwards, and passes on the command's exit status" {
|
||||
run cdd try bash -c 'exit 4'
|
||||
[ "$status" -eq 4 ]
|
||||
[ -z "$(ls "$TMPDIR")" ]
|
||||
}
|
||||
|
||||
@test "try --keep keeps the throwaway folder" {
|
||||
run cdd try --keep true
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" == *"Kept $TMPDIR/coredesktop-dev-try."* ]]
|
||||
[ -n "$(ls "$TMPDIR")" ]
|
||||
}
|
||||
|
||||
@test "try doesn't touch the real home" {
|
||||
run cdd try bash -c 'touch ~/made-by-try'
|
||||
[ "$status" -eq 0 ]
|
||||
[ ! -e "$HOME/made-by-try" ]
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load test_helper
|
||||
|
||||
HOOK_MARKER="# Installed by coredesktop-dev; remove with: coredesktop-dev hooks remove"
|
||||
|
||||
@test "update installs the packages and links the command, without asking anything" {
|
||||
run bash "$PROJECT/update.sh" < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
called install_packages shellcheck bats tea qemu-base libisoburn
|
||||
[ "$(readlink "$HOME/.local/bin/coredesktop-dev")" = "$PROJECT/bin/coredesktop-dev" ]
|
||||
}
|
||||
|
||||
@test "update fixes a link that points somewhere else" {
|
||||
mkdir -p "$HOME/.local/bin"
|
||||
ln -s /nowhere "$HOME/.local/bin/coredesktop-dev"
|
||||
|
||||
run bash "$PROJECT/update.sh" < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(readlink "$HOME/.local/bin/coredesktop-dev")" = "$PROJECT/bin/coredesktop-dev" ]
|
||||
}
|
||||
|
||||
@test "update leaves an unchanged pre-push hook alone" {
|
||||
make_working_copy
|
||||
cp "$PROJECT/hooks/pre-push" "$WC/.git/hooks/pre-push"
|
||||
touch -d '2020-01-01' "$WC/.git/hooks/pre-push"
|
||||
|
||||
run bash "$PROJECT/update.sh" < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(date -r "$WC/.git/hooks/pre-push" +%Y)" = 2020 ]
|
||||
[[ "$output" != *"Updated the pre-push hook"* ]]
|
||||
}
|
||||
|
||||
@test "update refreshes our pre-push hook when it has changed" {
|
||||
make_working_copy
|
||||
printf '%s\n' '#!/bin/bash' "$HOOK_MARKER" 'old version' > "$WC/.git/hooks/pre-push"
|
||||
|
||||
run bash "$PROJECT/update.sh" < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
cmp "$PROJECT/hooks/pre-push" "$WC/.git/hooks/pre-push"
|
||||
[[ "$output" == *"Updated the pre-push hook"* ]]
|
||||
}
|
||||
|
||||
@test "update doesn't touch someone else's pre-push hook" {
|
||||
make_working_copy
|
||||
printf '%s\n' '#!/bin/bash' 'mine' > "$WC/.git/hooks/pre-push"
|
||||
|
||||
run bash "$PROJECT/update.sh" < /dev/null
|
||||
[ "$status" -eq 0 ]
|
||||
[ "$(tail -n 1 "$WC/.git/hooks/pre-push")" = mine ]
|
||||
}
|
||||
Reference in New Issue
Block a user