diff --git a/target/scripts/startup/setup-stack.sh b/target/scripts/startup/setup-stack.sh index 300ce5fb..8a1d1c04 100644 --- a/target/scripts/startup/setup-stack.sh +++ b/target/scripts/startup/setup-stack.sh @@ -1469,11 +1469,13 @@ function _setup_security_stack if [[ ${SPAMASSASSIN_SPAM_TO_INBOX} -eq 1 ]] then - _notify 'inf' 'Configure Spamassassin/Amavis to put SPAM inbox' + _notify 'inf' 'Configuring Spamassassin/Amavis to send SPAM to inbox' sed -i "s|\$final_spam_destiny.*=.*$|\$final_spam_destiny = D_PASS;|g" /etc/amavis/conf.d/49-docker-mailserver sed -i "s|\$final_bad_header_destiny.*=.*$|\$final_bad_header_destiny = D_PASS;|g" /etc/amavis/conf.d/49-docker-mailserver else + _notify 'inf' 'Configuring Spamassassin/Amavis to bounce SPAM' + sed -i "s|\$final_spam_destiny.*=.*$|\$final_spam_destiny = D_BOUNCE;|g" /etc/amavis/conf.d/49-docker-mailserver sed -i "s|\$final_bad_header_destiny.*=.*$|\$final_bad_header_destiny = D_BOUNCE;|g" /etc/amavis/conf.d/49-docker-mailserver diff --git a/test/mail_spam_bounced.bats b/test/mail_spam_bounced.bats index da62e3e3..17db7dd8 100644 --- a/test/mail_spam_bounced.bats +++ b/test/mail_spam_bounced.bats @@ -2,73 +2,75 @@ load 'test_helper/common' # Test case # --------- -# When SPAMASSASSIN_SPAM_TO_INBOX=0, spam messages must be bounced. +# When SPAMASSASSIN_SPAM_TO_INBOX=0, spam messages must be bounced (rejected). +# SPAMASSASSIN_SPAM_TO_INBOX=1 is covered in `mail_spam_junk_folder.bats`. +# Original test PR: https://github.com/docker-mailserver/docker-mailserver/pull/1485 +# TODO: ENV setup will move to actual ENV files in future. function setup() { - run_setup_file_if_necessary + run_setup_file_if_necessary } function teardown() { - run_teardown_file_if_necessary + docker rm -f "${TEST_NAME}" + run_teardown_file_if_necessary } function setup_file() { - local PRIVATE_CONFIG - PRIVATE_CONFIG="$(duplicate_config_for_container . mail_spam_bounced_defined)" - docker run -d --name mail_spam_bounced_defined \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_SPAMASSASSIN=1 \ - -e SPAMASSASSIN_SPAM_TO_INBOX=0 \ - -h mail.my-domain.com -t "${NAME}" - - wait_for_finished_setup_in_container mail_spam_bounced_defined - - PRIVATE_CONFIG="$(duplicate_config_for_container . mail_spam_bounced_defined)" - docker run -d --name mail_spam_bounced_undefined \ - -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \ - -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ - -e ENABLE_SPAMASSASSIN=1 \ - -h mail.my-domain.com -t "${NAME}" - - wait_for_finished_setup_in_container mail_spam_bounced_undefined + init_with_defaults } -function teardown_file() { - docker rm -f mail_spam_bounced_defined - docker rm -f mail_spam_bounced_undefined -} +# Not used +# function teardown_file() { +# } @test "first" { skip 'this test must come first to reliably identify when to run setup_file' } -@test "checking amavis: spam message is bounced" { - # this warning should only be raised when no explicit value for SPAMASSASSIN_SPAM_TO_INBOX is defined - run sh -c "docker logs mail_spam_bounced_defined | grep 'Spam messages WILL NOT BE DELIVERED'" +@test "checking amavis: spam message is bounced (rejected)" { + local TEST_ENV_FILE="${PRIVATE_CONFIG}/defined.env" + echo 'ENABLE_SPAMASSASSIN=1' > "${TEST_ENV_FILE}" + echo 'SPAMASSASSIN_SPAM_TO_INBOX=0' >> "${TEST_ENV_FILE}" + + common_container_setup "${TEST_ENV_FILE}" + + run _should_emit_warning assert_failure - # send a spam message - run docker exec mail_spam_bounced_defined /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt" - assert_success - - run repeat_until_success_or_timeout 20 sh -c "docker logs mail_spam_bounced_defined | grep 'Blocked SPAM {NoBounceInbound,Quarantined}'" - assert_success + _should_bounce_spam } -@test "checking amavis: spam message is bounced, undefined SPAMASSASSIN_SPAM_TO_INBOX raise a warning" { - run sh -c "docker logs mail_spam_bounced_undefined | grep 'Spam messages WILL NOT BE DELIVERED'" +@test "checking amavis: spam message is bounced (rejected), undefined SPAMASSASSIN_SPAM_TO_INBOX should raise a warning" { + # SPAMASSASSIN_SPAM_TO_INBOX=0 is the default. If no explicit ENV value is set, it should log a warning at startup. + local TEST_ENV_FILE="${PRIVATE_CONFIG}/undefined.env" + echo 'ENABLE_SPAMASSASSIN=1' > "${TEST_ENV_FILE}" + + common_container_setup "${TEST_ENV_FILE}" + + run _should_emit_warning assert_success - # send a spam message - run docker exec mail_spam_bounced_defined /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt" - assert_success - - run repeat_until_success_or_timeout 20 sh -c "docker logs mail_spam_bounced_defined | grep 'Blocked SPAM {NoBounceInbound,Quarantined}'" - assert_success + _should_bounce_spam } @test "last" { skip 'this test is only there to reliably mark the end for the teardown_file' } + +# This warning should only be raised when the env SPAMASSASSIN_SPAM_TO_INBOX has no explicit value set +function _should_emit_warning() { + sh -c "docker logs ${TEST_NAME} | grep 'Spam messages WILL NOT BE DELIVERED'" +} + +function _should_bounce_spam() { + wait_for_smtp_port_in_container_to_respond "${TEST_NAME}" + + # send a spam message + run docker exec "${TEST_NAME}" /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt" + assert_success + + run repeat_until_success_or_timeout 20 sh -c "docker logs ${TEST_NAME} | grep 'Blocked SPAM {NoBounceInbound,Quarantined}'" + assert_success +} diff --git a/test/test_helper/common.bash b/test/test_helper/common.bash index baccc553..4b0ff38d 100644 --- a/test/test_helper/common.bash +++ b/test/test_helper/common.bash @@ -104,6 +104,7 @@ function wait_for_amavis_port_in_container() { wait_for_tcp_port_in_container 10024 "${1}" } +# TODO: Should also fail early on "docker logs ${1} | egrep '^[ FATAL ]'"? # @param ${1} name of the postfix container function wait_for_finished_setup_in_container() { local STATUS=0 @@ -205,3 +206,34 @@ function wait_for_empty_mail_queue_in_container() { # shellcheck disable=SC2016 repeat_in_container_until_success_or_timeout "${TIMEOUT}" "${CONTAINER_NAME}" bash -c '[[ $(mailq) == *"Mail queue is empty"* ]]' } + +# Common defaults appropriate for most tests, override vars in each test when necessary. +# TODO: Check how many tests need write access. Consider using `docker create` + `docker cp` for easier cleanup. +function init_with_defaults() { + # Ignore absolute dir path and file extension, only extract filename: + export TEST_NAME + TEST_NAME="$(basename "${BATS_TEST_FILENAME}" '.bats')" + + export PRIVATE_CONFIG + PRIVATE_CONFIG="$(duplicate_config_for_container . "${TEST_NAME}")" + export TEST_FILES_VOLUME="${PWD}/test/test-files:/tmp/docker-mailserver-test:ro" + export TEST_CONFIG_VOLUME="${PRIVATE_CONFIG}:/tmp/docker-mailserver:ro" + + export TEST_FQDN='mail.my-domain.com' +} + +# Common docker run command that should satisfy most tests which only modify ENV. +function common_container_setup() { + local TEST_ENV_FILE=$1 + + run docker run -d --name "${TEST_NAME}" \ + --volume "${TEST_FILES_VOLUME}" \ + --volume "${TEST_CONFIG_VOLUME}" \ + --hostname "${TEST_FQDN}" \ + --env-file "${TEST_ENV_FILE}" \ + --tty \ + "${NAME}" + assert_success + + wait_for_finished_setup_in_container "${TEST_NAME}" +} \ No newline at end of file