diff --git a/test/helper/common.bash b/test/helper/common.bash index b5e02eef..5543a20f 100644 --- a/test/helper/common.bash +++ b/test/helper/common.bash @@ -60,7 +60,7 @@ function __handle_container_name() { printf '%s' "${CONTAINER_NAME}" return 0 else - echo 'ERROR: (helper/common.sh) Container name was either provided explicitly without the required `dms-test_` prefix, or CONTAINER_NAME is not set for implicit usage' >&2 + echo 'ERROR: (helper/common.sh) Container name was either provided explicitly without the required "dms-test_" prefix, or CONTAINER_NAME is not set for implicit usage' >&2 exit 1 fi } @@ -119,6 +119,27 @@ function _exec_in_container_bash() { _exec_in_container /bin/bash -c "${@}" ; } # @param ... = Bash command to execute function _run_in_container_bash() { _run_in_container /bin/bash -c "${@}" ; } +# Run a command in Bash and filter the output given a regex. +# +# @param ${1} = command to run in Bash +# @param ${2} = regex to filter [OPTIONAL] +# +# ## Attention +# +# The regex is given to `grep -E`, so make sure it is compatible. +# +# ## Note +# +# If no regex is provided, this function will default to one that strips +# empty lines and Bash comments from the output. +function _run_in_container_bash_and_filter_output() { + local COMMAND=${1:?Command must be provided} + local FILTER_REGEX=${2:-^[[:space:]]*$|^ *#} + + _run_in_container_bash "${COMMAND} | grep -E -v '${FILTER_REGEX}'" + assert_success +} + # ? << Functions to execute commands inside a container # ! ------------------------------------------------------------------- # ? >> Functions about executing commands with timeouts diff --git a/test/test-files/email-templates/smtp-only.txt b/test/test-files/email-templates/smtp-only.txt index 220ace15..08288bf6 100644 --- a/test/test-files/email-templates/smtp-only.txt +++ b/test/test-files/email-templates/smtp-only.txt @@ -1,4 +1,4 @@ -HELO mail.localhost +HELO mail.example.test MAIL FROM: test@localhost RCPT TO: user2@external.tld DATA diff --git a/test/tests/serial/mail_quotas_disabled.bats b/test/tests/serial/mail_quotas_disabled.bats index a012614e..bc9aa5bc 100644 --- a/test/tests/serial/mail_quotas_disabled.bats +++ b/test/tests/serial/mail_quotas_disabled.bats @@ -1,43 +1,33 @@ -load "${REPOSITORY_ROOT}/test/test_helper/common" - -# Test case -# --------- -# When ENABLE_QUOTAS is explicitly disabled (ENABLE_QUOTAS=0), dovecot quota must not be enabled. +load "${REPOSITORY_ROOT}/test/helper/common" +load "${REPOSITORY_ROOT}/test/helper/setup" +BATS_TEST_NAME_PREFIX='[Quotas Disabled] ' +CONTAINER_NAME='dms-test_quotas-disabled' function setup_file() { - local PRIVATE_CONFIG - PRIVATE_CONFIG=$(duplicate_config_for_container .) - - docker run -d --name mail_no_quotas \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_QUOTAS=0 \ - -h mail.my-domain.com -t "${NAME}" - - wait_for_finished_setup_in_container mail_no_quotas + _init_with_defaults + local CUSTOM_SETUP_ARGUMENTS=(--env ENABLE_QUOTAS=0) + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' } -function teardown_file() { - docker rm -f mail_no_quotas -} +function teardown_file() { _default_teardown ; } -@test "checking dovecot: (ENABLE_QUOTAS=0) quota plugin is disabled" { - run docker exec mail_no_quotas /bin/sh -c "grep '\$mail_plugins quota' /etc/dovecot/conf.d/10-mail.conf" +@test "(Dovecot) quota plugin is disabled" { + _run_in_container_bash_and_filter_output 'cat /etc/dovecot/conf.d/10-mail.conf' + refute_output --partial 'quota' + + _run_in_container_bash_and_filter_output 'cat /etc/dovecot/conf.d/20-imap.conf' + refute_output --partial 'imap_quota' + + _run_in_container_bash "[[ -f /etc/dovecot/conf.d/90-quota.conf ]]" assert_failure - run docker exec mail_no_quotas /bin/sh -c "grep '\$mail_plugins imap_quota' /etc/dovecot/conf.d/20-imap.conf" - assert_failure - - run docker exec mail_no_quotas ls /etc/dovecot/conf.d/90-quota.conf - assert_failure - - run docker exec mail_no_quotas ls /etc/dovecot/conf.d/90-quota.conf.disab + _run_in_container_bash "[[ -f /etc/dovecot/conf.d/90-quota.conf.disab ]]" assert_success } -@test "checking postfix: (ENABLE_QUOTAS=0) dovecot quota absent in postconf" { - run docker exec mail_no_quotas /bin/bash -c "postconf | grep 'check_policy_service inet:localhost:65265'" - assert_failure +@test "(Postfix) Dovecot quota absent in postconf" { + _run_in_container postconf + assert_success + refute_output --partial "check_policy_service inet:localhost:65265'" } - diff --git a/test/tests/serial/mail_smtponly.bats b/test/tests/serial/mail_smtponly.bats index 9549ace5..425d7008 100644 --- a/test/tests/serial/mail_smtponly.bats +++ b/test/tests/serial/mail_smtponly.bats @@ -1,64 +1,44 @@ -load "${REPOSITORY_ROOT}/test/test_helper/common" +load "${REPOSITORY_ROOT}/test/helper/common" +load "${REPOSITORY_ROOT}/test/helper/setup" + +BATS_TEST_NAME_PREFIX='[SMTP-Only] ' +CONTAINER_NAME='dms-test_env-smtp-only' function setup_file() { - docker run --rm -d --name mail_smtponly \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e SMTP_ONLY=1 \ - -e PERMIT_DOCKER=network \ - -e OVERRIDE_HOSTNAME=mail.my-domain.com \ - -t "${NAME}" + _init_with_defaults - wait_for_finished_setup_in_container mail_smtponly - wait_for_smtp_port_in_container mail_smtponly + local CUSTOM_SETUP_ARGUMENTS=( + --env SMTP_ONLY=1 + --env PERMIT_DOCKER=network + ) + + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' + + _wait_for_smtp_port_in_container } -function teardown_file() { - docker rm -f mail_smtponly -} +function teardown_file() { _default_teardown ; } -# -# configuration checks -# - -@test "checking configuration: hostname/domainname override" { - run docker exec mail_smtponly /bin/bash -c "cat /etc/mailname | grep my-domain.com" +@test "Dovecot quota absent in postconf" { + _run_in_container postconf assert_success + refute_output --partial "check_policy_service inet:localhost:65265'" } -# -# imap -# +# TODO: needs complete rework when proper DNS container is running for tests +@test "sending mail should work" { + skip 'TODO: This test is absolutely broken and needs reworking!' -@test "checking configuration: dovecot quota absent in postconf (disabled using SMTP_ONLY)" { - run docker exec mail_smtponly /bin/bash -c "postconf | grep 'check_policy_service inet:localhost:65265'" - assert_failure -} - -# -# smtp -# - -@test "checking smtp_only: mail send should work" { - run docker exec mail_smtponly /bin/sh -c "postconf smtp_host_lookup=no" assert_success - _reload_postfix mail_smtponly - wait_for_smtp_port_in_container mail_smtponly - run docker exec mail_smtponly /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/smtp-only.txt" + # it looks as if someone tries to send mail to another domain outside of DMS + _run_in_container_bash "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/smtp-only.txt" assert_success - run docker exec mail_smtponly /bin/sh -c 'grep -cE "to=.*status\=sent" /var/log/mail/mail.log' + _wait_for_empty_mail_queue_in_container + + # this seemingly succeeds, but looking at the logs, it doesn't + _run_in_container_bash 'grep -cE "to=.*status\=sent" /var/log/mail/mail.log' + # this is absolutely useless! `grep -c` count 0 but also returns 0; the mail was never properly sent! [[ ${status} -ge 0 ]] } - -# -# PERMIT_DOCKER=network -# - -@test "checking PERMIT_DOCKER=network: opendmarc/opendkim config" { - run docker exec mail_smtponly /bin/sh -c "cat /etc/opendmarc/ignore.hosts | grep '172.16.0.0/12'" - assert_success - - run docker exec mail_smtponly /bin/sh -c "cat /etc/opendkim/TrustedHosts | grep '172.16.0.0/12'" - assert_success -} diff --git a/test/tests/serial/mail_special_use_folders.bats b/test/tests/serial/mail_special_use_folders.bats index f5b613a6..f4be9113 100644 --- a/test/tests/serial/mail_special_use_folders.bats +++ b/test/tests/serial/mail_special_use_folders.bats @@ -1,40 +1,38 @@ -load "${REPOSITORY_ROOT}/test/test_helper/common" +load "${REPOSITORY_ROOT}/test/helper/common" +load "${REPOSITORY_ROOT}/test/helper/setup" -setup_file() { - local PRIVATE_CONFIG - PRIVATE_CONFIG=$(duplicate_config_for_container .) +BATS_TEST_NAME_PREFIX='[Special Use Folders] ' +CONTAINER_NAME='dms-test_special-use-folders' - docker run -d --name mail_special_use_folders \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_CLAMAV=0 \ - -e ENABLE_SPAMASSASSIN=0 \ - -e PERMIT_DOCKER=host \ - -h mail.my-domain.com -t "${NAME}" - - wait_for_smtp_port_in_container mail_special_use_folders +function setup_file() { + _init_with_defaults + local CUSTOM_SETUP_ARGUMENTS=(--env PERMIT_DOCKER=host) + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' + _wait_for_smtp_port_in_container } -teardown_file() { - docker rm -f mail_special_use_folders -} +function teardown_file() { _default_teardown ; } -@test "checking normal delivery" { - run docker exec mail_special_use_folders /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt" +@test "normal delivery works" { + _run_in_container_bash "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt" assert_success - # shellcheck disable=SC2016 - repeat_until_success_or_timeout 30 docker exec mail_special_use_folders /bin/sh -c '[ $(ls /var/mail/localhost.localdomain/user1/new | wc -l) -eq 1 ]' + _count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new 1 } -@test "checking special-use folders not yet created" { - run docker exec mail_special_use_folders /bin/bash -c "ls -A /var/mail/localhost.localdomain/user1 | grep -E '.Drafts|.Sent|.Trash' | wc -l" +@test "(IMAP) special-use folders should not exist yet" { + _run_in_container find /var/mail/localhost.localdomain/user1 -maxdepth 1 -type d assert_success - assert_output 0 + refute_output --partial '.Drafts' + refute_output --partial '.Sent' + refute_output --partial '.Trash' } -@test "checking special-use folders available in IMAP" { - run docker exec mail_special_use_folders /bin/sh -c "nc -w 8 0.0.0.0 143 < /tmp/docker-mailserver-test/nc_templates/imap_special_use_folders.txt | grep -E 'Drafts|Junk|Trash|Sent' | wc -l" +@test "(IMAP) special-use folders should be created when necessary" { + _run_in_container_bash "nc -w 8 0.0.0.0 143 < /tmp/docker-mailserver-test/nc_templates/imap_special_use_folders.txt" assert_success - assert_output 4 + assert_output --partial 'Drafts' + assert_output --partial 'Junk' + assert_output --partial 'Trash' + assert_output --partial 'Sent' } diff --git a/test/tests/serial/mail_time.bats b/test/tests/serial/mail_time.bats index 6bf7eb42..350880f1 100644 --- a/test/tests/serial/mail_time.bats +++ b/test/tests/serial/mail_time.bats @@ -1,29 +1,23 @@ -load "${REPOSITORY_ROOT}/test/test_helper/common" +load "${REPOSITORY_ROOT}/test/helper/common" +load "${REPOSITORY_ROOT}/test/helper/setup" -setup_file() { - local PRIVATE_CONFIG - PRIVATE_CONFIG=$(duplicate_config_for_container .) +BATS_TEST_NAME_PREFIX='[Timezone] ' +CONTAINER_NAME='dms-test_timezone' - docker run -d --name mail_time \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e TZ='Asia/Jakarta' \ - -e LOG_LEVEL=debug \ - -h mail.my-domain.com -t "${NAME}" - - wait_for_smtp_port_in_container mail_time +function setup_file() { + _init_with_defaults + local CUSTOM_SETUP_ARGUMENTS=(--env TZ='Asia/Jakarta') + _common_container_setup 'CUSTOM_SETUP_ARGUMENTS' } -teardown_file() { - docker rm -f mail_time -} +function teardown_file() { _default_teardown ; } -@test "checking time: setting the time with TZ works correctly" { - run docker exec mail_time cat /etc/timezone +@test "setting the time with TZ works correctly" { + _run_in_container cat /etc/timezone assert_success assert_output 'Asia/Jakarta' - run docker exec mail_time date '+%Z' + _run_in_container date '+%Z' assert_success assert_output 'WIB' } diff --git a/test/tests/serial/permit_docker.bats b/test/tests/serial/permit_docker.bats index deea8082..85f00484 100644 --- a/test/tests/serial/permit_docker.bats +++ b/test/tests/serial/permit_docker.bats @@ -84,3 +84,12 @@ teardown_file() { assert_output --partial "550 5.5.1 Protocol error" [[ ${status} -ge 0 ]] } + +@test "checking PERMIT_DOCKER=network: opendmarc/opendkim config" { + skip 'TODO: this test was taken from mail_smtponly, where it did not actually belong to' + run docker exec mail_smtponly /bin/sh -c "cat /etc/opendmarc/ignore.hosts | grep '172.16.0.0/12'" + assert_success + + run docker exec mail_smtponly /bin/sh -c "cat /etc/opendkim/TrustedHosts | grep '172.16.0.0/12'" + assert_success +}