docker-mailserver/test/tests/serial/tests.bats
Brennan Kinney 1024e0ccf2
tests: Extract some test cases out from tests.bats (#2980)
While working on tests, I noticed that some of the configs being mounted were adding a few seconds to the start-up time of each container. Notably `postfix-*` and `dovecot.conf` config files, which have been extracted out into their own tests with those files moved into a separate config folder.

`tests.bats` has been adapted to the common setup helper, and removed ENV no longer required to run those tests. Future PRs will extract out more tests.

Review may be easier via individual commit diffs and their associated commit messages describing relevant changes.

<details>
<summary>Commit message history for reference</summary>

```markdown
tests(chore): `tests.bats` - Remove redundant config
===
- ONEDIR volume support no longer relevant, this should have been dropped.
- ClamAV ENV no longer relevant as related tests have been extracted already.
- Same with the some of the SpamAssassin ENV config.
- `VIRUSMAILS_DELETE_DELAY` is tested in the file, but doesn't use this ENV at all? (runs a separate instance to test the ENV instead)
- Hostname updated in preparation for migrating to new test helpers. Relevant test lines referencing the hostname have likewise been updated.
```

```markdown
tests(chore): `tests.bats` - Convert to common setup
===
ENV remains the same, but required adding `ENABLE_AMAVIS=1` to bring that back, while the following became redundant as they're now defaulting to explicitly disabled in the helper method:

- `ENABLE_CLAMAV=0`
- `LOG_LEVEL=debug`
- `ENABLE_UPDATE_CHECK=0`
- `--hostname` + `--tty` + standard `--volume` lines
- `-e` option expanded to long-name `--env`, and all `\` dropped as no longer necessary.

`wait_for_finished_setup_in_container` is now redundant thanks to `common_container_setup`.
```

```markdown
tests(refactor): `tests.bats` - Extract out Dovecot Sieve tests
===
Sieve test files relocated into `test/config/dovecot-sieve/` for better isolation.

`dovecot.sieve` was not using the `reject` import, and we should not encourage it? (docs still do):
https://support.tigertech.net/sieve#the-sieve-reject-jmp
```

```markdown
tests: `tests.bats` - Extract out `checking smtp` tests
===
Migrated to the standard template and copied over the original test cases with `_run_in_container` adjustment only.

Identified minimum required ENV along with which mail is required for each test case.
```

```markdown
tests(refactor): `smtp-delivery.bats`
===
- Disabled `ENABLE_SRS=1`, not necessary for these tests.
- Added a SpamAssassin related test (X-SPAM headers) which requires `SA_TAG` to properly pass (or `ENABLE_SRS=1` to deliver into inbox).
- Many lines with double quotes changed to single quote wrapping, and moving out `grep` filters into `assert_output --partial` lines instead.
- Instead of `wc -l` making failures less helpful, switch to the helper method `_should_output_number_of_lines`
- x2 `assert_output` with different EOF style of usage was not actually failing on tests when it should. Changed to assert partial output of each expected line, and count the number of lines instead.
- Added additional comments related to the test cases with a `TODO` note about `SPAMASSASSIN_SPAM_TO_INBOX=1`.
- Revised test case names, including using the common prefix var.
- `tests.bats` no longer needs to send all these emails, no other test cases require them. This affects a test checking a `/mail` folder exists which has been corrected, and a quotas test case adjusted to expect an empty quota size output.
```

```markdown
tests: `tests.bats` - Extract out test cases for config overrides
===
Slight improvement by additionally matching `postconf` output to verify the setting is properly applied.
```

```markdown
tests: `tests.bats` - Extract out Amavis SpamAssassin test case
===
Removes the need for SpamAssassin ENV in `tests.bats`.
```

</details>
2023-01-07 11:36:20 +13:00

733 lines
25 KiB
Bash

load "${REPOSITORY_ROOT}/test/helper/common"
load "${REPOSITORY_ROOT}/test/helper/setup"
CONTAINER_NAME='mail'
setup_file() {
init_with_defaults
mv "${TEST_TMP_CONFIG}/user-patches/user-patches.sh" "${TEST_TMP_CONFIG}/user-patches.sh"
local CONTAINER_ARGS_ENV_CUSTOM=(
--env ENABLE_AMAVIS=1
--env AMAVIS_LOGLEVEL=2
--env ENABLE_QUOTAS=1
--env ENABLE_SRS=1
--env PERMIT_DOCKER=host
--env PFLOGSUMM_TRIGGER=logrotate
--env REPORT_RECIPIENT=user1@localhost.localdomain
--env REPORT_SENDER=report1@mail.example.test
--env SPOOF_PROTECTION=1
--env SSL_TYPE='snakeoil'
--ulimit "nofile=$(ulimit -Sn):$(ulimit -Hn)"
--health-cmd "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
)
common_container_setup 'CONTAINER_ARGS_ENV_CUSTOM'
# generate accounts after container has been started
docker exec mail setup email add 'added@localhost.localdomain' 'mypassword'
docker exec mail setup email add 'pass@localhost.localdomain' 'may be \a `p^a.*ssword'
# this relies on the checksum file being updated after all changes have been applied
wait_until_change_detection_event_completes mail
wait_for_service mail postfix
wait_for_smtp_port_in_container mail
}
teardown_file() {
docker rm -f mail
}
#
# configuration checks
#
@test "checking configuration: user-patches.sh executed" {
run docker logs mail
assert_output --partial "Default user-patches.sh successfully executed"
}
@test "checking configuration: hostname/domainname" {
run docker run "${IMAGE_NAME:?}"
assert_success
}
#
# healthcheck
#
# NOTE: Healthcheck defaults an interval of 30 seconds
# If Postfix is temporarily down (eg: restart triggered by `check-for-changes.sh`),
# it may result in a false-positive `unhealthy` state.
# Be careful with re-locating this test if earlier tests could potentially fail it by
# triggering the `changedetector` service.
@test "checking container healthcheck" {
# ensure, that at least 30 seconds have passed since container start
while [[ "$(docker inspect --format='{{.State.Health.Status}}' mail)" == "starting" ]]; do
sleep 1
done
run docker inspect --format='{{.State.Health.Status}}' mail
assert_output "healthy"
assert_success
}
#
# processes
#
@test "checking process: postfix" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/lib/postfix/sbin/master'"
assert_success
}
@test "checking process: clamd (is not runnning)" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/clamd'"
assert_failure
}
@test "checking process: new" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/amavisd-new'"
assert_success
}
@test "checking process: opendkim" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/opendkim'"
assert_success
}
@test "checking process: opendmarc" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/opendmarc'"
assert_success
}
@test "checking process: fail2ban (disabled in default configuration)" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/bin/python3 /usr/bin/fail2ban-server'"
assert_failure
}
@test "checking process: fetchmail (disabled in default configuration)" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/bin/fetchmail'"
assert_failure
}
#
# imap
#
@test "checking process: dovecot imaplogin (enabled in default configuration)" {
run docker exec mail /bin/bash -c "ps aux --forest | grep -v grep | grep '/usr/sbin/dovecot'"
assert_success
}
@test "checking imap: server is ready with STARTTLS" {
run docker exec mail /bin/bash -c "nc -w 2 0.0.0.0 143 | grep '* OK' | grep 'STARTTLS' | grep 'ready'"
assert_success
}
@test "checking imap: authentication works" {
run docker exec mail /bin/sh -c "nc -w 1 0.0.0.0 143 < /tmp/docker-mailserver-test/auth/imap-auth.txt"
assert_success
}
@test "checking imap: added user authentication works" {
run docker exec mail /bin/sh -c "nc -w 1 0.0.0.0 143 < /tmp/docker-mailserver-test/auth/added-imap-auth.txt"
assert_success
}
#
# sasl
#
@test "checking sasl: doveadm auth test works with good password" {
run docker exec mail /bin/sh -c "doveadm auth test -x service=smtp user2@otherdomain.tld mypassword | grep 'auth succeeded'"
assert_success
}
@test "checking sasl: doveadm auth test fails with bad password" {
run docker exec mail /bin/sh -c "doveadm auth test -x service=smtp user2@otherdomain.tld BADPASSWORD | grep 'auth failed'"
assert_success
}
#
# logs
#
@test "checking logs: mail related logs should be located in a subdirectory" {
run docker exec mail /bin/sh -c "ls -1 /var/log/mail/ | grep -E 'mail.log'"
assert_success
}
#
# accounts
#
@test "checking accounts: user accounts" {
run docker exec mail doveadm user '*'
assert_success
assert_line --index 0 "user1@localhost.localdomain"
assert_line --index 1 "user2@otherdomain.tld"
assert_line --index 2 "user3@localhost.localdomain"
assert_line --index 3 "added@localhost.localdomain"
}
@test "checking accounts: user mail folder for user1" {
run docker exec mail /bin/bash -c "ls -d /var/mail/localhost.localdomain/user1"
assert_success
}
@test "checking accounts: user mail folder for user2" {
run docker exec mail /bin/bash -c "ls -d /var/mail/otherdomain.tld/user2"
assert_success
}
@test "checking accounts: user mail folder for user3" {
run docker exec mail /bin/bash -c "ls -d /var/mail/localhost.localdomain/user3"
assert_success
}
@test "checking accounts: user mail folder for added user" {
run docker exec mail /bin/bash -c "ls -d /var/mail/localhost.localdomain/added"
assert_success
}
@test "checking accounts: comments are not parsed" {
run docker exec mail /bin/bash -c "ls /var/mail | grep 'comment'"
assert_failure
}
#
# postfix
#
@test "checking postfix: vhost file is correct" {
run docker exec mail cat /etc/postfix/vhost
assert_success
assert_line --index 0 "localdomain2.com"
assert_line --index 1 "localhost.localdomain"
assert_line --index 2 "otherdomain.tld"
}
#
# postsrsd
#
@test "checking SRS: main.cf entries" {
run docker exec mail grep "sender_canonical_maps = tcp:localhost:10001" /etc/postfix/main.cf
assert_success
run docker exec mail grep "sender_canonical_classes = envelope_sender" /etc/postfix/main.cf
assert_success
run docker exec mail grep "recipient_canonical_maps = tcp:localhost:10002" /etc/postfix/main.cf
assert_success
run docker exec mail grep "recipient_canonical_classes = envelope_recipient,header_recipient" /etc/postfix/main.cf
assert_success
}
@test "checking SRS: postsrsd running" {
run docker exec mail /bin/sh -c "ps aux | grep ^postsrsd"
assert_success
}
@test "checking SRS: fallback to hostname is handled correctly" {
run docker exec mail grep "SRS_DOMAIN=example.test" /etc/default/postsrsd
assert_success
}
#
# system
#
@test "checking system: freshclam cron is disabled" {
run docker exec mail bash -c "grep '/usr/bin/freshclam' -r /etc/cron.d"
assert_failure
}
@test "checking amavis: virusmail wiper cron exists" {
run docker exec mail bash -c "crontab -l | grep '/usr/local/bin/virus-wiper'"
assert_success
}
@test "checking amavis: VIRUSMAILS_DELETE_DELAY override works as expected" {
# shellcheck disable=SC2016
run docker run --rm -e VIRUSMAILS_DELETE_DELAY=2 "${IMAGE_NAME:?}" /bin/bash -c 'echo "${VIRUSMAILS_DELETE_DELAY}"'
assert_output 2
}
@test "checking amavis: old virusmail is wipped by cron" {
docker exec mail bash -c 'touch -d "`date --date=2000-01-01`" /var/lib/amavis/virusmails/should-be-deleted'
run docker exec mail bash -c '/usr/local/bin/virus-wiper'
assert_success
run docker exec mail bash -c 'ls -la /var/lib/amavis/virusmails/ | grep should-be-deleted'
assert_failure
}
@test "checking amavis: recent virusmail is not wipped by cron" {
docker exec mail bash -c 'touch -d "`date`" /var/lib/amavis/virusmails/should-not-be-deleted'
run docker exec mail bash -c '/usr/local/bin/virus-wiper'
assert_success
run docker exec mail bash -c 'ls -la /var/lib/amavis/virusmails/ | grep should-not-be-deleted'
assert_success
}
@test "checking system: /var/log/mail/mail.log is error free" {
run docker exec mail grep 'non-null host address bits in' /var/log/mail/mail.log
assert_failure
run docker exec mail grep 'mail system configuration error' /var/log/mail/mail.log
assert_failure
run docker exec mail grep ': error:' /var/log/mail/mail.log
assert_failure
run docker exec mail grep -i 'is not writable' /var/log/mail/mail.log
assert_failure
run docker exec mail grep -i 'permission denied' /var/log/mail/mail.log
assert_failure
run docker exec mail grep -i '(!)connect' /var/log/mail/mail.log
assert_failure
run docker exec mail grep -i 'using backwards-compatible default setting' /var/log/mail/mail.log
assert_failure
run docker exec mail grep -i 'connect to 127.0.0.1:10023: Connection refused' /var/log/mail/mail.log
assert_failure
}
@test "checking system: /var/log/auth.log is error free" {
run docker exec mail grep 'Unable to open env file: /etc/default/locale' /var/log/auth.log
assert_failure
}
@test "checking system: sets the server fqdn" {
run docker exec mail hostname
assert_success
assert_output "mail.example.test"
}
@test "checking system: sets the server domain name in /etc/mailname" {
run docker exec mail cat /etc/mailname
assert_success
assert_output "example.test"
}
@test "checking system: postfix should not log to syslog" {
run docker exec mail grep 'postfix' /var/log/syslog
assert_failure
}
@test "checking system: amavis decoders installed and available" {
run docker exec mail /bin/sh -c "grep -E '.*(Internal decoder|Found decoder) for\s+\..*' /var/log/mail/mail.log*|grep -Eo '(mail|Z|gz|bz2|xz|lzma|lrz|lzo|lz4|rpm|cpio|tar|deb|rar|arj|arc|zoo|doc|cab|tnef|zip|kmz|7z|jar|swf|lha|iso|exe)' | sort | uniq"
assert_success
# Support for doc and zoo removed in buster
cat <<'EOF' | assert_output
7z
Z
arc
arj
bz2
cab
cpio
deb
exe
gz
iso
jar
kmz
lha
lrz
lz4
lzma
lzo
mail
rar
rpm
swf
tar
tnef
xz
zip
EOF
}
#
# accounts
#
@test "checking accounts: user_without_domain creation should be rejected since user@domain format is required" {
run docker exec mail /bin/sh -c "addmailuser user_without_domain mypassword"
assert_failure
assert_output --partial 'should include the domain (eg: user@example.com)'
}
@test "checking accounts: user3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" {
docker exec mail /bin/sh -c "addmailuser user3@domain.tld mypassword"
run docker exec mail /bin/sh -c "grep '^user3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success
[[ -n ${output} ]]
}
@test "checking accounts: auser3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" {
docker exec mail /bin/sh -c "addmailuser auser3@domain.tld mypassword"
run docker exec mail /bin/sh -c "grep '^auser3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success
[[ -n ${output} ]]
}
@test "checking accounts: a.ser3 should have been added to /tmp/docker-mailserver/postfix-accounts.cf" {
docker exec mail /bin/sh -c "addmailuser a.ser3@domain.tld mypassword"
run docker exec mail /bin/sh -c "grep '^a\.ser3@domain\.tld|' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success
[[ -n ${output} ]]
}
@test "checking accounts: user3 should have been removed from /tmp/docker-mailserver/postfix-accounts.cf but not auser3" {
wait_until_account_maildir_exists mail 'user3@domain.tld'
docker exec mail /bin/sh -c "delmailuser -y user3@domain.tld"
run docker exec mail /bin/sh -c "grep '^user3@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_failure
[[ -z ${output} ]]
run docker exec mail /bin/sh -c "grep '^auser3@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf"
assert_success
[[ -n ${output} ]]
}
@test "checking user updating password for user in /tmp/docker-mailserver/postfix-accounts.cf" {
add_mail_account_then_wait_until_ready mail 'user4@domain.tld'
initialpass=$(docker exec mail /bin/sh -c "grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf")
sleep 2
docker exec mail /bin/sh -c "updatemailuser user4@domain.tld mynewpassword"
sleep 2
changepass=$(docker exec mail /bin/sh -c "grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf")
[[ ${initialpass} != "${changepass}" ]]
run docker exec mail /bin/sh -c "delmailuser -y auser3@domain.tld"
assert_success
}
@test "checking accounts: listmailuser (quotas disabled)" {
run docker exec mail /bin/sh -c "echo 'ENABLE_QUOTAS=0' >> /etc/dms-settings && listmailuser | head -n 1"
assert_success
assert_output '* user1@localhost.localdomain'
}
@test "checking accounts: listmailuser (quotas enabled)" {
run docker exec mail /bin/sh -c "sed -i '/ENABLE_QUOTAS=0/d' /etc/dms-settings; listmailuser | head -n 1"
assert_success
assert_output '* user1@localhost.localdomain ( 0 / ~ ) [0%]'
}
@test "checking accounts: no error is generated when deleting a user if /tmp/docker-mailserver/postfix-accounts.cf is missing" {
run docker run --rm \
-v "$(duplicate_config_for_container without-accounts/ without-accounts-deleting-user)":/tmp/docker-mailserver/ \
"${IMAGE_NAME:?}" /bin/sh -c 'delmailuser -y user3@domain.tld'
assert_success
[[ -z ${output} ]]
}
@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 \
-v "${PRIVATE_CONFIG}/without-accounts/":/tmp/docker-mailserver/ \
"${IMAGE_NAME:?}" /bin/sh -c 'addmailuser user3@domain.tld mypassword'
assert_success
run docker run --rm \
-v "${PRIVATE_CONFIG}/without-accounts/":/tmp/docker-mailserver/ \
"${IMAGE_NAME:?}" /bin/sh -c 'grep user3@domain.tld -i /tmp/docker-mailserver/postfix-accounts.cf'
assert_success
[[ -n ${output} ]]
}
@test "checking quota: setquota user must be existing" {
add_mail_account_then_wait_until_ready mail 'quota_user@domain.tld'
run docker exec mail /bin/sh -c "setquota quota_user 50M"
assert_failure
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 50M"
assert_success
run docker exec mail /bin/sh -c "setquota username@fulldomain 50M"
assert_failure
run docker exec mail /bin/sh -c "delmailuser -y quota_user@domain.tld"
assert_success
}
@test "checking quota: setquota <quota> must be well formatted" {
add_mail_account_then_wait_until_ready mail 'quota_user@domain.tld'
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 26GIGOTS"
assert_failure
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 123"
assert_failure
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld M"
assert_failure
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld -60M"
assert_failure
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 10B"
assert_success
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 10k"
assert_success
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 10M"
assert_success
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 10G"
assert_success
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 10T"
assert_success
run docker exec mail /bin/sh -c "delmailuser -y quota_user@domain.tld"
assert_success
}
@test "checking quota: delquota user must be existing" {
add_mail_account_then_wait_until_ready mail 'quota_user@domain.tld'
run docker exec mail /bin/sh -c "delquota uota_user@domain.tld"
assert_failure
run docker exec mail /bin/sh -c "delquota quota_user"
assert_failure
run docker exec mail /bin/sh -c "delquota dontknowyou@domain.tld"
assert_failure
run docker exec mail /bin/sh -c "setquota quota_user@domain.tld 10T"
assert_success
run docker exec mail /bin/sh -c "delquota quota_user@domain.tld"
assert_success
run docker exec mail /bin/sh -c "grep -i 'quota_user@domain.tld' /tmp/docker-mailserver/dovecot-quotas.cf"
assert_failure
run docker exec mail /bin/sh -c "delmailuser -y quota_user@domain.tld"
assert_success
}
@test "checking quota: delquota allow when no quota for existing user" {
add_mail_account_then_wait_until_ready mail 'quota_user@domain.tld'
run docker exec mail /bin/sh -c "grep -i 'quota_user@domain.tld' /tmp/docker-mailserver/dovecot-quotas.cf"
assert_failure
run docker exec mail /bin/sh -c "delquota quota_user@domain.tld"
assert_success
run docker exec mail /bin/sh -c "delquota quota_user@domain.tld"
assert_success
run docker exec mail /bin/sh -c "delmailuser -y quota_user@domain.tld"
assert_success
}
@test "checking quota: dovecot quota present in postconf" {
run docker exec mail /bin/bash -c "postconf | grep 'check_policy_service inet:localhost:65265'"
assert_success
}
@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]+'")
run echo "${postfix_mailbox_size}"
refute_output ""
# 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]+'")
assert_equal "${postfix_virtual_mailbox_size}" "${postfix_mailbox_size}"
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]+'")
run echo "${dovecot_mailbox_size_mb}"
refute_output ""
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" {
postfix_message_size=$(docker exec mail sh -c "postconf | grep -Po '(?<=message_size_limit = )[0-9]+'")
run echo "${postfix_message_size}"
refute_output ""
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]+'")
run echo "${dovecot_message_size_mb}"
refute_output ""
assert_equal "${postfix_message_size_mb}" "${dovecot_message_size_mb}"
}
@test "checking quota: quota directive is removed when mailbox is removed" {
add_mail_account_then_wait_until_ready mail 'quserremoved@domain.tld'
run docker exec mail /bin/sh -c "setquota quserremoved@domain.tld 12M"
assert_success
run docker exec mail /bin/sh -c 'cat /tmp/docker-mailserver/dovecot-quotas.cf | grep -E "^quserremoved@domain.tld\:12M\$" | wc -l | grep 1'
assert_success
run docker exec mail /bin/sh -c "delmailuser -y quserremoved@domain.tld"
assert_success
run docker exec mail /bin/sh -c 'cat /tmp/docker-mailserver/dovecot-quotas.cf | grep -E "^quserremoved@domain.tld\:12M\$"'
assert_failure
}
@test "checking quota: dovecot applies user quota" {
run docker exec mail /bin/sh -c "doveadm quota get -u 'user1@localhost.localdomain' | grep 'User quota STORAGE'"
assert_output --partial "- 0"
run docker exec mail /bin/sh -c "setquota user1@localhost.localdomain 50M"
assert_success
# 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(.*)\"'"
assert_success
run docker exec mail /bin/sh -c "delquota user1@localhost.localdomain"
assert_success
# 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+)-(.*)\"'"
assert_success
}
@test "checking quota: warn message received when quota exceeded" {
skip 'disabled as it fails randomly: https://github.com/docker-mailserver/docker-mailserver/pull/2511'
# create user
add_mail_account_then_wait_until_ready mail 'quotauser@otherdomain.tld'
run docker exec mail /bin/sh -c 'setquota quotauser@otherdomain.tld 10k'
assert_success
# 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(.*)\"'"
assert_success
# dovecot and postfix has been restarted
wait_for_service mail postfix
wait_for_service mail dovecot
sleep 10
# send some big emails
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/quota-exceeded.txt"
assert_success
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/quota-exceeded.txt"
assert_success
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/email-templates/quota-exceeded.txt"
assert_success
# check for quota warn message existence
run repeat_until_success_or_timeout 20 sh -c "docker exec mail sh -c 'grep \"Subject: quota warning\" /var/mail/otherdomain.tld/quotauser/new/ -R'"
assert_success
run repeat_until_success_or_timeout 20 sh -c "docker logs mail | grep 'Quota exceeded (mailbox for user is full)'"
assert_success
# 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'
assert_success
assert_output "2"
run docker exec mail /bin/sh -c "delmailuser -y quotauser@otherdomain.tld"
assert_success
}
#
# PERMIT_DOCKER mynetworks
#
@test "checking PERMIT_DOCKER: can get container ip" {
run docker exec mail /bin/sh -c "ip addr show eth0 | grep 'inet ' | sed 's/[^0-9\.\/]*//g' | cut -d '/' -f 1 | egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'"
assert_success
}
@test "checking PERMIT_DOCKER: my network value" {
run docker exec mail /bin/sh -c "postconf | grep '^mynetworks =' | egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.0\.0/16'"
assert_success
}
#
# amavis
#
@test "checking amavis: config overrides" {
run docker exec mail /bin/sh -c "grep 'Test Verification' /etc/amavis/conf.d/50-user | wc -l"
assert_success
assert_output 1
}
# TODO investigate why this test fails
@test "checking user login: predefined user can login" {
skip 'disabled as it fails randomly: https://github.com/docker-mailserver/docker-mailserver/pull/2177'
run docker exec mail /bin/bash -c "doveadm auth test -x service=smtp pass@localhost.localdomain 'may be \\a \`p^a.*ssword' | grep 'passdb'"
assert_output "passdb: pass@localhost.localdomain auth succeeded"
}
#
# LDAP
#
# postfix
@test "checking dovecot: postmaster address" {
run docker exec mail /bin/sh -c "grep 'postmaster_address = postmaster@example.test' /etc/dovecot/conf.d/15-lda.conf"
assert_success
}
@test "checking spoofing: rejects sender forging" {
# checking rejection of spoofed sender
wait_for_smtp_port_in_container_to_respond mail
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed.txt"
assert_output --partial 'Sender address rejected: not owned by user'
}
@test "checking spoofing: accepts sending as alias" {
run docker exec mail /bin/sh -c "nc 0.0.0.0 25 < /tmp/docker-mailserver-test/auth/added-smtp-auth-spoofed-alias.txt | grep 'End data with'"
assert_success
}
#
# Pflogsumm delivery check
#
@test "checking pflogsum delivery" {
# checking logrotation working and report being sent
docker exec mail logrotate --force /etc/logrotate.d/maillog
sleep 10
run docker exec mail grep "Subject: Postfix Summary for " /var/mail/localhost.localdomain/user1/new/ -R
assert_success
# check sender is the one specified in REPORT_SENDER
run docker exec mail grep "From: report1@mail.example.test" /var/mail/localhost.localdomain/user1/new/ -R
assert_success
# check sender is not the default one.
run docker exec mail grep "From: mailserver-report@mail.example.test" /var/mail/localhost.localdomain/user1/new/ -R
assert_failure
}
#
# supervisor
#
@test "checking restart of process: postfix" {
run docker exec mail /bin/bash -c "pkill master && sleep 10 && ps aux --forest | grep -v grep | grep '/usr/lib/postfix/sbin/master'"
assert_success
}
@test "checking restart of process: amavisd-new" {
run docker exec mail /bin/bash -c "pkill amavi && sleep 12 && ps aux --forest | grep -v grep | grep '/usr/sbin/amavisd-new (master)'"
assert_success
}
@test "checking restart of process: opendkim" {
run docker exec mail /bin/bash -c "pkill opendkim && sleep 10 && ps aux --forest | grep -v grep | grep '/usr/sbin/opendkim'"
assert_success
}
@test "checking restart of process: opendmarc" {
run docker exec mail /bin/bash -c "pkill opendmarc && sleep 10 && ps aux --forest | grep -v grep | grep '/usr/sbin/opendmarc'"
assert_success
}