mirror of
https://github.com/docker-mailserver/docker-mailserver.git
synced 2024-01-19 02:48:50 +00:00
tests: streamline tests and helpers further (#3747)
Co-authored-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
This commit is contained in:
parent
aba218e6d7
commit
06fab3f129
|
@ -8,6 +8,13 @@ All notable changes to this project will be documented in this file. The format
|
||||||
|
|
||||||
### Updates
|
### Updates
|
||||||
|
|
||||||
|
- **Tests**:
|
||||||
|
- Refactored mail sending ([#3747](https://github.com/docker-mailserver/docker-mailserver/pull/3747)):
|
||||||
|
- This change is a follow-up to [#3732](https://github.com/docker-mailserver/docker-mailserver/pull/3732) from DMS v13.2.
|
||||||
|
- `swaks` version is now the latest from Github releases instead of the Debian package.
|
||||||
|
- `_nc_wrapper`, `_send_mail` and related helpers expect the `.txt` filepath extension again.
|
||||||
|
- `sending.bash` helper methods were refactored to better integrate `swaks` and accommodate different usage contexts.
|
||||||
|
- `test/files/emails/existing/` files were removed similar to previous removal of SMTP auth files as they became redundant with `swaks`.
|
||||||
- **Internal:**
|
- **Internal:**
|
||||||
- tests: Replace `wc -l` with `grep -c` ([#3752](https://github.com/docker-mailserver/docker-mailserver/pull/3752))
|
- tests: Replace `wc -l` with `grep -c` ([#3752](https://github.com/docker-mailserver/docker-mailserver/pull/3752))
|
||||||
- Postfix is now configured with `smtputf8_enable = no` in our default `main.cf` config (_instead of during container startup_). ([#3750](https://github.com/docker-mailserver/docker-mailserver/pull/3750))
|
- Postfix is now configured with `smtputf8_enable = no` in our default `main.cf` config (_instead of during container startup_). ([#3750](https://github.com/docker-mailserver/docker-mailserver/pull/3750))
|
||||||
|
|
|
@ -80,7 +80,7 @@ function _install_packages() {
|
||||||
# `bind9-dnsutils` provides the `dig` command
|
# `bind9-dnsutils` provides the `dig` command
|
||||||
# `iputils-ping` provides the `ping` command
|
# `iputils-ping` provides the `ping` command
|
||||||
DEBUG_PACKAGES=(
|
DEBUG_PACKAGES=(
|
||||||
bind9-dnsutils iputils-ping less nano swaks
|
bind9-dnsutils iputils-ping less nano
|
||||||
)
|
)
|
||||||
|
|
||||||
apt-get "${QUIET}" --no-install-recommends install \
|
apt-get "${QUIET}" --no-install-recommends install \
|
||||||
|
@ -192,7 +192,15 @@ function _install_getmail() {
|
||||||
|
|
||||||
function _install_utils() {
|
function _install_utils() {
|
||||||
_log 'debug' 'Installing utils sourced from Github'
|
_log 'debug' 'Installing utils sourced from Github'
|
||||||
|
_log 'trace' 'Installing jaq'
|
||||||
curl -sL "https://github.com/01mf02/jaq/releases/latest/download/jaq-v1.2.0-$(uname -m)-unknown-linux-gnu" -o /usr/bin/jaq && chmod +x /usr/bin/jaq
|
curl -sL "https://github.com/01mf02/jaq/releases/latest/download/jaq-v1.2.0-$(uname -m)-unknown-linux-gnu" -o /usr/bin/jaq && chmod +x /usr/bin/jaq
|
||||||
|
|
||||||
|
_log 'trace' 'Installing swaks'
|
||||||
|
local SWAKS_VERSION='20240103.0'
|
||||||
|
local SWAKS_RELEASE="swaks-${SWAKS_VERSION}"
|
||||||
|
curl -sSfL "https://github.com/jetmore/swaks/releases/download/v${SWAKS_VERSION}/${SWAKS_RELEASE}.tar.gz" | tar -xz
|
||||||
|
mv "${SWAKS_RELEASE}/swaks" /usr/local/bin
|
||||||
|
rm -r "${SWAKS_RELEASE}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function _remove_data_after_package_installations() {
|
function _remove_data_after_package_installations() {
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <added@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-added.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <alias1@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-alias-external.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local Alias <alias2@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-alias-local.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local Alias With Delimiter <alias1+test@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-alias-recipient-delimiter.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <wildcard@localdomain2.com>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-catchall-local.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <bounce-always@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-regexp-alias-external.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <test123@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-regexp-alias-local.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,6 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Cc: Existing Local Alias <alias2@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-user-and-cc-local-alias.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message existing-user1.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <dockermailserver@external.tld>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message non-existing-user.txt
|
|
||||||
This is a test mail.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <pass@example.test>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Date: Sat, 22 May 2010 07:43:25 -0400
|
|
||||||
Subject: Test Message rspamd/pass.txt
|
|
||||||
This mail should pass and Rspamd should not mark it.
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <spam-header@example.test>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Date: Sat, 21 Jan 2023 11:11:11 +0000
|
|
||||||
Subject: Test Message rspamd-spam-header.txt
|
|
||||||
YJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <spam@example.test>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Date: Sat, 21 Jan 2023 11:11:11 +0000
|
|
||||||
Subject: Test Message rspamd-spam.txt
|
|
||||||
XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X
|
|
|
@ -1,5 +0,0 @@
|
||||||
From: Docker Mail Server <virus@example.test>
|
|
||||||
To: Existing Local User <user1@localhost.localdomain>
|
|
||||||
Date: Sat, 21 Jan 2023 11:11:11 +0000
|
|
||||||
Subject: Test Message rspamd-virus.txt
|
|
||||||
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
|
|
|
@ -466,7 +466,7 @@ function _print_mail_log_for_id() {
|
||||||
local MAIL_ID=${1:?Mail ID must be provided}
|
local MAIL_ID=${1:?Mail ID must be provided}
|
||||||
local CONTAINER_NAME=$(__handle_container_name "${2:-}")
|
local CONTAINER_NAME=$(__handle_container_name "${2:-}")
|
||||||
|
|
||||||
_run_in_container grep -F "${MAIL_ID}" /var/log/mail.log
|
_run_in_container grep -E "${MAIL_ID}" /var/log/mail.log
|
||||||
}
|
}
|
||||||
|
|
||||||
# A simple wrapper for netcat (`nc`). This is useful when sending
|
# A simple wrapper for netcat (`nc`). This is useful when sending
|
||||||
|
@ -480,7 +480,7 @@ function _nc_wrapper() {
|
||||||
|
|
||||||
[[ -v CONTAINER_NAME ]] || return 1
|
[[ -v CONTAINER_NAME ]] || return 1
|
||||||
|
|
||||||
_run_in_container_bash "nc ${NC_PARAMETERS} < /tmp/docker-mailserver-test/${FILE}.txt"
|
_run_in_container_bash "nc ${NC_PARAMETERS} < /tmp/docker-mailserver-test/${FILE}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ? << Miscellaneous helper functions
|
# ? << Miscellaneous helper functions
|
||||||
|
|
|
@ -7,23 +7,38 @@
|
||||||
# ! ATTENTION: This file is loaded by `common.sh` - do not load it yourself!
|
# ! ATTENTION: This file is loaded by `common.sh` - do not load it yourself!
|
||||||
# ! ATTENTION: This file requires helper functions from `common.sh`!
|
# ! ATTENTION: This file requires helper functions from `common.sh`!
|
||||||
|
|
||||||
# Sends a mail from localhost (127.0.0.1) to a container. To send
|
# Sends an e-mail from the container named by the environment variable `CONTAINER_NAME`
|
||||||
# a custom email, create a file at `test/files/<TEST FILE>`,
|
# to the same or another container.
|
||||||
# and provide `<TEST FILE>` as an argument to this function.
|
|
||||||
#
|
#
|
||||||
# Parameters include all options that one can supply to `swaks`
|
# To send a custom email, you can
|
||||||
# itself. The `--data` parameter expects a relative path from `emails/`
|
#
|
||||||
# where the contents will be implicitly provided to `swaks` via STDIN.
|
# 1. create a file at `test/files/<TEST FILE>` and provide `<TEST FILE>` via `--data` as an argument to this function;
|
||||||
|
# 2. use this function without the `--data` argument, in which case we provide a default;
|
||||||
|
# 3. provide data inline (`--data <INLINE DATA>`).
|
||||||
|
#
|
||||||
|
# The very first parameter **may** be `--expect-rejection` - use it of you expect the mail transaction to not finish
|
||||||
|
# successfully. All other (following) parameters include all options that one can supply to `swaks` itself.
|
||||||
|
# As mentioned before, the `--data` parameter expects a value of either:
|
||||||
|
#
|
||||||
|
# - A relative path from `test/files/emails/`
|
||||||
|
# - An "inline" data string (e.g., `Date: 1 Jan 2024\nSubject: This is a test`)
|
||||||
|
#
|
||||||
|
# ## Output
|
||||||
|
#
|
||||||
|
# This functions prints the output of the transaction that `swaks` prints.
|
||||||
#
|
#
|
||||||
# ## Attention
|
# ## Attention
|
||||||
#
|
#
|
||||||
# This function assumes `CONTAINER_NAME` to be properly set (to the container
|
# This function assumes `CONTAINER_NAME` to be properly set (to the container
|
||||||
# name the command should be executed in)!
|
# name the command should be executed in)!
|
||||||
#
|
#
|
||||||
# This function will just send the email in an "asynchronous" fashion, i.e. it will
|
# This function will send the email in an "asynchronous" fashion,
|
||||||
# send the email but it will not make sure the mail queue is empty after the mail
|
# it will return without waiting for the Postfix mail queue to be emptied.
|
||||||
# has been sent.
|
|
||||||
function _send_email() {
|
function _send_email() {
|
||||||
|
local RETURN_VALUE=0
|
||||||
|
local COMMAND_STRING
|
||||||
|
|
||||||
|
function __parse_arguments() {
|
||||||
[[ -v CONTAINER_NAME ]] || return 1
|
[[ -v CONTAINER_NAME ]] || return 1
|
||||||
|
|
||||||
# Parameter defaults common to our testing needs:
|
# Parameter defaults common to our testing needs:
|
||||||
|
@ -34,8 +49,7 @@ function _send_email() {
|
||||||
local PORT=25
|
local PORT=25
|
||||||
# Extra options for `swaks` that aren't covered by the default options above:
|
# Extra options for `swaks` that aren't covered by the default options above:
|
||||||
local ADDITIONAL_SWAKS_OPTIONS=()
|
local ADDITIONAL_SWAKS_OPTIONS=()
|
||||||
# Specifically for handling `--data` option below:
|
local DATA_WAS_SUPPLIED=0
|
||||||
local FINAL_SWAKS_OPTIONS=()
|
|
||||||
|
|
||||||
while [[ ${#} -gt 0 ]]; do
|
while [[ ${#} -gt 0 ]]; do
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
|
@ -45,30 +59,66 @@ function _send_email() {
|
||||||
( '--server' ) SERVER=${2:?--server given but no argument} ; shift 2 ;;
|
( '--server' ) SERVER=${2:?--server given but no argument} ; shift 2 ;;
|
||||||
( '--port' ) PORT=${2:?--port given but no argument} ; shift 2 ;;
|
( '--port' ) PORT=${2:?--port given but no argument} ; shift 2 ;;
|
||||||
( '--data' )
|
( '--data' )
|
||||||
local TEMPLATE_FILE="/tmp/docker-mailserver-test/emails/${2:?--data given but no argument provided}.txt"
|
ADDITIONAL_SWAKS_OPTIONS+=('--data')
|
||||||
FINAL_SWAKS_OPTIONS+=('--data')
|
local FILE_PATH="/tmp/docker-mailserver-test/emails/${2:?--data given but no argument provided}"
|
||||||
FINAL_SWAKS_OPTIONS+=('-')
|
if _exec_in_container_bash "[[ -e ${FILE_PATH} ]]"; then
|
||||||
FINAL_SWAKS_OPTIONS+=('<')
|
ADDITIONAL_SWAKS_OPTIONS+=("@${FILE_PATH}")
|
||||||
FINAL_SWAKS_OPTIONS+=("${TEMPLATE_FILE}")
|
else
|
||||||
|
ADDITIONAL_SWAKS_OPTIONS+=("'${2}'")
|
||||||
|
fi
|
||||||
shift 2
|
shift 2
|
||||||
|
DATA_WAS_SUPPLIED=1
|
||||||
;;
|
;;
|
||||||
( * ) ADDITIONAL_SWAKS_OPTIONS+=("${1}") ; shift 1 ;;
|
( * ) ADDITIONAL_SWAKS_OPTIONS+=("'${1}'") ; shift 1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
_run_in_container_bash "swaks --server ${SERVER} --port ${PORT} --ehlo ${EHLO} --from ${FROM} --to ${TO} ${ADDITIONAL_SWAKS_OPTIONS[*]} ${FINAL_SWAKS_OPTIONS[*]}"
|
if [[ ${DATA_WAS_SUPPLIED} -eq 0 ]]; then
|
||||||
|
# Fallback template (without the implicit `Message-Id` + `X-Mailer` headers from swaks):
|
||||||
|
# NOTE: It is better to let Postfix generate and append the `Message-Id` header itself,
|
||||||
|
# as it will contain the Queue ID for tracking in logs (which is also returned in swaks output).
|
||||||
|
ADDITIONAL_SWAKS_OPTIONS+=('--data')
|
||||||
|
ADDITIONAL_SWAKS_OPTIONS+=("'Date: %DATE%\nTo: %TO_ADDRESS%\nFrom: %FROM_ADDRESS%\nSubject: test %DATE%\n%NEW_HEADERS%\n%BODY%\n'")
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "swaks --server '${SERVER}' --port '${PORT}' --ehlo '${EHLO}' --from '${FROM}' --to '${TO}' ${ADDITIONAL_SWAKS_OPTIONS[*]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ ${1:-} == --expect-rejection ]]; then
|
||||||
|
shift 1
|
||||||
|
COMMAND_STRING=$(__parse_arguments "${@}")
|
||||||
|
_run_in_container_bash "${COMMAND_STRING}"
|
||||||
|
RETURN_VALUE=${?}
|
||||||
|
else
|
||||||
|
COMMAND_STRING=$(__parse_arguments "${@}")
|
||||||
|
_run_in_container_bash "${COMMAND_STRING}"
|
||||||
|
assert_success
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
echo "${output}"
|
||||||
|
return "${RETURN_VALUE}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Like `_send_email` with two major differences:
|
# Like `_send_email` with two major differences:
|
||||||
#
|
#
|
||||||
# 1. this function waits for the mail to be processed; there is no asynchronicity
|
# 1. this function waits for the mail to be processed; there is no asynchronicity
|
||||||
# because filtering the logs in a synchronous way is easier and safer!
|
# because filtering the logs in a synchronous way is easier and safer;
|
||||||
# 2. this function prints an ID one can later filter by to check logs
|
# 2. this function takes the name of a variable and inserts IDs one can later
|
||||||
|
# filter by to check logs.
|
||||||
#
|
#
|
||||||
# No. 2 is especially useful in case you send more than one email in a single
|
# No. 2 is especially useful in case you send more than one email in a single
|
||||||
# test file and need to assert certain log entries for each mail individually.
|
# test file and need to assert certain log entries for each mail individually.
|
||||||
#
|
#
|
||||||
# This function takes the same arguments as `_send_mail`.
|
# The first argument has to be the name of the variable that the e-mail ID is stored in.
|
||||||
|
# The second argument **can** be the flag `--expect-rejection`.
|
||||||
|
#
|
||||||
|
# - If this flag is supplied, the function does not check whether the whole mail delivery
|
||||||
|
# transaction was successful. Additionally the queue ID will be retrieved differently.
|
||||||
|
# - CAUTION: It must still be possible to `grep` for the Message-ID that Postfix
|
||||||
|
# generated in the mail log; otherwise this function fails.
|
||||||
|
#
|
||||||
|
# The rest of the arguments are the same as `_send_email`.
|
||||||
#
|
#
|
||||||
# ## Attention
|
# ## Attention
|
||||||
#
|
#
|
||||||
|
@ -82,20 +132,35 @@ function _send_email() {
|
||||||
# chosen. Sending more than one mail at any given point in time with this function
|
# chosen. Sending more than one mail at any given point in time with this function
|
||||||
# is UNDEFINED BEHAVIOR!
|
# is UNDEFINED BEHAVIOR!
|
||||||
function _send_email_and_get_id() {
|
function _send_email_and_get_id() {
|
||||||
[[ -v CONTAINER_NAME ]] || return 1
|
# Export the variable denoted by ${1} so everyone has access
|
||||||
|
export "${1:?Mail ID must be set for _send_email_and_get_id}"
|
||||||
|
# Get a "reference" to the content of the variable denoted by ${1} so we can manipulate the content
|
||||||
|
local -n ID_ENV_VAR_REF=${1:?}
|
||||||
|
# Prepare the message ID header here because we will shift away ${1} later
|
||||||
|
local MID="<${1}@dms-tests>"
|
||||||
|
# Get rid of ${1} so only the arguments for swaks remain
|
||||||
|
shift 1
|
||||||
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
local QUEUE_ID
|
||||||
_send_email "${@}"
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
|
||||||
|
|
||||||
local MAIL_ID
|
|
||||||
# The unique ID Postfix (and other services) use may be different in length
|
# The unique ID Postfix (and other services) use may be different in length
|
||||||
# on different systems (e.g. amd64 (11) vs aarch64 (10)). Hence, we use a
|
# on different systems (e.g. amd64 (11) vs aarch64 (10)). Hence, we use a
|
||||||
# range to safely capture it.
|
# range to safely capture it.
|
||||||
MAIL_ID=$(_exec_in_container tac /var/log/mail.log \
|
local QUEUE_ID_REGEX='[A-Z0-9]{9,12}'
|
||||||
| grep -E -m 1 'postfix/smtpd.*: [A-Z0-9]+: client=localhost' \
|
|
||||||
| grep -E -o '[A-Z0-9]{9,12}' || true)
|
|
||||||
|
|
||||||
assert_not_equal "${MAIL_ID}" ''
|
_wait_for_empty_mail_queue_in_container
|
||||||
echo "${MAIL_ID}"
|
local OUTPUT=$(_send_email "${@}" --header "Message-Id: ${MID}")
|
||||||
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
|
# We store Postfix's queue ID first
|
||||||
|
ID_ENV_VAR_REF=$(_exec_in_container tac /var/log/mail.log \
|
||||||
|
| grep -E "postfix/cleanup.*: ${QUEUE_ID_REGEX}:.*message-id=${MID}" \
|
||||||
|
| grep -E --only-matching --max-count 1 "${QUEUE_ID_REGEX}" || :)
|
||||||
|
# But we also requre potential Dovecot sieve output, which requires the mesage ID,
|
||||||
|
# so we need to provide the message ID too.
|
||||||
|
ID_ENV_VAR_REF+="|${MID}"
|
||||||
|
|
||||||
|
# Last but not least, we perform plausibility checks on the IDs.
|
||||||
|
assert_not_equal "${ID_ENV_VAR_REF}" ''
|
||||||
|
run echo "${ID_ENV_VAR_REF}"
|
||||||
|
assert_line --regexp "^${QUEUE_ID_REGEX}\|${MID}$"
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,12 +225,9 @@ function teardown_file() { _default_teardown ; }
|
||||||
sleep 10
|
sleep 10
|
||||||
|
|
||||||
# send some big emails
|
# send some big emails
|
||||||
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded'
|
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded.txt'
|
||||||
assert_success
|
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded.txt'
|
||||||
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded'
|
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded.txt'
|
||||||
assert_success
|
|
||||||
_send_email --to 'quotauser@otherdomain.tld' --data 'quota-exceeded'
|
|
||||||
assert_success
|
|
||||||
# check for quota warn message existence
|
# check for quota warn message existence
|
||||||
run _repeat_until_success_or_timeout 20 _exec_in_container grep -R 'Subject: quota warning' /var/mail/otherdomain.tld/quotauser/new/
|
run _repeat_until_success_or_timeout 20 _exec_in_container grep -R 'Subject: quota warning' /var/mail/otherdomain.tld/quotauser/new/
|
||||||
assert_success
|
assert_success
|
||||||
|
|
|
@ -26,11 +26,9 @@ function setup_file() {
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
|
|
||||||
# Single mail sent from 'spam@spam.com' that is handled by User (relocate) and Global (copy) sieves for user1:
|
# Single mail sent from 'spam@spam.com' that is handled by User (relocate) and Global (copy) sieves for user1:
|
||||||
_send_email --data 'sieve/spam-folder'
|
_send_email --data 'sieve/spam-folder.txt'
|
||||||
assert_success
|
|
||||||
# Mail for user2 triggers the sieve-pipe:
|
# Mail for user2 triggers the sieve-pipe:
|
||||||
_send_email --to 'user2@otherdomain.tld' --data 'sieve/pipe'
|
_send_email --to 'user2@otherdomain.tld' --data 'sieve/pipe.txt'
|
||||||
assert_success
|
|
||||||
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,7 @@ function teardown() { _default_teardown ; }
|
||||||
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
|
|
||||||
_send_email --data 'existing/user1'
|
_send_email
|
||||||
assert_success
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
# Mail received should be stored as `u.1` (one file per message)
|
# Mail received should be stored as `u.1` (one file per message)
|
||||||
|
@ -48,8 +47,7 @@ function teardown() { _default_teardown ; }
|
||||||
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
|
|
||||||
_send_email --data 'existing/user1'
|
_send_email
|
||||||
assert_success
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
# Mail received should be stored in `m.1` (1 or more messages)
|
# Mail received should be stored in `m.1` (1 or more messages)
|
||||||
|
|
|
@ -14,8 +14,7 @@ function setup_file() {
|
||||||
function teardown_file() { _default_teardown ; }
|
function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
@test 'normal delivery works' {
|
@test 'normal delivery works' {
|
||||||
_send_email --data 'existing/user1'
|
_send_email
|
||||||
assert_success
|
|
||||||
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new 1
|
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "(IMAP) special-use folders should be created when necessary" {
|
@test "(IMAP) special-use folders should be created when necessary" {
|
||||||
_nc_wrapper 'nc/imap_special_use_folders' '-w 8 0.0.0.0 143'
|
_nc_wrapper 'nc/imap_special_use_folders.txt' '-w 8 0.0.0.0 143'
|
||||||
assert_output --partial 'Drafts'
|
assert_output --partial 'Drafts'
|
||||||
assert_output --partial 'Junk'
|
assert_output --partial 'Junk'
|
||||||
assert_output --partial 'Trash'
|
assert_output --partial 'Trash'
|
||||||
|
|
|
@ -25,8 +25,7 @@ function setup_file() {
|
||||||
|
|
||||||
_wait_for_service postfix
|
_wait_for_service postfix
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
_send_email --from 'virus@external.tld' --data 'amavis/virus'
|
_send_email --from 'virus@external.tld' --data 'amavis/virus.txt'
|
||||||
assert_success
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,7 @@ function setup_file() {
|
||||||
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
_common_container_setup 'CUSTOM_SETUP_ARGUMENTS'
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
|
|
||||||
_send_email --data 'existing/user1'
|
_send_email
|
||||||
assert_success
|
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ function teardown_file() {
|
||||||
CONTAINER1_IP=$(_get_container_ip "${CONTAINER1_NAME}")
|
CONTAINER1_IP=$(_get_container_ip "${CONTAINER1_NAME}")
|
||||||
# Trigger a ban by failing to login twice:
|
# Trigger a ban by failing to login twice:
|
||||||
for _ in {1..2}; do
|
for _ in {1..2}; do
|
||||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email \
|
CONTAINER_NAME=${CONTAINER2_NAME} _send_email --expect-rejection \
|
||||||
--server "${CONTAINER1_IP}" \
|
--server "${CONTAINER1_IP}" \
|
||||||
--port 465 \
|
--port 465 \
|
||||||
--auth PLAIN \
|
--auth PLAIN \
|
||||||
|
|
|
@ -51,7 +51,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
_reload_postfix
|
_reload_postfix
|
||||||
|
|
||||||
# Send test mail (it should fail to deliver):
|
# Send test mail (it should fail to deliver):
|
||||||
_send_email --from 'user@external.tld' --port 25 --data 'postgrey'
|
_send_email --expect-rejection --from 'user@external.tld' --port 25 --data 'postgrey.txt'
|
||||||
assert_failure
|
assert_failure
|
||||||
assert_output --partial 'Recipient address rejected: Delayed by Postgrey'
|
assert_output --partial 'Recipient address rejected: Delayed by Postgrey'
|
||||||
|
|
||||||
|
@ -67,8 +67,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
# Wait until `$POSTGREY_DELAY` seconds pass before trying again:
|
# Wait until `$POSTGREY_DELAY` seconds pass before trying again:
|
||||||
sleep 3
|
sleep 3
|
||||||
# Retry delivering test mail (it should be trusted this time):
|
# Retry delivering test mail (it should be trusted this time):
|
||||||
_send_email --from 'user@external.tld' --port 25 --data 'postgrey'
|
_send_email --from 'user@external.tld' --port 25 --data 'postgrey.txt'
|
||||||
assert_success
|
|
||||||
|
|
||||||
# Confirm postgrey permitted delivery (triplet is now trusted):
|
# Confirm postgrey permitted delivery (triplet is now trusted):
|
||||||
_should_have_log_entry \
|
_should_have_log_entry \
|
||||||
|
@ -87,7 +86,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
# - It'd also cause the earlier greylist test to fail.
|
# - It'd also cause the earlier greylist test to fail.
|
||||||
# - TODO: Actually confirm whitelist feature works correctly as these test cases are using a workaround:
|
# - TODO: Actually confirm whitelist feature works correctly as these test cases are using a workaround:
|
||||||
@test "should whitelist sender 'user@whitelist.tld'" {
|
@test "should whitelist sender 'user@whitelist.tld'" {
|
||||||
_nc_wrapper 'nc/postgrey_whitelist' '-w 0 0.0.0.0 10023'
|
_nc_wrapper 'nc/postgrey_whitelist.txt' '-w 0 0.0.0.0 10023'
|
||||||
|
|
||||||
_should_have_log_entry \
|
_should_have_log_entry \
|
||||||
'action=pass' \
|
'action=pass' \
|
||||||
|
@ -96,7 +95,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "should whitelist recipient 'user2@otherdomain.tld'" {
|
@test "should whitelist recipient 'user2@otherdomain.tld'" {
|
||||||
_nc_wrapper 'nc/postgrey_whitelist_recipients' '-w 0 0.0.0.0 10023'
|
_nc_wrapper 'nc/postgrey_whitelist_recipients.txt' '-w 0 0.0.0.0 10023'
|
||||||
|
|
||||||
_should_have_log_entry \
|
_should_have_log_entry \
|
||||||
'action=pass' \
|
'action=pass' \
|
||||||
|
|
|
@ -44,7 +44,7 @@ function teardown_file() {
|
||||||
# Use `nc` to send all SMTP commands at once instead (emulate a misbehaving client that should be rejected)
|
# Use `nc` to send all SMTP commands at once instead (emulate a misbehaving client that should be rejected)
|
||||||
# NOTE: Postscreen only runs on port 25, avoid implicit ports in test methods
|
# NOTE: Postscreen only runs on port 25, avoid implicit ports in test methods
|
||||||
@test 'should fail send when talking out of turn' {
|
@test 'should fail send when talking out of turn' {
|
||||||
CONTAINER_NAME=${CONTAINER2_NAME} _nc_wrapper 'emails/nc_raw/postscreen' "${CONTAINER1_IP} 25"
|
CONTAINER_NAME=${CONTAINER2_NAME} _nc_wrapper 'emails/nc_raw/postscreen.txt' "${CONTAINER1_IP} 25"
|
||||||
# Expected postscreen log entry:
|
# Expected postscreen log entry:
|
||||||
assert_output --partial 'Protocol error'
|
assert_output --partial 'Protocol error'
|
||||||
|
|
||||||
|
@ -56,14 +56,10 @@ function teardown_file() {
|
||||||
@test "should successfully pass postscreen and get postfix greeting message (respecting postscreen_greet_wait time)" {
|
@test "should successfully pass postscreen and get postfix greeting message (respecting postscreen_greet_wait time)" {
|
||||||
# Configure `send_email()` to send from the mail client container (CONTAINER2_NAME) via ENV override,
|
# Configure `send_email()` to send from the mail client container (CONTAINER2_NAME) via ENV override,
|
||||||
# mail is sent to the DMS server container (CONTAINER1_NAME) via `--server` parameter:
|
# mail is sent to the DMS server container (CONTAINER1_NAME) via `--server` parameter:
|
||||||
CONTAINER_NAME=${CONTAINER2_NAME} _send_email --server "${CONTAINER1_IP}" --port 25 --data 'postscreen'
|
# TODO: Use _send_email_and_get_id when proper resolution of domain names is possible:
|
||||||
# NOTE: Cannot assert_success due to sender address not being resolvable.
|
CONTAINER_NAME=${CONTAINER2_NAME} _send_email --expect-rejection --server "${CONTAINER1_IP}" --port 25 --data 'postscreen.txt'
|
||||||
# TODO: Uncomment when proper resolution of domain names is possible:
|
# CONTAINER_NAME=${CONTAINER2_NAME} _send_email_and_get_id MAIL_ID_POSTSCREEN --server "${CONTAINER1_IP}" --data 'postscreen.txt'
|
||||||
# assert_success
|
# _print_mail_log_for_id "${MAIL_ID_POSTSCREEN}"
|
||||||
|
|
||||||
# TODO: Prefer this approach when `_send_email_and_get_id()` can support separate client and server containers:
|
|
||||||
# local MAIL_ID=$(_send_email_and_get_id --port 25 --data 'postscreen')
|
|
||||||
# _print_mail_log_for_id "${MAIL_ID}"
|
|
||||||
# assert_output --partial "stored mail into mailbox 'INBOX'"
|
# assert_output --partial "stored mail into mailbox 'INBOX'"
|
||||||
|
|
||||||
_run_in_container cat /var/log/mail.log
|
_run_in_container cat /var/log/mail.log
|
||||||
|
|
|
@ -43,16 +43,24 @@ function setup_file() {
|
||||||
_wait_for_service postfix
|
_wait_for_service postfix
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
|
|
||||||
# We will send 3 emails: the first one should pass just fine; the second one should
|
# ref: https://rspamd.com/doc/gtube_patterns.html
|
||||||
# be rejected due to spam; the third one should be rejected due to a virus.
|
local GTUBE_SUFFIX='*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'
|
||||||
export MAIL_ID1=$(_send_email_and_get_id --from 'rspamd-pass@example.test' --data 'rspamd/pass')
|
|
||||||
export MAIL_ID2=$(_send_email_and_get_id --from 'rspamd-spam@example.test' --data 'rspamd/spam')
|
|
||||||
export MAIL_ID3=$(_send_email_and_get_id --from 'rspamd-virus@example.test' --data 'rspamd/virus')
|
|
||||||
export MAIL_ID4=$(_send_email_and_get_id --from 'rspamd-spam-header@example.test' --data 'rspamd/spam-header')
|
|
||||||
|
|
||||||
for ID in MAIL_ID{1,2,3,4}; do
|
# We will send 4 emails:
|
||||||
[[ -n ${!ID} ]] || { echo "${ID} is empty - aborting!" ; return 1 ; }
|
# 1. The first one should pass just fine
|
||||||
done
|
_send_email_and_get_id MAIL_ID_PASS
|
||||||
|
# 2. The second one should be rejected (GTUBE pattern)
|
||||||
|
_send_email_and_get_id MAIL_ID_REJECT --expect-rejection --body "XJS${GTUBE_SUFFIX}"
|
||||||
|
# 3. The third one should be rejected due to a virus (ClamAV EICAR pattern)
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
_send_email_and_get_id MAIL_ID_VIRUS --expect-rejection \
|
||||||
|
--body 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'
|
||||||
|
# 4. The fourth one will receive an added header (GTUBE pattern)
|
||||||
|
_send_email_and_get_id MAIL_ID_HEADER --body "YJS${GTUBE_SUFFIX}"
|
||||||
|
|
||||||
|
_run_in_container cat /var/log/mail.log
|
||||||
|
assert_success
|
||||||
|
refute_output --partial 'inet:localhost:11332: Connection refused'
|
||||||
}
|
}
|
||||||
|
|
||||||
function teardown_file() { _default_teardown ; }
|
function teardown_file() { _default_teardown ; }
|
||||||
|
@ -104,7 +112,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
@test 'normal mail passes fine' {
|
@test 'normal mail passes fine' {
|
||||||
_service_log_should_contain_string 'rspamd' 'F \(no action\)'
|
_service_log_should_contain_string 'rspamd' 'F \(no action\)'
|
||||||
|
|
||||||
_print_mail_log_for_id "${MAIL_ID1}"
|
_print_mail_log_for_id "${MAIL_ID_PASS}"
|
||||||
assert_output --partial "stored mail into mailbox 'INBOX'"
|
assert_output --partial "stored mail into mailbox 'INBOX'"
|
||||||
|
|
||||||
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new/ 1
|
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new/ 1
|
||||||
|
@ -114,7 +122,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
_service_log_should_contain_string 'rspamd' 'S \(reject\)'
|
_service_log_should_contain_string 'rspamd' 'S \(reject\)'
|
||||||
_service_log_should_contain_string 'rspamd' 'reject "Gtube pattern"'
|
_service_log_should_contain_string 'rspamd' 'reject "Gtube pattern"'
|
||||||
|
|
||||||
_print_mail_log_for_id "${MAIL_ID2}"
|
_print_mail_log_for_id "${MAIL_ID_REJECT}"
|
||||||
assert_output --partial 'milter-reject'
|
assert_output --partial 'milter-reject'
|
||||||
assert_output --partial '5.7.1 Gtube pattern'
|
assert_output --partial '5.7.1 Gtube pattern'
|
||||||
|
|
||||||
|
@ -125,7 +133,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
_service_log_should_contain_string 'rspamd' 'T \(reject\)'
|
_service_log_should_contain_string 'rspamd' 'T \(reject\)'
|
||||||
_service_log_should_contain_string 'rspamd' 'reject "ClamAV FOUND VIRUS "Eicar-Signature"'
|
_service_log_should_contain_string 'rspamd' 'reject "ClamAV FOUND VIRUS "Eicar-Signature"'
|
||||||
|
|
||||||
_print_mail_log_for_id "${MAIL_ID3}"
|
_print_mail_log_for_id "${MAIL_ID_VIRUS}"
|
||||||
assert_output --partial 'milter-reject'
|
assert_output --partial 'milter-reject'
|
||||||
assert_output --partial '5.7.1 ClamAV FOUND VIRUS "Eicar-Signature"'
|
assert_output --partial '5.7.1 ClamAV FOUND VIRUS "Eicar-Signature"'
|
||||||
refute_output --partial "stored mail into mailbox 'INBOX'"
|
refute_output --partial "stored mail into mailbox 'INBOX'"
|
||||||
|
@ -214,7 +222,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
_service_log_should_contain_string 'rspamd' 'S \(add header\)'
|
_service_log_should_contain_string 'rspamd' 'S \(add header\)'
|
||||||
_service_log_should_contain_string 'rspamd' 'add header "Gtube pattern"'
|
_service_log_should_contain_string 'rspamd' 'add header "Gtube pattern"'
|
||||||
|
|
||||||
_print_mail_log_for_id "${MAIL_ID4}"
|
_print_mail_log_for_id "${MAIL_ID_HEADER}"
|
||||||
assert_output --partial "fileinto action: stored mail into mailbox 'Junk'"
|
assert_output --partial "fileinto action: stored mail into mailbox 'Junk'"
|
||||||
|
|
||||||
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new/ 1
|
_count_files_in_directory_in_container /var/mail/localhost.localdomain/user1/new/ 1
|
||||||
|
@ -256,7 +264,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
# Move an email to the "Junk" folder from "INBOX"; the first email we
|
# Move an email to the "Junk" folder from "INBOX"; the first email we
|
||||||
# sent should pass fine, hence we can now move it.
|
# sent should pass fine, hence we can now move it.
|
||||||
_nc_wrapper 'nc/rspamd_imap_move_to_junk' '0.0.0.0 143'
|
_nc_wrapper 'nc/rspamd_imap_move_to_junk.txt' '0.0.0.0 143'
|
||||||
sleep 1 # wait for the transaction to finish
|
sleep 1 # wait for the transaction to finish
|
||||||
|
|
||||||
_run_in_container cat /var/log/mail/mail.log
|
_run_in_container cat /var/log/mail/mail.log
|
||||||
|
@ -270,7 +278,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
# Move an email to the "INBOX" folder from "Junk"; there should be two mails
|
# Move an email to the "INBOX" folder from "Junk"; there should be two mails
|
||||||
# in the "Junk" folder, since the second email we sent during setup should
|
# in the "Junk" folder, since the second email we sent during setup should
|
||||||
# have landed in the Junk folder already.
|
# have landed in the Junk folder already.
|
||||||
_nc_wrapper 'nc/rspamd_imap_move_to_inbox' '0.0.0.0 143'
|
_nc_wrapper 'nc/rspamd_imap_move_to_inbox.txt' '0.0.0.0 143'
|
||||||
sleep 1 # wait for the transaction to finish
|
sleep 1 # wait for the transaction to finish
|
||||||
|
|
||||||
_run_in_container cat /var/log/mail/mail.log
|
_run_in_container cat /var/log/mail/mail.log
|
||||||
|
|
|
@ -95,7 +95,7 @@ function teardown() { _default_teardown ; }
|
||||||
function _should_send_spam_message() {
|
function _should_send_spam_message() {
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
_wait_for_tcp_port_in_container 10024 # port 10024 is for Amavis
|
_wait_for_tcp_port_in_container 10024 # port 10024 is for Amavis
|
||||||
_send_email --from 'spam@external.tld' --data 'amavis/spam'
|
_send_email --from 'spam@external.tld' --data 'amavis/spam.txt'
|
||||||
}
|
}
|
||||||
|
|
||||||
function _should_be_received_by_amavis() {
|
function _should_be_received_by_amavis() {
|
||||||
|
|
|
@ -207,7 +207,7 @@ function _should_have_correct_mail_headers() {
|
||||||
# (eg: OVERRIDE_HOSTNAME or `--hostname mail --domainname example.test`)
|
# (eg: OVERRIDE_HOSTNAME or `--hostname mail --domainname example.test`)
|
||||||
local EXPECTED_HOSTNAME=${3:-${EXPECTED_FQDN}}
|
local EXPECTED_HOSTNAME=${3:-${EXPECTED_FQDN}}
|
||||||
|
|
||||||
_send_email --from 'user@external.tld' --data 'existing/user1'
|
_send_email --from 'user@external.tld'
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
_count_files_in_directory_in_container '/var/mail/localhost.localdomain/user1/new/' '1'
|
_count_files_in_directory_in_container '/var/mail/localhost.localdomain/user1/new/' '1'
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,9 @@ function teardown_file() {
|
||||||
|
|
||||||
# TODO replace with _send_email as soon as it supports DSN
|
# TODO replace with _send_email as soon as it supports DSN
|
||||||
# TODO ref: https://github.com/jetmore/swaks/issues/41
|
# TODO ref: https://github.com/jetmore/swaks/issues/41
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated'
|
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated.txt'
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 465'
|
_nc_wrapper 'emails/nc_raw/dsn/authenticated.txt' '0.0.0.0 465'
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 587'
|
_nc_wrapper 'emails/nc_raw/dsn/authenticated.txt' '0.0.0.0 587'
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
_run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log
|
_run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log
|
||||||
|
@ -62,7 +62,7 @@ function teardown_file() {
|
||||||
@test "should only send a DSN when requested from ports 465/587" {
|
@test "should only send a DSN when requested from ports 465/587" {
|
||||||
export CONTAINER_NAME=${CONTAINER2_NAME}
|
export CONTAINER_NAME=${CONTAINER2_NAME}
|
||||||
|
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated'
|
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated.txt'
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
# DSN requests can now only be made on ports 465 and 587,
|
# DSN requests can now only be made on ports 465 and 587,
|
||||||
|
@ -74,8 +74,8 @@ function teardown_file() {
|
||||||
assert_failure
|
assert_failure
|
||||||
|
|
||||||
# These ports are excluded via master.cf.
|
# These ports are excluded via master.cf.
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 465'
|
_nc_wrapper 'emails/nc_raw/dsn/authenticated.txt' '0.0.0.0 465'
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 587'
|
_nc_wrapper 'emails/nc_raw/dsn/authenticated.txt' '0.0.0.0 587'
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
_run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log
|
_run_in_container grep "${LOG_DSN}" /var/log/mail/mail.log
|
||||||
|
@ -85,9 +85,9 @@ function teardown_file() {
|
||||||
@test "should never send a DSN" {
|
@test "should never send a DSN" {
|
||||||
export CONTAINER_NAME=${CONTAINER3_NAME}
|
export CONTAINER_NAME=${CONTAINER3_NAME}
|
||||||
|
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated'
|
_nc_wrapper 'emails/nc_raw/dsn/unauthenticated.txt'
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 465'
|
_nc_wrapper 'emails/nc_raw/dsn/authenticated.txt' '0.0.0.0 465'
|
||||||
_nc_wrapper 'emails/nc_raw/dsn/authenticated' '0.0.0.0 587'
|
_nc_wrapper 'emails/nc_raw/dsn/authenticated.txt' '0.0.0.0 587'
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
# DSN requests are rejected regardless of origin.
|
# DSN requests are rejected regardless of origin.
|
||||||
|
|
|
@ -38,7 +38,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
@test "delivers mail to existing account" {
|
@test "delivers mail to existing account" {
|
||||||
_wait_for_smtp_port_in_container
|
_wait_for_smtp_port_in_container
|
||||||
_send_email --data 'existing/user1' # send a test email
|
_send_email
|
||||||
|
|
||||||
# Verify delivery was successful, log line should look similar to:
|
# Verify delivery was successful, log line should look similar to:
|
||||||
# postfix/lmtp[1274]: 0EA424ABE7D9: to=<user1@localhost.localdomain>, relay=127.0.0.1[127.0.0.1]:24, delay=0.13, delays=0.07/0.01/0.01/0.05, dsn=2.0.0, status=sent (250 2.0.0 <user1@localhost.localdomain> ixPpB+Zvv2P7BAAAUi6ngw Saved)
|
# postfix/lmtp[1274]: 0EA424ABE7D9: to=<user1@localhost.localdomain>, relay=127.0.0.1[127.0.0.1]:24, delay=0.13, delays=0.07/0.01/0.01/0.05, dsn=2.0.0, status=sent (250 2.0.0 <user1@localhost.localdomain> ixPpB+Zvv2P7BAAAUi6ngw Saved)
|
||||||
|
|
|
@ -26,11 +26,10 @@ function teardown_file() { _default_teardown ; }
|
||||||
# this test covers https://github.com/docker-mailserver/docker-mailserver/issues/681
|
# this test covers https://github.com/docker-mailserver/docker-mailserver/issues/681
|
||||||
@test "(Postfix) remove privacy details of the sender" {
|
@test "(Postfix) remove privacy details of the sender" {
|
||||||
_send_email \
|
_send_email \
|
||||||
--port 587 -tls --auth LOGIN \
|
--port 587 -tls --auth PLAIN \
|
||||||
--auth-user user1@localhost.localdomain \
|
--auth-user user1@localhost.localdomain \
|
||||||
--auth-password mypassword \
|
--auth-password mypassword \
|
||||||
--data 'privacy'
|
--data 'privacy.txt'
|
||||||
assert_success
|
|
||||||
|
|
||||||
_run_until_success_or_timeout 120 _exec_in_container_bash '[[ -d /var/mail/localhost.localdomain/user1/new ]]'
|
_run_until_success_or_timeout 120 _exec_in_container_bash '[[ -d /var/mail/localhost.localdomain/user1/new ]]'
|
||||||
assert_success
|
assert_success
|
||||||
|
|
|
@ -63,46 +63,43 @@ function setup_file() {
|
||||||
|
|
||||||
# TODO: Move to clamav tests (For use when ClamAV is enabled):
|
# TODO: Move to clamav tests (For use when ClamAV is enabled):
|
||||||
# _repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" test -e /var/run/clamav/clamd.ctl
|
# _repeat_in_container_until_success_or_timeout 60 "${CONTAINER_NAME}" test -e /var/run/clamav/clamd.ctl
|
||||||
# _send_email --from 'virus@external.tld' --data 'amavis/virus'
|
# _send_email --from 'virus@external.tld' --data 'amavis/virus.txt'
|
||||||
|
|
||||||
# Required for 'delivers mail to existing alias':
|
# Required for 'delivers mail to existing alias':
|
||||||
_send_email --to alias1@localhost.localdomain --data 'existing/alias-external'
|
_send_email --to alias1@localhost.localdomain --header "Subject: Test Message existing-alias-external"
|
||||||
# Required for 'delivers mail to existing alias with recipient delimiter':
|
# Required for 'delivers mail to existing alias with recipient delimiter':
|
||||||
_send_email --to alias1~test@localhost.localdomain --data 'existing/alias-recipient-delimiter'
|
_send_email --to alias1~test@localhost.localdomain --header 'Subject: Test Message existing-alias-recipient-delimiter'
|
||||||
# Required for 'delivers mail to existing catchall':
|
# Required for 'delivers mail to existing catchall':
|
||||||
_send_email --to wildcard@localdomain2.com --data 'existing/catchall-local'
|
_send_email --to wildcard@localdomain2.com --header 'Subject: Test Message existing-catchall-local'
|
||||||
# Required for 'delivers mail to regexp alias':
|
# Required for 'delivers mail to regexp alias':
|
||||||
_send_email --to test123@localhost.localdomain --data 'existing/regexp-alias-local'
|
_send_email --to test123@localhost.localdomain --header 'Subject: Test Message existing-regexp-alias-local'
|
||||||
|
|
||||||
# Required for 'rejects mail to unknown user':
|
# Required for 'rejects mail to unknown user':
|
||||||
_send_email --to nouser@localhost.localdomain --data 'non-existing-user'
|
_send_email --expect-rejection --to nouser@localhost.localdomain
|
||||||
|
assert_failure
|
||||||
# Required for 'redirects mail to external aliases':
|
# Required for 'redirects mail to external aliases':
|
||||||
_send_email --to bounce-always@localhost.localdomain --data 'existing/regexp-alias-external'
|
_send_email --to bounce-always@localhost.localdomain
|
||||||
_send_email --to alias2@localhost.localdomain --data 'existing/alias-local'
|
_send_email --to alias2@localhost.localdomain
|
||||||
# Required for 'rejects spam':
|
# Required for 'rejects spam':
|
||||||
_send_email --from 'spam@external.tld' --data 'amavis/spam'
|
_send_email --from 'spam@external.tld' --data 'amavis/spam.txt'
|
||||||
|
|
||||||
# Required for 'delivers mail to existing account':
|
# Required for 'delivers mail to existing account':
|
||||||
_send_email --data 'existing/user1'
|
_send_email --header 'Subject: Test Message existing-user1'
|
||||||
assert_success
|
|
||||||
_send_email --to user2@otherdomain.tld
|
_send_email --to user2@otherdomain.tld
|
||||||
assert_success
|
|
||||||
_send_email --to user3@localhost.localdomain
|
_send_email --to user3@localhost.localdomain
|
||||||
assert_success
|
_send_email --to added@localhost.localdomain --header 'Subject: Test Message existing-added'
|
||||||
_send_email --to added@localhost.localdomain --data 'existing/added'
|
_send_email \
|
||||||
assert_success
|
--to user1@localhost.localdomain \
|
||||||
_send_email --to user1@localhost.localdomain --data 'existing/user-and-cc-local-alias'
|
--header 'Subject: Test Message existing-user-and-cc-local-alias' \
|
||||||
assert_success
|
--cc 'alias2@localhost.localdomain'
|
||||||
_send_email --data 'sieve/spam-folder'
|
_send_email --data 'sieve/spam-folder.txt'
|
||||||
assert_success
|
_send_email --to user2@otherdomain.tld --data 'sieve/pipe.txt'
|
||||||
_send_email --to user2@otherdomain.tld --data 'sieve/pipe'
|
|
||||||
assert_success
|
|
||||||
_run_in_container_bash 'sendmail root < /tmp/docker-mailserver-test/emails/sendmail/root-email.txt'
|
_run_in_container_bash 'sendmail root < /tmp/docker-mailserver-test/emails/sendmail/root-email.txt'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
function _unsuccessful() {
|
function _unsuccessful() {
|
||||||
_send_email --port 465 --auth "${1}" --auth-user "${2}" --auth-password wrongpassword
|
_send_email --expect-rejection --port 465 --auth "${1}" --auth-user "${2}" --auth-password wrongpassword --quit-after AUTH
|
||||||
assert_failure
|
assert_failure
|
||||||
assert_output --partial 'authentication failed'
|
assert_output --partial 'authentication failed'
|
||||||
assert_output --partial 'No authentication type succeeded'
|
assert_output --partial 'No authentication type succeeded'
|
||||||
|
@ -110,7 +107,6 @@ function _unsuccessful() {
|
||||||
|
|
||||||
function _successful() {
|
function _successful() {
|
||||||
_send_email --port 465 --auth "${1}" --auth-user "${2}" --auth-password mypassword --quit-after AUTH
|
_send_email --port 465 --auth "${1}" --auth-user "${2}" --auth-password mypassword --quit-after AUTH
|
||||||
assert_success
|
|
||||||
assert_output --partial 'Authentication successful'
|
assert_output --partial 'Authentication successful'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,12 @@ function teardown_file() { _default_teardown ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@test 'authentication works' {
|
@test 'authentication works' {
|
||||||
_nc_wrapper 'auth/pop3-auth' '-w 1 0.0.0.0 110'
|
_nc_wrapper 'auth/pop3-auth.txt' '-w 1 0.0.0.0 110'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
@test 'added user authentication works' {
|
@test 'added user authentication works' {
|
||||||
_nc_wrapper 'auth/added-pop3-auth' '-w 1 0.0.0.0 110'
|
_nc_wrapper 'auth/added-pop3-auth.txt' '-w 1 0.0.0.0 110'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ function setup_file() {
|
||||||
function teardown_file() { _default_teardown ; }
|
function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
@test '(Dovecot) LDAP RIMAP connection and authentication works' {
|
@test '(Dovecot) LDAP RIMAP connection and authentication works' {
|
||||||
_nc_wrapper 'auth/imap-auth' '-w 1 0.0.0.0 143'
|
_nc_wrapper 'auth/imap-auth.txt' '-w 1 0.0.0.0 143'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ function teardown_file() { _default_teardown ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@test '(SASLauthd) RIMAP SMTP authentication works' {
|
@test '(SASLauthd) RIMAP SMTP authentication works' {
|
||||||
_send_email \
|
_send_email --expect-rejection \
|
||||||
--auth LOGIN \
|
--auth PLAIN \
|
||||||
--auth-user user1@localhost.localdomain \
|
--auth-user user1@localhost.localdomain \
|
||||||
--auth-password mypassword \
|
--auth-password mypassword \
|
||||||
--quit-after AUTH
|
--quit-after AUTH
|
||||||
|
@ -41,20 +41,18 @@ function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
_send_email \
|
_send_email \
|
||||||
--port 465 \
|
--port 465 \
|
||||||
--auth LOGIN \
|
--auth PLAIN \
|
||||||
--auth-user user1@localhost.localdomain \
|
--auth-user user1@localhost.localdomain \
|
||||||
--auth-password mypassword \
|
--auth-password mypassword \
|
||||||
--quit-after AUTH
|
--quit-after AUTH
|
||||||
assert_success
|
|
||||||
assert_output --partial 'Authentication successful'
|
assert_output --partial 'Authentication successful'
|
||||||
|
|
||||||
_send_email \
|
_send_email \
|
||||||
--port 587 \
|
--port 587 \
|
||||||
--auth LOGIN \
|
--auth PLAIN \
|
||||||
--auth-user user1@localhost.localdomain \
|
--auth-user user1@localhost.localdomain \
|
||||||
--auth-password mypassword \
|
--auth-password mypassword \
|
||||||
--quit-after AUTH
|
--quit-after AUTH
|
||||||
assert_success
|
|
||||||
assert_output --partial 'Authentication successful'
|
assert_output --partial 'Authentication successful'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,7 +248,7 @@ function teardown() {
|
||||||
|
|
||||||
# dovecot
|
# dovecot
|
||||||
@test "dovecot: ldap imap connection and authentication works" {
|
@test "dovecot: ldap imap connection and authentication works" {
|
||||||
_nc_wrapper 'auth/imap-ldap-auth' '-w 1 0.0.0.0 143'
|
_nc_wrapper 'auth/imap-ldap-auth.txt' '-w 1 0.0.0.0 143'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,25 +326,26 @@ function teardown() {
|
||||||
@test "spoofing (with LDAP): rejects sender forging" {
|
@test "spoofing (with LDAP): rejects sender forging" {
|
||||||
_wait_for_smtp_port_in_container_to_respond dms-test_ldap
|
_wait_for_smtp_port_in_container_to_respond dms-test_ldap
|
||||||
|
|
||||||
_send_email \
|
_send_email --expect-rejection \
|
||||||
--port 465 -tlsc --auth LOGIN \
|
--port 465 -tlsc --auth PLAIN \
|
||||||
--auth-user some.user@localhost.localdomain \
|
--auth-user some.user@localhost.localdomain \
|
||||||
--auth-password secret \
|
--auth-password secret \
|
||||||
--ehlo mail \
|
--ehlo mail \
|
||||||
--from ldap@localhost.localdomain \
|
--from ldap@localhost.localdomain \
|
||||||
--data 'auth/ldap-smtp-auth-spoofed'
|
--data 'auth/ldap-smtp-auth-spoofed.txt'
|
||||||
|
assert_failure
|
||||||
assert_output --partial 'Sender address rejected: not owned by user'
|
assert_output --partial 'Sender address rejected: not owned by user'
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "spoofing (with LDAP): accepts sending as alias" {
|
@test "spoofing (with LDAP): accepts sending as alias" {
|
||||||
_send_email \
|
_send_email \
|
||||||
--port 465 -tlsc --auth LOGIN \
|
--port 465 -tlsc --auth PLAIN \
|
||||||
--auth-user some.user@localhost.localdomain \
|
--auth-user some.user@localhost.localdomain \
|
||||||
--auth-password secret \
|
--auth-password secret \
|
||||||
--ehlo mail \
|
--ehlo mail \
|
||||||
--from postmaster@localhost.localdomain \
|
--from postmaster@localhost.localdomain \
|
||||||
--to some.user@localhost.localdomain \
|
--to some.user@localhost.localdomain \
|
||||||
--data 'auth/ldap-smtp-auth-spoofed-alias'
|
--data 'auth/ldap-smtp-auth-spoofed-alias.txt'
|
||||||
assert_output --partial 'End data with'
|
assert_output --partial 'End data with'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,20 +354,21 @@ function teardown() {
|
||||||
# Template used has invalid AUTH: https://github.com/docker-mailserver/docker-mailserver/pull/3006#discussion_r1073321432
|
# Template used has invalid AUTH: https://github.com/docker-mailserver/docker-mailserver/pull/3006#discussion_r1073321432
|
||||||
skip 'TODO: This test seems to have been broken from the start (?)'
|
skip 'TODO: This test seems to have been broken from the start (?)'
|
||||||
|
|
||||||
_send_email \
|
_send_email --expect-rejection \
|
||||||
--port 465 -tlsc --auth LOGIN \
|
--port 465 -tlsc --auth PLAIN \
|
||||||
--auth-user some.user.email@localhost.localdomain \
|
--auth-user some.user.email@localhost.localdomain \
|
||||||
--auth-password secret \
|
--auth-password secret \
|
||||||
--ehlo mail \
|
--ehlo mail \
|
||||||
--from randomspoofedaddress@localhost.localdomain \
|
--from randomspoofedaddress@localhost.localdomain \
|
||||||
--to some.user@localhost.localdomain \
|
--to some.user@localhost.localdomain \
|
||||||
--data 'auth/ldap-smtp-auth-spoofed-sender-with-filter-exception'
|
--data 'auth/ldap-smtp-auth-spoofed-sender-with-filter-exception.txt'
|
||||||
|
assert_failure
|
||||||
assert_output --partial 'Sender address rejected: not owned by user'
|
assert_output --partial 'Sender address rejected: not owned by user'
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "saslauthd: ldap smtp authentication" {
|
@test "saslauthd: ldap smtp authentication" {
|
||||||
_send_email \
|
_send_email --expect-rejection \
|
||||||
--auth LOGIN \
|
--auth PLAIN \
|
||||||
--auth-user some.user@localhost.localdomain \
|
--auth-user some.user@localhost.localdomain \
|
||||||
--auth-password wrongpassword \
|
--auth-password wrongpassword \
|
||||||
--quit-after AUTH
|
--quit-after AUTH
|
||||||
|
@ -379,12 +381,11 @@ function teardown() {
|
||||||
--auth-user some.user@localhost.localdomain \
|
--auth-user some.user@localhost.localdomain \
|
||||||
--auth-password secret \
|
--auth-password secret \
|
||||||
--quit-after AUTH
|
--quit-after AUTH
|
||||||
assert_success
|
|
||||||
assert_output --partial 'Authentication successful'
|
assert_output --partial 'Authentication successful'
|
||||||
|
|
||||||
_send_email \
|
_send_email \
|
||||||
--port 587 -tls \
|
--port 587 -tls \
|
||||||
--auth LOGIN \
|
--auth PLAIN \
|
||||||
--auth-user some.user@localhost.localdomain \
|
--auth-user some.user@localhost.localdomain \
|
||||||
--auth-password secret \
|
--auth-password secret \
|
||||||
--quit-after AUTH
|
--quit-after AUTH
|
||||||
|
|
|
@ -80,12 +80,12 @@ function teardown_file() { _default_teardown ; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "imap: authentication works" {
|
@test "imap: authentication works" {
|
||||||
_nc_wrapper 'auth/imap-auth' '-w 1 0.0.0.0 143'
|
_nc_wrapper 'auth/imap-auth.txt' '-w 1 0.0.0.0 143'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "imap: added user authentication works" {
|
@test "imap: added user authentication works" {
|
||||||
_nc_wrapper 'auth/added-imap-auth' '-w 1 0.0.0.0 143'
|
_nc_wrapper 'auth/added-imap-auth.txt' '-w 1 0.0.0.0 143'
|
||||||
assert_success
|
assert_success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,13 +293,13 @@ EOF
|
||||||
|
|
||||||
# An authenticated user cannot use an envelope sender (MAIL FROM)
|
# An authenticated user cannot use an envelope sender (MAIL FROM)
|
||||||
# address they do not own according to `main.cf:smtpd_sender_login_maps` lookup
|
# address they do not own according to `main.cf:smtpd_sender_login_maps` lookup
|
||||||
_send_email \
|
_send_email --expect-rejection \
|
||||||
--port 465 -tlsc --auth LOGIN \
|
--port 465 -tlsc --auth PLAIN \
|
||||||
--auth-user added@localhost.localdomain \
|
--auth-user added@localhost.localdomain \
|
||||||
--auth-password mypassword \
|
--auth-password mypassword \
|
||||||
--ehlo mail \
|
--ehlo mail \
|
||||||
--from user2@localhost.localdomain \
|
--from user2@localhost.localdomain \
|
||||||
--data 'auth/added-smtp-auth-spoofed'
|
--data 'auth/added-smtp-auth-spoofed.txt'
|
||||||
assert_output --partial 'Sender address rejected: not owned by user'
|
assert_output --partial 'Sender address rejected: not owned by user'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,12 +310,12 @@ EOF
|
||||||
# to each table. Address is authorized when a result that maps to
|
# to each table. Address is authorized when a result that maps to
|
||||||
# the DMS account is returned.
|
# the DMS account is returned.
|
||||||
_send_email \
|
_send_email \
|
||||||
--port 465 -tlsc --auth LOGIN \
|
--port 465 -tlsc --auth PLAIN \
|
||||||
--auth-user user1@localhost.localdomain \
|
--auth-user user1@localhost.localdomain \
|
||||||
--auth-password mypassword \
|
--auth-password mypassword \
|
||||||
--ehlo mail \
|
--ehlo mail \
|
||||||
--from alias1@localhost.localdomain \
|
--from alias1@localhost.localdomain \
|
||||||
--data 'auth/added-smtp-auth-spoofed-alias'
|
--data 'auth/added-smtp-auth-spoofed-alias.txt'
|
||||||
assert_success
|
assert_success
|
||||||
assert_output --partial 'End data with'
|
assert_output --partial 'End data with'
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ function setup_file() {
|
||||||
function teardown_file() { _default_teardown ; }
|
function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
@test 'should successfully deliver mail' {
|
@test 'should successfully deliver mail' {
|
||||||
_send_email --data 'existing/user1'
|
_send_email --header 'Subject: Test Message existing-user1'
|
||||||
_wait_for_empty_mail_queue_in_container
|
_wait_for_empty_mail_queue_in_container
|
||||||
|
|
||||||
# Should be successfully sent (received) by Postfix:
|
# Should be successfully sent (received) by Postfix:
|
||||||
|
@ -31,7 +31,7 @@ function teardown_file() { _default_teardown ; }
|
||||||
|
|
||||||
# Verify successful delivery via Dovecot to `/var/mail` account by searching for the subject:
|
# Verify successful delivery via Dovecot to `/var/mail` account by searching for the subject:
|
||||||
_repeat_in_container_until_success_or_timeout 20 "${CONTAINER_NAME}" grep -R \
|
_repeat_in_container_until_success_or_timeout 20 "${CONTAINER_NAME}" grep -R \
|
||||||
'Subject: Test Message existing-user1.txt' \
|
'Subject: Test Message existing-user1' \
|
||||||
'/var/mail/localhost.localdomain/user1/new/'
|
'/var/mail/localhost.localdomain/user1/new/'
|
||||||
assert_success
|
assert_success
|
||||||
_should_output_number_of_lines 1
|
_should_output_number_of_lines 1
|
||||||
|
|
Loading…
Reference in a new issue