Merge pull request #1613 from martin-schulze-vireso/feature/extract_even_more_tests

This commit is contained in:
Georg Lauterbach 2020-10-28 11:16:15 +01:00 committed by GitHub
commit f0105f6d47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1152 additions and 710 deletions

View File

@ -13,7 +13,7 @@ Here's a quick guide:
refactoring and documentation changes require no new tests. If you are adding refactoring and documentation changes require no new tests. If you are adding
functionality or fixing a bug, we need tests! functionality or fixing a bug, we need tests!
4. Run the tests. `make build-no-cache generate-accounts run generate-accounts-after-run fixtures tests clean` 4. Run the tests. `make build-no-cache generate-accounts run fixtures tests clean`
5. Push to your fork and submit a pull request. If the changes will apply cleanly 5. Push to your fork and submit a pull request. If the changes will apply cleanly
to the master branch, you will only need to submit one pull request. to the master branch, you will only need to submit one pull request.

5
.gitignore vendored
View File

@ -32,7 +32,10 @@ test/config/postfix-send-access.cf
test/config/postfix-send-access.cfe test/config/postfix-send-access.cfe
test/config/relay-hosts/chksum test/config/relay-hosts/chksum
test/config/relay-hosts/postfix-aliases.cf test/config/relay-hosts/postfix-aliases.cf
test/config/without-accounts/
test/config/without-virtual/ test/config/without-virtual/
test/config/with-domain/ test/config/with-domain/
test/onedir test/onedir
test/duplicate_configs
config.bak
testconfig.bak

View File

@ -39,7 +39,7 @@ script:
- make eclint - make eclint
- make hadolint - make hadolint
- make shellcheck - make shellcheck
- make generate-accounts run generate-accounts-after-run fixtures tests - make generate-accounts tests
after_script: after_script:
- make clean - make clean

113
Makefile
View File

@ -6,9 +6,9 @@ VCS_VERSION := $(shell git describe --tags --contains --always)
SLEEP = 15s SLEEP = 15s
all: build backup generate-accounts run generate-accounts-after-run fixtures tests clean all: build backup generate-accounts tests clean
no-build: backup generate-accounts run generate-accounts-after-run fixtures tests clean no-build: backup generate-accounts tests clean
complete_test: lint build generate-accounts run generate-accounts-after-run fixtures tests complete_test: lint build generate-accounts tests
build: build:
docker build \ docker build \
@ -28,111 +28,6 @@ generate-accounts:
@ echo "# this is a test comment, please don't delete me :'(" >> test/config/postfix-accounts.cf @ echo "# this is a test comment, please don't delete me :'(" >> test/config/postfix-accounts.cf
@ echo " # this is also a test comment, :O" >> test/config/postfix-accounts.cf @ echo " # this is also a test comment, :O" >> test/config/postfix-accounts.cf
run:
# run containers
-@ echo "Sleeping $(SLEEP) after each container"
docker run --rm -d --name mail \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-v "`pwd`/test/onedir":/var/mail-state \
-v "`pwd`/test/config/user-patches/user-patches.sh":/tmp/docker-mailserver/user-patches.sh \
-e ENABLE_CLAMAV=1 \
-e SPOOF_PROTECTION=1 \
-e ENABLE_SPAMASSASSIN=1 \
-e REPORT_RECIPIENT=user1@localhost.localdomain \
-e REPORT_SENDER=report1@mail.my-domain.com \
-e SA_TAG=-5.0 \
-e SA_TAG2=2.0 \
-e SA_KILL=3.0 \
-e SA_SPAM_SUBJECT="SPAM: " \
-e VIRUSMAILS_DELETE_DELAY=7 \
-e ENABLE_SRS=1 \
-e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_MANAGESIEVE=1 \
--cap-add=SYS_PTRACE \
-e PERMIT_DOCKER=host \
-e DMS_DEBUG=0 \
-h mail.my-domain.com -t $(NAME)
-@ sleep $(SLEEP)
docker run --rm -d --name mail_smtponly_without_config \
-e SMTP_ONLY=1 \
-e ENABLE_LDAP=1 \
-e PERMIT_DOCKER=network \
-e OVERRIDE_HOSTNAME=mail.mydomain.com \
-t $(NAME)
-@ sleep $(SLEEP)
docker run --rm -d --name mail_override_hostname \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \
-e ENABLE_SRS=1 \
-e OVERRIDE_HOSTNAME=mail.my-domain.com \
-h unknown.domain.tld \
-t $(NAME)
-@ sleep $(SLEEP)
docker run --rm -d --name mail_domainname \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \
-e ENABLE_SRS=1 \
-e DOMAINNAME=my-domain.com \
-h unknown.domain.tld \
-t $(NAME)
-@ sleep $(SLEEP)
docker run --rm -d --name mail_srs_domainname \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \
-e ENABLE_SRS=1 \
-e SRS_DOMAINNAME=srs.my-domain.com \
-e DOMAINNAME=my-domain.com \
-h unknown.domain.tld \
-t $(NAME)
-@ sleep $(SLEEP)
docker run --rm -d --name mail_disabled_clamav_spamassassin \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_CLAMAV=0 \
-e ENABLE_SPAMASSASSIN=0 \
-e DMS_DEBUG=0 \
-h mail.my-domain.com -t $(NAME)
-@ sleep $(SLEEP)
generate-accounts-after-run:
@ docker run --rm -e MAIL_USER=added@localhost.localdomain -e MAIL_PASS=mypassword -t $(NAME) /bin/sh -c 'echo "$$MAIL_USER|$$(doveadm pw -s SHA512-CRYPT -u $$MAIL_USER -p $$MAIL_PASS)"' >> test/config/postfix-accounts.cf
@ docker exec mail addmailuser pass@localhost.localdomain 'may be \a `p^a.*ssword'
@ sleep $(SLEEP)
fixtures:
# setup sieve
docker cp "`pwd`/test/config/sieve/dovecot.sieve" mail:/var/mail/localhost.localdomain/user1/.dovecot.sieve
sleep $(SLEEP)
sleep $(SLEEP)
# sending test mails
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-external.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-recipient-delimiter.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user2.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-added.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user-and-cc-local-alias.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-regexp-alias-external.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-regexp-alias-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-catchall-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/sieve-spam-folder.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/sieve-pipe.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/non-existing-user.txt"
docker exec mail_disabled_clamav_spamassassin /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
docker exec mail /bin/sh -c "sendmail root < /tmp/docker-mailserver-test/email-templates/root-email.txt"
# postfix virtual transport lmtp
docker exec mail_override_hostname /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
# wait for mails to be analyzed
sleep 80
tests: tests:
./test/bats/bin/bats test/*.bats ./test/bats/bin/bats test/*.bats
@ -152,7 +47,7 @@ clean:
sudo rm -rf test/config ;\ sudo rm -rf test/config ;\
mv testconfig.bak test/config ;\ mv testconfig.bak test/config ;\
fi fi
-@ sudo rm -rf test/onedir test/alias test/quota test/relay test/config/dovecot-lmtp/userdb test/config/key* test/config/opendkim/keys/domain.tld/ test/config/opendkim/keys/example.com/ test/config/opendkim/keys/localdomain2.com/ test/config/postfix-aliases.cf test/config/postfix-receive-access.cf test/config/postfix-receive-access.cfe test/config/dovecot-quotas.cf test/config/postfix-send-access.cf test/config/postfix-send-access.cfe test/config/relay-hosts/chksum test/config/relay-hosts/postfix-aliases.cf test/config/dhparams.pem test/config/dovecot-lmtp/dh.pem test/config/relay-hosts/dovecot-quotas.cf test/config/user-patches.sh test/alias/config/postfix-virtual.cf test/quota/config/dovecot-quotas.cf test/quota/config/postfix-accounts.cf test/relay/config/postfix-relaymap.cf test/relay/config/postfix-sasl-password.cf -@ sudo rm -rf test/onedir test/alias test/quota test/relay test/config/dovecot-lmtp/userdb test/config/key* test/config/opendkim/keys/domain.tld/ test/config/opendkim/keys/example.com/ test/config/opendkim/keys/localdomain2.com/ test/config/postfix-aliases.cf test/config/postfix-receive-access.cf test/config/postfix-receive-access.cfe test/config/dovecot-quotas.cf test/config/postfix-send-access.cf test/config/postfix-send-access.cfe test/config/relay-hosts/chksum test/config/relay-hosts/postfix-aliases.cf test/config/dhparams.pem test/config/dovecot-lmtp/dh.pem test/config/relay-hosts/dovecot-quotas.cf test/config/user-patches.sh test/alias/config/postfix-virtual.cf test/quota/config/dovecot-quotas.cf test/quota/config/postfix-accounts.cf test/relay/config/postfix-relaymap.cf test/relay/config/postfix-sasl-password.cf test/duplicate_configs/
lint: eclint hadolint shellcheck lint: eclint hadolint shellcheck

View File

@ -53,7 +53,6 @@ do
then then
echo "${LOG_DATE} Change detected" echo "${LOG_DATE} Change detected"
CHANGED=$(grep -Fxvf "${CHKSUM_FILE}" "${CHKSUM_FILE}.new" | sed 's/^[^ ]\+ //') CHANGED=$(grep -Fxvf "${CHKSUM_FILE}" "${CHKSUM_FILE}.new" | sed 's/^[^ ]\+ //')
mv "${CHKSUM_FILE}.new" "${CHKSUM_FILE}"
# Bug alert! This overwrites the alias set by start-mailserver.sh # Bug alert! This overwrites the alias set by start-mailserver.sh
# Take care that changes in one script are propagated to the other # Take care that changes in one script are propagated to the other
@ -231,6 +230,9 @@ s/$/ regexp:\/etc\/postfix\/regexp/
# prevent restart of dovecot when smtp_only=1 # prevent restart of dovecot when smtp_only=1
[[ ${SMTP_ONLY} -ne 1 ]] && supervisorctl restart dovecot [[ ${SMTP_ONLY} -ne 1 ]] && supervisorctl restart dovecot
) 200<postfix-accounts.cf # end lock ) 200<postfix-accounts.cf # end lock
# mark changes as applied
mv "${CHKSUM_FILE}.new" "${CHKSUM_FILE}"
fi fi
sleep 1 sleep 1

View File

@ -0,0 +1 @@
This marker file is there to identify the correct config being copied

View File

View File

@ -1,9 +1,11 @@
load 'test_helper/common' load 'test_helper/common'
function setup() { function setup() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container relay-hosts)"
docker run -d --name mail_with_default_relay \ docker run -d --name mail_with_default_relay \
-v "`pwd`/test/config/relay-hosts":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DEFAULT_RELAY_HOST=default.relay.host.invalid:25 \ -e DEFAULT_RELAY_HOST=default.relay.host.invalid:25 \
--cap-add=SYS_PTRACE \ --cap-add=SYS_PTRACE \
-e PERMIT_DOCKER=host \ -e PERMIT_DOCKER=host \
@ -23,4 +25,4 @@ function teardown() {
@test "checking default relay host: default relay host is added to main.cf" { @test "checking default relay host: default relay host is added to main.cf" {
run docker exec mail_with_default_relay /bin/sh -c 'grep -e "^relayhost =" /etc/postfix/main.cf' run docker exec mail_with_default_relay /bin/sh -c 'grep -e "^relayhost =" /etc/postfix/main.cf'
assert_output 'relayhost = default.relay.host.invalid:25' assert_output 'relayhost = default.relay.host.invalid:25'
} }

View File

@ -21,17 +21,20 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_default_dhparams_both_one_dir)"
docker run -d --name mail_default_dhparams_one_dir \ docker run -d --name mail_default_dhparams_one_dir \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e ONE_DIR=1 \ -e ONE_DIR=1 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
wait_for_finished_setup_in_container mail_default_dhparams_one_dir wait_for_finished_setup_in_container mail_default_dhparams_one_dir
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_default_dhparams_both_not_one_dir)"
docker run -d --name mail_default_dhparams_not_one_dir \ docker run -d --name mail_default_dhparams_not_one_dir \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e ONE_DIR=0 \ -e ONE_DIR=0 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}

View File

@ -13,20 +13,22 @@ load 'test_helper/common'
function setup() { function setup() {
run_setup_file_if_necessary run_setup_file_if_necessary
} }
function teardown() { function teardown() {
run_teardown_file_if_necessary run_teardown_file_if_necessary
} }
function setup_file() { function setup_file() {
# copy the custom DHE params in local config local PRIVATE_CONFIG
cp "`pwd`/test/test-files/ssl/custom-dhe-params.pem" "`pwd`/test/config/dhparams.pem" PRIVATE_CONFIG=$(duplicate_config_for_container .)
# copy the custom DHE params in local config
cp "$(pwd)/test/test-files/ssl/custom-dhe-params.pem" "${PRIVATE_CONFIG}/dhparams.pem"
docker run -d --name mail_manual_dhparams_not_one_dir \ docker run -d --name mail_manual_dhparams_not_one_dir \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e ONE_DIR=0 \ -e ONE_DIR=0 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
@ -34,9 +36,7 @@ function setup_file() {
} }
function teardown_file() { function teardown_file() {
# remove custom dhe file docker rm -f mail_manual_dhparams_not_one_dir
rm "`pwd`/test/config/dhparams.pem"
docker rm -f mail_manual_dhparams_not_one_dir
} }
@test "first" { @test "first" {

View File

@ -20,10 +20,12 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_manual_dhparams_one_dir \ docker run -d --name mail_manual_dhparams_one_dir \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-v "`pwd`/test/test-files/ssl/custom-dhe-params.pem":/var/mail-state/lib-shared/dhparams.pem:ro \ -v "$(pwd)/test/test-files/ssl/custom-dhe-params.pem":/var/mail-state/lib-shared/dhparams.pem:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e ONE_DIR=1 \ -e ONE_DIR=1 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}

View File

@ -0,0 +1,62 @@
load 'test_helper/common'
setup() {
run_setup_file_if_necessary
}
teardown() {
run_teardown_file_if_necessary
}
setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run --rm -d --name mail_disabled_clamav_spamassassin \
-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 DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME}
# TODO: find a better way to know when we have waited long enough
# for clamav to should have come up, if it were enabled
wait_for_smtp_port_in_container mail_disabled_clamav_spamassassin
docker exec mail_disabled_clamav_spamassassin /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
}
teardown_file() {
docker rm -f mail_disabled_clamav_spamassassin
}
@test "first" {
skip 'only used to call setup_file from setup'
}
@test "checking process: clamav (clamav disabled by ENABLED_CLAMAV=0)" {
run docker exec mail_disabled_clamav_spamassassin /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'"
assert_failure
}
@test "checking spamassassin: should not be listed in amavis when disabled" {
run docker exec mail_disabled_clamav_spamassassin /bin/sh -c "grep -i 'ANTI-SPAM-SA code' /var/log/mail/mail.log | grep 'NOT loaded'"
assert_success
}
@test "checking clamav: should not be listed in amavis when disabled" {
run docker exec mail_disabled_clamav_spamassassin grep -i 'Found secondary av scanner ClamAV-clamscan' /var/log/mail/mail.log
assert_failure
}
@test "checking clamav: should not be called when disabled" {
run docker exec mail_disabled_clamav_spamassassin grep -i 'connect to /var/run/clamav/clamd.ctl failed' /var/log/mail/mail.log
assert_failure
}
@test "checking restart of process: clamav (clamav disabled by ENABLED_CLAMAV=0)" {
run docker exec mail_disabled_clamav_spamassassin /bin/bash -c "pkill -f clamd && sleep 10 && ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'"
assert_failure
}
@test "last" {
skip 'only used to call teardown_file from teardown'
}

View File

@ -9,9 +9,11 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run --rm -d --name mail_fail2ban \ docker run --rm -d --name mail_fail2ban \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_FAIL2BAN=1 \ -e ENABLE_FAIL2BAN=1 \
-e POSTSCREEN_ACTION=ignore \ -e POSTSCREEN_ACTION=ignore \
--cap-add=NET_ADMIN \ --cap-add=NET_ADMIN \

View File

@ -9,9 +9,11 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_fetchmail \ docker run -d --name mail_fetchmail \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_FETCHMAIL=1 \ -e ENABLE_FETCHMAIL=1 \
--cap-add=NET_ADMIN \ --cap-add=NET_ADMIN \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
@ -61,4 +63,4 @@ function teardown_file() {
@test "last" { @test "last" {
skip 'this test is only there to reliably mark the end for the teardown_file' skip 'this test is only there to reliably mark the end for the teardown_file'
} }

View File

@ -9,10 +9,13 @@ teardown() {
} }
setup_file() { setup_file() {
local PRIVATE_CONFIG PRIVATE_ETC
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
PRIVATE_ETC="$(duplicate_config_for_container dovecot-lmtp/ mail_lmtp_ip_dovecot-lmtp)"
docker run -d --name mail_lmtp_ip \ docker run -d --name mail_lmtp_ip \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/config/dovecot-lmtp":/etc/dovecot \ -v "${PRIVATE_ETC}":/etc/dovecot \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1 \ -e ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1 \
-e POSTFIX_DAGENT=lmtp:127.0.0.1:24 \ -e POSTFIX_DAGENT=lmtp:127.0.0.1:24 \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
@ -43,7 +46,7 @@ teardown_file() {
wait_for_smtp_port_in_container mail_lmtp_ip wait_for_smtp_port_in_container mail_lmtp_ip
run docker exec mail_lmtp_ip /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt" run docker exec mail_lmtp_ip /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
assert_success assert_success
# polling needs to avoid wc -l's unconditionally successful return status # polling needs to avoid wc -l's unconditionally successful return status
repeat_until_success_or_timeout 60 docker exec mail_lmtp_ip /bin/sh -c "grep 'postfix/lmtp' /var/log/mail/mail.log | grep 'status=sent' | grep ' Saved)'" repeat_until_success_or_timeout 60 docker exec mail_lmtp_ip /bin/sh -c "grep 'postfix/lmtp' /var/log/mail/mail.log | grep 'status=sent' | grep ' Saved)'"
run docker exec mail_lmtp_ip /bin/sh -c "grep 'postfix/lmtp' /var/log/mail/mail.log | grep 'status=sent' | grep ' Saved)' | wc -l" run docker exec mail_lmtp_ip /bin/sh -c "grep 'postfix/lmtp' /var/log/mail/mail.log | grep 'status=sent' | grep ' Saved)' | wc -l"
@ -53,4 +56,4 @@ teardown_file() {
@test "last" { @test "last" {
skip 'only used to call teardown_file from teardown' skip 'only used to call teardown_file from teardown'
} }

View File

@ -0,0 +1,88 @@
load 'test_helper/common'
function setup() {
run_setup_file_if_necessary
}
function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run --rm -d --name mail_override_hostname \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \
-e ENABLE_SRS=1 \
-e OVERRIDE_HOSTNAME=mail.my-domain.com \
-h unknown.domain.tld \
-t ${NAME}
wait_for_smtp_port_in_container mail_override_hostname
# postfix virtual transport lmtp
docker exec mail_override_hostname /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
}
@test "first" {
skip 'only used to call setup_file from setup'
}
@test "checking configuration: hostname/domainname override: check container hostname is applied correctly" {
run docker exec mail_override_hostname /bin/bash -c "hostname | grep unknown.domain.tld"
assert_success
}
@test "checking configuration: hostname/domainname override: check overriden hostname is applied to all configs" {
run docker exec mail_override_hostname /bin/bash -c "cat /etc/mailname | grep my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "postconf -n | grep mydomain | grep my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "postconf -n | grep myhostname | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "doveconf | grep hostname | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "cat /etc/opendmarc.conf | grep AuthservID | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "cat /etc/opendmarc.conf | grep TrustedAuthservIDs | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "cat /etc/amavis/conf.d/05-node_id | grep myhostname | grep mail.my-domain.com"
assert_success
}
@test "checking configuration: hostname/domainname override: check hostname in postfix HELO message" {
run docker exec mail_override_hostname /bin/bash -c "nc -w 1 0.0.0.0 25 | grep mail.my-domain.com"
assert_success
}
@test "checking configuration: hostname/domainname override: check headers of received mail" {
run docker exec mail_override_hostname /bin/sh -c "ls -A /var/mail/localhost.localdomain/user1/new | wc -l | grep 1"
assert_success
run docker exec mail_override_hostname /bin/sh -c "cat /var/mail/localhost.localdomain/user1/new/* | grep mail.my-domain.com"
assert_success
# test whether the container hostname is not found in received mail
run docker exec mail_override_hostname /bin/sh -c "cat /var/mail/localhost.localdomain/user1/new/* | grep unknown.domain.tld"
assert_failure
}
@test "checking SRS: OVERRIDE_HOSTNAME is handled correctly" {
run docker exec mail_override_hostname grep "SRS_DOMAIN=my-domain.com" /etc/default/postsrsd
assert_success
}
@test "checking dovecot: postmaster address" {
run docker exec mail_override_hostname /bin/sh -c "grep 'postmaster_address = postmaster@my-domain.com' /etc/dovecot/conf.d/15-lda.conf"
assert_success
}
#
# clean exit
#
@test "checking that the container stops cleanly" {
run docker stop -t 60 mail_override_hostname
assert_success
}
@test "last" {
skip 'only used to call teardown_file from teardown'
}

View File

@ -9,9 +9,11 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_pop3 \ docker run -d --name mail_pop3 \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_POP3=1 \ -e ENABLE_POP3=1 \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
@ -91,4 +93,4 @@ function teardown_file() {
@test "last" { @test "last" {
skip 'this test is only there to reliably mark the end for the teardown_file' skip 'this test is only there to reliably mark the end for the teardown_file'
} }

View File

@ -4,80 +4,73 @@ load 'test_helper/common'
# --------- # ---------
# POSTFIX_INET_PROTOCOLS value is set # POSTFIX_INET_PROTOCOLS value is set
function setup() {
run_setup_file_if_necessary
}
function teardown() {
run_teardown_file_if_necessary
}
function setup_file() {
docker run -d --name mail_postfix_inet_default \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_postfix_inet_default
docker run -d --name mail_postfix_inet_all \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTFIX_INET_PROTOCOLS=all \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_postfix_inet_all
docker run -d --name mail_postfix_inet_ipv4 \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTFIX_INET_PROTOCOLS=ipv4 \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_postfix_inet_ipv4
docker run -d --name mail_postfix_inet_ipv6 \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTFIX_INET_PROTOCOLS=ipv6 \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_postfix_inet_ipv6
}
function teardown_file() {
docker rm -f mail_postfix_inet_default
docker rm -f mail_postfix_inet_all
docker rm -f mail_postfix_inet_ipv4
docker rm -f mail_postfix_inet_ipv6
}
@test "first" {
skip 'this test must come first to reliably identify when to run setup_file'
}
@test "checking postfix: inet default" { @test "checking postfix: inet default" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . )"
docker run -d --name mail_postfix_inet_default \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-h mail.my-domain.com -t "${NAME}"
teardown() { docker rm -f mail_postfix_inet_default; }
wait_for_finished_setup_in_container mail_postfix_inet_default
run docker exec mail_postfix_inet_default postconf inet_protocols run docker exec mail_postfix_inet_default postconf inet_protocols
assert_output "inet_protocols = all" assert_output "inet_protocols = all"
assert_success assert_success
} }
@test "checking postfix: inet all" { @test "checking postfix: inet all" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . )"
docker run -d --name mail_postfix_inet_all \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTFIX_INET_PROTOCOLS=all \
-h mail.my-domain.com -t "${NAME}"
teardown() { docker rm -f mail_postfix_inet_all; }
wait_for_finished_setup_in_container mail_postfix_inet_all
run docker exec mail_postfix_inet_all postconf inet_protocols run docker exec mail_postfix_inet_all postconf inet_protocols
assert_output "inet_protocols = all" assert_output "inet_protocols = all"
assert_success assert_success
} }
@test "checking postfix: inet ipv4" { @test "checking postfix: inet ipv4" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . )"
docker run -d --name mail_postfix_inet_ipv4 \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTFIX_INET_PROTOCOLS=ipv4 \
-h mail.my-domain.com -t "${NAME}"
teardown() { docker rm -f mail_postfix_inet_ipv4; }
wait_for_finished_setup_in_container mail_postfix_inet_ipv4
run docker exec mail_postfix_inet_ipv4 postconf inet_protocols run docker exec mail_postfix_inet_ipv4 postconf inet_protocols
assert_output "inet_protocols = ipv4" assert_output "inet_protocols = ipv4"
assert_success assert_success
} }
@test "checking postfix: inet ipv6" { @test "checking postfix: inet ipv6" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . )"
docker run -d --name mail_postfix_inet_ipv6 \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTFIX_INET_PROTOCOLS=ipv6 \
-h mail.my-domain.com -t "${NAME}"
teardown() { docker rm -f mail_postfix_inet_ipv6; }
wait_for_finished_setup_in_container mail_postfix_inet_ipv6
run docker exec mail_postfix_inet_ipv6 postconf inet_protocols run docker exec mail_postfix_inet_ipv6 postconf inet_protocols
assert_output "inet_protocols = ipv6" assert_output "inet_protocols = ipv6"
assert_success assert_success
} }
@test "last" {
skip 'this test is only there to reliably mark the end for the teardown_file'
}

View File

@ -12,12 +12,14 @@ teardown() {
} }
setup_file() { setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_postscreen \ docker run -d --name mail_postscreen \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e POSTSCREEN_ACTION=enforce \ -e POSTSCREEN_ACTION=enforce \
--cap-add=NET_ADMIN \ --cap-add=NET_ADMIN \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
docker run --name mail_postscreen_sender \ docker run --name mail_postscreen_sender \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
@ -59,4 +61,4 @@ teardown_file() {
@test "last" { @test "last" {
skip 'only used to call teardown_file from teardown' skip 'only used to call teardown_file from teardown'
} }

View File

@ -9,15 +9,17 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_privacy \ docker run -d --name mail_privacy \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SASL_PASSWD="external-domain.com username:password" \ -e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_MANAGESIEVE=1 \ -e ENABLE_MANAGESIEVE=1 \
--cap-add=SYS_PTRACE \ --cap-add=SYS_PTRACE \
-e PERMIT_DOCKER=host \ -e PERMIT_DOCKER=host \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
wait_for_amavis_port_in_container mail_privacy wait_for_amavis_port_in_container mail_privacy
wait_for_smtp_port_in_container mail_privacy wait_for_smtp_port_in_container mail_privacy

View File

@ -14,12 +14,14 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_no_quotas \ docker run -d --name mail_no_quotas \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e ENABLE_QUOTAS=0 \ -e ENABLE_QUOTAS=0 \
-h mail.my-domain.com -t "${NAME}" -h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_no_quotas wait_for_finished_setup_in_container mail_no_quotas
} }

View File

@ -9,14 +9,16 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run --rm -d --name mail_smtponly \ docker run --rm -d --name mail_smtponly \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SMTP_ONLY=1 \ -e SMTP_ONLY=1 \
-e PERMIT_DOCKER=network \ -e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e OVERRIDE_HOSTNAME=mail.my-domain.com \ -e OVERRIDE_HOSTNAME=mail.my-domain.com \
-t ${NAME} -t ${NAME}
wait_for_finished_setup_in_container mail_smtponly wait_for_finished_setup_in_container mail_smtponly
} }

View File

@ -14,20 +14,23 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_spam_bounced_defined)"
docker run -d --name mail_spam_bounced_defined \ docker run -d --name mail_spam_bounced_defined \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_SPAMASSASSIN=1 \ -e ENABLE_SPAMASSASSIN=1 \
-e SPAMASSASSIN_SPAM_TO_INBOX=0 \ -e SPAMASSASSIN_SPAM_TO_INBOX=0 \
-h mail.my-domain.com -t "${NAME}" -h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_spam_bounced_defined 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 \ docker run -d --name mail_spam_bounced_undefined \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_SPAMASSASSIN=1 \ -e ENABLE_SPAMASSASSIN=1 \
-h mail.my-domain.com -t "${NAME}" -h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_spam_bounced_undefined wait_for_finished_setup_in_container mail_spam_bounced_undefined
} }

View File

@ -4,49 +4,22 @@ load 'test_helper/common'
# --------- # ---------
# When SPAMASSASSIN_SPAM_TO_INBOX=1, spam messages must be delivered and eventually (MOVE_SPAM_TO_JUNK=1) moved to the Junk folder. # When SPAMASSASSIN_SPAM_TO_INBOX=1, spam messages must be delivered and eventually (MOVE_SPAM_TO_JUNK=1) moved to the Junk folder.
function setup() {
run_setup_file_if_necessary
}
function teardown() {
run_teardown_file_if_necessary
}
function setup_file() {
docker run -d --name mail_spam_moved_junk \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_SPAMASSASSIN=1 \
-e SPAMASSASSIN_SPAM_TO_INBOX=1 \
-e MOVE_SPAM_TO_JUNK=1 \
-e SA_SPAM_SUBJECT="SPAM: " \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_spam_moved_junk
docker run -d --name mail_spam_moved_new \
-v "`pwd`/test/config":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_SPAMASSASSIN=1 \
-e SPAMASSASSIN_SPAM_TO_INBOX=1 \
-e MOVE_SPAM_TO_JUNK=0 \
-e SA_SPAM_SUBJECT="SPAM: " \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail_spam_moved_new
}
function teardown_file() {
docker rm -f mail_spam_moved_new
docker rm -f mail_spam_moved_junk
}
@test "first" {
skip 'this test must come first to reliably identify when to run setup_file'
}
@test "checking amavis: spam message is delivered and moved to the Junk folder (MOVE_SPAM_TO_JUNK=1)" { @test "checking amavis: spam message is delivered and moved to the Junk folder (MOVE_SPAM_TO_JUNK=1)" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_spam_moved_junk)"
docker run -d --name mail_spam_moved_junk \
-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=1 \
-e MOVE_SPAM_TO_JUNK=1 \
-e SA_SPAM_SUBJECT="SPAM: " \
-h mail.my-domain.com -t "${NAME}"
teardown() { docker rm -f mail_spam_moved_junk; }
wait_for_smtp_port_in_container mail_spam_moved_junk
# send a spam message # send a spam message
run docker exec mail_spam_moved_junk /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt" run docker exec mail_spam_moved_junk /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt"
assert_success assert_success
@ -60,6 +33,21 @@ function teardown_file() {
} }
@test "checking amavis: spam message is delivered to INBOX (MOVE_SPAM_TO_JUNK=0)" { @test "checking amavis: spam message is delivered to INBOX (MOVE_SPAM_TO_JUNK=0)" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_spam_moved_new)"
docker run -d --name mail_spam_moved_new \
-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=1 \
-e MOVE_SPAM_TO_JUNK=0 \
-e SA_SPAM_SUBJECT="SPAM: " \
-h mail.my-domain.com -t "${NAME}"
teardown() { docker rm -f mail_spam_moved_new; }
wait_for_smtp_port_in_container mail_spam_moved_new
# send a spam message # send a spam message
run docker exec mail_spam_moved_new /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt" run docker exec mail_spam_moved_new /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt"
assert_success assert_success
@ -71,7 +59,3 @@ function teardown_file() {
run repeat_until_success_or_timeout 20 sh -c "docker exec mail_spam_moved_new sh -c 'grep \"Subject: SPAM: \" /var/mail/localhost.localdomain/user1/new/ -R'" run repeat_until_success_or_timeout 20 sh -c "docker exec mail_spam_moved_new sh -c 'grep \"Subject: SPAM: \" /var/mail/localhost.localdomain/user1/new/ -R'"
assert_success assert_success
} }
@test "last" {
skip 'this test is only there to reliably mark the end for the teardown_file'
}

View File

@ -9,9 +9,11 @@ teardown() {
} }
setup_file() { setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_special_use_folders \ docker run -d --name mail_special_use_folders \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SASL_PASSWD="external-domain.com username:password" \ -e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_CLAMAV=0 \ -e ENABLE_CLAMAV=0 \
-e ENABLE_SPAMASSASSIN=0 \ -e ENABLE_SPAMASSASSIN=0 \

View File

@ -0,0 +1,38 @@
load 'test_helper/common'
@test "checking SRS: SRS_DOMAINNAME is used correctly" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_srs_domainname)"
docker run --rm -d --name mail_srs_domainname \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \
-e ENABLE_SRS=1 \
-e SRS_DOMAINNAME=srs.my-domain.com \
-e DOMAINNAME=my-domain.com \
-h unknown.domain.tld \
-t ${NAME}
teardown() { docker rm -f mail_srs_domainname; }
repeat_until_success_or_timeout 15 docker exec mail_srs_domainname grep "SRS_DOMAIN=srs.my-domain.com" /etc/default/postsrsd
}
@test "checking SRS: DOMAINNAME is handled correctly" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_domainname)"
docker run --rm -d --name mail_domainname \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e PERMIT_DOCKER=network \
-e DMS_DEBUG=0 \
-e ENABLE_SRS=1 \
-e DOMAINNAME=my-domain.com \
-h unknown.domain.tld \
-t ${NAME}
teardown() { docker rm -f mail_domainname; }
repeat_until_success_or_timeout 15 docker exec mail_domainname grep "SRS_DOMAIN=my-domain.com" /etc/default/postsrsd
}

View File

@ -9,29 +9,34 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_lets_domain)"
docker run -d --name mail_lets_domain \ docker run -d --name mail_lets_domain \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-v "`pwd`/test/config/letsencrypt/my-domain.com":/etc/letsencrypt/live/my-domain.com \ -v "${PRIVATE_CONFIG}/letsencrypt/my-domain.com":/etc/letsencrypt/live/my-domain.com \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e SSL_TYPE=letsencrypt \ -e SSL_TYPE=letsencrypt \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
wait_for_finished_setup_in_container mail_lets_domain wait_for_finished_setup_in_container mail_lets_domain
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_lets_hostname)"
docker run -d --name mail_lets_hostname \ docker run -d --name mail_lets_hostname \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-v "`pwd`/test/config/letsencrypt/mail.my-domain.com":/etc/letsencrypt/live/mail.my-domain.com \ -v "${PRIVATE_CONFIG}/letsencrypt/mail.my-domain.com":/etc/letsencrypt/live/mail.my-domain.com \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e SSL_TYPE=letsencrypt \ -e SSL_TYPE=letsencrypt \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
wait_for_finished_setup_in_container mail_lets_hostname wait_for_finished_setup_in_container mail_lets_hostname
cp "`pwd`/test/config/letsencrypt/acme.json" "`pwd`/test/config/acme.json" PRIVATE_CONFIG="$(duplicate_config_for_container . mail_lets_acme_json)"
cp "$(private_config_path mail_lets_acme_json)/letsencrypt/acme.json" "$(private_config_path mail_lets_acme_json)/acme.json"
docker run -d --name mail_lets_acme_json \ docker run -d --name mail_lets_acme_json \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/config/acme.json":/etc/letsencrypt/acme.json:ro \ -v "${PRIVATE_CONFIG}/acme.json":/etc/letsencrypt/acme.json:ro \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e SSL_TYPE=letsencrypt \ -e SSL_TYPE=letsencrypt \
-e "SSL_DOMAIN=*.example.com" \ -e "SSL_DOMAIN=*.example.com" \
@ -44,7 +49,6 @@ function teardown_file() {
docker rm -f mail_lets_domain docker rm -f mail_lets_domain
docker rm -f mail_lets_hostname docker rm -f mail_lets_hostname
docker rm -f mail_lets_acme_json docker rm -f mail_lets_acme_json
rm "`pwd`/test/config/acme.json"
} }
# this test must come first to reliably identify when to run setup_file # this test must come first to reliably identify when to run setup_file
@ -103,16 +107,16 @@ function teardown_file() {
@test "can extract certs from acme.json" { @test "can extract certs from acme.json" {
run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/key.pem" run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/key.pem"
assert_output "$(cat "`pwd`/test/config/letsencrypt/mail.my-domain.com/privkey.pem")" assert_output "$(cat "$(private_config_path mail_lets_acme_json)/letsencrypt/mail.my-domain.com/privkey.pem")"
assert_success assert_success
run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/fullchain.pem" run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/fullchain.pem"
assert_output "$(cat "`pwd`/test/config/letsencrypt/mail.my-domain.com/fullchain.pem")" assert_output "$(cat "$(private_config_path mail_lets_acme_json)/letsencrypt/mail.my-domain.com/fullchain.pem")"
assert_success assert_success
} }
@test "can detect changes" { @test "can detect changes" {
cp "`pwd`/test/config/letsencrypt/acme-changed.json" "`pwd`/test/config/acme.json" cp "$(private_config_path mail_lets_acme_json)/letsencrypt/acme-changed.json" "$(private_config_path mail_lets_acme_json)/acme.json"
sleep 11 sleep 11
run docker exec mail_lets_acme_json /bin/bash -c "supervisorctl tail changedetector" run docker exec mail_lets_acme_json /bin/bash -c "supervisorctl tail changedetector"
assert_output --partial "Cert found in /etc/letsencrypt/acme.json for *.example.com" assert_output --partial "Cert found in /etc/letsencrypt/acme.json for *.example.com"
@ -121,11 +125,11 @@ function teardown_file() {
assert_output --partial "Change detected" assert_output --partial "Change detected"
run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/key.pem" run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/key.pem"
assert_output "$(cat "`pwd`/test/config/letsencrypt/changed/key.pem")" assert_output "$(cat "$(private_config_path mail_lets_acme_json)/letsencrypt/changed/key.pem")"
assert_success assert_success
run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/fullchain.pem" run docker exec mail_lets_acme_json /bin/bash -c "cat /etc/letsencrypt/live/mail.my-domain.com/fullchain.pem"
assert_output "$(cat "`pwd`/test/config/letsencrypt/changed/fullchain.pem")" assert_output "$(cat "$(private_config_path mail_lets_acme_json)/letsencrypt/changed/fullchain.pem")"
assert_success assert_success
} }

View File

@ -9,14 +9,16 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_manual_ssl \ docker run -d --name mail_manual_ssl \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SSL_TYPE=manual \ -e SSL_TYPE=manual \
-e SSL_CERT_PATH=/tmp/docker-mailserver/letsencrypt/mail.my-domain.com/fullchain.pem \ -e SSL_CERT_PATH=/tmp/docker-mailserver/letsencrypt/mail.my-domain.com/fullchain.pem \
-e SSL_KEY_PATH=/tmp/docker-mailserver/letsencrypt/mail.my-domain.com/privkey.pem \ -e SSL_KEY_PATH=/tmp/docker-mailserver/letsencrypt/mail.my-domain.com/privkey.pem \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
wait_for_finished_setup_in_container mail_manual_ssl wait_for_finished_setup_in_container mail_manual_ssl
} }
@ -51,10 +53,11 @@ function teardown_file() {
} }
@test "checking ssl: manual cert works correctly" { @test "checking ssl: manual cert works correctly" {
wait_for_tcp_port_in_container 587 mail_manual_ssl
run docker exec mail_manual_ssl /bin/sh -c "timeout 1 openssl s_client -connect 0.0.0.0:587 -starttls smtp -CApath /etc/ssl/certs/ | grep 'Verify return code: 10 (certificate has expired)'" run docker exec mail_manual_ssl /bin/sh -c "timeout 1 openssl s_client -connect 0.0.0.0:587 -starttls smtp -CApath /etc/ssl/certs/ | grep 'Verify return code: 10 (certificate has expired)'"
assert_success assert_success
} }
@test "last" { @test "last" {
skip 'this test is only there to reliably mark the end for the teardown_file' skip 'this test is only there to reliably mark the end for the teardown_file'
} }

View File

@ -1,33 +1,37 @@
load 'test_helper/common' load 'test_helper/common'
function setup() { function setup() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_undef_spam_subject \ docker run -d --name mail_undef_spam_subject \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_SPAMASSASSIN=1 \ -e ENABLE_SPAMASSASSIN=1 \
-e SA_SPAM_SUBJECT="undef" \ -e SA_SPAM_SUBJECT="undef" \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_undef_spam_subject_2)"
CONTAINER=$(docker run -d \ CONTAINER=$(docker run -d \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-v "`pwd`/test/onedir":/var/mail-state \ -v "$(pwd)/test/onedir":/var/mail-state \
-e ENABLE_CLAMAV=1 \ -e ENABLE_CLAMAV=1 \
-e SPOOF_PROTECTION=1 \ -e SPOOF_PROTECTION=1 \
-e ENABLE_SPAMASSASSIN=1 \ -e ENABLE_SPAMASSASSIN=1 \
-e REPORT_RECIPIENT=user1@localhost.localdomain \ -e REPORT_RECIPIENT=user1@localhost.localdomain \
-e REPORT_SENDER=report1@mail.my-domain.com \ -e REPORT_SENDER=report1@mail.my-domain.com \
-e SA_TAG=-5.0 \ -e SA_TAG=-5.0 \
-e SA_TAG2=2.0 \ -e SA_TAG2=2.0 \
-e SA_KILL=3.0 \ -e SA_KILL=3.0 \
-e SA_SPAM_SUBJECT="SPAM: " \ -e SA_SPAM_SUBJECT="SPAM: " \
-e VIRUSMAILS_DELETE_DELAY=7 \ -e VIRUSMAILS_DELETE_DELAY=7 \
-e ENABLE_SRS=1 \ -e ENABLE_SRS=1 \
-e SASL_PASSWD="external-domain.com username:password" \ -e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_MANAGESIEVE=1 \ -e ENABLE_MANAGESIEVE=1 \
--cap-add=SYS_PTRACE \ --cap-add=SYS_PTRACE \
-e PERMIT_DOCKER=host \ -e PERMIT_DOCKER=host \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME}) -h mail.my-domain.com -t ${NAME})
wait_for_finished_setup_in_container mail_undef_spam_subject wait_for_finished_setup_in_container mail_undef_spam_subject
wait_for_finished_setup_in_container "$CONTAINER" wait_for_finished_setup_in_container "$CONTAINER"
} }
@ -47,4 +51,4 @@ function teardown() {
assert_success assert_success
run docker exec mail_undef_spam_subject /bin/sh -c "grep '\$sa_spam_subject_tag' /etc/amavis/conf.d/20-debian_defaults | grep '= undef'" run docker exec mail_undef_spam_subject /bin/sh -c "grep '\$sa_spam_subject_tag' /etc/amavis/conf.d/20-debian_defaults | grep '= undef'"
assert_success assert_success
} }

View File

@ -10,9 +10,11 @@ teardown() {
} }
setup_file() { setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_with_imap \ docker run -d --name mail_with_imap \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_SASLAUTHD=1 \ -e ENABLE_SASLAUTHD=1 \
-e SASLAUTHD_MECHANISMS=rimap \ -e SASLAUTHD_MECHANISMS=rimap \
-e SASLAUTHD_MECH_OPTIONS=127.0.0.1 \ -e SASLAUTHD_MECH_OPTIONS=127.0.0.1 \

View File

@ -15,11 +15,13 @@ function setup_file() {
docker run -d --name ldap_for_mail \ docker run -d --name ldap_for_mail \
-e LDAP_DOMAIN="localhost.localdomain" \ -e LDAP_DOMAIN="localhost.localdomain" \
-h ldap.my-domain.com -t ldap -h ldap.my-domain.com -t ldap
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_with_ldap \ docker run -d --name mail_with_ldap \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_LDAP=1 \ -e ENABLE_LDAP=1 \
-e LDAP_SERVER_HOST=ldap \ -e LDAP_SERVER_HOST=ldap \
-e LDAP_START_TLS=no \ -e LDAP_START_TLS=no \
@ -214,7 +216,7 @@ function teardown_file() {
# Pflogsumm delivery check # Pflogsumm delivery check
# #
@test "checking pflogsum delivery" { @test "checking pflogsum delivery" {
# checking default sender is correctly set when env variable not defined # checking default sender is correctly set when env variable not defined
run docker exec mail_with_ldap grep "mailserver-report@mail.my-domain.com" /etc/logrotate.d/maillog run docker exec mail_with_ldap grep "mailserver-report@mail.my-domain.com" /etc/logrotate.d/maillog
assert_success assert_success

View File

@ -9,9 +9,11 @@ teardown() {
} }
setup_file() { setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_with_mdbox_format \ docker run -d --name mail_with_mdbox_format \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SASL_PASSWD="external-domain.com username:password" \ -e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_CLAMAV=0 \ -e ENABLE_CLAMAV=0 \
-e ENABLE_SPAMASSASSIN=0 \ -e ENABLE_SPAMASSASSIN=0 \

View File

@ -9,16 +9,18 @@ function teardown() {
} }
function setup_file() { function setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_with_postgrey \ docker run -d --name mail_with_postgrey \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e ENABLE_POSTGREY=1 \ -e ENABLE_POSTGREY=1 \
-e POSTGREY_DELAY=15 \ -e POSTGREY_DELAY=15 \
-e POSTGREY_MAX_AGE=35 \ -e POSTGREY_MAX_AGE=35 \
-e POSTGREY_AUTO_WHITELIST_CLIENTS=5 \ -e POSTGREY_AUTO_WHITELIST_CLIENTS=5 \
-e POSTGREY_TEXT="Delayed by postgrey" \ -e POSTGREY_TEXT="Delayed by postgrey" \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME} -h mail.my-domain.com -t ${NAME}
# using postfix availability as start indicator, this might be insufficient for postgrey # using postfix availability as start indicator, this might be insufficient for postgrey
wait_for_smtp_port_in_container mail_with_postgrey wait_for_smtp_port_in_container mail_with_postgrey
} }
@ -98,4 +100,4 @@ function teardown_file() {
@test "last" { @test "last" {
# this test is only there to reliably mark the end for the teardown_file # this test is only there to reliably mark the end for the teardown_file
} }

View File

@ -1,11 +1,13 @@
load 'test_helper/common' load 'test_helper/common'
function setup() { function setup() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
CONTAINER=$(docker run -d \ CONTAINER=$(docker run -d \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-h mail.my-domain.com -t ${NAME}) -h mail.my-domain.com -t ${NAME})
# using postfix availability as start indicator, this might be insufficient for postgrey # using postfix availability as start indicator, this might be insufficient for postgrey
wait_for_smtp_port_in_container $CONTAINER wait_for_smtp_port_in_container $CONTAINER
} }
@ -17,4 +19,4 @@ function teardown() {
@test "checking process: postgrey (disabled in default configuration)" { @test "checking process: postgrey (disabled in default configuration)" {
run docker exec $CONTAINER /bin/bash -c "ps aux --forest | grep -v grep | grep 'postgrey'" run docker exec $CONTAINER /bin/bash -c "ps aux --forest | grep -v grep | grep 'postgrey'"
assert_failure assert_failure
} }

View File

@ -16,7 +16,7 @@ function setup_file() {
docker run -d --name mail_with_relays \ docker run -d --name mail_with_relays \
-v "$tmp_confdir":/tmp/docker-mailserver \ -v "$tmp_confdir":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e RELAY_HOST=default.relay.com \ -e RELAY_HOST=default.relay.com \
-e RELAY_PORT=2525 \ -e RELAY_PORT=2525 \
-e RELAY_USER=smtp_user \ -e RELAY_USER=smtp_user \
@ -51,11 +51,7 @@ function teardown_file() {
run docker exec mail_with_relays grep -e domainzero.tld /etc/postfix/relayhost_map run docker exec mail_with_relays grep -e domainzero.tld /etc/postfix/relayhost_map
assert_output '' assert_output ''
run ./setup.sh -c mail_with_relays email add user0@domainzero.tld password123 run ./setup.sh -c mail_with_relays email add user0@domainzero.tld password123
for i in {1..10}; do run_until_success_or_timeout 10 docker exec mail_with_relays grep -e domainzero.tld /etc/postfix/relayhost_map
sleep 1
run docker exec mail_with_relays grep -e domainzero.tld /etc/postfix/relayhost_map
[[ $status == 0 ]] && break
done
assert_output -e '^@domainzero.tld\s+\[default.relay.com\]:2525$' assert_output -e '^@domainzero.tld\s+\[default.relay.com\]:2525$'
} }
@ -63,11 +59,7 @@ function teardown_file() {
run docker exec mail_with_relays grep -e domain2.tld /etc/postfix/relayhost_map run docker exec mail_with_relays grep -e domain2.tld /etc/postfix/relayhost_map
assert_output '' assert_output ''
run ./setup.sh -c mail_with_relays alias add user2@domain2.tld user2@domaintwo.tld run ./setup.sh -c mail_with_relays alias add user2@domain2.tld user2@domaintwo.tld
for i in {1..10}; do run_until_success_or_timeout 10 docker exec mail_with_relays grep -e domain2.tld /etc/postfix/relayhost_map
sleep 1
run docker exec mail_with_relays grep -e domain2.tld /etc/postfix/relayhost_map
[[ $status == 0 ]] && break
done
assert_output -e '^@domain2.tld\s+\[default.relay.com\]:2525$' assert_output -e '^@domain2.tld\s+\[default.relay.com\]:2525$'
} }

View File

@ -9,9 +9,11 @@ teardown() {
} }
setup_file() { setup_file() {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container .)"
docker run -d --name mail_with_sdbox_format \ docker run -d --name mail_with_sdbox_format \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SASL_PASSWD="external-domain.com username:password" \ -e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_CLAMAV=0 \ -e ENABLE_CLAMAV=0 \
-e ENABLE_SPAMASSASSIN=0 \ -e ENABLE_SPAMASSASSIN=0 \

View File

@ -7,26 +7,29 @@ setup() {
# use two networks (default ("bridge") and our custom network) to recreate problematic test case where PERMIT_DOCKER=host would not help # use two networks (default ("bridge") and our custom network) to recreate problematic test case where PERMIT_DOCKER=host would not help
# currently we cannot use --network in `docker run` multiple times, it will just use the last one # currently we cannot use --network in `docker run` multiple times, it will just use the last one
# instead we need to use create, network connect and start (see https://success.docker.com/article/multiple-docker-networks) # instead we need to use create, network connect and start (see https://success.docker.com/article/multiple-docker-networks)
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_smtponly_second_network)"
docker create --name mail_smtponly_second_network \ docker create --name mail_smtponly_second_network \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SMTP_ONLY=1 \ -e SMTP_ONLY=1 \
-e PERMIT_DOCKER=connected-networks \ -e PERMIT_DOCKER=connected-networks \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e OVERRIDE_HOSTNAME=mail.my-domain.com \ -e OVERRIDE_HOSTNAME=mail.my-domain.com \
--network ${NON_DEFAULT_DOCKER_MAIL_NETWORK_NAME} \ --network "${NON_DEFAULT_DOCKER_MAIL_NETWORK_NAME}" \
-t ${NAME} -t "${NAME}"
docker network connect ${NON_DEFAULT_DOCKER_MAIL_NETWORK_NAME}2 mail_smtponly_second_network docker network connect "${NON_DEFAULT_DOCKER_MAIL_NETWORK_NAME}2" mail_smtponly_second_network
docker start mail_smtponly_second_network docker start mail_smtponly_second_network
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_smtponly_second_network_sender)"
docker run -d --name mail_smtponly_second_network_sender \ docker run -d --name mail_smtponly_second_network_sender \
-v "`pwd`/test/config":/tmp/docker-mailserver \ -v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "`pwd`/test/test-files":/tmp/docker-mailserver-test:ro \ -v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-e SMTP_ONLY=1 \ -e SMTP_ONLY=1 \
-e PERMIT_DOCKER=connected-networks \ -e PERMIT_DOCKER=connected-networks \
-e DMS_DEBUG=0 \ -e DMS_DEBUG=0 \
-e OVERRIDE_HOSTNAME=mail.my-domain.com \ -e OVERRIDE_HOSTNAME=mail.my-domain.com \
--network ${NON_DEFAULT_DOCKER_MAIL_NETWORK_NAME}2 \ --network "${NON_DEFAULT_DOCKER_MAIL_NETWORK_NAME}2" \
-t ${NAME} -t "${NAME}"
# wait until postfix is up # wait until postfix is up
wait_for_smtp_port_in_container mail_smtponly_second_network wait_for_smtp_port_in_container mail_smtponly_second_network
@ -56,4 +59,4 @@ teardown() {
repeat_until_success_or_timeout 60 run docker exec mail_smtponly_second_network /bin/sh -c 'grep -cE "to=<user2\@external.tld>.*status\=sent" /var/log/mail/mail.log' repeat_until_success_or_timeout 60 run docker exec mail_smtponly_second_network /bin/sh -c 'grep -cE "to=<user2\@external.tld>.*status\=sent" /var/log/mail/mail.log'
[ "$status" -ge 0 ] [ "$status" -ge 0 ]
} }

251
test/test_helper.bats Normal file
View File

@ -0,0 +1,251 @@
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/common'
@test "repeat_until_success_or_timeout returns instantly on success" {
SECONDS=0
repeat_until_success_or_timeout 1 true
[[ ${SECONDS} -le 1 ]]
}
@test "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 "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 "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 "run_until_success_or_timeout returns instantly on success" {
SECONDS=0
run_until_success_or_timeout 2 true
[[ ${SECONDS} -le 1 ]]
assert_success
}
@test "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 "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 "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 "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 "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"
}
@test "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 "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 "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 "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 "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 detection to complete
repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" test -e /tmp/docker-mailserver-config-chksum
# 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 "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 detection to complete
repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" test -e /tmp/docker-mailserver-config-chksum
# 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 ]]
}
@test "wait_for_empty_mail_queue_in_container fails when timeout reached" {
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}"
}
@test "wait_for_empty_mail_queue_in_container succeeds within timeout" {
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 ]]
}

View File

@ -1,70 +1,136 @@
#! /bin/bash
load 'test_helper/bats-support/load' load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load' load 'test_helper/bats-assert/load'
# shellcheck disable=SC2034
NAME=tvial/docker-mailserver:testing NAME=tvial/docker-mailserver:testing
# default timeout is 120 seconds # default timeout is 120 seconds
TEST_TIMEOUT_IN_SECONDS=${TEST_TIMEOUT_IN_SECONDS-120} TEST_TIMEOUT_IN_SECONDS=${TEST_TIMEOUT_IN_SECONDS-120}
NUMBER_OF_LOG_LINES=${NUMBER_OF_LOG_LINES-10} NUMBER_OF_LOG_LINES=${NUMBER_OF_LOG_LINES-10}
# @param ${1} timeout
# @param --fatal-test <command eval string> additional test whose failure aborts immediately
# @param ... test to run
function repeat_until_success_or_timeout { function repeat_until_success_or_timeout {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then local FATAL_FAILURE_TEST_COMMAND
echo "First parameter for timeout must be an integer, recieved \"$1\"" if [[ "${1}" == "--fatal-test" ]]; then
FATAL_FAILURE_TEST_COMMAND="${2}"
shift 2
fi
if ! [[ "${1}" =~ ^[0-9]+$ ]]; then
echo "First parameter for timeout must be an integer, recieved \"${1}\""
return 1 return 1
fi fi
TIMEOUT=$1 local TIMEOUT=${1}
STARTTIME=$SECONDS local STARTTIME=${SECONDS}
shift 1 shift 1
until "$@" until "${@}"
do do
sleep 5 if [[ -n ${FATAL_FAILURE_TEST_COMMAND} ]] && ! eval "${FATAL_FAILURE_TEST_COMMAND}"; then
if [[ $(($SECONDS - $STARTTIME )) -gt $TIMEOUT ]]; then echo "\`${FATAL_FAILURE_TEST_COMMAND}\` failed, early aborting repeat_until_success of \`${*}\`" >&2
echo "Timed out on command: $@" return 1
fi
sleep 1
if [[ $(( SECONDS - STARTTIME )) -gt ${TIMEOUT} ]]; then
echo "Timed out on command: ${*}" >&2
return 1 return 1
fi fi
done done
} }
# @param $1 port # like repeat_until_success_or_timeout but with wrapping the command to run into `run` for later bats consumption
# @param $2 container name # @param ${1} timeout
function wait_for_tcp_port_in_container() { # @param ... test command to run
repeat_until_success_or_timeout $TEST_TIMEOUT_IN_SECONDS docker exec $2 /bin/sh -c "nc -z 0.0.0.0 $1" function run_until_success_or_timeout {
} if ! [[ ${1} =~ ^[0-9]+$ ]]; then
echo "First parameter for timeout must be an integer, recieved \"${1}\""
# @param $1 name of the postfix container return 1
function wait_for_smtp_port_in_container() {
wait_for_tcp_port_in_container 25 $1
}
# @param $1 name of the postfix container
function wait_for_amavis_port_in_container() {
wait_for_tcp_port_in_container 10024 $1
}
# @param $1 name of the postfix container
function wait_for_finished_setup_in_container() {
local status=0
repeat_until_success_or_timeout $TEST_TIMEOUT_IN_SECONDS sh -c "docker logs $1 | grep 'is up and running'" || status=1
if [[ $status -eq 1 ]]; then
echo "Last $NUMBER_OF_LOG_LINES lines of container \`$1\`'s log"
docker logs $1 | tail -n $NUMBER_OF_LOG_LINES
fi fi
return $status local TIMEOUT=${1}
local STARTTIME=${SECONDS}
shift 1
until run "${@}" && [[ $status -eq 0 ]]
do
sleep 1
if (( SECONDS - STARTTIME > TIMEOUT )); then
echo "Timed out on command: ${*}" >&2
return 1
fi
done
} }
SETUP_FILE_MARKER="$BATS_TMPDIR/`basename \"$BATS_TEST_FILENAME\"`.setup_file" # @param ${1} timeout
# @param ${2} container name
# @param ... test command for container
function repeat_in_container_until_success_or_timeout() {
local TIMEOUT="${1}"
local CONTAINER_NAME="${2}"
shift 2
repeat_until_success_or_timeout --fatal-test "container_is_running ${CONTAINER_NAME}" "${TIMEOUT}" docker exec "${CONTAINER_NAME}" "${@}"
}
function container_is_running() {
[[ "$(docker inspect -f '{{.State.Running}}' "${1}")" == "true" ]]
}
# @param ${1} port
# @param ${2} container name
function wait_for_tcp_port_in_container() {
repeat_until_success_or_timeout --fatal-test "container_is_running ${2}" "${TEST_TIMEOUT_IN_SECONDS}" docker exec "${2}" /bin/sh -c "nc -z 0.0.0.0 ${1}"
}
# @param ${1} name of the postfix container
function wait_for_smtp_port_in_container() {
wait_for_tcp_port_in_container 25 "${1}"
}
# @param ${1} name of the postfix container
function wait_for_amavis_port_in_container() {
wait_for_tcp_port_in_container 10024 "${1}"
}
# @param ${1} name of the postfix container
function wait_for_finished_setup_in_container() {
local STATUS=0
repeat_until_success_or_timeout --fatal-test "container_is_running ${1}" "${TEST_TIMEOUT_IN_SECONDS}" sh -c "docker logs ${1} | grep 'is up and running'" || STATUS=1
if [[ ${STATUS} -eq 1 ]]; then
echo "Last ${NUMBER_OF_LOG_LINES} lines of container \`${1}\`'s log"
docker logs "${1}" | tail -n "${NUMBER_OF_LOG_LINES}"
fi
return ${STATUS}
}
SETUP_FILE_MARKER="${BATS_TMPDIR}/$(basename "${BATS_TEST_FILENAME}").setup_file"
function native_setup_teardown_file_support() {
local VERSION_REGEX='([0-9]+)\.([0-9]+)\.([0-9]+)'
# bats versions that support setup_file out of the box don't need this
if [[ "${BATS_VERSION}" =~ ${VERSION_REGEX} ]]; then
numeric_version=$(( (BASH_REMATCH[1] * 100 + BASH_REMATCH[2]) * 100 + BASH_REMATCH[3] ))
if [[ ${numeric_version} -ge 10201 ]]; then
if [ "${BATS_TEST_NAME}" == 'test_first' ]; then
skip 'This version natively supports setup/teardown_file'
fi
return 0
fi
fi
return 1
}
# use in setup() in conjunction with a `@test "first" {}` to trigger setup_file reliably # use in setup() in conjunction with a `@test "first" {}` to trigger setup_file reliably
function run_setup_file_if_necessary() { function run_setup_file_if_necessary() {
if [ "$BATS_TEST_NAME" == 'test_first' ]; then native_setup_teardown_file_support && return 0
if [ "${BATS_TEST_NAME}" == 'test_first' ]; then
# prevent old markers from marking success or get an error if we cannot remove due to permissions # prevent old markers from marking success or get an error if we cannot remove due to permissions
rm -f "$SETUP_FILE_MARKER" rm -f "${SETUP_FILE_MARKER}"
setup_file setup_file
touch "$SETUP_FILE_MARKER" touch "${SETUP_FILE_MARKER}"
else else
if [ ! -f "$SETUP_FILE_MARKER" ]; then if [ ! -f "${SETUP_FILE_MARKER}" ]; then
skip "setup_file failed" skip "setup_file failed"
return 1 return 1
fi fi
@ -73,9 +139,53 @@ function run_setup_file_if_necessary() {
# use in teardown() in conjunction with a `@test "last" {}` to trigger teardown_file reliably # use in teardown() in conjunction with a `@test "last" {}` to trigger teardown_file reliably
function run_teardown_file_if_necessary() { function run_teardown_file_if_necessary() {
if [ "$BATS_TEST_NAME" == 'test_last' ]; then native_setup_teardown_file_support && return 0
if [ "${BATS_TEST_NAME}" == 'test_last' ]; then
# cleanup setup file marker # cleanup setup file marker
rm -f "$SETUP_FILE_MARKER" rm -f "${SETUP_FILE_MARKER}"
teardown_file teardown_file
fi fi
} }
# get the private config path for the given container or test file, if no container name was given
function private_config_path() {
echo "${PWD}/test/duplicate_configs/${1:-$(basename "${BATS_TEST_FILENAME}")}"
}
# @param ${1} relative source in test/config folder
# @param ${2} (optional) container name, defaults to ${BATS_TEST_FILENAME}
# @return path to the folder where the config is duplicated
function duplicate_config_for_container() {
local OUTPUT_FOLDER
OUTPUT_FOLDER="$(private_config_path "${2}")" || return $?
rm -rf "${OUTPUT_FOLDER:?}/" || return $? # cleanup
mkdir -p "${OUTPUT_FOLDER}" || return $?
cp -r "${PWD}/test/config/${1:?}/." "${OUTPUT_FOLDER}" || return $?
echo "${OUTPUT_FOLDER}"
}
function container_has_service_running() {
local CONTAINER_NAME="${1}"
local SERVICE_NAME="${2}"
docker exec "${CONTAINER_NAME}" /usr/bin/supervisorctl status "${SERVICE_NAME}" | grep RUNNING >/dev/null
}
function wait_for_service() {
local CONTAINER_NAME="${1}"
local SERVICE_NAME="${2}"
repeat_until_success_or_timeout --fatal-test "container_is_running ${CONTAINER_NAME}" "${TEST_TIMEOUT_IN_SECONDS}" \
container_has_service_running "${CONTAINER_NAME}" "${SERVICE_NAME}"
}
function wait_for_changes_to_be_detected_in_container() {
local CONTAINER_NAME="${1}"
local TIMEOUT=${TEST_TIMEOUT_IN_SECONDS}
# shellcheck disable=SC2016
repeat_in_container_until_success_or_timeout "${TIMEOUT}" "${CONTAINER_NAME}" bash -c 'source /usr/local/bin/helper_functions.sh; cmp --silent -- <(_monitored_files_checksums) "${CHKSUM_FILE}" >/dev/null'
}
function wait_for_empty_mail_queue_in_container() {
local CONTAINER_NAME="${1}"
local TIMEOUT=${TEST_TIMEOUT_IN_SECONDS}
repeat_in_container_until_success_or_timeout "${TIMEOUT}" "${CONTAINER_NAME}" bash -c '[[ $(mailq) == *"Mail queue is empty"* ]]'
}

View File

@ -2,25 +2,88 @@ load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load' load 'test_helper/bats-assert/load'
load 'test_helper/common' load 'test_helper/common'
# export IMAGE_NAME
# shared functions IMAGE_NAME="${NAME}"
#
function wait_for_service() { setup() {
containerName=$1 run_setup_file_if_necessary
serviceName=$2
count=0
while ! (docker exec $containerName /usr/bin/supervisorctl status $serviceName | grep RUNNING >/dev/null)
do
((count++)) && ((count==30)) && break
sleep 5
done
return $(docker exec $containerName /usr/bin/supervisorctl status $serviceName | grep RUNNING >/dev/null)
} }
function count_processed_changes() { setup_file() {
containerName=$1 local PRIVATE_CONFIG
docker exec $containerName cat /var/log/supervisor/changedetector.log | grep "Change detected" | wc -l PRIVATE_CONFIG="$(duplicate_config_for_container . mail)"
mv "${PRIVATE_CONFIG}/user-patches/user-patches.sh" "${PRIVATE_CONFIG}/user-patches.sh"
docker run --rm -d --name mail \
-v "${PRIVATE_CONFIG}":/tmp/docker-mailserver \
-v "$(pwd)/test/test-files":/tmp/docker-mailserver-test:ro \
-v "$(pwd)/test/onedir":/var/mail-state \
-e ENABLE_CLAMAV=1 \
-e SPOOF_PROTECTION=1 \
-e ENABLE_SPAMASSASSIN=1 \
-e REPORT_RECIPIENT=user1@localhost.localdomain \
-e REPORT_SENDER=report1@mail.my-domain.com \
-e SA_TAG=-5.0 \
-e SA_TAG2=2.0 \
-e SA_KILL=3.0 \
-e SA_SPAM_SUBJECT="SPAM: " \
-e VIRUSMAILS_DELETE_DELAY=7 \
-e ENABLE_SRS=1 \
-e SASL_PASSWD="external-domain.com username:password" \
-e ENABLE_MANAGESIEVE=1 \
--cap-add=SYS_PTRACE \
-e PERMIT_DOCKER=host \
-e DMS_DEBUG=0 \
-h mail.my-domain.com -t "${NAME}"
wait_for_finished_setup_in_container mail
# generate accounts after container has been started
docker run --rm -e MAIL_USER=added@localhost.localdomain -e MAIL_PASS=mypassword -t "${NAME}" /bin/sh -c 'echo "${MAIL_USER}|$(doveadm pw -s SHA512-CRYPT -u ${MAIL_USER} -p ${MAIL_PASS})"' >> "${PRIVATE_CONFIG}/postfix-accounts.cf"
docker exec mail addmailuser pass@localhost.localdomain 'may be \a `p^a.*ssword'
# setup sieve
docker cp "${PRIVATE_CONFIG}/sieve/dovecot.sieve" mail:/var/mail/localhost.localdomain/user1/.dovecot.sieve
# this relies on the checksum file beeing updated after all changes have been applied
wait_for_changes_to_be_detected_in_container mail
wait_for_smtp_port_in_container mail
# wait for clamav to be fully setup or we will get errors on the log
repeat_in_container_until_success_or_timeout 60 mail test -e /var/run/clamav/clamd.ctl
# sending test mails
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-spam.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/amavis-virus.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-external.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-alias-recipient-delimiter.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user1.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user2.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-added.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-user-and-cc-local-alias.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-regexp-alias-external.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-regexp-alias-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/existing-catchall-local.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/sieve-spam-folder.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/sieve-pipe.txt"
docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/non-existing-user.txt"
docker exec mail /bin/sh -c "sendmail root < /tmp/docker-mailserver-test/email-templates/root-email.txt"
wait_for_empty_mail_queue_in_container mail
}
teardown() {
run_teardown_file_if_necessary
}
teardown_file() {
docker rm -f mail
}
# this test must come first to reliably identify when to run setup_file
@test "first" {
skip 'Starting testing of letsencrypt SSL'
} }
# #
@ -28,53 +91,15 @@ function count_processed_changes() {
# #
@test "checking configuration: user-patches.sh executed" { @test "checking configuration: user-patches.sh executed" {
run echo -n "`docker logs mail | grep 'user\-patches\.sh'`" run docker logs mail
assert_output --partial "Default user-patches.sh successfully executed" assert_output --partial "Default user-patches.sh successfully executed"
} }
@test "checking configuration: hostname/domainname" { @test "checking configuration: hostname/domainname" {
run docker run `docker inspect --format '{{ .Config.Image }}' mail` run docker run "${IMAGE_NAME:?}"
assert_success assert_success
} }
@test "checking configuration: hostname/domainname override: check container hostname is applied correctly" {
run docker exec mail_override_hostname /bin/bash -c "hostname | grep unknown.domain.tld"
assert_success
}
@test "checking configuration: hostname/domainname override: check overriden hostname is applied to all configs" {
run docker exec mail_override_hostname /bin/bash -c "cat /etc/mailname | grep my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "postconf -n | grep mydomain | grep my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "postconf -n | grep myhostname | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "doveconf | grep hostname | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "cat /etc/opendmarc.conf | grep AuthservID | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "cat /etc/opendmarc.conf | grep TrustedAuthservIDs | grep mail.my-domain.com"
assert_success
run docker exec mail_override_hostname /bin/bash -c "cat /etc/amavis/conf.d/05-node_id | grep myhostname | grep mail.my-domain.com"
assert_success
}
@test "checking configuration: hostname/domainname override: check hostname in postfix HELO message" {
run docker exec mail_override_hostname /bin/bash -c "nc -w 1 0.0.0.0 25 | grep mail.my-domain.com"
assert_success
}
@test "checking configuration: hostname/domainname override: check headers of received mail" {
run docker exec mail_override_hostname /bin/sh -c "ls -A /var/mail/localhost.localdomain/user1/new | wc -l | grep 1"
assert_success
run docker exec mail_override_hostname /bin/sh -c "cat /var/mail/localhost.localdomain/user1/new/* | grep mail.my-domain.com"
assert_success
# test whether the container hostname is not found in received mail
run docker exec mail_override_hostname /bin/sh -c "cat /var/mail/localhost.localdomain/user1/new/* | grep unknown.domain.tld"
assert_failure
}
# #
# processes # processes
# #
@ -114,11 +139,6 @@ function count_processed_changes() {
assert_failure assert_failure
} }
@test "checking process: clamav (clamav disabled by ENABLED_CLAMAV=0)" {
run docker exec mail_disabled_clamav_spamassassin /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'"
assert_failure
}
# #
# imap # imap
# #
@ -182,7 +202,8 @@ function count_processed_changes() {
} }
@test "checking smtp: authentication fails with wrong password (plain)" { @test "checking smtp: authentication fails with wrong password (plain)" {
run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-plain-wrong.txt | grep 'authentication failed'" run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-plain-wrong.txt"
assert_output --partial 'authentication failed'
assert_success assert_success
} }
@ -192,7 +213,8 @@ function count_processed_changes() {
} }
@test "checking smtp: authentication fails with wrong password (login)" { @test "checking smtp: authentication fails with wrong password (login)" {
run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt | grep 'authentication failed'" run docker exec mail /bin/sh -c "nc -w 20 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/smtp-auth-login-wrong.txt"
assert_output --partial 'authentication failed'
assert_success assert_success
} }
@ -219,7 +241,7 @@ function count_processed_changes() {
@test "checking smtp: delivers mail to existing account" { @test "checking smtp: delivers mail to existing account" {
run docker exec mail /bin/sh -c "grep 'postfix/lmtp' /var/log/mail/mail.log | grep 'status=sent' | grep ' Saved)' | sed 's/.* to=</</g' | sed 's/, relay.*//g' | sort | uniq -c | tr -s \" \"" run docker exec mail /bin/sh -c "grep 'postfix/lmtp' /var/log/mail/mail.log | grep 'status=sent' | grep ' Saved)' | sed 's/.* to=</</g' | sed 's/, relay.*//g' | sort | uniq -c | tr -s \" \""
assert_success assert_success
cat <<'EOF' | assert_output assert_output <<'EOF'
1 <added@localhost.localdomain> 1 <added@localhost.localdomain>
6 <user1@localhost.localdomain> 6 <user1@localhost.localdomain>
1 <user1@localhost.localdomain>, orig_to=<postmaster@my-domain.com> 1 <user1@localhost.localdomain>, orig_to=<postmaster@my-domain.com>
@ -314,9 +336,9 @@ EOF
@test "checking accounts: user accounts" { @test "checking accounts: user accounts" {
run docker exec mail doveadm user '*' run docker exec mail doveadm user '*'
assert_success assert_success
[ "${lines[0]}" = "user1@localhost.localdomain" ] assert_line --index 0 "user1@localhost.localdomain"
[ "${lines[1]}" = "user2@otherdomain.tld" ] assert_line --index 1 "user2@otherdomain.tld"
[ "${lines[2]}" = "added@localhost.localdomain" ] assert_line --index 2 "added@localhost.localdomain"
} }
@test "checking accounts: user mail folder for user1" { @test "checking accounts: user mail folder for user1" {
@ -346,9 +368,9 @@ EOF
@test "checking postfix: vhost file is correct" { @test "checking postfix: vhost file is correct" {
run docker exec mail cat /etc/postfix/vhost run docker exec mail cat /etc/postfix/vhost
assert_success assert_success
[ "${lines[0]}" = "localdomain2.com" ] assert_line --index 0 "localdomain2.com"
[ "${lines[1]}" = "localhost.localdomain" ] assert_line --index 1 "localhost.localdomain"
[ "${lines[2]}" = "otherdomain.tld" ] assert_line --index 2 "otherdomain.tld"
} }
@test "checking postfix: main.cf overrides" { @test "checking postfix: main.cf overrides" {
@ -384,11 +406,6 @@ EOF
assert_failure assert_failure
} }
@test "checking spamassassin: should not be listed in amavis when disabled" {
run docker exec mail_disabled_clamav_spamassassin /bin/sh -c "grep -i 'ANTI-SPAM-SA code' /var/log/mail/mail.log | grep 'NOT loaded'"
assert_success
}
@test "checking spamassassin: all registered domains should see spam headers" { @test "checking spamassassin: all registered domains should see spam headers" {
run docker exec mail /bin/sh -c "grep -ir 'X-Spam-' /var/mail/localhost.localdomain/user1/new" run docker exec mail /bin/sh -c "grep -ir 'X-Spam-' /var/mail/localhost.localdomain/user1/new"
assert_success assert_success
@ -406,16 +423,6 @@ EOF
assert_success assert_success
} }
@test "checking clamav: should not be listed in amavis when disabled" {
run docker exec mail_disabled_clamav_spamassassin grep -i 'Found secondary av scanner ClamAV-clamscan' /var/log/mail/mail.log
assert_failure
}
@test "checking clamav: should not be called when disabled" {
run docker exec mail_disabled_clamav_spamassassin grep -i 'connect to /var/run/clamav/clamd.ctl failed' /var/log/mail/mail.log
assert_failure
}
# #
# opendkim # opendkim
# #
@ -427,7 +434,16 @@ EOF
} }
@test "checking opendkim: /etc/opendkim/KeyTable dummy file generated without keys provided" { @test "checking opendkim: /etc/opendkim/KeyTable dummy file generated without keys provided" {
run docker exec mail_smtponly_without_config /bin/bash -c "cat /etc/opendkim/KeyTable" docker run --rm -d --name mail_smtponly_without_config \
-e SMTP_ONLY=1 \
-e ENABLE_LDAP=1 \
-e PERMIT_DOCKER=network \
-e OVERRIDE_HOSTNAME=mail.mydomain.com \
-t "${NAME}"
teardown() { docker rm -f mail_smtponly_without_config; }
run repeat_in_container_until_success_or_timeout 15 mail_smtponly_without_config /bin/bash -c "cat /etc/opendkim/KeyTable"
assert_success assert_success
} }
@ -448,19 +464,23 @@ EOF
# Instead it tests the file-size (here 511) - which may differ with a different domain names # Instead it tests the file-size (here 511) - which may differ with a different domain names
# This test may be re-used as a global test to provide better test coverage. # This test may be re-used as a global test to provide better test coverage.
@test "checking opendkim: generator creates default keys size" { @test "checking opendkim: generator creates default keys size" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_default_key_size)"
# Prepare default key size 2048 # Prepare default key size 2048
rm -rf "$(pwd)/test/config/keyDefault" && mkdir -p "$(pwd)/test/config/keyDefault" rm -rf "${PRIVATE_CONFIG}/keyDefault"
mkdir -p "${PRIVATE_CONFIG}/keyDefault"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/keyDefault/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/keyDefault/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config | wc -l'
assert_success assert_success
assert_output 6 assert_output 6
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/keyDefault/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/keyDefault/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` \ "${IMAGE_NAME:?}" \
/bin/sh -c 'stat -c%s /etc/opendkim/keys/localhost.localdomain/mail.txt' /bin/sh -c 'stat -c%s /etc/opendkim/keys/localhost.localdomain/mail.txt'
assert_success assert_success
@ -471,19 +491,22 @@ EOF
# Instead it tests the file-size (here 511) - which may differ with a different domain names # Instead it tests the file-size (here 511) - which may differ with a different domain names
# This test may be re-used as a global test to provide better test coverage. # This test may be re-used as a global test to provide better test coverage.
@test "checking opendkim: generator creates key size 2048" { @test "checking opendkim: generator creates key size 2048" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_key_size_2048)"
# Prepare set key size 2048 # Prepare set key size 2048
rm -rf "$(pwd)/test/config/key2048" && mkdir -p "$(pwd)/test/config/key2048" rm -rf "${PRIVATE_CONFIG}/key2048"
mkdir -p "${PRIVATE_CONFIG}/config/key2048"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/key2048/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/key2048/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config 2048 | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config 2048 | wc -l'
assert_success assert_success
assert_output 6 assert_output 6
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/key2048/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/key2048/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` \ "${IMAGE_NAME:?}" \
/bin/sh -c 'stat -c%s /etc/opendkim/keys/localhost.localdomain/mail.txt' /bin/sh -c 'stat -c%s /etc/opendkim/keys/localhost.localdomain/mail.txt'
assert_success assert_success
@ -494,19 +517,22 @@ EOF
# Instead it tests the file-size (here 329) - which may differ with a different domain names # Instead it tests the file-size (here 329) - which may differ with a different domain names
# This test may be re-used as a global test to provide better test coverage. # This test may be re-used as a global test to provide better test coverage.
@test "checking opendkim: generator creates key size 1024" { @test "checking opendkim: generator creates key size 1024" {
local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_key_size_1024)"
# Prepare set key size 1024 # Prepare set key size 1024
rm -rf "$(pwd)/test/config/key1024" && mkdir -p "$(pwd)/test/config/key1024" rm -rf "${PRIVATE_CONFIG}/key1024"
mkdir -p "${PRIVATE_CONFIG}/key1024"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/key1024/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/key1024/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config 1024 | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config 1024 | wc -l'
assert_success assert_success
assert_output 6 assert_output 6
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/key1024/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/key1024/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` \ "${IMAGE_NAME:?}" \
/bin/sh -c 'stat -c%s /etc/opendkim/keys/localhost.localdomain/mail.txt' /bin/sh -c 'stat -c%s /etc/opendkim/keys/localhost.localdomain/mail.txt'
assert_success assert_success
@ -514,140 +540,151 @@ EOF
} }
@test "checking opendkim: generator creates keys, tables and TrustedHosts" { @test "checking opendkim: generator creates keys, tables and TrustedHosts" {
rm -rf "$(pwd)/test/config/empty" && mkdir -p "$(pwd)/test/config/empty" local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . mail_dkim_generator_creates_keys_tables_TrustedHosts)"
rm -rf "${PRIVATE_CONFIG}/empty"
mkdir -p "${PRIVATE_CONFIG}/empty"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/empty/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/empty/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config | wc -l'
assert_success assert_success
assert_output 6 assert_output 6
# Check keys for localhost.localdomain # Check keys for localhost.localdomain
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/empty/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/empty/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check keys for otherdomain.tld # Check keys for otherdomain.tld
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/empty/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/empty/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check presence of tables and TrustedHosts # Check presence of tables and TrustedHosts
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/empty/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/empty/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l" "${IMAGE_NAME:?}" /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l"
assert_success assert_success
assert_output 4 assert_output 4
} }
@test "checking opendkim: generator creates keys, tables and TrustedHosts without postfix-accounts.cf" { @test "checking opendkim: generator creates keys, tables and TrustedHosts without postfix-accounts.cf" {
rm -rf "$(pwd)/test/config/without-accounts" && mkdir -p "$(pwd)/test/config/without-accounts" local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . )"
rm -rf "${PRIVATE_CONFIG}/without-accounts"
mkdir -p "${PRIVATE_CONFIG}/without-accounts"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-accounts/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/without-accounts/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config | wc -l'
assert_success assert_success
assert_output 5 assert_output 5
# Check keys for localhost.localdomain # Check keys for localhost.localdomain
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-accounts/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/without-accounts/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check keys for otherdomain.tld # Check keys for otherdomain.tld
# run docker run --rm \ # run docker run --rm \
# -v "$(pwd)/test/config/without-accounts/opendkim":/etc/opendkim \ # -v "${PRIVATE_CONFIG}/without-accounts/opendkim":/etc/opendkim \
# `docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l' # "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l'
# assert_success # assert_success
# [ "$output" -eq 0 ] # [ "${output}" -eq 0 ]
# Check presence of tables and TrustedHosts # Check presence of tables and TrustedHosts
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-accounts/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/without-accounts/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l" "${IMAGE_NAME:?}" /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l"
assert_success assert_success
assert_output 4 assert_output 4
} }
@test "checking opendkim: generator creates keys, tables and TrustedHosts without postfix-virtual.cf" { @test "checking opendkim: generator creates keys, tables and TrustedHosts without postfix-virtual.cf" {
rm -rf "$(pwd)/test/config/without-virtual" && mkdir -p "$(pwd)/test/config/without-virtual" local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . "${BATS_TEST_NAME}")"
rm -rf "${PRIVATE_CONFIG}/without-virtual"
mkdir -p "${PRIVATE_CONFIG}/without-virtual"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-virtual/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/without-virtual/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config | wc -l'
assert_success assert_success
assert_output 5 assert_output 5
# Check keys for localhost.localdomain # Check keys for localhost.localdomain
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-virtual/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/without-virtual/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check keys for otherdomain.tld # Check keys for otherdomain.tld
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-virtual/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/without-virtual/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check presence of tables and TrustedHosts # Check presence of tables and TrustedHosts
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-virtual/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/without-virtual/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l" "${IMAGE_NAME:?}" /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys'|wc -l"
assert_success assert_success
assert_output 4 assert_output 4
} }
@test "checking opendkim: generator creates keys, tables and TrustedHosts using domain name" { @test "checking opendkim: generator creates keys, tables and TrustedHosts using domain name" {
rm -rf "$(pwd)/test/config/with-domain" && mkdir -p "$(pwd)/test/config/with-domain" local PRIVATE_CONFIG
PRIVATE_CONFIG="$(duplicate_config_for_container . "${BATS_TEST_NAME}")"
rm -rf "${PRIVATE_CONFIG}/with-domain" && mkdir -p "${PRIVATE_CONFIG}/with-domain"
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/with-domain/":/tmp/docker-mailserver/ \
-v "$(pwd)/test/config/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \ -v "${PRIVATE_CONFIG}/postfix-accounts.cf":/tmp/docker-mailserver/postfix-accounts.cf \
-v "$(pwd)/test/config/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \ -v "${PRIVATE_CONFIG}/postfix-virtual.cf":/tmp/docker-mailserver/postfix-virtual.cf \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-config | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-config | wc -l'
assert_success assert_success
assert_output 6 assert_output 6
# Generate key using domain name # Generate key using domain name
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/with-domain/":/tmp/docker-mailserver/ \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'generate-dkim-domain testdomain.tld | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'generate-dkim-domain testdomain.tld | wc -l'
assert_success assert_success
assert_output 1 assert_output 1
# Check keys for localhost.localdomain # Check keys for localhost.localdomain
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/localhost.localdomain/ | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check keys for otherdomain.tld # Check keys for otherdomain.tld
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/otherdomain.tld | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check keys for testdomain.tld # Check keys for testdomain.tld
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'ls -1 /etc/opendkim/keys/testdomain.tld | wc -l' "${IMAGE_NAME:?}" /bin/sh -c 'ls -1 /etc/opendkim/keys/testdomain.tld | wc -l'
assert_success assert_success
assert_output 2 assert_output 2
# Check presence of tables and TrustedHosts # Check presence of tables and TrustedHosts
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys' | wc -l" "${IMAGE_NAME:?}" /bin/sh -c "ls -1 /etc/opendkim | grep -E 'KeyTable|SigningTable|TrustedHosts|keys' | wc -l"
assert_success assert_success
assert_output 4 assert_output 4
# Check valid entries actually present in KeyTable # Check valid entries actually present in KeyTable
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c \ "${IMAGE_NAME:?}" /bin/sh -c \
"egrep 'localhost.localdomain|otherdomain.tld|localdomain2.com|testdomain.tld' /etc/opendkim/KeyTable | wc -l" "egrep 'localhost.localdomain|otherdomain.tld|localdomain2.com|testdomain.tld' /etc/opendkim/KeyTable | wc -l"
assert_success assert_success
assert_output 4 assert_output 4
# Check valid entries actually present in SigningTable # Check valid entries actually present in SigningTable
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/with-domain/opendkim":/etc/opendkim \ -v "${PRIVATE_CONFIG}/with-domain/opendkim":/etc/opendkim \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c \ "${IMAGE_NAME:?}" /bin/sh -c \
"egrep 'localhost.localdomain|otherdomain.tld|localdomain2.com|testdomain.tld' /etc/opendkim/SigningTable | wc -l" "egrep 'localhost.localdomain|otherdomain.tld|localdomain2.com|testdomain.tld' /etc/opendkim/SigningTable | wc -l"
assert_success assert_success
assert_output 4 assert_output 4
@ -687,20 +724,7 @@ EOF
assert_success assert_success
} }
@test "checking SRS: SRS_DOMAINNAME is used correctly" {
run docker exec mail_srs_domainname grep "SRS_DOMAIN=srs.my-domain.com" /etc/default/postsrsd
assert_success
}
@test "checking SRS: OVERRIDE_HOSTNAME is handled correctly" {
run docker exec mail_override_hostname grep "SRS_DOMAIN=my-domain.com" /etc/default/postsrsd
assert_success
}
@test "checking SRS: DOMAINNAME is handled correctly" {
run docker exec mail_domainname grep "SRS_DOMAIN=my-domain.com" /etc/default/postsrsd
assert_success
}
@test "checking SRS: fallback to hostname is handled correctly" { @test "checking SRS: fallback to hostname is handled correctly" {
run docker exec mail grep "SRS_DOMAIN=my-domain.com" /etc/default/postsrsd run docker exec mail grep "SRS_DOMAIN=my-domain.com" /etc/default/postsrsd
assert_success assert_success
@ -721,8 +745,8 @@ EOF
} }
@test "checking amavis: VIRUSMAILS_DELETE_DELAY override works as expected" { @test "checking amavis: VIRUSMAILS_DELETE_DELAY override works as expected" {
run docker run --rm -e VIRUSMAILS_DELETE_DELAY=2 `docker inspect --format '{{ .Config.Image }}' mail` /bin/bash -c 'echo $VIRUSMAILS_DELETE_DELAY | grep 2' run docker run --rm -e VIRUSMAILS_DELETE_DELAY=2 "${IMAGE_NAME:?}" /bin/bash -c 'echo "${VIRUSMAILS_DELETE_DELAY}"'
assert_success assert_output 2
} }
@test "checking amavis: old virusmail is wipped by cron" { @test "checking amavis: old virusmail is wipped by cron" {
@ -857,7 +881,7 @@ EOF
run docker exec mail /bin/sh -c "grep '^user3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf" run docker exec mail /bin/sh -c "grep '^user3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success assert_success
[ ! -z "$output" ] [ -n "${output}" ]
} }
@test "checking accounts: auser3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" { @test "checking accounts: auser3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" {
@ -865,7 +889,7 @@ EOF
run docker exec mail /bin/sh -c "grep '^auser3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf" run docker exec mail /bin/sh -c "grep '^auser3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success assert_success
[ ! -z "$output" ] [ -n "${output}" ]
} }
@test "checking accounts: a.ser3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" { @test "checking accounts: a.ser3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" {
@ -873,7 +897,7 @@ EOF
run docker exec mail /bin/sh -c "grep '^a\.ser3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf" run docker exec mail /bin/sh -c "grep '^a\.ser3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success assert_success
[ ! -z "$output" ] [ -n "${output}" ]
} }
@test "checking accounts: user3 should have been removed from /tmp/docker-mailserver/postfix-accounts.cf but not auser3" { @test "checking accounts: user3 should have been removed from /tmp/docker-mailserver/postfix-accounts.cf but not auser3" {
@ -881,27 +905,23 @@ EOF
run docker exec mail /bin/sh -c "grep '^user3@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf" run docker exec mail /bin/sh -c "grep '^user3@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_failure assert_failure
[ -z "$output" ] [ -z "${output}" ]
run docker exec mail /bin/sh -c "grep '^auser3@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf" run docker exec mail /bin/sh -c "grep '^auser3@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success assert_success
[ ! -z "$output" ] [ -n "${output}" ]
} }
@test "checking user updating password for user in /tmp/docker-mailserver/postfix-accounts.cf" { @test "checking user updating password for user in /tmp/docker-mailserver/postfix-accounts.cf" {
docker exec mail /bin/sh -c "addmailuser user4@domain.tld mypassword" docker exec mail /bin/sh -c "addmailuser user4@domain.tld mypassword"
initialpass=$(run docker exec mail /bin/sh -c "grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf") initialpass=$(docker exec mail /bin/sh -c "grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf")
sleep 2 sleep 2
docker exec mail /bin/sh -c "updatemailuser user4@domain.tld mynewpassword" docker exec mail /bin/sh -c "updatemailuser user4@domain.tld mynewpassword"
sleep 2 sleep 2
changepass=$(run docker exec mail /bin/sh -c "grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf") changepass=$(docker exec mail /bin/sh -c "grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf")
if [ initialpass != changepass ]; then [ "$initialpass" != "$changepass" ]
status="0"
else
status="1"
fi
docker exec mail /bin/sh -c "delmailuser -y auser3@domain.tld" docker exec mail /bin/sh -c "delmailuser -y auser3@domain.tld"
@ -916,22 +936,24 @@ EOF
@test "checking accounts: no error is generated when deleting a user if /tmp/docker-mailserver/postfix-accounts.cf is missing" { @test "checking accounts: no error is generated when deleting a user if /tmp/docker-mailserver/postfix-accounts.cf is missing" {
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-accounts/":/tmp/docker-mailserver/ \ -v "$(duplicate_config_for_container without-accounts/ without-accounts-deleting-user)":/tmp/docker-mailserver/ \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'delmailuser -y user3@domain.tld' "${IMAGE_NAME:?}" /bin/sh -c 'delmailuser -y user3@domain.tld'
assert_success assert_success
[ -z "$output" ] [ -z "${output}" ]
} }
@test "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf even when that file does not exist" { @test "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf even when that file does not exist" {
local PRIVATE_CONFIG
PRIVATE_CONFIG=$(duplicate_config_for_container without-accounts/ without-accounts_file_does_not_exist)
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-accounts/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/without-accounts/":/tmp/docker-mailserver/ \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'addmailuser user3@domain.tld mypassword' "${IMAGE_NAME:?}" /bin/sh -c 'addmailuser user3@domain.tld mypassword'
assert_success assert_success
run docker run --rm \ run docker run --rm \
-v "$(pwd)/test/config/without-accounts/":/tmp/docker-mailserver/ \ -v "${PRIVATE_CONFIG}/without-accounts/":/tmp/docker-mailserver/ \
`docker inspect --format '{{ .Config.Image }}' mail` /bin/sh -c 'grep user3@domain.tld -i /tmp/docker-mailserver/postfix-accounts.cf' "${IMAGE_NAME:?}" /bin/sh -c 'grep user3@domain.tld -i /tmp/docker-mailserver/postfix-accounts.cf'
assert_success assert_success
[ ! -z "$output" ] [ -n "${output}" ]
} }
@ -1026,35 +1048,35 @@ EOF
@test "checking quota: dovecot mailbox max size must be equal to postfix mailbox max size" { @test "checking quota: dovecot mailbox max size must be equal to postfix mailbox max size" {
postfix_mailbox_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=mailbox_size_limit = )[0-9]+'") postfix_mailbox_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=mailbox_size_limit = )[0-9]+'")
run echo "$postfix_mailbox_size" run echo "${postfix_mailbox_size}"
refute_output "" refute_output ""
# dovecot relies on virtual_mailbox_size by default # dovecot relies on virtual_mailbox_size by default
postfix_virtual_mailbox_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=virtual_mailbox_limit = )[0-9]+'") postfix_virtual_mailbox_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=virtual_mailbox_limit = )[0-9]+'")
assert_equal "$postfix_virtual_mailbox_size" "$postfix_mailbox_size" assert_equal "${postfix_virtual_mailbox_size}" "${postfix_mailbox_size}"
postfix_mailbox_size_mb=$(($postfix_mailbox_size / 1000000)) postfix_mailbox_size_mb=$(( postfix_mailbox_size / 1000000))
dovecot_mailbox_size_mb=$(docker exec mail sh -c "doveconf | grep -oP '(?<=quota_rule \= \*\:storage=)[0-9]+'") dovecot_mailbox_size_mb=$(docker exec mail sh -c "doveconf | grep -oP '(?<=quota_rule \= \*\:storage=)[0-9]+'")
run echo "$dovecot_mailbox_size_mb" run echo "${dovecot_mailbox_size_mb}"
refute_output "" refute_output ""
assert_equal "$postfix_mailbox_size_mb" "$dovecot_mailbox_size_mb" assert_equal "${postfix_mailbox_size_mb}" "${dovecot_mailbox_size_mb}"
} }
@test "checking quota: dovecot message max size must be equal to postfix messsage max size" { @test "checking quota: dovecot message max size must be equal to postfix messsage max size" {
postfix_message_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=message_size_limit = )[0-9]+'") postfix_message_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=message_size_limit = )[0-9]+'")
run echo "$postfix_message_size" run echo "${postfix_message_size}"
refute_output "" refute_output ""
postfix_message_size_mb=$(($postfix_message_size / 1000000)) postfix_message_size_mb=$(( postfix_message_size / 1000000))
dovecot_message_size_mb=$(docker exec mail sh -c "doveconf | grep -oP '(?<=quota_max_mail_size = )[0-9]+'") dovecot_message_size_mb=$(docker exec mail sh -c "doveconf | grep -oP '(?<=quota_max_mail_size = )[0-9]+'")
run echo "$dovecot_message_size_mb" run echo "${dovecot_message_size_mb}"
refute_output "" refute_output ""
assert_equal "$postfix_message_size_mb" "$dovecot_message_size_mb" assert_equal "${postfix_message_size_mb}" "${dovecot_message_size_mb}"
} }
@test "checking quota: quota directive is removed when mailbox is removed" { @test "checking quota: quota directive is removed when mailbox is removed" {
@ -1075,43 +1097,24 @@ EOF
} }
@test "checking quota: dovecot applies user quota" { @test "checking quota: dovecot applies user quota" {
sleep 15 # wait until any other change has finished wait_for_changes_to_be_detected_in_container mail
run docker exec mail /bin/sh -c "doveadm quota get -u 'user1@localhost.localdomain' | grep 'User quota STORAGE'" run docker exec mail /bin/sh -c "doveadm quota get -u 'user1@localhost.localdomain' | grep 'User quota STORAGE'"
assert_output --partial "- 0" assert_output --partial "- 0"
# set a quota
originalChangesProcessed=$(count_processed_changes mail)
run docker exec mail /bin/sh -c "setquota user1@localhost.localdomain 50M" run docker exec mail /bin/sh -c "setquota user1@localhost.localdomain 50M"
assert_success assert_success
# wait until change detector has processed the change wait_for_changes_to_be_detected_in_container mail
count=0
while [ "${originalChangesProcessed}" = "$(count_processed_changes mail)" ]
do
((count++)) && ((count==60)) && break
sleep 1
done
[ "${originalChangesProcessed}" != "$(count_processed_changes mail)" ]
assert_success
# wait until quota has been updated # wait until quota has been updated
run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'doveadm quota get -u user1@localhost.localdomain | grep -oP \"(User quota STORAGE\s+[0-9]+\s+)51200(.*)\"'" run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'doveadm quota get -u user1@localhost.localdomain | grep -oP \"(User quota STORAGE\s+[0-9]+\s+)51200(.*)\"'"
assert_success assert_success
# remove the quota
originalChangesProcessed=$(count_processed_changes mail)
run docker exec mail /bin/sh -c "delquota user1@localhost.localdomain" run docker exec mail /bin/sh -c "delquota user1@localhost.localdomain"
assert_success assert_success
# wait until change detector has processed the change wait_for_changes_to_be_detected_in_container mail
count=0
while [ "${originalChangesProcessed}" = "$(count_processed_changes mail)" ]
do
((count++)) && ((count==60)) && break
sleep 1
done
[ "${originalChangesProcessed}" != "$(count_processed_changes mail)" ]
assert_success
# wait until quota has been updated # wait until quota has been updated
run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'doveadm quota get -u user1@localhost.localdomain | grep -oP \"(User quota STORAGE\s+[0-9]+\s+)-(.*)\"'" run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'doveadm quota get -u user1@localhost.localdomain | grep -oP \"(User quota STORAGE\s+[0-9]+\s+)-(.*)\"'"
@ -1119,22 +1122,13 @@ EOF
} }
@test "checking quota: warn message received when quota exceeded" { @test "checking quota: warn message received when quota exceeded" {
sleep 15 # wait until any other change has finished wait_for_changes_to_be_detected_in_container mail
originalChangesProcessed=$(count_processed_changes mail)
# create user # create user
run docker exec mail /bin/sh -c "addmailuser quotauser@otherdomain.tld mypassword && setquota quotauser@otherdomain.tld 10k" run docker exec mail /bin/sh -c "addmailuser quotauser@otherdomain.tld mypassword && setquota quotauser@otherdomain.tld 10k"
assert_success assert_success
count=0 wait_for_changes_to_be_detected_in_container mail
while [ "${originalChangesProcessed}" = "$(count_processed_changes mail)" ]
do
((count++)) && ((count==60)) && break
sleep 1
done
[ "${originalChangesProcessed}" != "$(count_processed_changes mail)" ]
assert_success
# wait until quota has been updated # wait until quota has been updated
run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'doveadm quota get -u quotauser@otherdomain.tld | grep -oP \"(User quota STORAGE\s+[0-9]+\s+)10(.*)\"'" run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'doveadm quota get -u quotauser@otherdomain.tld | grep -oP \"(User quota STORAGE\s+[0-9]+\s+)10(.*)\"'"
@ -1159,6 +1153,7 @@ EOF
run repeat_until_success_or_timeout 20 sh -c "docker logs mail | grep 'Quota exceeded (mailbox for user is full)'" run repeat_until_success_or_timeout 20 sh -c "docker logs mail | grep 'Quota exceeded (mailbox for user is full)'"
assert_success assert_success
docker exec mail ls -l '/var/mail/otherdomain.tld/quotauser/new/'
# ensure only the first big message and the warn message are present (other messages are rejected: mailbox is full) # ensure only the first big message and the warn message are present (other messages are rejected: mailbox is full)
run docker exec mail sh -c 'ls /var/mail/otherdomain.tld/quotauser/new/ | wc -l' run docker exec mail sh -c 'ls /var/mail/otherdomain.tld/quotauser/new/ | wc -l'
assert_success assert_success
@ -1206,13 +1201,13 @@ EOF
@test "checking setup.sh: Without arguments: status 1, show help text" { @test "checking setup.sh: Without arguments: status 1, show help text" {
run ./setup.sh run ./setup.sh
assert_failure assert_failure
[ "${lines[1]}" = "Usage: ./setup.sh [-i IMAGE_NAME] [-c CONTAINER_NAME] <subcommand> <subcommand> [args]" ] assert_line --index 1 "Usage: ./setup.sh [-i IMAGE_NAME] [-c CONTAINER_NAME] <subcommand> <subcommand> [args]"
} }
@test "checking setup.sh: Wrong arguments" { @test "checking setup.sh: Wrong arguments" {
run ./setup.sh lol troll run ./setup.sh lol troll
assert_failure assert_failure
[ "${lines[1]}" = "Usage: ./setup.sh [-i IMAGE_NAME] [-c CONTAINER_NAME] <subcommand> <subcommand> [args]" ] assert_line --index 1 "Usage: ./setup.sh [-i IMAGE_NAME] [-c CONTAINER_NAME] <subcommand> <subcommand> [args]"
} }
# email # email
@ -1220,25 +1215,14 @@ EOF
wait_for_service mail changedetector wait_for_service mail changedetector
assert_success assert_success
originalChangesProcessed=$(count_processed_changes mail)
run ./setup.sh -c mail email add setup_email_add@example.com test_password run ./setup.sh -c mail email add setup_email_add@example.com test_password
assert_success assert_success
value=$(cat ./test/config/postfix-accounts.cf | grep setup_email_add@example.com | awk -F '|' '{print $1}') value=$(grep setup_email_add@example.com "$(private_config_path mail)/postfix-accounts.cf" | awk -F '|' '{print $1}')
[ "$value" = "setup_email_add@example.com" ] [ "${value}" = "setup_email_add@example.com" ]
assert_success assert_success
# wait until change detector has processed the change wait_for_changes_to_be_detected_in_container mail
count=0
while [ "${originalChangesProcessed}" = "$(count_processed_changes mail)" ]
do
((count++)) && ((count==60)) && break
sleep 1
done
[ "${originalChangesProcessed}" != "$(count_processed_changes mail)" ]
assert_success
# Dovecot has been restarted, but this test often fails so presumably it may not be ready # Dovecot has been restarted, but this test often fails so presumably it may not be ready
# Add a short sleep to see if that helps to make the test more stable # Add a short sleep to see if that helps to make the test more stable
@ -1260,21 +1244,18 @@ EOF
run ./setup.sh -c mail email add lorem@impsum.org test_test run ./setup.sh -c mail email add lorem@impsum.org test_test
assert_success assert_success
initialpass=$(cat ./test/config/postfix-accounts.cf | grep lorem@impsum.org | awk -F '|' '{print $2}') initialpass=$(grep lorem@impsum.org "$(private_config_path mail)/postfix-accounts.cf" | awk -F '|' '{print $2}')
[ "$initialpass" != "" ] [ "${initialpass}" != "" ]
assert_success assert_success
run ./setup.sh -c mail email update lorem@impsum.org my password run ./setup.sh -c mail email update lorem@impsum.org my password
assert_success assert_success
updatepass=$(cat ./test/config/postfix-accounts.cf | grep lorem@impsum.org | awk -F '|' '{print $2}') updatepass=$(grep lorem@impsum.org "$(private_config_path mail)/postfix-accounts.cf" | awk -F '|' '{print $2}')
[ "$updatepass" != "" ] [ "${updatepass}" != "" ]
assert_success [ "${initialpass}" != "${updatepass}" ]
[ "$initialpass" != "$updatepass" ] docker exec mail doveadm pw -t "${updatepass}" -p 'my password' | grep 'verified'
assert_success
docker exec mail doveadm pw -t "$updatepass" -p 'my password' | grep 'verified'
assert_success assert_success
} }
@ -1290,7 +1271,7 @@ EOF
# #
# run docker exec mail ls /var/mail/impsum.org/lorem # run docker exec mail ls /var/mail/impsum.org/lorem
# assert_failure # assert_failure
run grep lorem@impsum.org ./test/config/postfix-accounts.cf run grep lorem@impsum.org "$(private_config_path mail)/postfix-accounts.cf"
assert_failure assert_failure
} }
@ -1423,14 +1404,14 @@ EOF
# debug # debug
@test "checking setup.sh: setup.sh debug fetchmail" { @test "checking setup.sh: setup.sh debug fetchmail" {
run ./setup.sh -c mail debug fetchmail run ./setup.sh -c mail debug fetchmail
[ "$status" -eq 11 ] assert_failure 11
[[ "$output" == *"fetchmail: normal termination, status 11"* ]] assert_output --partial "fetchmail: normal termination, status 11"
} }
@test "checking setup.sh: setup.sh debug inspect" { @test "checking setup.sh: setup.sh debug inspect" {
run ./setup.sh -c mail debug inspect run ./setup.sh -c mail debug inspect
assert_success assert_success
[ "${lines[0]}" = "Image: tvial/docker-mailserver:testing" ] assert_line --index 0 "Image: tvial/docker-mailserver:testing"
[ "${lines[1]}" = "Container: mail" ] assert_line --index 1 "Container: mail"
} }
@test "checking setup.sh: setup.sh debug login ls" { @test "checking setup.sh: setup.sh debug login ls" {
run ./setup.sh -c mail debug login ls run ./setup.sh -c mail debug login ls
@ -1486,15 +1467,12 @@ EOF
@test "checking dovecot: postmaster address" { @test "checking dovecot: postmaster address" {
run docker exec mail /bin/sh -c "grep 'postmaster_address = postmaster@my-domain.com' /etc/dovecot/conf.d/15-lda.conf" run docker exec mail /bin/sh -c "grep 'postmaster_address = postmaster@my-domain.com' /etc/dovecot/conf.d/15-lda.conf"
assert_success assert_success
run docker exec mail_override_hostname /bin/sh -c "grep 'postmaster_address = postmaster@my-domain.com' /etc/dovecot/conf.d/15-lda.conf"
assert_success
} }
@test "checking spoofing: rejects sender forging" { @test "checking spoofing: rejects sender forging" {
# checking rejection of spoofed sender # checking rejection of spoofed sender
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed.txt | grep 'Sender address rejected: not owned by user'" run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed.txt"
assert_success assert_output --partial 'Sender address rejected: not owned by user'
} }
@test "checking spoofing: accepts sending as alias" { @test "checking spoofing: accepts sending as alias" {
@ -1604,11 +1582,6 @@ EOF
assert_success assert_success
} }
@test "checking restart of process: clamav (clamav disabled by ENABLED_CLAMAV=0)" {
run docker exec mail_disabled_clamav_spamassassin /bin/bash -c "pkill -f clamd && sleep 10 && ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'"
assert_failure
}
# #
# root mail delivery # root mail delivery
# #
@ -1618,11 +1591,6 @@ EOF
assert_success assert_success
} }
# @test "last" {
# clean exit # this test is only there to reliably mark the end for the teardown_file
#
@test "checking that the container stops cleanly" {
run docker stop -t 60 mail_override_hostname
assert_success
} }