SPS · log · files · refs · tags · releases · people · languages · GitHub · file
tests/test_setup.sh
15249 bytes at 2909919 · GitHub
#!/bin/sh
# setup: plan, answers, validation, and a fixture install.
set -eu
case $0 in */*) test_dir=${0%/*} ;; *) test_dir=. ;; esac
project_dir=$(CDPATH= cd "$test_dir/.." 2>/dev/null && pwd) || exit 1
fail() { printf 'test_setup: %s\n' "$*" >&2; exit 1; }
contains() { case $1 in *"$2"*) : ;; *) fail "expected output to contain '$2'" ;; esac; }
setup=$project_dir/bin/setup
export SPS_LIBDIR=$project_dir/lib
export PATH=$project_dir/bin:$PATH
tmp=$(mktemp -d "${TMPDIR:-/tmp}/sps-test-setup.XXXXXX") || fail mktemp
trap 'rm -rf "$tmp"' 0 HUP INT TERM
profiles=$("$setup" --list-profiles)
contains "$profiles" 'minimal'
contains "$profiles" 'plasma-desktop'
contains "$profiles" 'plasma-full'
contains "$profiles" 'server'
sets=$("$setup" --list-sets)
contains "$sets" 'printing'
contains "$sets" 'browsers'
contains "$sets" 'shells-extra'
contains "$sets" 'ssh'
contains "$sets" 'storage'
contains "$sets" 'wifi'
contains "$sets" 'firmware'
contains "$sets" 'bluetooth'
contains "$sets" 'drivers'
contains "$sets" 'flatpak'
plan=$("$setup" --plan --target /mnt --profile minimal --disable qol-cli --enable flatpak)
contains "$plan" 'flatpak'
contains "$plan" 'json-glib'
contains "$plan" 'libseccomp'
contains "$plan" 'gpgme'
contains "$plan" 'appstream'
plan=$("$setup" --plan --target /mnt --profile minimal --disable qol-cli)
contains "$plan" 'Profile: minimal'
contains "$plan" 'base-system'
contains "$plan" 'splux-base'
contains "$plan" 'fastfetch'
contains "$plan" 'Init: none'
plan=$("$setup" --plan --target /mnt --profile minimal --init systemd --disable qol-cli)
contains "$plan" 'Init: systemd'
contains "$plan" 'init-systemd'
plan=$("$setup" --plan --target /mnt --profile minimal --init openrc --disable qol-cli)
contains "$plan" 'Init: openrc'
contains "$plan" 'init-openrc'
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --user alex \
--hostname darkstar --timezone UTC --keymap us --nvidia yes \
--locale en_US.UTF-8 --shell /bin/bash --extra neovim,htop \
--ssh yes --printing yes)
contains "$plan" 'Hostname: darkstar'
contains "$plan" 'User: alex'
contains "$plan" 'Locale: en_US.UTF-8'
contains "$plan" 'Shell: /bin/bash'
contains "$plan" 'plasma-desktop'
contains "$plan" 'nvidia-open'
contains "$plan" 'qol-cli'
contains "$plan" 'neovim'
contains "$plan" 'htop'
contains "$plan" 'openssh'
contains "$plan" 'cups'
"$setup" --plan --target /mnt --profile server \
--write-answers "$tmp/answers" >/dev/null
grep -qx 'profile server' "$tmp/answers" || fail 'answers missing profile'
grep -qx 'target /mnt' "$tmp/answers" || fail 'answers missing target'
plan=$("$setup" --plan --read-answers "$tmp/answers" --hostname other)
contains "$plan" 'Hostname: other'
contains "$plan" 'Profile: server'
set +e
"$setup" --plan --target /mnt --profile no-such-profile >/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 3 ] || fail "unknown profile returned $st"
contains "$(cat "$tmp/err")" 'unknown profile'
set +e
"$setup" --plan --target mnt --profile minimal >/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 2 ] || fail "relative target returned $st"
set +e
"$setup" --plan --target /mnt --profile minimal --hostname 'bad host' \
>/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 2 ] || fail "bad hostname returned $st"
# Fixture profile install into a disposable root.
export SPS_SETUP_DIR=$project_dir/tests/setup-fixture
root=$tmp/root
db=$tmp/db
cache=$tmp/cache
build=$tmp/build
repo=$tmp/repo
mkdir -p "$root" "$db" "$cache" "$build" "$repo/hello" "$repo/extra-pkg"
mkdir -p "$tmp/nolive-fixture"
: >"$tmp/sps.conf"
printf 'dir test %s 10\n' "$repo" >"$tmp/repos.conf"
export SPS_ROOT=$root SPS_DB=$db SPS_CACHE=$cache SPS_BUILD=$build
export SPS_CONFIG=$tmp/sps.conf SPS_REPOS_CONFIG=$tmp/repos.conf
export SPS_LIVE_ROOT=$tmp/nolive-fixture
cat >"$repo/hello/recipe" <<'EOF'
name hello
version 1.0
release 1
arch any
description fixture hello
install mkdir -p "$PKG/usr/share/sps-test"
install printf '%s\n' hello >"$PKG/usr/share/sps-test/hello"
EOF
cat >"$repo/extra-pkg/recipe" <<'EOF'
name extra-pkg
version 1.0
release 1
arch any
description fixture extra
install mkdir -p "$PKG/usr/share/sps-test"
install printf '%s\n' extra >"$PKG/usr/share/sps-test/extra"
EOF
src update >/dev/null
"$setup" --non-interactive --no-update --target "$root" --profile tiny \
--hostname fixture --timezone UTC --keymap us --user tester \
--enable extra --user-gecos 'Test User' >/dev/null
[ "$(cat "$root/usr/share/sps-test/hello")" = hello ] || fail 'hello missing'
[ "$(cat "$root/usr/share/sps-test/extra")" = extra ] || fail 'extra missing'
[ "$(cat "$root/etc/hostname")" = fixture ] || fail 'hostname not written'
[ "$(cat "$root/etc/locale.conf")" = 'LANG=C.UTF-8' ] || fail 'locale not written'
grep -q '^tester:x:1000:1000:Test User:/home/tester:/bin/sh$' \
"$root/etc/passwd" || fail 'user not recorded'
awk -F: '$1=="tester" && $2=="!" { found=1 } END { exit !found }' \
"$root/etc/shadow" || fail 'user without password flags must stay locked'
awk -F: '$1=="root" && $2=="!" { found=1 } END { exit !found }' \
"$root/etc/shadow" || fail 'root without password flags must stay locked'
if grep -q 'password-hash' "$root/etc/sps/setup-answers"; then
fail 'setup-answers must not store password hashes'
fi
[ -f "$root/etc/sps/setup-answers" ] || fail 'setup-answers missing'
[ -f "$root/root/sps-bootloader.txt" ] || fail 'bootloader notes missing'
[ -f "$root/root/sps-network.txt" ] || fail 'network notes missing'
[ -f "$root/root/sps-fstab.txt" ] || fail 'fstab notes missing'
[ -f "$root/root/sps-services.txt" ] || fail 'services notes missing'
grep -q 'Init is none' "$root/root/sps-services.txt" ||
fail 'fixture with init none should not pretend to enable services'
grep -q 'grub-install' "$root/root/sps-bootloader.txt" ||
fail 'bootloader notes omitted grub-install warning'
printf '%s\n' 'test-user-pw' >"$tmp/user.pw"
printf '%s\n' 'test-root-pw' >"$tmp/root.pw"
chmod 600 "$tmp/user.pw" "$tmp/root.pw"
root_pw=$tmp/root-pw
mkdir -p "$root_pw"
"$setup" --non-interactive --no-update --target "$root_pw" --profile tiny \
--hostname pwtest --timezone UTC --keymap us --user tester \
--enable extra --user-gecos 'PW User' \
--user-password-file "$tmp/user.pw" \
--root-password-file "$tmp/root.pw" >/dev/null
awk -F: '$1=="tester" && $2!="" && $2!="!" && $2!="*" { found=1 }
END { exit !found }' "$root_pw/etc/shadow" ||
fail 'user password file did not update shadow'
awk -F: '$1=="root" && $2!="" && $2!="!" && $2!="*" { found=1 }
END { exit !found }' "$root_pw/etc/shadow" ||
fail 'root password file did not update shadow'
if grep -q 'password-hash' "$root_pw/etc/sps/setup-answers"; then
fail 'setup-answers must not store password hashes'
fi
grep -q 'wheel:.*tester' "$root_pw/etc/group" ||
fail 'first user should be in wheel when that group exists'
printf '%s\n' 'setup fixture tests passed'
# Bundled live recipes: index them in place offline during setup, but the
# installed machine re-points at the official Git repositories.
live=$tmp/live
mkdir -p "$live/usr/src/sps/core/hello" "$live/usr/src/sps/extra/placeholder"
cat >"$live/usr/src/sps/core/hello/recipe" <<'EOF'
name hello
version 1.0
release 1
arch any
description bundled hello
install mkdir -p "$PKG/usr/share/sps-test"
install printf '%s\n' bundled >"$PKG/usr/share/sps-test/hello"
EOF
cat >"$live/usr/src/sps/extra/placeholder/recipe" <<'EOF'
name placeholder
version 1.0
release 1
arch any
description bundled extra placeholder
install true
EOF
root_seed=$tmp/root-seed
db_seed=$tmp/db-seed
cache_seed=$tmp/cache-seed
build_seed=$tmp/build-seed
mkdir -p "$root_seed" "$db_seed" "$cache_seed" "$build_seed"
(
unset SPS_ROOT SPS_DB SPS_CACHE SPS_BUILD SPS_CONFIG SPS_REPOS_CONFIG
export SPS_LIVE_ROOT=$live
export SPS_SETUP_DIR=$project_dir/tests/setup-fixture
export SPS_LIBDIR=$project_dir/lib
export PATH=$project_dir/bin:$PATH
"$setup" --non-interactive --target "$root_seed" --profile tiny \
--hostname seeded --timezone UTC --keymap us --user tester \
--user-gecos 'Seed User'
) || fail 'bundled-recipe setup failed'
[ "$(cat "$root_seed/usr/share/sps-test/hello")" = bundled ] ||
fail 'bundled hello was not installed'
if grep -E '^[[:space:]]*dir (core|extra) ' "$root_seed/etc/sps/repos.conf" >/dev/null; then
fail 'installed repos.conf must not keep bundled trees as dir repos'
fi
grep -qx 'git core https://github.com/RobertFlexx/sps-core.git 100' \
"$root_seed/etc/sps/repos.conf" ||
fail 'installed repos.conf must track git core by default'
grep -qx 'git extra https://github.com/RobertFlexx/sps-extra.git 80' \
"$root_seed/etc/sps/repos.conf" ||
fail 'installed repos.conf must track git extra by default'
grep -F 'sps-community.git' "$root_seed/etc/sps/repos.conf" >/dev/null ||
fail 'installed repos.conf must document opt-in community'
if grep -E '^[[:space:]]*git community ' "$root_seed/etc/sps/repos.conf" >/dev/null; then
fail 'setup must not enable community'
fi
# No bundled trees: repos.conf is git clones, and --no-update must not
# require the network.
nolive=$tmp/nolive
mkdir -p "$nolive"
root_git=$tmp/root-git
mkdir -p "$root_git"
(
unset SPS_ROOT SPS_DB SPS_CACHE SPS_BUILD SPS_CONFIG SPS_REPOS_CONFIG
export SPS_LIVE_ROOT=$nolive
export SPS_SETUP_DIR=$project_dir/tests/setup-fixture
export SPS_LIBDIR=$project_dir/lib
export PATH=$project_dir/bin:$PATH
export SPS_ROOT=$root SPS_DB=$db SPS_CACHE=$cache SPS_BUILD=$build
export SPS_CONFIG=$tmp/sps.conf SPS_REPOS_CONFIG=$tmp/repos.conf
"$setup" --non-interactive --no-update --target "$root_git" \
--profile tiny --hostname gitfallback --timezone UTC \
--keymap us --user tester
) || fail 'git-fallback --no-update setup failed'
grep -q 'git core https://github.com/RobertFlexx/sps-core.git' \
"$root_git/etc/sps/repos.conf" ||
fail 'empty live root should write git core'
grep -q 'git extra https://github.com/RobertFlexx/sps-extra.git' \
"$root_git/etc/sps/repos.conf" ||
fail 'empty live root should write git extra'
if grep -E '^[[:space:]]*git community ' "$root_git/etc/sps/repos.conf" >/dev/null; then
fail 'git-fallback setup must not enable community'
fi
grep -F 'sps-community.git' "$root_git/etc/sps/repos.conf" >/dev/null ||
fail 'git-fallback repos.conf must document opt-in community'
# Later plans use the real profiles, not the fixture directory.
unset SPS_SETUP_DIR
# Guided layouts: --plan does not need --format yes; a real run does.
plan=$("$setup" --plan --target /mnt --profile minimal --disable qol-cli \
--partition efi-root --disk /dev/vda)
contains "$plan" 'Partition: efi-root'
contains "$plan" 'Format: no'
contains "$plan" 'Disk: /dev/vda'
plan=$("$setup" --plan --target /mnt --profile minimal --disable qol-cli \
--partition efi-root --disk /dev/vda --format yes)
contains "$plan" 'Format: yes'
set +e
"$setup" --plan --target /mnt --profile minimal --disable qol-cli \
--install-bootloader >/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 2 ] || fail "--install-bootloader without --disk returned $st"
contains "$(cat "$tmp/err")" '--disk'
grep -q -- '--removable' "$setup" ||
fail 'EFI grub-install must write EFI/BOOT/BOOTX64.EFI'
grep -q -- '--no-nvram' "$setup" ||
fail 'EFI removable grub-install must not require firmware NVRAM'
grep -q efibootmgr "$setup" ||
fail 'EFI grub-install must use efibootmgr when it is on PATH'
set +e
"$setup" --non-interactive --no-update --target "$tmp/noformat" \
--profile minimal --disable qol-cli --partition efi-root --disk /dev/vda \
>/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 2 ] || fail "guided without --format yes returned $st"
contains "$(cat "$tmp/err")" '--format yes'
grep -q 'remount,rw,exec' "$project_dir/lib/setup/partition.sh" ||
fail 'setup must remount the target exec so autoconf can run conftest'
grep -q 'live gcc cannot create executables' "$setup" ||
fail 'setup must probe live gcc before sget install'
grep -q 'live meson cannot run' "$setup" ||
fail 'setup must probe live meson before sget install'
grep -q sps_print_default_conf "$setup" ||
fail 'setup must write sps.conf before sget install'
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init systemd \
--disable qol-cli --disable power --disable firmware)
contains "$plan" 'Init: systemd'
contains "$plan" 'sddm'
contains "$plan" 'init-systemd'
contains "$plan" 'Services: yes'
case $plan in
*elogind*) fail 'plasma + systemd must not pull elogind' ;;
esac
# Power is on by default for Plasma. polkit must come from that set
# without naming elogind; sget resolves polkit's optional logind later.
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init systemd \
--disable qol-cli --disable firmware)
contains "$plan" 'polkit'
contains "$plan" 'init-systemd'
case $plan in
*elogind*) fail 'plasma + systemd + power must not list elogind' ;;
esac
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init openrc \
--disable qol-cli)
contains "$plan" 'init-openrc'
plan=$("$setup" --plan --target /mnt --profile minimal --init s6 --disable qol-cli)
contains "$plan" 'Init: s6'
contains "$plan" 'init-s6'
plan=$("$setup" --plan --target /mnt --profile minimal --init runit --disable qol-cli)
contains "$plan" 'init-runit'
plan=$("$setup" --plan --target /mnt --profile minimal --init dinit --disable qol-cli)
contains "$plan" 'init-dinit'
plan=$("$setup" --plan --target /mnt --profile minimal --init shepherd --disable qol-cli)
contains "$plan" 'init-shepherd'
plan=$("$setup" --plan --target /mnt --profile minimal --init sysvinit --disable qol-cli)
contains "$plan" 'Init: sysvinit'
contains "$plan" 'init-sysvinit'
set +e
"$setup" --plan --target /mnt --profile minimal --init systemd \
--disable qol-cli --extra elogind >/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 7 ] || fail "systemd + extra elogind returned $st"
contains "$(cat "$tmp/err")" 'elogind'
set +e
"$setup" --plan --target /mnt --profile minimal --init systemd \
--disable qol-cli --extra s6 >/dev/null 2>"$tmp/err"
st=$?
set -e
[ "$st" -eq 7 ] || fail "systemd + extra s6 returned $st"
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init s6 \
--disable qol-cli --disable firmware)
contains "$plan" 'init-s6'
case $plan in
*init-systemd*) fail 'plasma + s6 must not pull init-systemd' ;;
esac
plan=$("$setup" --plan --target /mnt --profile plasma-desktop --init sysvinit \
--disable qol-cli --disable firmware)
contains "$plan" 'init-sysvinit'
case $plan in
*init-systemd*) fail 'plasma + sysvinit must not pull init-systemd' ;;
esac
plan=$("$setup" --plan --target /mnt --profile minimal --init systemd \
--disable qol-cli --extra sddm --services no)
contains "$plan" 'sddm'
contains "$plan" 'Services: no'
"$setup" --plan --target /mnt --profile minimal --disable qol-cli \
--write-answers "$tmp/svc-answers" >/dev/null
grep -qx 'services yes' "$tmp/svc-answers" || fail 'answers missing services'
grep -qx 'install-bootloader no' "$tmp/svc-answers" ||
fail 'answers missing install-bootloader'
printf '%s\n' 'setup tests passed'