test: cover DOKKU_LIB_HOST_ROOT storage mounts in bats

Add a Dokku-in-Docker bats suite that writes under DOKKU_LIB_HOST_ROOT and
checks storage:exec, set those env vars in the docker CI container, and add
unit bats for the bare-metal (unset) and rewritten docker-args paths.
This commit is contained in:
Jose Diaz-Gonzalez
2026-10-11 04:19:47 -04:00
parent cbde55a4a0
commit f768eb6d07
4 changed files with 176 additions and 1 deletions

View File

@@ -336,7 +336,11 @@ tests-ci-retry-failed:
tar xzf /tmp/bats-retry.tgz -C /usr/local/bin
bats-retry --execute test-results/bats
test-ci-docker: setup-docker-deploy-tests deploy-test-checks-root deploy-test-config deploy-test-multi deploy-test-go-fail-predeploy deploy-test-go-fail-postdeploy test-ci-binaries
deploy-test-storage-lib-host-root:
@echo deploy-test-storage-lib-host-root
cd tests/docker && bats storage.bats
test-ci-docker: setup-docker-deploy-tests deploy-test-checks-root deploy-test-config deploy-test-multi deploy-test-go-fail-predeploy deploy-test-go-fail-postdeploy deploy-test-storage-lib-host-root test-ci-binaries
generate-ssl-tars: generate-ssl-tar generate-ssl-sans-tar generate-ssl-wildcard-tar

View File

@@ -123,8 +123,13 @@ build_dokku_docker_image() {
run_dokku_container() {
echo "=====> run_dokku_container on CIRCLE_NODE_INDEX: $CIRCLE_NODE_INDEX"
echo "redirect: https://github.com/dokku/dokku-redirect.git" | sudo tee /var/lib/dokku/plugin-list
# DOKKU_HOST_ROOT / DOKKU_LIB_HOST_ROOT match the install docs: the host
# mounts /var/lib/dokku at /mnt/dokku, and in-container /var/lib/dokku/{home,data}
# are symlinks into that volume.
docker run -d \
--env DOKKU_HOSTNAME=dokku.me \
--env DOKKU_HOST_ROOT=/var/lib/dokku/home/dokku \
--env DOKKU_LIB_HOST_ROOT=/var/lib/dokku/var/lib/dokku \
--name dokku \
--publish 3022:22 \
--publish 80:80 \

49
tests/docker/storage.bats Normal file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env bats
# Dokku-in-Docker coverage for DOKKU_LIB_HOST_ROOT. These tests talk to the
# `dokku` container started by tests/ci/setup.sh docker and read/write the
# host path that volume backs (/var/lib/dokku -> /mnt/dokku).
setup_file() {
if ! docker inspect dokku >/dev/null 2>&1; then
echo "dokku container is not running; skip docker storage tests" >&2
return 1
fi
DOKKU_LIB_HOST_ROOT="$(docker exec dokku bash -c 'echo -n "$DOKKU_LIB_HOST_ROOT"')"
if [[ -z "$DOKKU_LIB_HOST_ROOT" ]]; then
echo "DOKKU_LIB_HOST_ROOT is unset inside the dokku container" >&2
return 1
fi
export DOKKU_LIB_HOST_ROOT
}
setup() {
ENTRY_NAME="rdmtest-docker-hostroot-$$"
export ENTRY_NAME
}
teardown() {
docker exec dokku dokku storage:destroy "$ENTRY_NAME" --force >/dev/null 2>&1 || true
sudo rm -rf "${DOKKU_LIB_HOST_ROOT}/data/storage/${ENTRY_NAME}"
}
@test "(docker) storage:exec sees a file written under DOKKU_LIB_HOST_ROOT" {
run docker exec dokku dokku storage:create "$ENTRY_NAME" --chown root
echo "output: $output"
echo "status: $status"
[[ "$status" -eq 0 ]]
# storage:create mkdirs under DOKKU_LIB_ROOT inside the container, which is
# the same tree as DOKKU_LIB_HOST_ROOT on the host via the /mnt/dokku volume.
HOST_STORAGE_DIR="${DOKKU_LIB_HOST_ROOT}/data/storage/${ENTRY_NAME}"
[[ -d "$HOST_STORAGE_DIR" ]]
echo "Hello World!" | sudo tee "${HOST_STORAGE_DIR}/welcome.txt" >/dev/null
run docker exec dokku dokku storage:exec "$ENTRY_NAME" -- cat /data/welcome.txt
echo "output: $output"
echo "status: $status"
[[ "$status" -eq 0 ]]
[[ "$output" == *"Hello World!"* ]]
}

117
tests/unit/storage-5.bats Normal file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env bats
load test_helper
setup() {
global_setup
create_app
rm -rf "${DOKKU_LIB_ROOT}"/data/storage/rdmtest*
}
teardown() {
destroy_app
global_teardown
}
@test "(storage) without DOKKU_LIB_HOST_ROOT docker-args and storage:exec use DOKKU_LIB_ROOT" {
unset DOKKU_LIB_HOST_ROOT
run /bin/bash -c "dokku storage:create rdmtest-bare"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku storage:mount $TEST_APP rdmtest-bare --container-dir /data"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "echo '' | dokku plugin:trigger docker-args-process-deploy $TEST_APP herokuish latest web | grep -o -- '-v [^ ]*'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "-v ${DOKKU_LIB_ROOT}/data/storage/rdmtest-bare:/data"
run /bin/bash -c "docker pull alpine:3 >/dev/null"
assert_success
run /bin/bash -c "dokku storage:exec rdmtest-bare -- /bin/sh -c 'echo bare-metal > /data/marker && cat /data/marker'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "bare-metal"
run /bin/bash -c "cat ${DOKKU_LIB_ROOT}/data/storage/rdmtest-bare/marker"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "bare-metal"
run /bin/bash -c "dokku storage:unmount --all $TEST_APP"
assert_success
run /bin/bash -c "dokku storage:destroy rdmtest-bare --force"
assert_success
}
@test "(storage) with DOKKU_LIB_HOST_ROOT docker-args rewrites the mount host path" {
HOST_ROOT="$(mktemp -d /tmp/dokku-lib-host.XXXXXX)"
export DOKKU_LIB_HOST_ROOT="$HOST_ROOT"
run /bin/bash -c "dokku storage:create rdmtest-hostroot"
echo "output: $output"
echo "status: $status"
assert_success
# Create still lands under DOKKU_LIB_ROOT inside Dokku.
run /bin/bash -c "test -d ${DOKKU_LIB_ROOT}/data/storage/rdmtest-hostroot"
assert_success
run /bin/bash -c "dokku storage:mount $TEST_APP rdmtest-hostroot --container-dir /data"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "echo '' | dokku plugin:trigger docker-args-process-deploy $TEST_APP herokuish latest web | grep -o -- '-v [^ ]*'"
echo "output: $output"
echo "status: $status"
assert_success
assert_output "-v ${HOST_ROOT}/data/storage/rdmtest-hostroot:/data"
run /bin/bash -c "dokku storage:unmount --all $TEST_APP"
assert_success
run /bin/bash -c "dokku storage:destroy rdmtest-hostroot --force"
assert_success
rm -rf "$HOST_ROOT"
}
@test "(storage) with DOKKU_LIB_HOST_ROOT storage:exec mounts the host-root path" {
# Simulate Dokku-in-Docker: filesystem ops use DOKKU_LIB_ROOT, but Docker -v
# mounts must resolve under DOKKU_LIB_HOST_ROOT.
HOST_ROOT="$(mktemp -d /tmp/dokku-lib-host.XXXXXX)"
export DOKKU_LIB_HOST_ROOT="$HOST_ROOT"
run /bin/bash -c "dokku storage:create rdmtest-hostroot-exec --chown root"
echo "output: $output"
echo "status: $status"
assert_success
mkdir -p "${HOST_ROOT}/data/storage/rdmtest-hostroot-exec"
echo "Hello World!" >"${HOST_ROOT}/data/storage/rdmtest-hostroot-exec/welcome.txt"
run /bin/bash -c "docker pull alpine:3 >/dev/null"
assert_success
run /bin/bash -c "dokku storage:exec rdmtest-hostroot-exec -- cat /data/welcome.txt"
echo "output: $output"
echo "status: $status"
assert_success
assert_output_contains "Hello World!"
# The in-container create path must not have received the host-written file.
run /bin/bash -c "test ! -f ${DOKKU_LIB_ROOT}/data/storage/rdmtest-hostroot-exec/welcome.txt"
assert_success
run /bin/bash -c "dokku storage:destroy rdmtest-hostroot-exec --force"
assert_success
rm -rf "$HOST_ROOT"
}