use new function for tracking logs

The new function, called `_send_email_with_mid`, aligns with suggestions
from @polarethene and is heavily simplified compared to its predecessor
`_send_email_and_get_id`. New helpers will be introduced to filter logs
according to the MID constructed in this function.
This commit is contained in:
georglauterbach 2024-01-16 19:18:04 +01:00
parent 3a64a7a97c
commit 9c621f1bd9
No known key found for this signature in database
GPG Key ID: F367F7C43C118578
1 changed files with 13 additions and 56 deletions

View File

@ -4,6 +4,8 @@
# ! 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`!
# ! ATTENTION: Functions prefixed with `__` are intended for internal use within
# ! this file (or other helpers) only, not in tests.
# shellcheck disable=SC2034,SC2155 # shellcheck disable=SC2034,SC2155
@ -100,67 +102,22 @@ function _send_email() {
return "${RETURN_VALUE}" return "${RETURN_VALUE}"
} }
# Like `_send_email` with two major differences: # Contruct the message ID for the 'Message-ID' header.
# #
# 1. this function waits for the mail to be processed; there is no asynchronicity # @param ${1} = message ID part before '@' (later used when filtering logs again)
# because filtering the logs in a synchronous way is easier and safer; function __construct_mid() {
# 2. this function takes the name of a variable and inserts IDs one can later echo "<${1:?Message-ID prefix is required}@dms-tests>"
# filter by to check logs. }
# Like `_send_email` but adds a "Message-Id: ${1}@dms-tests>" header, which
# allows for filtering logs later.
# #
# No. 2 is especially useful in case you send more than one email in a single # @param ${1} = message ID part before '@' (later used when filtering logs again)
# test file and need to assert certain log entries for each mail individually. function _send_email_with_mid() {
# local MID=$(__construct_mid "${1:?Left-hand side of MID missing}")
# 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
#
# This function assumes `CONTAINER_NAME` to be properly set (to the container
# name the command should be executed in)!
#
# ## Safety
#
# This functions assumes **no concurrent sending of emails to the same container**!
# If two clients send simultaneously, there is no guarantee the correct ID is
# chosen. Sending more than one mail at any given point in time with this function
# is UNDEFINED BEHAVIOR!
function _send_email_and_get_id() {
# 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 shift 1
# The unique ID Postfix (and other services) use may be different in length
# on different systems. Hence, we use a range to safely capture it.
local QUEUE_ID_REGEX='[A-Z0-9]{9,12}'
_wait_for_empty_mail_queue_in_container
_send_email "${@}" --header "Message-Id: ${MID}" _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}$"
} }
# Send a spam e-mail by utilizing GTUBE. # Send a spam e-mail by utilizing GTUBE.