docker-mailserver/test/tests/serial/test_helper.bats
Brennan Kinney 75ee0c1145 tests(refactor): Conversion to parallel tests and use revised helpers
- Introduced `CONTAINER_NAME` and `TEST_NAME_PREFIX` as new vars for better managing test consistency (DRY).
- `CONTAINER_NAME` replaces any repeated container name with the variable. The value will differ slightly as the prior prefix (`mail_`) has been changed to `dms-test-`.
- `TEST_NAME_PREFIX` provides a prefix value for each `@test` description string.

---

chore: Add a reference template for tests
2022-11-26 14:52:42 +13:00

272 lines
9.2 KiB
Bash

load "${REPOSITORY_ROOT}/test/test_helper/common"
TEST_NAME_PREFIX='test helper functions:'
@test "${TEST_NAME_PREFIX} repeat_until_success_or_timeout returns instantly on success" {
SECONDS=0
repeat_until_success_or_timeout 1 true
[[ ${SECONDS} -le 1 ]]
}
@test "${TEST_NAME_PREFIX} repeat_until_success_or_timeout waits for timeout on persistent failure" {
SECONDS=0
run repeat_until_success_or_timeout 2 false
[[ ${SECONDS} -ge 2 ]]
assert_failure
assert_output --partial "Timed out on command"
}
@test "${TEST_NAME_PREFIX} repeat_until_success_or_timeout aborts immediately on fatal failure" {
SECONDS=0
run repeat_until_success_or_timeout --fatal-test false 2 false
[[ ${SECONDS} -le 1 ]]
assert_failure
assert_output --partial "early aborting"
}
@test "${TEST_NAME_PREFIX} repeat_until_success_or_timeout expects integer timeout" {
run repeat_until_success_or_timeout 1 true
assert_success
run repeat_until_success_or_timeout timeout true
assert_failure
run repeat_until_success_or_timeout --fatal-test true timeout true
assert_failure
}
@test "${TEST_NAME_PREFIX} run_until_success_or_timeout returns instantly on success" {
SECONDS=0
run_until_success_or_timeout 2 true
[[ ${SECONDS} -le 1 ]]
assert_success
}
@test "${TEST_NAME_PREFIX} run_until_success_or_timeout waits for timeout on persistent failure" {
SECONDS=0
! run_until_success_or_timeout 2 false
[[ ${SECONDS} -ge 2 ]]
assert_failure
}
@test "${TEST_NAME_PREFIX} repeat_in_container_until_success_or_timeout fails immediately for non-running container" {
SECONDS=0
! repeat_in_container_until_success_or_timeout 10 name-of-non-existing-container true
[[ ${SECONDS} -le 1 ]]
}
@test "${TEST_NAME_PREFIX} repeat_in_container_until_success_or_timeout run command in container" {
local CONTAINER_NAME
CONTAINER_NAME=$(docker run --rm -d alpine sleep 100)
SECONDS=0
! repeat_in_container_until_success_or_timeout 10 "${CONTAINER_NAME}" sh -c "echo '${CONTAINER_NAME}' > /tmp/marker"
[[ ${SECONDS} -le 1 ]]
run docker exec "${CONTAINER_NAME}" cat /tmp/marker
assert_output "${CONTAINER_NAME}"
}
@test "${TEST_NAME_PREFIX} container_is_running" {
local CONTAINER_NAME
CONTAINER_NAME=$(docker run --rm -d alpine sleep 100)
container_is_running "${CONTAINER_NAME}"
docker rm -f "${CONTAINER_NAME}"
! container_is_running "${CONTAINER_NAME}"
}
@test "${TEST_NAME_PREFIX} wait_for_smtp_port_in_container aborts wait after timeout" {
local CONTAINER_NAME
CONTAINER_NAME=$(docker run --rm -d alpine sleep 100)
SECONDS=0
TEST_TIMEOUT_IN_SECONDS=2 run wait_for_smtp_port_in_container "${CONTAINER_NAME}"
[[ ${SECONDS} -ge 2 ]]
assert_failure
assert_output --partial "Timed out on command"
}
# NOTE: Test requires external network access available
@test "${TEST_NAME_PREFIX} wait_for_smtp_port_in_container returns immediately when port found" {
local CONTAINER_NAME
CONTAINER_NAME=$(docker run --rm -d alpine sh -c "sleep 10")
docker exec "${CONTAINER_NAME}" apk add netcat-openbsd
docker exec "${CONTAINER_NAME}" nc -l 25 &
SECONDS=0
TEST_TIMEOUT_IN_SECONDS=5 run wait_for_smtp_port_in_container "${CONTAINER_NAME}"
[[ ${SECONDS} -lt 5 ]]
assert_success
}
@test "${TEST_NAME_PREFIX} wait_for_finished_setup_in_container" {
# variable not local to make visible to teardown
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container .)
CONTAINER_NAME=$(docker run -d --rm \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-h mail.my-domain.com \
-t "${NAME}")
teardown() { docker rm -f "${CONTAINER_NAME}"; }
# the setup should not be finished immediately after starting
! TEST_TIMEOUT_IN_SECONDS=0 wait_for_finished_setup_in_container "${CONTAINER_NAME}"
# but it will finish eventually
SECONDS=1
wait_for_finished_setup_in_container "${CONTAINER_NAME}"
[[ ${SECONDS} -gt 0 ]]
}
@test "${TEST_NAME_PREFIX} duplicate_config_for_container" {
local path
path=$(duplicate_config_for_container duplicate_config_test)
run cat "${path}/marker"
assert_line "This marker file is there to identify the correct config being copied"
run duplicate_config_for_container non-existant-source-folder "${BATS_TEST_NAME}2"
assert_failure
}
@test "${TEST_NAME_PREFIX} container_has_service_running/wait_for_service" {
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container .)
# variable not local to make visible to teardown
CONTAINER_NAME=$(docker run -d --rm \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-h mail.my-domain.com \
-t "${NAME}")
teardown() { docker rm -f "${CONTAINER_NAME}"; }
# pick a service that was not started
! container_has_service_running "${CONTAINER_NAME}" clamav
# wait for a service that should be started
wait_for_service "${CONTAINER_NAME}" postfix
# shut down the service
docker exec "${CONTAINER_NAME}" supervisorctl stop postfix
# now it should be off
SECONDS=0
TEST_TIMEOUT_IN_SECONDS=5 run wait_for_service "${CONTAINER_NAME}" postfix
[[ ${SECONDS} -ge 5 ]]
assert_failure
}
@test "${TEST_NAME_PREFIX} wait_for_changes_to_be_detected_in_container fails when timeout is reached" {
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container .)
# variable not local to make visible to teardown
CONTAINER_NAME=$(docker run -d --rm \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-h mail.my-domain.com \
-t "${NAME}")
teardown() { docker rm -f "${CONTAINER_NAME}"; }
# wait for the initial checksum file to be created
# shellcheck disable=SC2016
repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" bash -c 'source /usr/local/bin/helpers/index.sh; test -e "${CHKSUM_FILE}"'
# there should be no changes in the beginning
TEST_TIMEOUT_IN_SECONDS=0 wait_for_changes_to_be_detected_in_container "${CONTAINER_NAME}"
# trigger some change
docker exec "${CONTAINER_NAME}" /bin/sh -c "addmailuser auser3@mail.my-domain.com mypassword"
# that should be picked up as not yet detected
! TEST_TIMEOUT_IN_SECONDS=0 wait_for_changes_to_be_detected_in_container "${CONTAINER_NAME}"
}
@test "${TEST_NAME_PREFIX} wait_for_changes_to_be_detected_in_container succeeds within timeout" {
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container .)
# variable not local to make visible to teardown
CONTAINER_NAME=$(docker run -d --rm \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-h mail.my-domain.com \
-t "${NAME}")
teardown() { docker rm -f "${CONTAINER_NAME}"; }
# wait for the initial checksum file to be created
# shellcheck disable=SC2016
repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" bash -c 'source /usr/local/bin/helpers/index.sh; test -e "${CHKSUM_FILE}"'
# trigger some change
docker exec "${CONTAINER_NAME}" /bin/sh -c "addmailuser auser3@mail.my-domain.com mypassword"
# that should eventually be detected
SECONDS=0
wait_for_changes_to_be_detected_in_container "${CONTAINER_NAME}"
[[ ${SECONDS} -gt 0 ]]
}
# TODO investigate why this test fails
@test "${TEST_NAME_PREFIX} wait_for_empty_mail_queue_in_container fails when timeout reached" {
skip 'disabled as it fails randomly: https://github.com/docker-mailserver/docker-mailserver/pull/2177'
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container .)
# variable not local to make visible to teardown
# enable ClamAV to make message delivery slower, so we can detect it
CONTAINER_NAME=$(docker run -d --rm \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_CLAMAV=1 \
-h mail.my-domain.com \
-t "${NAME}")
teardown() { docker rm -f "${CONTAINER_NAME}"; }
wait_for_smtp_port_in_container "${CONTAINER_NAME}" || docker logs "${CONTAINER_NAME}"
SECONDS=0
# no mails -> should return immediately
TEST_TIMEOUT_IN_SECONDS=5 wait_for_empty_mail_queue_in_container "${CONTAINER_NAME}"
[[ ${SECONDS} -lt 5 ]]
# fill the queue with a message
docker exec "${CONTAINER_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
# that should still be stuck in the queue
! TEST_TIMEOUT_IN_SECONDS=0 wait_for_empty_mail_queue_in_container "${CONTAINER_NAME}"
}
# TODO investigate why this test fails
@test "${TEST_NAME_PREFIX} wait_for_empty_mail_queue_in_container succeeds within timeout" {
skip 'disabled as it fails randomly: https://github.com/docker-mailserver/docker-mailserver/pull/2177'
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container .)
# variable not local to make visible to teardown
# enable ClamAV to make message delivery slower, so we can detect it
CONTAINER_NAME=$(docker run -d --rm \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_CLAMAV=1 \
-h mail.my-domain.com \
-t "${NAME}")
teardown() { docker rm -f "${CONTAINER_NAME}"; }
wait_for_smtp_port_in_container "${CONTAINER_NAME}" || docker logs "${CONTAINER_NAME}"
# fill the queue with a message
docker exec "${CONTAINER_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
# give it some time to clear the queue
SECONDS=0
wait_for_empty_mail_queue_in_container "${CONTAINER_NAME}"
[[ ${SECONDS} -gt 0 ]]
}