Drop tests for shipped one-shot migrations (#10318)
Keep the migrations themselves for late-updaters. Drop the tests that only exercised frozen file rewrites from 4.0.0, and keep live invariants, privileged repairs, and the migrator.
This commit is contained in:
1 parent
eb56446c42
commit
36e56f4fb4
14 files changed
+26
-947
No files matched your search
@@ -163,6 +163,8 @@ rm ~/.local/state/omarchy/migrations/<migration>.sh
|
||||
omarchy-migrate
|
||||
```
|
||||
|
||||
Keep a dedicated test while the migration is still being written or bugfixed, if it calls an Omarchy helper whose interface can still change, or if it is a security-sensitive privileged repair (FIDO2, leftover installer artifacts, udev, sshd). Once a one-shot rewrite has shipped in a tagged release and is frozen, drop the test even when that rewrite used sudo, pacman, or limine-mkinitcpio. Keep the migration itself for late-updaters. Tests of `omarchy-migrate`, the login notifier, and `omarchy-upgrade-to-quattro` stay.
|
||||
|
||||
Omarchy 4.0 is upgraded through `bin/omarchy-upgrade-to-quattro`, not through the
|
||||
normal migration runner. Do not add compatibility migrations for old installer
|
||||
layouts; put pre-4 package-layout transition work in the upgrade command instead.
|
||||
|
||||
+3
-4
@@ -20,11 +20,10 @@ the end and exits non-zero.
|
||||
the theme pipeline: template rendering (`omarchy-theme-set-templates`,
|
||||
`omarchy-theme-color`, `omarchy-theme-osc`), the theme sync commands
|
||||
(tmux, GNOME, VS Code, Pi, Claude) run against stub binaries and a fake
|
||||
`$HOME`, and the theme-state migrations.
|
||||
`$HOME`.
|
||||
- **`./test/shell`** — runs every `test/shell.d/*-test.sh` (except
|
||||
`base-test.sh` itself). Each file is an independent suite covering one area:
|
||||
a shell plugin, a `bin/` command, a config invariant, a migration. This is
|
||||
where new tests go.
|
||||
a shell plugin, a `bin/` command, a config invariant, or a still-live migration. This is where new tests go.
|
||||
- **Acceptance** — everything that needs a real desktop doing real things.
|
||||
Deliberately excluded from `./test/all`; it runs in a VM, not the
|
||||
development session.
|
||||
@@ -132,7 +131,7 @@ only a live session can prove.
|
||||
fake `$HOME`, runs `bash -euo pipefail "$ROOT/migrations/<ts>.sh"`, and
|
||||
asserts the resulting state — including running it twice to prove
|
||||
idempotence, and once against non-legacy state to prove it leaves user
|
||||
customization alone.
|
||||
customization alone. Keep that test while the migration is still being written or bugfixed, if it calls an Omarchy helper whose interface can still change, or if it is a security-sensitive privileged repair. Once a one-shot rewrite has shipped in a tagged release and is frozen, drop the test even when that rewrite used sudo, pacman, or limine-mkinitcpio. Keep the migration itself for late-updaters. Tests of `omarchy-migrate`, the login notifier, and `omarchy-upgrade-to-quattro` stay.
|
||||
- **Assert the invariant, not the snapshot.** Config tests pin the property a
|
||||
test is named for (this widget stays adjacent to that one) rather than whole
|
||||
structures, so unrelated churn does not fail them.
|
||||
@@ -519,101 +519,6 @@ expected_background="$THEME_TMPDIR/.local/state/omarchy/current/theme/background
|
||||
[[ ! -e $THEME_TMPDIR/.config/omarchy/current ]] || fail "headless theme set avoids config current state"
|
||||
pass "headless theme set creates current background symlink"
|
||||
|
||||
make_tmpdir MIGRATION_TMPDIR
|
||||
mkdir -p \
|
||||
"$MIGRATION_TMPDIR/.config/omarchy/current/theme" \
|
||||
"$MIGRATION_TMPDIR/.config/alacritty" \
|
||||
"$MIGRATION_TMPDIR/.config/hypr" \
|
||||
"$MIGRATION_TMPDIR/.config/hyprland-preview-share-picker" \
|
||||
"$MIGRATION_TMPDIR/.config/btop/themes"
|
||||
printf 'tokyo-night\n' >"$MIGRATION_TMPDIR/.config/omarchy/current/theme.name"
|
||||
printf 'x\n' >"$MIGRATION_TMPDIR/.config/omarchy/current/theme/colors.toml"
|
||||
printf 'general.import = [ "~/.config/omarchy/current/theme/alacritty.toml" ]\n' >"$MIGRATION_TMPDIR/.config/alacritty/alacritty.toml"
|
||||
printf 'stylesheets: ["../omarchy/current/theme/hyprland-preview-share-picker.css"]\n' >"$MIGRATION_TMPDIR/.config/hyprland-preview-share-picker/config.yaml"
|
||||
cat >"$MIGRATION_TMPDIR/.config/hypr/hyprland.lua" <<'LUA'
|
||||
package.path = os.getenv("HOME")
|
||||
.. "/.config/?.lua;"
|
||||
.. (os.getenv("OMARCHY_PATH") or "/usr/share/omarchy")
|
||||
.. "/?.lua;"
|
||||
.. package.path
|
||||
LUA
|
||||
ln -s "$MIGRATION_TMPDIR/.config/omarchy/current/theme/btop.theme" "$MIGRATION_TMPDIR/.config/btop/themes/current.theme"
|
||||
HOME="$MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/1781043107.sh" >/dev/null
|
||||
[[ -f $MIGRATION_TMPDIR/.local/state/omarchy/current/theme.name ]] || fail "current theme migration moves theme name"
|
||||
[[ ! -e $MIGRATION_TMPDIR/.config/omarchy/current ]] || fail "current theme migration removes legacy config state"
|
||||
grep -Fq '~/.local/state/omarchy/current/theme/alacritty.toml' "$MIGRATION_TMPDIR/.config/alacritty/alacritty.toml" || fail "current theme migration updates alacritty import"
|
||||
grep -Fq '../../.local/state/omarchy/current/theme/hyprland-preview-share-picker.css' "$MIGRATION_TMPDIR/.config/hyprland-preview-share-picker/config.yaml" || fail "current theme migration updates relative stylesheet"
|
||||
grep -Fq '/.local/state/?.lua;' "$MIGRATION_TMPDIR/.config/hypr/hyprland.lua" || fail "current theme migration keeps Hyprland theme modules discoverable"
|
||||
[[ $(readlink "$MIGRATION_TMPDIR/.config/btop/themes/current.theme") == "$MIGRATION_TMPDIR/.local/state/omarchy/current/theme/btop.theme" ]] || fail "current theme migration updates btop symlink"
|
||||
pass "current theme migration moves state and rewrites shipped references"
|
||||
|
||||
make_tmpdir NVIM_MIGRATION_TMPDIR
|
||||
nvim_theme_link="$NVIM_MIGRATION_TMPDIR/.config/nvim/lua/plugins/theme.lua"
|
||||
nvim_expected_target="../../../../.local/state/omarchy/current/theme/neovim.lua"
|
||||
nvim_expected_resolved_target="$NVIM_MIGRATION_TMPDIR/.local/state/omarchy/current/theme/neovim.lua"
|
||||
mkdir -p \
|
||||
"$(dirname "$nvim_theme_link")" \
|
||||
"$NVIM_MIGRATION_TMPDIR/.config/omarchy/current/theme" \
|
||||
"$NVIM_MIGRATION_TMPDIR/.local/state/omarchy/current/theme"
|
||||
touch "$NVIM_MIGRATION_TMPDIR/.local/state/omarchy/current/theme/neovim.lua"
|
||||
for nvim_legacy_target in \
|
||||
"../../../omarchy/current/theme/neovim.lua" \
|
||||
"$NVIM_MIGRATION_TMPDIR/.config/omarchy/current/theme/neovim.lua"; do
|
||||
ln -sfn "$nvim_legacy_target" "$nvim_theme_link"
|
||||
HOME="$NVIM_MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/1781158082.sh" >/dev/null
|
||||
nvim_actual_target=$(readlink "$nvim_theme_link")
|
||||
nvim_resolved_target=$(readlink -f "$nvim_theme_link")
|
||||
[[ $nvim_actual_target == $nvim_expected_target ]] || fail "nvim theme migration updates theme symlink"
|
||||
[[ $nvim_resolved_target == $nvim_expected_resolved_target ]] || fail "nvim theme migration points to current theme"
|
||||
done
|
||||
pass "nvim theme migration relinks current theme"
|
||||
|
||||
for nvim_legacy_target in \
|
||||
"../../../omarchy/current/theme/neovim.lua" \
|
||||
"../../../../.config/omarchy/current/theme/neovim.lua" \
|
||||
"~/.config/omarchy/current/theme/neovim.lua" \
|
||||
"$NVIM_MIGRATION_TMPDIR/.config/omarchy/current/theme/neovim.lua"; do
|
||||
ln -sfn "$nvim_legacy_target" "$nvim_theme_link"
|
||||
HOME="$NVIM_MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/1785002349.sh" >/dev/null
|
||||
nvim_actual_target=$(readlink "$nvim_theme_link")
|
||||
nvim_resolved_target=$(readlink -f "$nvim_theme_link")
|
||||
[[ $nvim_actual_target == $nvim_expected_target ]] || fail "nvim theme repair migration updates $nvim_legacy_target"
|
||||
[[ $nvim_resolved_target == $nvim_expected_resolved_target ]] || fail "nvim theme repair migration points to current theme"
|
||||
done
|
||||
|
||||
HOME="$NVIM_MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/1785002349.sh" >/dev/null
|
||||
[[ $(readlink "$nvim_theme_link") == $nvim_expected_target ]] || fail "nvim theme repair migration is idempotent"
|
||||
|
||||
touch "$NVIM_MIGRATION_TMPDIR/custom-theme.lua"
|
||||
ln -sfn "../../../../custom-theme.lua" "$nvim_theme_link"
|
||||
HOME="$NVIM_MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/1785002349.sh" >/dev/null
|
||||
[[ $(readlink "$nvim_theme_link") == "../../../../custom-theme.lua" ]] || fail "nvim theme repair migration leaves custom symlinks alone"
|
||||
pass "nvim theme repair migration relinks every legacy spelling"
|
||||
|
||||
make_tmpdir HYPR_MIGRATION_TMPDIR
|
||||
mkdir -p "$HYPR_MIGRATION_TMPDIR/.config/hypr"
|
||||
cat >"$HYPR_MIGRATION_TMPDIR/.config/hypr/hyprland.lua" <<'LUA'
|
||||
-- Learn how to configure Hyprland: https://wiki.hypr.land/Configuring/Start/
|
||||
|
||||
-- Load user modules from ~/.config and Omarchy defaults from $OMARCHY_PATH.
|
||||
package.path = os.getenv("HOME")
|
||||
.. "/.config/?.lua;"
|
||||
.. (os.getenv("OMARCHY_PATH") or (os.getenv("HOME") .. "/.local/share/omarchy"))
|
||||
.. "/?.lua;"
|
||||
.. package.path
|
||||
|
||||
-- All Omarchy default setups
|
||||
require("default.hypr.omarchy")
|
||||
|
||||
-- Add any other personal Hyprland configuration below.
|
||||
o.window("Example", { workspace = "1" })
|
||||
LUA
|
||||
HOME="$HYPR_MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/1781063758.sh" >/dev/null
|
||||
grep -Fq 'dofile((os.getenv("OMARCHY_PATH") or "/usr/share/omarchy") .. "/default/hypr/bootstrap.lua")' "$HYPR_MIGRATION_TMPDIR/.config/hypr/hyprland.lua" || fail "hyprland bootstrap migration adds bootstrap"
|
||||
! grep -Fq 'package.path = os.getenv("HOME")' "$HYPR_MIGRATION_TMPDIR/.config/hypr/hyprland.lua" || fail "hyprland bootstrap migration removes legacy path block"
|
||||
grep -Fq 'o.window("Example", { workspace = "1" })' "$HYPR_MIGRATION_TMPDIR/.config/hypr/hyprland.lua" || fail "hyprland bootstrap migration preserves custom config"
|
||||
pass "hyprland bootstrap migration updates stale user entrypoint"
|
||||
|
||||
cp "$NEXT_THEME/colors.toml" "$CURRENT_THEME/colors.toml"
|
||||
cp "$NEXT_THEME/vscode-theme.json" "$CURRENT_THEME/vscode-theme.json"
|
||||
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(dirname "$0")/base-test.sh"
|
||||
|
||||
require_command jq
|
||||
|
||||
migration="$ROOT/migrations/1785344985.sh"
|
||||
test_dir=$(mktemp -d)
|
||||
trap 'rm -rf "$test_dir"' EXIT
|
||||
|
||||
mkdir -p "$test_dir/bin"
|
||||
|
||||
cat >"$test_dir/bin/omarchy-restart-shell" <<'STUB'
|
||||
#!/bin/bash
|
||||
|
||||
echo restart >>"$SHELL_RESTARTS"
|
||||
STUB
|
||||
|
||||
chmod +x "$test_dir/bin/"*
|
||||
|
||||
export SHELL_RESTARTS="$test_dir/shell-restarts"
|
||||
|
||||
home="$test_dir/home"
|
||||
config="$home/.config/omarchy/shell.json"
|
||||
|
||||
run_migration() {
|
||||
: >"$SHELL_RESTARTS"
|
||||
HOME="$home" PATH="$test_dir/bin:$PATH" bash -euo pipefail "$migration" >/dev/null
|
||||
}
|
||||
|
||||
# The shipped default minus the widget is what every machine installed before
|
||||
# this migration has on disk.
|
||||
write_config() {
|
||||
rm -rf "$home"
|
||||
mkdir -p "$home/.config/omarchy"
|
||||
jq "${1:-.}" "$ROOT/config/omarchy/shell.json" >"$config"
|
||||
}
|
||||
|
||||
without_widget='del(.bar.layout[][] | select((if type == "object" then .id else . end) == "omarchy.agents"))'
|
||||
|
||||
ids() {
|
||||
jq -c --arg section "$1" '[.bar.layout[$section][]? | if type == "object" then .id else . end]' "$config"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------ shipped default
|
||||
|
||||
jq -e '[.bar.layout.right[].id] | index("omarchy.agents")' "$ROOT/config/omarchy/shell.json" >/dev/null ||
|
||||
fail "shipped config puts the agents widget in the bar"
|
||||
pass "shipped config puts the agents widget in the bar"
|
||||
|
||||
# ------------------------------------------------------------------ placement
|
||||
|
||||
write_config "$without_widget"
|
||||
run_migration
|
||||
|
||||
[[ $(ids right) == '["omarchy.tray","omarchy.agents","omarchy.bluetooth","omarchy.network","omarchy.audio","omarchy.monitor","omarchy.power"]' ]] ||
|
||||
fail "migration inserts the agents widget after the tray" "$(ids right)"
|
||||
pass "migration inserts the agents widget after the tray"
|
||||
|
||||
(($(wc -l <"$SHELL_RESTARTS") == 0)) || fail "migration leaves the shell restart to omarchy update"
|
||||
pass "migration leaves the shell restart to omarchy update"
|
||||
|
||||
before=$(sha256sum "$config")
|
||||
run_migration
|
||||
[[ $before == $(sha256sum "$config") ]] || fail "migration is idempotent" "$(ids right)"
|
||||
pass "migration is idempotent"
|
||||
|
||||
# ------------------------------------------------------------------ curated bars
|
||||
|
||||
# A user who already placed the widget keeps it exactly where they put it, in
|
||||
# whichever section, and never gets a second copy.
|
||||
write_config "$without_widget | .bar.layout.center += [{ id: \"omarchy.agents\" }]"
|
||||
run_migration
|
||||
|
||||
[[ $(ids center) == *'"omarchy.agents"'* ]] || fail "migration leaves a user-placed widget alone" "$(ids center)"
|
||||
[[ $(ids right) != *'"omarchy.agents"'* ]] || fail "migration does not add a second copy" "$(ids right)"
|
||||
pass "migration respects a widget the user already placed"
|
||||
|
||||
# Layouts written before entries grew options are bare id strings.
|
||||
write_config "$without_widget | .bar.layout.right = [\"omarchy.tray\", \"omarchy.agents\", \"omarchy.power\"]"
|
||||
run_migration
|
||||
|
||||
[[ $(ids right) == '["omarchy.tray","omarchy.agents","omarchy.power"]' ]] ||
|
||||
fail "migration reads string-form entries" "$(ids right)"
|
||||
pass "migration reads string-form entries"
|
||||
|
||||
# A tray dropped from the right section must not strand the widget or drop it.
|
||||
write_config "$without_widget | del(.bar.layout.right[] | select(.id == \"omarchy.tray\"))"
|
||||
run_migration
|
||||
|
||||
[[ $(ids right) == '["omarchy.agents",'* ]] || fail "migration places the widget without a tray" "$(ids right)"
|
||||
pass "migration places the widget without a tray"
|
||||
|
||||
# ------------------------------------------------------------------ everything else
|
||||
|
||||
write_config "$without_widget"
|
||||
cp "$config" "$test_dir/before.json"
|
||||
run_migration
|
||||
|
||||
diff <(jq -S 'del(.bar.layout.right)' "$test_dir/before.json") <(jq -S 'del(.bar.layout.right)' "$config") >/dev/null ||
|
||||
fail "migration touches nothing but the right section" "$(diff <(jq -S . "$test_dir/before.json") <(jq -S . "$config"))"
|
||||
pass "migration touches nothing but the right section"
|
||||
|
||||
# A config the migration cannot parse is left alone rather than truncated.
|
||||
rm -rf "$home"
|
||||
mkdir -p "$home/.config/omarchy"
|
||||
printf '{ not json' >"$config"
|
||||
run_migration
|
||||
|
||||
[[ $(cat "$config") == '{ not json' ]] || fail "migration leaves an unparsable config untouched" "$(cat "$config")"
|
||||
pass "migration leaves an unparsable config untouched"
|
||||
@@ -1,109 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(dirname "$0")/base-test.sh"
|
||||
|
||||
migration="$ROOT/migrations/1786380259.sh"
|
||||
test_dir=$(mktemp -d)
|
||||
trap 'rm -rf "$test_dir"' EXIT
|
||||
|
||||
mkdir -p "$test_dir/bin"
|
||||
|
||||
# sudo runs the real command, so sed acts on the redirected main.conf below and
|
||||
# the elevated power calls land in the stub beside it.
|
||||
cat >"$test_dir/bin/sudo" <<'STUB'
|
||||
#!/bin/bash
|
||||
|
||||
printf 'sudo %s\n' "$*" >>"$CALLS"
|
||||
exec "$@"
|
||||
STUB
|
||||
|
||||
cat >"$test_dir/bin/omarchy-bluetooth-power" <<'STUB'
|
||||
#!/bin/bash
|
||||
|
||||
printf 'omarchy-bluetooth-power %s\n' "$*" >>"$CALLS"
|
||||
[[ $1 == "is-on" ]] || exit 0
|
||||
[[ ${POWERED:-} == "yes" ]]
|
||||
STUB
|
||||
|
||||
chmod +x "$test_dir/bin/"*
|
||||
|
||||
export CALLS="$test_dir/calls"
|
||||
|
||||
marker="$test_dir/marker"
|
||||
main_conf="$test_dir/main.conf"
|
||||
|
||||
reset_machine() {
|
||||
rm -f "$marker"
|
||||
printf '[Policy]\nAutoEnable=false\n' >"$main_conf"
|
||||
}
|
||||
|
||||
run_migration() {
|
||||
: >"$CALLS"
|
||||
|
||||
OMARCHY_BLUETOOTH_MIGRATION_MARKER="$marker" \
|
||||
OMARCHY_BLUETOOTH_MAIN_CONF="$main_conf" \
|
||||
PATH="$test_dir/bin:$PATH" \
|
||||
bash -euo pipefail "$migration" >/dev/null
|
||||
}
|
||||
|
||||
# An adapter that is powered right now is one the user turned on, so it stays on.
|
||||
reset_machine
|
||||
POWERED=yes run_migration
|
||||
|
||||
grep -qx 'omarchy-bluetooth-power on' "$CALLS" ||
|
||||
fail "migration keeps a powered adapter on" "$(cat "$CALLS")"
|
||||
pass "migration keeps a powered adapter on"
|
||||
|
||||
grep -qx '#AutoEnable=true' "$main_conf" ||
|
||||
fail "migration puts AutoEnable back to its default" "$(cat "$main_conf")"
|
||||
pass "migration puts AutoEnable back to its default"
|
||||
|
||||
[[ -e $marker ]] || fail "migration records the machine as done"
|
||||
pass "migration records the machine as done"
|
||||
|
||||
# Anything else is a machine that has been booting with Bluetooth off, and the
|
||||
# block is what carries that over now AutoEnable no longer holds the adapter down.
|
||||
reset_machine
|
||||
POWERED=no run_migration
|
||||
|
||||
grep -qx 'omarchy-bluetooth-power off' "$CALLS" ||
|
||||
fail "migration carries an unpowered adapter over to the block" "$(cat "$CALLS")"
|
||||
pass "migration carries an unpowered adapter over to the block"
|
||||
|
||||
# No daemon to ask reads the same way: off is what the machine has been doing.
|
||||
reset_machine
|
||||
run_migration
|
||||
|
||||
grep -qx 'omarchy-bluetooth-power off' "$CALLS" ||
|
||||
fail "migration blocks when no adapter can be read" "$(cat "$CALLS")"
|
||||
pass "migration blocks when no adapter can be read"
|
||||
|
||||
# /dev/rfkill is only writable unelevated from an active graphical seat, so an
|
||||
# update run over SSH would abort here and abort again on every retry.
|
||||
grep -qx 'sudo omarchy-bluetooth-power off' "$CALLS" ||
|
||||
fail "migration changes the radio through sudo" "$(cat "$CALLS")"
|
||||
pass "migration changes the radio through sudo"
|
||||
|
||||
# A second account must not undo an administrator's later choice, since migration
|
||||
# completion is recorded per user.
|
||||
printf '[Policy]\nAutoEnable=false\n' >"$main_conf"
|
||||
POWERED=yes run_migration
|
||||
|
||||
grep -qx 'AutoEnable=false' "$main_conf" ||
|
||||
fail "migration leaves a later opt-out alone" "$(cat "$main_conf")"
|
||||
pass "migration leaves a later opt-out alone"
|
||||
|
||||
[[ ! -s $CALLS ]] ||
|
||||
fail "migration touches no radio state on a second run" "$(cat "$CALLS")"
|
||||
pass "migration touches no radio state on a second run"
|
||||
|
||||
# Only the exact line Omarchy wrote is reverted, so a hand-edited opt-out stands.
|
||||
reset_machine
|
||||
printf '[Policy]\nAutoEnable = false\n' >"$main_conf"
|
||||
POWERED=yes run_migration
|
||||
|
||||
grep -qx 'AutoEnable = false' "$main_conf" ||
|
||||
fail "migration keeps a hand-edited AutoEnable" "$(cat "$main_conf")"
|
||||
pass "migration keeps a hand-edited AutoEnable"
|
||||
@@ -38,6 +38,15 @@ jq -e '
|
||||
' "$ROOT/config/omarchy/shell.json" >/dev/null
|
||||
pass "default clock date format has no leading zero"
|
||||
|
||||
jq -e '
|
||||
def ids: map(.id // .);
|
||||
(.bar.layout.right | ids) as $ids |
|
||||
($ids | index("omarchy.tray")) as $tray |
|
||||
($ids | index("omarchy.agents")) as $agents |
|
||||
$tray != null and $agents == $tray + 1
|
||||
' "$ROOT/config/omarchy/shell.json" >/dev/null
|
||||
pass "default right layout keeps agents next to the tray"
|
||||
|
||||
ROOT="$ROOT" python3 <<'PY'
|
||||
import json
|
||||
import os
|
||||
@@ -418,39 +427,3 @@ if grep -RIl 'upgrade-to-quattro\|Omarchy 4\.0 is upgraded' "$ROOT/migrations" >
|
||||
fail "4.0 upgrade is not modeled as a migration"
|
||||
fi
|
||||
pass "4.0 upgrade is handled outside the migration runner"
|
||||
|
||||
clock_migration=$(grep -rl 'Remove leading zero from bar clock date' "$ROOT/migrations" | head -n 1 || true)
|
||||
[[ -n $clock_migration ]] || fail "clock date format user migration exists"
|
||||
|
||||
cat >"$TMPDIR/home/.config/omarchy/shell.json" <<'JSON'
|
||||
{
|
||||
"version": 1,
|
||||
"bar": {
|
||||
"layout": {
|
||||
"left": [],
|
||||
"center": [
|
||||
{ "id": "omarchy.clock", "formatAlt": "dd MMMM 'W'ww yyyy" },
|
||||
{ "id": "omarchy.weather" }
|
||||
],
|
||||
"right": [
|
||||
{ "id": "local.clock", "formatAlt": "dd MMMM 'W'ww yyyy" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"plugins": []
|
||||
}
|
||||
JSON
|
||||
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" bash "$clock_migration"
|
||||
|
||||
jq -e '
|
||||
.bar.layout.center[0].formatAlt == "d MMMM \u0027W\u0027ww yyyy" and
|
||||
.bar.layout.right[0].formatAlt == "dd MMMM \u0027W\u0027ww yyyy"
|
||||
' "$TMPDIR/home/.config/omarchy/shell.json" >/dev/null
|
||||
pass "clock date format migration removes leading zero from clock"
|
||||
|
||||
before=$(sha256sum "$TMPDIR/home/.config/omarchy/shell.json" | awk '{print $1}')
|
||||
HOME="$TMPDIR/home" OMARCHY_PATH="$ROOT" bash "$clock_migration"
|
||||
after=$(sha256sum "$TMPDIR/home/.config/omarchy/shell.json" | awk '{print $1}')
|
||||
[[ $before == "$after" ]] || fail "clock date format migration is idempotent"
|
||||
pass "clock date format migration is idempotent"
|
||||
@@ -1,111 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
migration="$ROOT/migrations/1786482992.sh"
|
||||
packaged_defaults="$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf"
|
||||
|
||||
grep -Fq 'KERNEL_CMDLINE[default]+=" initramfs_async=0"' "$packaged_defaults" ||
|
||||
fail "the packaged Limine defaults still unpack the initramfs synchronously"
|
||||
pass "packaged Limine defaults keep Plymouth alive at the LUKS prompt"
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
stub_bin="$test_tmp/bin"
|
||||
calls="$test_tmp/calls.log"
|
||||
mkdir -p "$stub_bin"
|
||||
: >"$calls"
|
||||
|
||||
cat >"$stub_bin/omarchy-cmd-present" <<'SH'
|
||||
#!/bin/bash
|
||||
|
||||
(( ${LIMINE_MKINITCPIO_INSTALLED:-1} == 1 ))
|
||||
SH
|
||||
|
||||
cat >"$stub_bin/sudo" <<'SH'
|
||||
#!/bin/bash
|
||||
|
||||
printf 'sudo' >>"$TEST_LOG"
|
||||
printf '\t%s' "$@" >>"$TEST_LOG"
|
||||
printf '\n' >>"$TEST_LOG"
|
||||
"$@"
|
||||
SH
|
||||
|
||||
cat >"$stub_bin/limine-mkinitcpio" <<'SH'
|
||||
#!/bin/bash
|
||||
|
||||
echo 'limine-mkinitcpio' >>"$TEST_LOG"
|
||||
SH
|
||||
|
||||
chmod +x "$stub_bin"/*
|
||||
|
||||
defaults_conf="$test_tmp/omarchy-defaults.conf"
|
||||
running_cmdline="$test_tmp/cmdline"
|
||||
rebuild_marker="$test_tmp/rebuild-complete"
|
||||
|
||||
cp "$packaged_defaults" "$defaults_conf"
|
||||
|
||||
# A boot image baked before quattro's defaults landed: the pre-quattro command
|
||||
# line plus the machine's own root parameters, and none of the new ones.
|
||||
stale_cmdline='quiet splash cryptdevice=PARTUUID=fake:root root=/dev/mapper/root rw'
|
||||
|
||||
# Everything the packaged defaults ask for, as a rebuilt image would carry it.
|
||||
configured=$(sed -n 's/^KERNEL_CMDLINE\[default\]+="\(.*\)"[[:space:]]*$/\1/p' "$defaults_conf" | tr '\n' ' ')
|
||||
current_cmdline="cryptdevice=PARTUUID=fake:root root=/dev/mapper/root rw $configured"
|
||||
|
||||
run_migration() {
|
||||
PATH="$stub_bin:$PATH" \
|
||||
TEST_LOG="$calls" \
|
||||
OMARCHY_LIMINE_DEFAULTS_CONF="$defaults_conf" \
|
||||
OMARCHY_RUNNING_CMDLINE="$running_cmdline" \
|
||||
OMARCHY_LIMINE_REBUILD_MARKER="$rebuild_marker" \
|
||||
bash -euo pipefail "$migration" >/dev/null
|
||||
}
|
||||
|
||||
echo "$stale_cmdline" >"$running_cmdline"
|
||||
run_migration
|
||||
|
||||
grep -Fxq 'limine-mkinitcpio' "$calls" ||
|
||||
fail "a boot image older than the Limine defaults is rebuilt"
|
||||
[[ -f $rebuild_marker ]] || fail "the rebuild records the machine-wide repair"
|
||||
pass "migration rebuilds a boot image that predates the Limine defaults"
|
||||
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "a recorded rebuild is not repeated" "$(cat "$calls")"
|
||||
pass "migration is machine-idempotent before reboot"
|
||||
|
||||
rm -f "$rebuild_marker"
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
grep -Fxq 'limine-mkinitcpio' "$calls" ||
|
||||
fail "an interrupted rebuild is retried"
|
||||
[[ -f $rebuild_marker ]] || fail "a retried rebuild records completion"
|
||||
pass "migration retries an interrupted rebuild"
|
||||
|
||||
echo "$current_cmdline" >"$running_cmdline"
|
||||
rm -f "$rebuild_marker"
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "a boot image matching the defaults is left alone" "$(cat "$calls")"
|
||||
[[ ! -e $rebuild_marker ]] || fail "an untouched machine is not marked as repaired"
|
||||
pass "migration skips a boot image that already carries the defaults"
|
||||
|
||||
echo "$stale_cmdline" >"$running_cmdline"
|
||||
: >"$calls"
|
||||
LIMINE_MKINITCPIO_INSTALLED=0 run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "installs without limine-mkinitcpio are skipped" "$(cat "$calls")"
|
||||
|
||||
mv "$defaults_conf" "$defaults_conf.away"
|
||||
run_migration
|
||||
mv "$defaults_conf.away" "$defaults_conf"
|
||||
|
||||
[[ ! -s $calls ]] || fail "installs without the Limine defaults are skipped" "$(cat "$calls")"
|
||||
pass "migration skips installs it does not apply to"
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
packaged_defaults="$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf"
|
||||
|
||||
grep -Fq 'KERNEL_CMDLINE[default]+=" initramfs_async=0"' "$packaged_defaults" ||
|
||||
fail "the packaged Limine defaults still unpack the initramfs synchronously"
|
||||
pass "packaged Limine defaults keep Plymouth alive at the LUKS prompt"
|
||||
@@ -6,7 +6,6 @@ source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
dns="$ROOT/bin/omarchy-dns"
|
||||
hardware_network="$ROOT/install/hardware/network.sh"
|
||||
migration="$ROOT/migrations/1782002156.sh"
|
||||
|
||||
! grep -F 'systemd-networkd' "$dns" >/dev/null || fail "omarchy-dns no longer restarts systemd-networkd"
|
||||
grep -F 'NetworkManager/conf.d/20-omarchy-dns.conf' "$dns" >/dev/null
|
||||
@@ -26,10 +25,3 @@ grep -F 'systemd-networkd.socket' "$hardware_network" >/dev/null
|
||||
grep -F '20-wlan.network' "$hardware_network" >/dev/null
|
||||
grep -F 'omarchy-networkd-retired' "$hardware_network" >/dev/null
|
||||
pass "hardware setup retires archinstall networkd state"
|
||||
|
||||
grep -F 'OMARCHY_UPGRADE_TO_QUATTRO_LIVE' "$migration" >/dev/null
|
||||
grep -F 'systemctl disable --now "$unit"' "$migration" >/dev/null
|
||||
grep -F 'systemctl stop systemd-networkd.service' "$migration" >/dev/null
|
||||
grep -F 'NetworkManager.service' "$migration" >/dev/null
|
||||
grep -F '20-wlan.network' "$migration" >/dev/null
|
||||
pass "migration repairs upgraded systems with networkd still active"
|
||||
@@ -1,131 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
migration="$ROOT/migrations/1786605598.sh"
|
||||
packaged_hooks="$ROOT/etc/mkinitcpio.conf.d/omarchy_hooks.conf"
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
stub_bin="$test_tmp/bin"
|
||||
calls="$test_tmp/calls.log"
|
||||
mkdir -p "$stub_bin"
|
||||
: >"$calls"
|
||||
|
||||
cat >"$stub_bin/omarchy-cmd-present" <<'SH'
|
||||
#!/bin/bash
|
||||
|
||||
(( ${LIMINE_MKINITCPIO_INSTALLED:-1} == 1 ))
|
||||
SH
|
||||
|
||||
cat >"$stub_bin/sudo" <<'SH'
|
||||
#!/bin/bash
|
||||
|
||||
printf 'sudo' >>"$TEST_LOG"
|
||||
printf '\t%s' "$@" >>"$TEST_LOG"
|
||||
printf '\n' >>"$TEST_LOG"
|
||||
"$@"
|
||||
SH
|
||||
|
||||
cat >"$stub_bin/limine-mkinitcpio" <<'SH'
|
||||
#!/bin/bash
|
||||
|
||||
echo 'limine-mkinitcpio' >>"$TEST_LOG"
|
||||
SH
|
||||
|
||||
chmod +x "$stub_bin"/*
|
||||
|
||||
hooks_conf="$test_tmp/omarchy_hooks.conf"
|
||||
nvidia_conf="$test_tmp/nvidia.conf"
|
||||
rebuild_marker="$test_tmp/rebuild-complete"
|
||||
|
||||
cp "$packaged_hooks" "$hooks_conf"
|
||||
echo 'MODULES+=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)' >"$nvidia_conf"
|
||||
|
||||
# Each argument is a PCI device as "vendor:class", in sysfs's own format.
|
||||
write_pci_devices() {
|
||||
rm -rf "$test_tmp/devices"
|
||||
mkdir -p "$test_tmp/devices"
|
||||
|
||||
local index=0
|
||||
local spec
|
||||
for spec in "$@"; do
|
||||
local slot
|
||||
slot=$(printf '0000:%02x:00.0' "$index")
|
||||
mkdir -p "$test_tmp/devices/$slot"
|
||||
printf '%s\n' "${spec%%:*}" >"$test_tmp/devices/$slot/vendor"
|
||||
printf '%s\n' "${spec##*:}" >"$test_tmp/devices/$slot/class"
|
||||
index=$((index + 1))
|
||||
done
|
||||
}
|
||||
|
||||
run_migration() {
|
||||
PATH="$stub_bin:$PATH" \
|
||||
TEST_LOG="$calls" \
|
||||
OMARCHY_MKINITCPIO_HOOKS_CONF="$hooks_conf" \
|
||||
OMARCHY_MKINITCPIO_NVIDIA_CONF="$nvidia_conf" \
|
||||
OMARCHY_KMS_REBUILD_MARKER="$rebuild_marker" \
|
||||
OMARCHY_PCI_DEVICES_PATH="$test_tmp/devices" \
|
||||
bash -euo pipefail "$migration" >/dev/null
|
||||
}
|
||||
|
||||
# NVIDIA-only machine with the proprietary driver: the packaged conditional
|
||||
# drops kms, so the stale initramfs must be rebuilt once.
|
||||
write_pci_devices 0x10de:0x030000
|
||||
run_migration
|
||||
|
||||
grep -Fxq 'limine-mkinitcpio' "$calls" ||
|
||||
fail "an NVIDIA-only machine rebuilds its initramfs"
|
||||
[[ -f $rebuild_marker ]] || fail "the rebuild records the machine-wide repair"
|
||||
pass "migration rebuilds the initramfs on an NVIDIA-only machine"
|
||||
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "a recorded rebuild is not repeated" "$(cat "$calls")"
|
||||
pass "migration is machine-idempotent across users"
|
||||
|
||||
rm -f "$rebuild_marker"
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
grep -Fxq 'limine-mkinitcpio' "$calls" ||
|
||||
fail "an interrupted rebuild is retried"
|
||||
pass "migration retries an interrupted rebuild"
|
||||
|
||||
# Hybrid machine: the conditional keeps kms, so the initramfs already matches.
|
||||
write_pci_devices 0x1002:0x030000 0x10de:0x030200
|
||||
rm -f "$rebuild_marker"
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "a hybrid machine is left alone" "$(cat "$calls")"
|
||||
[[ ! -e $rebuild_marker ]] || fail "an untouched machine is not marked as repaired"
|
||||
pass "migration skips a hybrid machine that keeps kms"
|
||||
|
||||
# A user-edited hooks conf predating the conditional (the packaged update sits
|
||||
# in a .pacnew) still carries kms unconditionally: nothing to rebuild for.
|
||||
write_pci_devices 0x10de:0x030000
|
||||
echo 'HOOKS=(base udev autodetect modconf kms block filesystems fsck)' >"$hooks_conf"
|
||||
: >"$calls"
|
||||
run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "a user-edited hooks conf is left alone" "$(cat "$calls")"
|
||||
pass "migration skips a hooks conf without the conditional"
|
||||
|
||||
cp "$packaged_hooks" "$hooks_conf"
|
||||
|
||||
: >"$calls"
|
||||
LIMINE_MKINITCPIO_INSTALLED=0 run_migration
|
||||
|
||||
[[ ! -s $calls ]] || fail "installs without limine-mkinitcpio are skipped" "$(cat "$calls")"
|
||||
|
||||
mv "$nvidia_conf" "$nvidia_conf.away"
|
||||
run_migration
|
||||
mv "$nvidia_conf.away" "$nvidia_conf"
|
||||
|
||||
[[ ! -s $calls ]] || fail "machines without the proprietary NVIDIA driver are skipped" "$(cat "$calls")"
|
||||
pass "migration skips installs it does not apply to"
|
||||
@@ -1,162 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
stub_bin="$test_tmp/bin"
|
||||
mkdir -p "$stub_bin"
|
||||
|
||||
cat >"$stub_bin/systemctl" <<'STUB'
|
||||
#!/bin/bash
|
||||
|
||||
printf '%s\n' "$*" >>"$SYSTEMCTL_CALLS"
|
||||
|
||||
case "$*" in
|
||||
'--user show-environment')
|
||||
[[ ${MANAGER_AVAILABLE:-true} == "true" ]]
|
||||
;;
|
||||
'--user daemon-reload')
|
||||
if [[ ${FAIL_SYSTEMCTL_ACTION:-} == "daemon-reload" ]]; then
|
||||
echo "reload failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
'--user show --property=ActiveState --value graphical-session.target')
|
||||
if [[ ${FAIL_SYSTEMCTL_ACTION:-} == "show-graphical" ]]; then
|
||||
echo "state lookup failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
printf '%s\n' "${GRAPHICAL_STATE:-inactive}"
|
||||
;;
|
||||
'--user show --property=ActiveState --value omarchy-sleep-lock.service')
|
||||
printf '%s\n' "${SLEEP_LOCK_STATE:-inactive}"
|
||||
;;
|
||||
'--user restart omarchy-sleep-lock.service')
|
||||
if [[ ${FAIL_SYSTEMCTL_ACTION:-} == "restart" ]]; then
|
||||
echo "restart failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
'--user stop omarchy-sleep-lock.service')
|
||||
if [[ ${FAIL_SYSTEMCTL_ACTION:-} == "stop" ]]; then
|
||||
echo "stop failed" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
'--user reset-failed omarchy-sleep-lock.service') ;;
|
||||
*) exit 1 ;;
|
||||
esac
|
||||
STUB
|
||||
chmod +x "$stub_bin/systemctl"
|
||||
|
||||
migration="$ROOT/migrations/1785608166.sh"
|
||||
|
||||
run_migration() {
|
||||
local home="$1" calls="$2"
|
||||
shift 2
|
||||
|
||||
mkdir -p "$home/run"
|
||||
HOME="$home" XDG_CONFIG_HOME="$home/.config" XDG_RUNTIME_DIR="$home/run" \
|
||||
SYSTEMCTL_CALLS="$calls" PATH="$stub_bin:$PATH" \
|
||||
"$@" bash -euo pipefail "$migration"
|
||||
}
|
||||
|
||||
active_home="$test_tmp/active-home"
|
||||
active_calls="$test_tmp/active-calls"
|
||||
mkdir -p "$active_home/.config/systemd/user"
|
||||
printf '%s\n' '[Service]' 'ExecStart=/usr/bin/omarchy-system-sleep-monitor' \
|
||||
>"$active_home/.config/systemd/user/omarchy-sleep-lock.service"
|
||||
|
||||
run_migration "$active_home" "$active_calls" \
|
||||
env GRAPHICAL_STATE=active SLEEP_LOCK_STATE=active >/dev/null
|
||||
|
||||
dropin="$active_home/.config/systemd/user/omarchy-sleep-lock.service.d/90-omarchy-session-environment.conf"
|
||||
grep -Fx 'After=dbus.socket wayland-session-waitenv.service' "$dropin" >/dev/null ||
|
||||
fail "sleep lock migration orders a retained unit after the session environment import"
|
||||
grep -Fx 'PartOf=graphical-session.target' "$dropin" >/dev/null ||
|
||||
fail "sleep lock migration ties a retained unit to the graphical session lifecycle"
|
||||
grep -Fx 'ConditionEnvironment=OMARCHY_PATH' "$dropin" >/dev/null ||
|
||||
fail "sleep lock migration gates a retained unit on the Omarchy path"
|
||||
grep -Fx 'ConditionEnvironment=WAYLAND_DISPLAY' "$dropin" >/dev/null ||
|
||||
fail "sleep lock migration gates a retained unit on the Wayland display"
|
||||
pass "sleep lock migration repairs retained full-unit overrides with a drop-in"
|
||||
|
||||
grep -Fx -- '--user daemon-reload' "$active_calls" >/dev/null ||
|
||||
fail "sleep lock migration reloads the live user manager"
|
||||
grep -Fx -- '--user reset-failed omarchy-sleep-lock.service' "$active_calls" >/dev/null ||
|
||||
fail "sleep lock migration cannot recover a start-limited monitor"
|
||||
grep -Fx -- '--user restart omarchy-sleep-lock.service' "$active_calls" >/dev/null ||
|
||||
fail "sleep lock migration leaves an active monitor with its inherited environment"
|
||||
grep -Fx -- '--user stop omarchy-sleep-lock.service' "$active_calls" >/dev/null &&
|
||||
fail "sleep lock migration stops the monitor inside an active graphical session"
|
||||
pass "sleep lock migration replaces the monitor inside an active graphical session"
|
||||
|
||||
inactive_home="$test_tmp/inactive-home"
|
||||
inactive_calls="$test_tmp/inactive-calls"
|
||||
mkdir -p "$inactive_home"
|
||||
|
||||
run_migration "$inactive_home" "$inactive_calls" \
|
||||
env GRAPHICAL_STATE=inactive >/dev/null
|
||||
|
||||
grep -Fx -- '--user stop omarchy-sleep-lock.service' "$inactive_calls" >/dev/null ||
|
||||
fail "sleep lock migration leaves a stale monitor running after logout"
|
||||
grep -Fx -- '--user restart omarchy-sleep-lock.service' "$inactive_calls" >/dev/null &&
|
||||
fail "sleep lock migration starts the monitor outside a graphical session"
|
||||
pass "sleep lock migration stops a monitor left behind after logout"
|
||||
|
||||
failed_calls="$test_tmp/failed-calls"
|
||||
if run_migration "$test_tmp/failed-home" "$failed_calls" \
|
||||
env GRAPHICAL_STATE=active SLEEP_LOCK_STATE=active FAIL_SYSTEMCTL_ACTION=restart \
|
||||
>"$test_tmp/failed-output" 2>&1; then
|
||||
fail "sleep lock migration marks a failed active-session repair complete"
|
||||
fi
|
||||
grep -F 'will be retried by omarchy-migrate' "$test_tmp/failed-output" >/dev/null ||
|
||||
fail "sleep lock migration does not explain that a failed repair remains pending"
|
||||
pass "sleep lock migration keeps an active-session repair failure retryable"
|
||||
|
||||
reload_failed_calls="$test_tmp/reload-failed-calls"
|
||||
if run_migration "$test_tmp/reload-failed-home" "$reload_failed_calls" \
|
||||
env FAIL_SYSTEMCTL_ACTION=daemon-reload >"$test_tmp/reload-failed-output" 2>&1; then
|
||||
fail "sleep lock migration ignores a failed user-manager reload"
|
||||
fi
|
||||
grep -F 'Could not reload the user service manager' "$test_tmp/reload-failed-output" >/dev/null ||
|
||||
fail "sleep lock migration does not report a failed user-manager reload"
|
||||
pass "sleep lock migration keeps a failed user-manager reload retryable"
|
||||
|
||||
stop_failed_calls="$test_tmp/stop-failed-calls"
|
||||
if run_migration "$test_tmp/stop-failed-home" "$stop_failed_calls" \
|
||||
env GRAPHICAL_STATE=inactive FAIL_SYSTEMCTL_ACTION=stop \
|
||||
>"$test_tmp/stop-failed-output" 2>&1; then
|
||||
fail "sleep lock migration ignores a stale monitor that could not be stopped"
|
||||
fi
|
||||
grep -F 'Could not stop stale omarchy-sleep-lock.service' "$test_tmp/stop-failed-output" >/dev/null ||
|
||||
fail "sleep lock migration does not report a stale monitor stop failure"
|
||||
pass "sleep lock migration keeps a stale-monitor stop failure retryable"
|
||||
|
||||
state_failed_calls="$test_tmp/state-failed-calls"
|
||||
if run_migration "$test_tmp/state-failed-home" "$state_failed_calls" \
|
||||
env FAIL_SYSTEMCTL_ACTION=show-graphical >"$test_tmp/state-failed-output" 2>&1; then
|
||||
fail "sleep lock migration ignores a failed session-state inspection"
|
||||
fi
|
||||
grep -F 'Could not inspect graphical-session.target' "$test_tmp/state-failed-output" >/dev/null ||
|
||||
fail "sleep lock migration does not report a failed session-state inspection"
|
||||
pass "sleep lock migration keeps an indeterminate session repair retryable"
|
||||
|
||||
deferred_home="$test_tmp/deferred-home"
|
||||
deferred_calls="$test_tmp/deferred-calls"
|
||||
mkdir -p "$deferred_home/.config/systemd/user"
|
||||
touch "$deferred_home/.config/systemd/user/omarchy-sleep-lock.service"
|
||||
|
||||
run_migration "$deferred_home" "$deferred_calls" \
|
||||
env MANAGER_AVAILABLE=false >/dev/null
|
||||
|
||||
[[ -f $deferred_home/.config/systemd/user/omarchy-sleep-lock.service.d/90-omarchy-session-environment.conf ]] ||
|
||||
fail "sleep lock migration does not persist the repair without a live user manager"
|
||||
deferred_call_count=$(wc -l <"$deferred_calls")
|
||||
(( deferred_call_count == 1 )) ||
|
||||
fail "sleep lock migration tries to mutate a user manager that is not running"
|
||||
pass "sleep lock migration defers safely when no user manager is running"
|
||||
@@ -71,14 +71,6 @@ grep -Fx 'WantedBy=graphical-session.target' "$fcitx_service" >/dev/null ||
|
||||
grep -Fx 'ConditionEnvironment=WAYLAND_DISPLAY' "$fcitx_service" >/dev/null ||
|
||||
fail "an update over SSH has a live user manager and no display; starting fcitx5 there wedges the unit active-but-blind, and Wants= will not replace it at graphical login"
|
||||
|
||||
fcitx_migration="$ROOT/migrations/1785167800.sh"
|
||||
grep -F 'is-active --quiet graphical-session.target' "$fcitx_migration" >/dev/null ||
|
||||
fail "migration kills fcitx5 and starts the unit outside a graphical session"
|
||||
grep -F 'systemctl --user enable omarchy-fcitx5.service' "$fcitx_migration" >/dev/null ||
|
||||
fail "migration must enable without --now; --now starts the unit before the session-gate check"
|
||||
grep -F 'Could not start omarchy-fcitx5.service' "$fcitx_migration" >/dev/null ||
|
||||
fail "migration pkills a working fcitx5, so a failed handover must be reported instead of marked complete"
|
||||
|
||||
grep -F 'pkill -x fcitx5' "$ROOT/bin/omarchy-restart-xcompose" >/dev/null ||
|
||||
fail "restart-xcompose cannot reload a fcitx5 running outside the unit, so it silently keeps serving the old table"
|
||||
|
||||
@@ -111,10 +103,4 @@ pass "systemd-oomd acts on sustained memory stall"
|
||||
|
||||
grep -Fx 'systemctl enable systemd-oomd.service' "$ROOT/install/config/enable-services.sh" >/dev/null ||
|
||||
fail "new installs ship the oomd drop-ins with the daemon that reads them disabled"
|
||||
|
||||
oomd_migration=$(grep -rl 'systemd-oomd.service' "$ROOT/migrations" | head -n 1 || true)
|
||||
[[ -n $oomd_migration ]] ||
|
||||
fail "existing installs never enable systemd-oomd; enable-services.sh only runs at install time"
|
||||
grep -F 'systemctl --user daemon-reload' "$oomd_migration" >/dev/null ||
|
||||
fail "migration leaves the user manager unaware of app.slice candidacy until the next login"
|
||||
pass "existing installs enable systemd-oomd and report app.slice without a relogin"
|
||||
pass "new installs enable systemd-oomd"
|
||||
@@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
|
||||
|
||||
migration=$(grep -rl 'Make Shift+Enter distinguishable for terminals and Codex' "$ROOT/migrations" | head -n 1 || true)
|
||||
[[ -n $migration ]] || fail "terminal Shift+Enter migration exists"
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMPDIR"' EXIT
|
||||
|
||||
test_home="$TMPDIR/home"
|
||||
mkdir -p \
|
||||
"$test_home/.config/alacritty" \
|
||||
"$test_home/.config/foot" \
|
||||
"$test_home/.config/ghostty" \
|
||||
"$test_home/.config/kitty"
|
||||
|
||||
cp "$ROOT/config/alacritty/alacritty.toml" "$test_home/.config/alacritty/alacritty.toml"
|
||||
sed -i 's/\\u001B\[13;2u/\\u001B\\r/' "$test_home/.config/alacritty/alacritty.toml"
|
||||
|
||||
cp "$ROOT/config/kitty/kitty.conf" "$test_home/.config/kitty/kitty.conf"
|
||||
sed -i '/shift+enter/d' "$test_home/.config/kitty/kitty.conf"
|
||||
|
||||
cp "$ROOT/config/ghostty/config" "$test_home/.config/ghostty/config"
|
||||
sed -i '/shift+enter/d' "$test_home/.config/ghostty/config"
|
||||
|
||||
cp "$ROOT/config/foot/foot.ini" "$test_home/.config/foot/foot.ini"
|
||||
sed -i '/text-bindings/,$d' "$test_home/.config/foot/foot.ini"
|
||||
|
||||
HOME="$test_home" bash "$migration" >/dev/null
|
||||
|
||||
grep -qxF '{ key = "Return", mods = "Shift", chars = "\u001B[13;2u" },' "$test_home/.config/alacritty/alacritty.toml" ||
|
||||
fail "migration updates Alacritty Shift+Return to CSI-u"
|
||||
pass "migration updates Alacritty Shift+Return to CSI-u"
|
||||
|
||||
grep -qxF 'map shift+enter send_text all \e[13;2u' "$test_home/.config/kitty/kitty.conf" ||
|
||||
fail "migration adds Kitty Shift+Enter CSI-u binding"
|
||||
grep -qxF 'map alt+shift+enter send_text all \e[13;4u' "$test_home/.config/kitty/kitty.conf" ||
|
||||
fail "migration adds Kitty Alt+Shift+Enter CSI-u binding"
|
||||
pass "migration adds Kitty CSI-u bindings"
|
||||
|
||||
grep -qxF 'keybind = shift+enter=csi:13;2u' "$test_home/.config/ghostty/config" ||
|
||||
fail "migration adds Ghostty Shift+Enter CSI-u binding"
|
||||
grep -qxF 'keybind = alt+shift+enter=csi:13;4u' "$test_home/.config/ghostty/config" ||
|
||||
fail "migration adds Ghostty Alt+Shift+Enter CSI-u binding"
|
||||
pass "migration adds Ghostty CSI-u bindings"
|
||||
|
||||
grep -qxF '\x1b[13;2u=Shift+Return' "$test_home/.config/foot/foot.ini" ||
|
||||
fail "migration adds Foot Shift+Return CSI-u binding"
|
||||
grep -qxF '\x1b[13;4u=Mod1+Shift+Return' "$test_home/.config/foot/foot.ini" ||
|
||||
fail "migration adds Foot Alt+Shift+Return CSI-u binding"
|
||||
pass "migration adds Foot CSI-u bindings"
|
||||
|
||||
before=$(find "$test_home/.config" -type f -print0 | sort -z | xargs -0 sha256sum)
|
||||
HOME="$test_home" bash "$migration" >/dev/null
|
||||
after=$(find "$test_home/.config" -type f -print0 | sort -z | xargs -0 sha256sum)
|
||||
|
||||
[[ $before == "$after" ]] || fail "terminal Shift+Enter migration is idempotent"
|
||||
pass "terminal Shift+Enter migration is idempotent"
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/base-test.sh"
|
||||
|
||||
migration=$(grep -rl 'Move zram tuning to a vendor drop-in' "$ROOT/migrations" | head -n 1 || true)
|
||||
[[ -n $migration ]] || fail "zram drop-in migration exists"
|
||||
|
||||
TMPDIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMPDIR"' EXIT
|
||||
|
||||
# The migration shells out to pacman (ownership check) and sudo (removal).
|
||||
# Stub both so the test never touches the real system, and let each case pick
|
||||
# what `pacman -Qo` reports through PACMAN_OWNS.
|
||||
stub_bin="$TMPDIR/bin"
|
||||
mkdir -p "$stub_bin"
|
||||
|
||||
cat >"$stub_bin/pacman" <<'STUB'
|
||||
#!/bin/bash
|
||||
[[ ${PACMAN_OWNS:-0} == 1 ]]
|
||||
STUB
|
||||
|
||||
cat >"$stub_bin/sudo" <<'STUB'
|
||||
#!/bin/bash
|
||||
exec "$@"
|
||||
STUB
|
||||
|
||||
chmod +x "$stub_bin/pacman" "$stub_bin/sudo"
|
||||
|
||||
# The migration removes the /etc copy only once the drop-in that replaces it is
|
||||
# installed. Point that at a fixture so the result does not depend on whether
|
||||
# the machine running the tests happens to carry the real one.
|
||||
dropin="$TMPDIR/90-omarchy.conf"
|
||||
: >"$dropin"
|
||||
|
||||
# omarchy-migrate runs each migration with `bash -euo pipefail` and stops the
|
||||
# whole chain on a non-zero exit, so match that invocation exactly.
|
||||
run_migration() {
|
||||
local conf="$1"
|
||||
PATH="$stub_bin:$PATH" OMARCHY_ZRAM_CONF="$conf" OMARCHY_ZRAM_DROPIN="$dropin" \
|
||||
bash -euo pipefail "$migration" >/dev/null ||
|
||||
fail "migration exits clean for $(basename "$conf")"
|
||||
}
|
||||
|
||||
# archinstall's own output: a [zram0] section with nothing but the algorithm.
|
||||
conf="$TMPDIR/archinstall.conf"
|
||||
printf '[zram0]\ncompression-algorithm = zstd\n' >"$conf"
|
||||
run_migration "$conf"
|
||||
[[ -f $conf ]] && fail "migration removes archinstall's generated config"
|
||||
pass "migration removes archinstall's generated config"
|
||||
|
||||
# Same shape, different algorithm, plus comments and blank lines.
|
||||
conf="$TMPDIR/commented.conf"
|
||||
printf '# written by archinstall\n\n[zram0]\ncompression-algorithm = lz4\n\n' >"$conf"
|
||||
run_migration "$conf"
|
||||
[[ -f $conf ]] && fail "migration ignores comments and a non-zstd algorithm"
|
||||
pass "migration ignores comments and a non-zstd algorithm"
|
||||
|
||||
# A config that sets nothing decides nothing, and must not take the migration
|
||||
# chain down with it.
|
||||
conf="$TMPDIR/comments-only.conf"
|
||||
printf '# nothing to see here\n\n' >"$conf"
|
||||
run_migration "$conf"
|
||||
[[ -f $conf ]] && fail "migration removes a config that sets nothing"
|
||||
pass "migration removes a config that sets nothing"
|
||||
|
||||
conf="$TMPDIR/empty.conf"
|
||||
: >"$conf"
|
||||
run_migration "$conf"
|
||||
[[ -f $conf ]] && fail "migration removes an empty config"
|
||||
pass "migration removes an empty config"
|
||||
|
||||
# A local override must survive.
|
||||
conf="$TMPDIR/local.conf"
|
||||
printf '[zram0]\ncompression-algorithm = zstd\nzram-size = ram / 4\n' >"$conf"
|
||||
run_migration "$conf"
|
||||
[[ -f $conf ]] || fail "migration keeps a locally edited config"
|
||||
pass "migration keeps a locally edited config"
|
||||
|
||||
# Package-owned copies go away with their package; the migration must not touch
|
||||
# them.
|
||||
conf="$TMPDIR/owned.conf"
|
||||
printf '[zram0]\ncompression-algorithm = zstd\n' >"$conf"
|
||||
PATH="$stub_bin:$PATH" PACMAN_OWNS=1 OMARCHY_ZRAM_CONF="$conf" OMARCHY_ZRAM_DROPIN="$dropin" \
|
||||
bash -euo pipefail "$migration" >/dev/null ||
|
||||
fail "migration exits clean for a package-owned config"
|
||||
[[ -f $conf ]] || fail "migration keeps a package-owned config"
|
||||
pass "migration keeps a package-owned config"
|
||||
|
||||
# Nothing to do, and running twice must stay clean.
|
||||
conf="$TMPDIR/absent.conf"
|
||||
run_migration "$conf"
|
||||
run_migration "$conf"
|
||||
pass "migration no-ops when the config is already gone"
|
||||
|
||||
# Without the drop-in installed, the /etc copy is the only thing configuring
|
||||
# zram at all. Removing it would leave the machine with no zram device, so the
|
||||
# migration has to leave it alone and stay clean doing it.
|
||||
conf="$TMPDIR/no-dropin.conf"
|
||||
printf '[zram0]\ncompression-algorithm = zstd\n' >"$conf"
|
||||
PATH="$stub_bin:$PATH" OMARCHY_ZRAM_CONF="$conf" OMARCHY_ZRAM_DROPIN="$TMPDIR/absent-dropin.conf" \
|
||||
bash -euo pipefail "$migration" >/dev/null ||
|
||||
fail "migration exits clean when the drop-in is missing"
|
||||
[[ -f $conf ]] || fail "migration keeps the config when the drop-in is missing"
|
||||
pass "migration keeps the config until the drop-in is installed"
|
||||
Reference in new issue
Block a user