docker-mailserver/test/tests/parallel/set3/mta/account_management.bats

161 lines
6.5 KiB
Plaintext
Raw Normal View History

tests(refactor): Extract mail account management tests from `tests.bats` (#3055) * chore: Extract out accounts test cases from `tests.bats` Standard test file format, the test cases have been copied over unmodified. * chore: Revise test case descriptions * tests(refactor): `accounts.bats` Revised test cases: - Some common test case logic extracted to test methods. - Update direct user management commands to use the `setup email ...` variants. - Improved assertions. - Removed `sleep 2` lines as the need for that is ambiguous (may no longer be relevant?) - Additional commentary for maintaining - Two test cases for missing `postfix-accounts.cf` opted to just run the image without any volumes instead, as the `without-accounts/` folder was empty anyway. 2nd test case can instead use a single `docker run` to check the newly created`postfix-accounts.cf` content. - `test/config/without-accounts/` remains as `open_dkim.bats` presently uses it. * chore: Remove unnecessary account removal assert Traced this back to the original PR where it appears to have been a typo and was probably intended as a cleanup on the `user4` account. Not necessary, removing. * chore: Rename `accounts.bat` -> `account_management.bats` --------- * feedback: Avoid `ls` for detecting directories Replace `ls -d` approach from original test cases Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> * feedback: Remove asserting empty output on failure Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com>
2023-02-03 22:52:30 +00:00
load "${REPOSITORY_ROOT}/test/helper/common"
load "${REPOSITORY_ROOT}/test/helper/setup"
BATS_TEST_NAME_PREFIX='[Mail Accounts] '
CONTAINER_NAME='dms-test_accounts'
function setup_file() {
_init_with_defaults
_common_container_setup
# Testing account added after start-up is also working correctly:
_add_mail_account_then_wait_until_ready 'added@localhost.localdomain' 'mypassword'
# Testing can create an account with potentially problematic input:
_add_mail_account_then_wait_until_ready 'pass@localhost.localdomain' 'may be \a `p^a.*ssword'
}
function teardown_file() { _default_teardown ; }
### Account Setup ###
@test "should have created all accounts in Dovecot UserDB" {
_run_in_container 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'
assert_line --index 4 'pass@localhost.localdomain'
assert_line --index 5 'alias1@localhost.localdomain'
# TODO: Probably not intentional?:
assert_line --index 6 '@localdomain2.com'
_should_output_number_of_lines 7
# Relevant log output from scripts/helpers/accounts.sh:_create_dovecot_alias_dummy_accounts():
# [ DEBUG ] Adding alias 'alias1@localhost.localdomain' for user 'user1@localhost.localdomain' to Dovecot's userdb
# [ DEBUG ] Alias 'alias2@localhost.localdomain' is non-local (or mapped to a non-existing account) and will not be added to Dovecot's userdb
# [ DEBUG ] Adding alias '@localdomain2.com' for user 'user1@localhost.localdomain' to Dovecot's userdb
}
@test "should have created maildir for 'user1@localhost.localdomain'" {
_run_in_container_bash '[[ -d /var/mail/localhost.localdomain/user1 ]]'
assert_success
}
@test "should have created maildir for 'user2@otherdomain.tld'" {
_run_in_container_bash '[[ -d /var/mail/otherdomain.tld/user2 ]]'
assert_success
}
@test "should have created maildir for 'user3@localhost.localdomain'" {
_run_in_container_bash '[[ -d /var/mail/localhost.localdomain/user3 ]]'
assert_success
}
@test "should have created maildir for 'added@localhost.localdomain'" {
_run_in_container_bash '[[ -d /var/mail/localhost.localdomain/added ]]'
assert_success
}
@test "should not accidentally parse comments in 'postfix-accounts.cf' as accounts" {
tests(refactor): `open_dkim.bats` (#3060) * tests(refactor): Make test cases for opendkim keysizes DRY - These all do roughly the same logic that can be split into two separate methods. - `_should_generate_dkim_key()` covers a bit more logic as it can be leveraged to handle other test cases that also perform the same logic. - The `config/opendkim/` doesn't seem necessary for tests. Only the first few test cases here are testing against it, so we can conditionally make that available. `process_check_restart.bats` also depended on it to run OpenDKIM successfully, but this was due to the `setup-stack.sh` config defaults failing to find an "empty" file forcing `supervisord` to constantly restart the process.. - With this, there we inverse the default opendkim config, so we don't have to mount unique / empty subfolders for each test case, followed by copying over the two extra configs. * tests(refactor): DRY up more test cases All the remaining test cases but the last one were refactored here for a clean commit diff. The last test case will be refactored in the following commit. Plenty of repeated logic spread across these test cases, now condensed into shared methods. * tests(refactor): Make final test case DRY * chore: Migrate to new testing helpers * chore: Revise test case descriptions * tests(refactor): Improve and simplify assertions * tests(refactor): Use common container setup instead of `docker run` - As the majority of test cases are only running `open-dkim` helper, we don't actually have to wait for a full container setup. So an alternative container start is called. - Also improves assertions a bit more instead of just counting lines. - Some test cases don't bind mount all of `/tmp/docker-mailserver` contents, thus don't raise permission errors on subsequent test runs. - Instead of `rm -f` on some config files, have opted to mount them read-only instead, or alternatively mount an anonymous empty volume instead. - Collapsed the first three test cases into one, thus no `setup_file()` necessary. - Shift the `_wait_for_finished_setup_in_container()` method into `_common_container_setup()` instead since nothing else is using `_common_container_start()` yet, this allows for avoiding the wait. * tests(refactor): Collapse dkim key size test cases into single test case This makes these tests a bit more DRY, and enhances the raised quality issue with these tests. Now not only is the domain checked in the generated DNS dkim record, but we also verify the key size is corrected in the public and private keys via openssl. * chore: Revise container names * chore: Swap order of test case 1 and 2 * tests(refactor): Assert generated log output - `__should_have_tables_trustedhosts_for_domain` shifted in each test case to just after generating the domains keys. - Asserts `open-dkim` logs instead of just counting them. - Added checks for domains that should not be present in a test case. - Additional coverage and notes about the alias from vhost `@localdomain.com` - Single assert statement with switch statement as all are using common args. * chore: Minor changes * tests(refactor): Share `find` logic in helpers and tests * tests(fix): Listing file content does not need to match line order The order printed from local system vs CI differed causing the CI to fail. The order of lines is irrelevant so `--index` is not required. Additionally correct the prefix of the called method to be only one `_` now that it's a `common.bash` helper method. * chore: Collapse custom DKIM selector test into custom DKIM domain test These cover the same test logic for the most part, the first domain could also be testing the custom selector. `special_use_folders.bats` + `mailbox_format_dbox` can assert lines instead, removing the need for `--partial`. * Apply suggestions from code review Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> * chore: Split switch statement method into wrapper methods --------- Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com>
2023-02-09 11:18:06 +00:00
_should_have_content_in_directory '/var/mail'
tests(refactor): Extract mail account management tests from `tests.bats` (#3055) * chore: Extract out accounts test cases from `tests.bats` Standard test file format, the test cases have been copied over unmodified. * chore: Revise test case descriptions * tests(refactor): `accounts.bats` Revised test cases: - Some common test case logic extracted to test methods. - Update direct user management commands to use the `setup email ...` variants. - Improved assertions. - Removed `sleep 2` lines as the need for that is ambiguous (may no longer be relevant?) - Additional commentary for maintaining - Two test cases for missing `postfix-accounts.cf` opted to just run the image without any volumes instead, as the `without-accounts/` folder was empty anyway. 2nd test case can instead use a single `docker run` to check the newly created`postfix-accounts.cf` content. - `test/config/without-accounts/` remains as `open_dkim.bats` presently uses it. * chore: Remove unnecessary account removal assert Traced this back to the original PR where it appears to have been a typo and was probably intended as a cleanup on the `user4` account. Not necessary, removing. * chore: Rename `accounts.bat` -> `account_management.bats` --------- * feedback: Avoid `ls` for detecting directories Replace `ls -d` approach from original test cases Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com> * feedback: Remove asserting empty output on failure Co-authored-by: Georg Lauterbach <44545919+georglauterbach@users.noreply.github.com>
2023-02-03 22:52:30 +00:00
refute_output --partial 'comment'
}
### Account Management ###
@test "should fail to create a user when the domain-part ('@example.com') is missing" {
_run_in_container setup email add user_without_domain mypassword
assert_failure
assert_output --partial 'should include the domain (eg: user@example.com)'
}
@test "should add new user 'user3@domain.tld' into 'postfix-accounts.cf'" {
__should_add_new_user 'user3@domain.tld'
}
# To catch mistakes from substring matching:
@test "should add new user 'auser3@domain.tld' into 'postfix-accounts.cf'" {
__should_add_new_user 'auser3@domain.tld'
}
# To catch mistakes from accidental pattern `.` matching as `u`:
@test "should add new user 'a.ser3@domain.tld' into 'postfix-accounts.cf'" {
__should_add_new_user 'a.ser3@domain.tld'
}
@test "should remove user3 (but not auser3) from 'postfix-accounts.cf'" {
# Waits until change event has created directory but not completed:
_wait_until_account_maildir_exists 'user3@domain.tld'
# Should trigger a new change event:
_exec_in_container setup email del -y 'user3@domain.tld'
# NOTE: This is only checking `postfix-accounts.cf`, account may still persist
# elsewhere momentarily such as the Dovecot UserDB until change event kicks in.
__check_mail_account_exists 'user3@domain.tld'
assert_failure
__check_mail_account_exists 'auser3@domain.tld'
assert_success
assert_output 'auser3@domain.tld'
}
@test "should update password for user4 by modifying entry in 'postfix-accounts.cf'" {
# This change tends to be bundled with change detection event from previous test case
# deleting 'user3@domain.tld', thus both changes are usually applied together.
# NOTE: Technically these two `setup email ...` commands are run async, there is no
# proper file locking applied to `postfix-accounts.cf`, potentially a race condition.
_add_mail_account_then_wait_until_ready 'user4@domain.tld'
local ORIGINAL_ENTRY UPDATED_ENTRY
ORIGINAL_ENTRY=$(_exec_in_container grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf)
_exec_in_container setup email update 'user4@domain.tld' mynewpassword
UPDATED_ENTRY=$(_exec_in_container grep '^user4@domain\.tld' -i /tmp/docker-mailserver/postfix-accounts.cf)
assert_not_equal "${ORIGINAL_ENTRY}" "${UPDATED_ENTRY}"
}
# TODO: Prone to failure sometimes from the change event in previous test case,
# as Dovecot service can be momentarily unavailable during reload?
@test "(ENV ENABLE_QUOTAS=0) 'setup email list' should not display quota information" {
_run_in_container_bash 'echo "ENABLE_QUOTAS=0" >> /etc/dms-settings && setup email list | head -n 1'
assert_success
assert_output '* user1@localhost.localdomain'
}
@test "(ENV ENABLE_QUOTAS=1) 'setup email list' should display quota information" {
_run_in_container_bash 'sed -i "/ENABLE_QUOTAS=0/d" /etc/dms-settings; setup email list | head -n 1'
assert_success
assert_output '* user1@localhost.localdomain ( 0 / ~ ) [0%]'
}
@test "(missing postfix-accounts.cf) 'setup email del' should not fail with an error" {
run docker run --rm "${IMAGE_NAME:?}" setup email del -y 'user3@domain.tld'
assert_success
assert_output ''
}
@test "(missing postfix-accounts.cf) 'setup email add' should create 'postfix-accounts.cf' and populate with new mail account" {
run docker run --rm "${IMAGE_NAME:?}" \
/bin/bash -c 'setup email add user3@domain.tld mypassword && grep -o "^user3@domain\.tld" /tmp/docker-mailserver/postfix-accounts.cf'
assert_success
assert_output 'user3@domain.tld'
}
function __should_add_new_user() {
local MAIL_ACCOUNT=${1}
_exec_in_container setup email add "${MAIL_ACCOUNT}" mypassword
__check_mail_account_exists "${MAIL_ACCOUNT}"
assert_success
assert_output "${MAIL_ACCOUNT}"
}
# Uses a double grep to avoid test case failures from accidental substring/pattern matching
function __check_mail_account_exists() {
local MAIL_ACCOUNT=${1}
# Filter out any comment lines, then truncate each line at their first `|` delimiter:
_run_in_container_bash "sed -e '/\s*#/d' -e 's/|.*//' /tmp/docker-mailserver/postfix-accounts.cf | grep '^${MAIL_ACCOUNT}' | grep -F '${MAIL_ACCOUNT}'"
}