@@ -52,33 +52,168 @@ jobs:
5252
5353 - name : User tests
5454 if : github.event_name != 'pull_request'
55+ shell : bash
5556 run : |
56- echo "=== Alpine Linux (3.24.1) - BEGIN"
57- ./proot-distro.py install -n alpine-3.24.1 alpine:3.24.1
58- ./proot-distro.py login alpine-3.24.1 -- cat /etc/os-release
59- ./proot-distro.py login alpine-3.24.1 -- apk update
60- ./proot-distro.py rename alpine-3.24.1 alpine-3.24.1-renamed
61- ./proot-distro.py backup -o /tmp/alpine.tar.gz alpine-3.24.1-renamed
62- ./proot-distro.py restore /tmp/alpine.tar.gz
63- ./proot-distro.py rm alpine-3.24.1-renamed
64- echo "=== Alpine Linux (3.24.1) - FINISH"
65-
66- echo "=== Debian (trixie) - BEGIN"
67- ./proot-distro.py install -n debian-trixie debian:trixie
68- ./proot-distro.py login debian-trixie -- cat /etc/os-release
69- ./proot-distro.py login debian-trixie -- apt update
70- ./proot-distro.py rename debian-trixie debian-trixie-renamed
71- ./proot-distro.py backup -o /tmp/debian.tar.gz debian-trixie-renamed
72- ./proot-distro.py restore /tmp/debian.tar.gz
73- ./proot-distro.py rm debian-trixie-renamed
74- echo "=== Debian (trixie) - FINISH"
75-
76- echo "=== Ubuntu (24.04) - BEGIN"
77- ./proot-distro.py install -n ubuntu-24.04 ubuntu:24.04
78- ./proot-distro.py login ubuntu-24.04 -- cat /etc/os-release
79- ./proot-distro.py login ubuntu-24.04 -- apt update
80- ./proot-distro.py rename ubuntu-24.04 ubuntu-24.04-renamed
81- ./proot-distro.py backup -o /tmp/ubuntu.tar.gz ubuntu-24.04-renamed
82- ./proot-distro.py restore /tmp/ubuntu.tar.gz
83- ./proot-distro.py rm ubuntu-24.04-renamed
84- echo "=== Ubuntu (24.04) - FINISH"
57+ set -Eeuo pipefail
58+
59+ PD=(./proot-distro.py)
60+ WORKDIR="$(mktemp -d)"
61+ export XDG_DATA_HOME="${WORKDIR}/data"
62+ export XDG_CACHE_HOME="${WORKDIR}/cache"
63+
64+ cleanup() {
65+ set +e
66+ "${PD[@]}" kill --all
67+ for name in \
68+ alpine-work alpine-restored alpine-built \
69+ debian-work debian-restored \
70+ ubuntu-work ubuntu-restored
71+ do
72+ "${PD[@]}" rm -q "${name}"
73+ done
74+ rm -rf "${WORKDIR}"
75+ }
76+ trap cleanup EXIT
77+
78+ pd() {
79+ "${PD[@]}" "$@"
80+ }
81+
82+ assert_contains() {
83+ local haystack="$1"
84+ local needle="$2"
85+ if [[ "${haystack}" != *"${needle}"* ]]; then
86+ echo "Expected output to contain: ${needle}" >&2
87+ echo "Actual output:" >&2
88+ printf '%s\n' "${haystack}" >&2
89+ return 1
90+ fi
91+ }
92+
93+ assert_file_contains() {
94+ local file="$1"
95+ local needle="$2"
96+ grep -Fq "${needle}" "${file}"
97+ }
98+
99+ assert_container_listed() {
100+ local name="$1"
101+ pd list -q | grep -Fx "${name}"
102+ }
103+
104+ echo "::group::Alpine Linux (3.24.1)"
105+ pd install -n alpine-work alpine:3.24.1
106+ assert_container_listed alpine-work
107+ assert_contains "$(pd login alpine-work -- cat /etc/os-release)" "ID=alpine"
108+ pd login alpine-work -- apk update
109+ pd login alpine-work -- apk add --no-cache ca-certificates curl
110+ assert_contains "$(pd login alpine-work -- curl --version)" "curl"
111+
112+ mkdir -p "${WORKDIR}/host-src/subdir"
113+ printf 'from-host\n' > "${WORKDIR}/host-src/subdir/message.txt"
114+ ln -s subdir/message.txt "${WORKDIR}/host-src/message-link"
115+ pd sync --checksum --delete "${WORKDIR}/host-src" alpine-work:/opt/fixture
116+ assert_contains "$(pd login alpine-work -- cat /opt/fixture/subdir/message.txt)" "from-host"
117+ assert_contains "$(pd login alpine-work -- readlink /opt/fixture/message-link)" "subdir/message.txt"
118+
119+ printf 'replacement\n' > "${WORKDIR}/host-src/subdir/message.txt"
120+ mkdir -p "${WORKDIR}/host-src/extra"
121+ printf 'keep\n' > "${WORKDIR}/host-src/extra/keep.txt"
122+ pd login alpine-work -- sh -c 'mkdir -p /opt/fixture/stale && echo stale > /opt/fixture/stale/remove-me'
123+ pd sync --checksum --delete "${WORKDIR}/host-src" alpine-work:/opt/fixture
124+ assert_contains "$(pd login alpine-work -- cat /opt/fixture/subdir/message.txt)" "replacement"
125+ if pd login alpine-work -- test -e /opt/fixture/stale/remove-me; then
126+ echo "sync --delete left stale data in the container" >&2
127+ exit 1
128+ fi
129+
130+ pd copy alpine-work:/opt/fixture/subdir/message.txt "${WORKDIR}/copied-from-alpine.txt"
131+ assert_file_contains "${WORKDIR}/copied-from-alpine.txt" "replacement"
132+ pd login alpine-work -- sh -c 'mkdir -p /tmp/move-src && echo moved > /tmp/move-src/file.txt'
133+ pd copy --move alpine-work:/tmp/move-src/file.txt alpine-work:/tmp/moved-file.txt
134+ assert_contains "$(pd login alpine-work -- cat /tmp/moved-file.txt)" "moved"
135+ if pd login alpine-work -- test -e /tmp/move-src/file.txt; then
136+ echo "copy --move left the source file behind" >&2
137+ exit 1
138+ fi
139+
140+ assert_contains "$(pd login alpine-work --env PD_USER_TEST=ok --work-dir /opt/fixture --bind "${WORKDIR}:/host-fixture" -- sh -c 'printf "%s:%s:%s" "$PD_USER_TEST" "$PWD" "$(cat /host-fixture/copied-from-alpine.txt)"')" "ok:/opt/fixture:replacement"
141+
142+ pd login alpine-work --detach -- sh -c 'while :; do sleep 1; done'
143+ sleep 2
144+ assert_contains "$(pd ps)" "alpine-work"
145+ test -n "$(pd ps -q)"
146+ pd kill alpine-work
147+ sleep 1
148+ if [[ -n "$(pd ps -q)" ]]; then
149+ echo "detached session was still active after kill" >&2
150+ pd ps
151+ exit 1
152+ fi
153+
154+ cat > "${WORKDIR}/host-src/Dockerfile" <<'EOF'
155+ FROM alpine:3.24.1
156+ COPY subdir/message.txt /usr/local/share/message.txt
157+ ENV BUILT_BY=proot-distro-user-tests
158+ WORKDIR /usr/local/share
159+ CMD ["/bin/sh", "-c", "printf '%s:%s:%s\n' \"$BUILT_BY\" \"$PWD\" \"$(cat message.txt)\""]
160+ EOF
161+ pd build -t user-tests/alpine-built:1 --install-as alpine-built "${WORKDIR}/host-src"
162+ assert_contains "$(pd run alpine-built)" "proot-distro-user-tests:/usr/local/share:replacement"
163+
164+ pd rename alpine-work alpine-restored
165+ pd backup -o "${WORKDIR}/alpine-restored.tar.gz" alpine-restored
166+ pd rm alpine-restored
167+ pd restore "${WORKDIR}/alpine-restored.tar.gz"
168+ assert_container_listed alpine-restored
169+ assert_contains "$(pd login alpine-restored -- cat /opt/fixture/subdir/message.txt)" "replacement"
170+ pd reset alpine-restored
171+ assert_contains "$(pd login alpine-restored -- cat /etc/os-release)" "ID=alpine"
172+ if pd login alpine-restored -- test -e /opt/fixture/subdir/message.txt; then
173+ echo "reset did not clear container-local data" >&2
174+ exit 1
175+ fi
176+ echo "::endgroup::"
177+
178+ echo "::group::Debian (trixie)"
179+ pd install -n debian-work debian:trixie
180+ assert_container_listed debian-work
181+ assert_contains "$(pd login debian-work -- cat /etc/os-release)" "ID=debian"
182+ pd login debian-work -- apt update
183+ pd login debian-work -- sh -c 'apt install -y --no-install-recommends ca-certificates file && rm -rf /var/lib/apt/lists/*'
184+ assert_contains "$(pd login debian-work -- file /bin/sh)" "symbolic link"
185+ pd login debian-work -- sh -c 'mkdir -p /srv/app && printf debian-data > /srv/app/data.txt'
186+ pd copy -r debian-work:/srv/app "${WORKDIR}/debian-app"
187+ assert_file_contains "${WORKDIR}/debian-app/data.txt" "debian-data"
188+ pd rename debian-work debian-restored
189+ pd backup -o "${WORKDIR}/debian-restored.tar.xz" debian-restored
190+ pd rm debian-restored
191+ pd restore "${WORKDIR}/debian-restored.tar.xz"
192+ assert_contains "$(pd login debian-restored -- cat /srv/app/data.txt)" "debian-data"
193+ echo "::endgroup::"
194+
195+ echo "::group::Ubuntu (24.04)"
196+ pd install -n ubuntu-work ubuntu:24.04
197+ assert_container_listed ubuntu-work
198+ assert_contains "$(pd login ubuntu-work -- cat /etc/os-release)" "ID=ubuntu"
199+ pd login ubuntu-work -- apt update
200+ pd login ubuntu-work -- sh -c 'apt install -y --no-install-recommends adduser && rm -rf /var/lib/apt/lists/*'
201+ pd login ubuntu-work -- sh -c 'useradd -m -s /bin/sh ciuser && echo user-data > /home/ciuser/data.txt && chown ciuser:ciuser /home/ciuser/data.txt'
202+ assert_contains "$(pd login ubuntu-work --user ciuser -- sh -c 'printf "%s:%s:%s" "$USER" "$HOME" "$(cat ~/data.txt)"')" "ciuser:/home/ciuser:user-data"
203+ pd login ubuntu-work -- sh -c 'mkdir -p /var/tmp/sync-src && echo before > /var/tmp/sync-src/value.txt'
204+ pd sync ubuntu-work:/var/tmp/sync-src "${WORKDIR}/ubuntu-sync"
205+ assert_file_contains "${WORKDIR}/ubuntu-sync/value.txt" "before"
206+ pd rename ubuntu-work ubuntu-restored
207+ pd backup -o "${WORKDIR}/ubuntu-restored.tar.gz" ubuntu-restored
208+ pd rm ubuntu-restored
209+ pd restore "${WORKDIR}/ubuntu-restored.tar.gz"
210+ assert_contains "$(pd login ubuntu-restored --user ciuser -- cat /home/ciuser/data.txt)" "user-data"
211+ echo "::endgroup::"
212+
213+ echo "::group::Cleanup and cache"
214+ pd rm alpine-restored
215+ pd rm alpine-built
216+ pd rm debian-restored
217+ pd rm ubuntu-restored
218+ pd clear-cache
219+ echo "::endgroup::"
0 commit comments