Changeset - d752715bb533
[Not reviewed]
0 41 0
Branko Majic (branko) - 4 years ago 2020-05-07 22:38:43
branko@majic.rs
MAR-149: Switch to using File.content_string instead of File.content in tests for all roles:

- The .content variant returns contents as bytes, while the
content_string returns a string (which is what is wanted in
practically all cases).
41 files changed with 194 insertions and 194 deletions:
0 comments (0 inline, 0 general)
roles/backup/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -13,20 +13,20 @@ def test_backup_patterns_content(host):
 
    """
 

	
 
    with host.sudo():
 

	
 
        backup_pattern = host.file('/etc/duply/main/patterns/test')
 

	
 
        assert backup_pattern.content == ''
 
        assert backup_pattern.content_string == ''
 

	
 

	
 
def test_include_content(host):
 
    """
 
    Tests if content of assembled include file containing backup patterns is
 
    correct.
 
    """
 

	
 
    with host.sudo():
 

	
 
        include = host.file('/etc/duply/main/include')
 

	
 
        assert include.content == ''
 
        assert include.content_string == ''
roles/backup/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -13,20 +13,20 @@ def test_backup_patterns_content(host):
 
    """
 

	
 
    with host.sudo():
 

	
 
        backup_pattern = host.file('/etc/duply/main/patterns/test')
 

	
 
        assert backup_pattern.content == "/etc/hosts\n/etc/ethers\n/var/log\n"
 
        assert backup_pattern.content_string == "/etc/hosts\n/etc/ethers\n/var/log\n"
 

	
 

	
 
def test_include_content(host):
 
    """
 
    Tests if content of assembled include file containing backup patterns is
 
    correct.
 
    """
 

	
 
    with host.sudo():
 

	
 
        include = host.file('/etc/duply/main/include')
 

	
 
        assert include.content == "/etc/hosts\n/etc/ethers\n/var/log\n"
 
        assert include.content_string == "/etc/hosts\n/etc/ethers\n/var/log\n"
roles/backup_client/molecule/default/tests/test_default.py
Show inline comments
 
@@ -126,13 +126,13 @@ def test_exclude_file(host):
 
        exclude = host.file('/etc/duply/main/exclude')
 

	
 
        assert exclude.is_file
 
        assert exclude.user == 'root'
 
        assert exclude.group == 'root'
 
        assert exclude.mode == 0o600
 
        assert exclude.content == "- **"
 
        assert exclude.content_string == "- **"
 

	
 

	
 
def test_pre_backup_script_directory(host):
 

	
 
    with host.sudo():
 

	
 
@@ -168,13 +168,13 @@ def test_cron_entry(host):
 
    cron = host.file('/etc/cron.d/backup')
 

	
 
    assert cron.is_file
 
    assert cron.user == 'root'
 
    assert cron.group == 'root'
 
    assert cron.mode == 0o644
 
    assert cron.content == "#Ansible: backup\n0 2 * * * root /usr/bin/duply main backup\n"
 
    assert cron.content_string == "#Ansible: backup\n0 2 * * * root /usr/bin/duply main backup\n"
 

	
 

	
 
def test_duply_include_file(host):
 
    """
 
    Tests include file existence and permissions.
 
    """
roles/backup_client/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -15,65 +15,65 @@ def test_gnupg_private_keys_file_content(host):
 

	
 
    with host.sudo():
 
        gnupg_private_keys = host.file('/etc/duply/main/private_keys.asc')
 

	
 
        # The rstrip() is added because Ansible strips last newline
 
        # when using the file lookup plugin.
 
        assert gnupg_private_keys.content == open('tests/data/gnupg/parameters-mandatory.asc', 'r').read().rstrip()
 
        assert gnupg_private_keys.content_string == open('tests/data/gnupg/parameters-mandatory.asc', 'r').read().rstrip()
 

	
 

	
 
def test_gnupg_public_keys_file_content(host):
 
    """
 
    Tests if no additional public GnuPG keys have been deployed (should be
 
    default without optional parameters).
 
    """
 

	
 
    with host.sudo():
 
        gnupg_public_keys = host.file('/etc/duply/main/public_keys.asc')
 

	
 
        assert gnupg_public_keys.content == ""
 
        assert gnupg_public_keys.content_string == ""
 

	
 

	
 
def test_backup_ssh_key_file_content(host):
 
    """
 
    Tests if correct key has been deployed for SSH client authentication.
 
    """
 

	
 
    with host.sudo():
 

	
 
        ssh_key = host.file('/etc/duply/main/ssh/identity')
 

	
 
        assert ssh_key.content == open('tests/data/ssh/parameters-mandatory', 'r').read()
 
        assert ssh_key.content_string == open('tests/data/ssh/parameters-mandatory', 'r').read()
 

	
 

	
 
def test_known_hosts_content(host):
 
    """
 
    Tests if known hosts file has been set-up with correct content.
 
    """
 

	
 
    with host.sudo():
 

	
 
        known_hosts = host.file('/etc/duply/main/ssh/known_hosts')
 

	
 
        assert known_hosts.content == open('tests/data/ssh/parameters-mandatory-known_hosts', 'r').read()
 
        assert known_hosts.content_string == open('tests/data/ssh/parameters-mandatory-known_hosts', 'r').read()
 

	
 

	
 
def test_duply_configuration_content(host):
 
    """
 
    Tests if duply configuration has been set-up correctly.
 
    """
 

	
 
    with host.sudo():
 

	
 
        duply_configuration = host.file('/etc/duply/main/conf')
 

	
 
        assert "GPG_KEYS_ENC='59C26F031A129C54'" in duply_configuration.content
 
        assert "GPG_KEY_SIGN='59C26F031A129C54'" in duply_configuration.content
 
        assert "TARGET='pexpect+sftp://bak-parameters-mandatory-s64@10.31.127.10:2222//duplicity'" in duply_configuration.content
 
        assert "GPG_KEYS_ENC='59C26F031A129C54'" in duply_configuration.content_string
 
        assert "GPG_KEY_SIGN='59C26F031A129C54'" in duply_configuration.content_string
 
        assert "TARGET='pexpect+sftp://bak-parameters-mandatory-s64@10.31.127.10:2222//duplicity'" in duply_configuration.content_string
 
        assert "DUPL_PARAMS=\"$DUPL_PARAMS --ssh-options='-oLogLevel=ERROR -oUserKnownHostsFile=/dev/null " \
 
            "-oGlobalKnownHostsFile=/etc/duply/main/ssh/known_hosts -oIdentityFile=/etc/duply/main/ssh/identity'\"" in duply_configuration.content
 
            "-oGlobalKnownHostsFile=/etc/duply/main/ssh/known_hosts -oIdentityFile=/etc/duply/main/ssh/identity'\"" in duply_configuration.content_string
 

	
 

	
 
def test_duply_gnupg_keyring_private_keys(host):
 
    """
 
    Tests if private key used for encryption/signing has been correctly
 
    imporeted into Duply GnuPG keyring.
roles/backup_client/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -13,66 +13,66 @@ def test_gnupg_private_keys_file_content(host):
 
    deployed.
 
    """
 

	
 
    with host.sudo():
 
        gnupg_private_keys = host.file('/etc/duply/main/private_keys.asc')
 

	
 
        assert gnupg_private_keys.content == open('tests/data/gnupg/parameters-optional.asc', 'r').read().strip()
 
        assert gnupg_private_keys.content_string == open('tests/data/gnupg/parameters-optional.asc', 'r').read().strip()
 

	
 

	
 
def test_gnupg_public_keys_file_content(host):
 
    """
 
    Tests if correct additional public GnuPG keys have been deployed.
 
    """
 

	
 
    with host.sudo():
 
        gnupg_public_keys = host.file('/etc/duply/main/public_keys.asc')
 

	
 
        assert open('tests/data/gnupg/additional_encryption_key_1.asc', 'r').read().strip() in gnupg_public_keys.content
 
        assert open('tests/data/gnupg/additional_encryption_key_2.asc', 'r').read().strip() in gnupg_public_keys.content
 
        assert open('tests/data/gnupg/additional_encryption_key_3.asc', 'r').read().strip() in gnupg_public_keys.content
 
        assert open('tests/data/gnupg/additional_encryption_key_1.asc', 'r').read().strip() in gnupg_public_keys.content_string
 
        assert open('tests/data/gnupg/additional_encryption_key_2.asc', 'r').read().strip() in gnupg_public_keys.content_string
 
        assert open('tests/data/gnupg/additional_encryption_key_3.asc', 'r').read().strip() in gnupg_public_keys.content_string
 

	
 

	
 
def test_backup_ssh_key_file_content(host):
 
    """
 
    Tests if correct key has been deployed for SSH client authentication.
 
    """
 

	
 
    with host.sudo():
 

	
 
        ssh_key = host.file('/etc/duply/main/ssh/identity')
 

	
 
        assert ssh_key.content == open('tests/data/ssh/parameters-optional', 'r').read().strip()
 
        assert ssh_key.content_string == open('tests/data/ssh/parameters-optional', 'r').read().strip()
 

	
 

	
 
def test_known_hosts_content(host):
 
    """
 
    Tests if known hosts file has been set-up with correct content.
 
    """
 

	
 
    with host.sudo():
 

	
 
        known_hosts = host.file('/etc/duply/main/ssh/known_hosts')
 

	
 
        assert known_hosts.content == open('tests/data/ssh/parameters-optional-known_hosts', 'r').read()
 
        assert known_hosts.content_string == open('tests/data/ssh/parameters-optional-known_hosts', 'r').read()
 

	
 

	
 
def test_duply_configuration_content(host):
 
    """
 
    Tests if duply configuration has been set-up correctly.
 
    """
 

	
 
    with host.sudo():
 

	
 
        duply_configuration = host.file('/etc/duply/main/conf')
 

	
 
        assert "GPG_KEYS_ENC='C4B2AE9F7A4F400A,3093C91BC3A9444B,86816FD928063B3F,8A14CD6C71223B72'" in duply_configuration.content
 
        assert "GPG_KEY_SIGN='C4B2AE9F7A4F400A'" in duply_configuration.content
 
        assert "TARGET='pexpect+sftp://backupuser@10.31.127.10:3333//duplicity/parameters-optional-s64'" in duply_configuration.content
 
        assert "GPG_KEYS_ENC='C4B2AE9F7A4F400A,3093C91BC3A9444B,86816FD928063B3F,8A14CD6C71223B72'" in duply_configuration.content_string
 
        assert "GPG_KEY_SIGN='C4B2AE9F7A4F400A'" in duply_configuration.content_string
 
        assert "TARGET='pexpect+sftp://backupuser@10.31.127.10:3333//duplicity/parameters-optional-s64'" in duply_configuration.content_string
 
        assert "DUPL_PARAMS=\"$DUPL_PARAMS --ssh-options='-oLogLevel=ERROR -oUserKnownHostsFile=/dev/null " \
 
            "-oGlobalKnownHostsFile=/etc/duply/main/ssh/known_hosts -oIdentityFile=/etc/duply/main/ssh/identity'\"" in duply_configuration.content
 
            "-oGlobalKnownHostsFile=/etc/duply/main/ssh/known_hosts -oIdentityFile=/etc/duply/main/ssh/identity'\"" in duply_configuration.content_string
 

	
 

	
 
def test_duply_gnupg_keyring_private_keys(host):
 
    """
 
    Tests if private key used for encryption/signing has been correctly
 
    imporeted into Duply GnuPG keyring.
roles/backup_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -36,13 +36,13 @@ def test_regular_ssh_server_configuration(host):
 
    Tests if the default SSH server has been configured correctly (to prevent
 
    access to it via backup users).
 
    """
 

	
 
    with host.sudo():
 

	
 
        assert "DenyGroups backup" in host.file('/etc/ssh/sshd_config').content
 
        assert "DenyGroups backup" in host.file('/etc/ssh/sshd_config').content_string
 

	
 

	
 
def test_backup_ssh_server_configuration_directory(host):
 
    """
 
    Tests if the backup SSH server configuration directory has been created
 
    correctly.
 
@@ -67,13 +67,13 @@ def test_backup_ssh_server_service_configuration(host):
 
    config_file = host.file('/etc/default/ssh-backup')
 

	
 
    assert config_file.is_file
 
    assert config_file.user == 'root'
 
    assert config_file.group == 'root'
 
    assert config_file.mode == 0o644
 
    assert 'SSHD_OPTS="-f /etc/ssh-backup/sshd_config"' in config_file.content
 
    assert 'SSHD_OPTS="-f /etc/ssh-backup/sshd_config"' in config_file.content_string
 

	
 

	
 
def test_backup_ssh_server_configuration(host):
 
    """
 
    Tests if the backup SSH server configuration file has been set-up correctly.
 
    """
 
@@ -83,22 +83,22 @@ def test_backup_ssh_server_configuration(host):
 
        config_file = host.file('/etc/ssh-backup/sshd_config')
 

	
 
        assert config_file.is_file
 
        assert config_file.user == 'root'
 
        assert config_file.group == 'root'
 
        assert config_file.mode == 0o600
 
        assert "AllowGroups backup" in config_file.content
 
        assert "ChrootDirectory %h" in config_file.content
 
        assert "ForceCommand internal-sftp" in config_file.content
 
        assert "Subsystem sftp internal-sftp" in config_file.content
 
        assert "PasswordAuthentication no" in config_file.content
 
        assert "PubkeyAuthentication yes" in config_file.content
 
        assert "PermitRootLogin no" in config_file.content
 
        assert "HostKey /etc/ssh-backup/ssh_host_rsa_key" in config_file.content
 
        assert "HostKey /etc/ssh-backup/ssh_host_ecdsa_key" in config_file.content
 
        assert "HostKey /etc/ssh-backup/ssh_host_ed25519_key" in config_file.content
 
        assert "AllowGroups backup" in config_file.content_string
 
        assert "ChrootDirectory %h" in config_file.content_string
 
        assert "ForceCommand internal-sftp" in config_file.content_string
 
        assert "Subsystem sftp internal-sftp" in config_file.content_string
 
        assert "PasswordAuthentication no" in config_file.content_string
 
        assert "PubkeyAuthentication yes" in config_file.content_string
 
        assert "PermitRootLogin no" in config_file.content_string
 
        assert "HostKey /etc/ssh-backup/ssh_host_rsa_key" in config_file.content_string
 
        assert "HostKey /etc/ssh-backup/ssh_host_ecdsa_key" in config_file.content_string
 
        assert "HostKey /etc/ssh-backup/ssh_host_ed25519_key" in config_file.content_string
 

	
 

	
 
def test_backup_ssh_server_keys(host):
 
    """
 
    Tests if the backup SSH server private keys have been deployed correctly.
 
    """
 
@@ -107,34 +107,34 @@ def test_backup_ssh_server_keys(host):
 

	
 
        dsa = host.file('/etc/ssh-backup/ssh_host_dsa_key')
 
        assert dsa.is_file
 
        assert dsa.user == 'root'
 
        assert dsa.group == 'root'
 
        assert dsa.mode == 0o600
 
        assert dsa.content == open('tests/data/ssh/server_dsa', 'r').read()
 
        assert dsa.content_string == open('tests/data/ssh/server_dsa', 'r').read()
 

	
 
        rsa = host.file('/etc/ssh-backup/ssh_host_rsa_key')
 
        assert rsa.is_file
 
        assert rsa.user == 'root'
 
        assert rsa.group == 'root'
 
        assert rsa.mode == 0o600
 
        assert rsa.content == open('tests/data/ssh/server_rsa', 'r').read()
 
        assert rsa.content_string == open('tests/data/ssh/server_rsa', 'r').read()
 

	
 
        ed25519 = host.file('/etc/ssh-backup/ssh_host_ed25519_key')
 
        assert ed25519.is_file
 
        assert ed25519.user == 'root'
 
        assert ed25519.group == 'root'
 
        assert ed25519.mode == 0o600
 
        assert ed25519.content == open('tests/data/ssh/server_ed25519', 'r').read()
 
        assert ed25519.content_string == open('tests/data/ssh/server_ed25519', 'r').read()
 

	
 
        ecdsa = host.file('/etc/ssh-backup/ssh_host_ecdsa_key')
 
        assert ecdsa.is_file
 
        assert ecdsa.user == 'root'
 
        assert ecdsa.group == 'root'
 
        assert ecdsa.mode == 0o600
 
        assert ecdsa.content == open('tests/data/ssh/server_ecdsa', 'r').read()
 
        assert ecdsa.content_string == open('tests/data/ssh/server_ecdsa', 'r').read()
 

	
 

	
 
def test_backup_ssh_server_systemd_service(host):
 
    """
 
    Tests if the backup SSH server systemd service file has been deployed
 
    correctly.
 
@@ -143,13 +143,13 @@ def test_backup_ssh_server_systemd_service(host):
 
    service_file = host.file('/etc/systemd/system/ssh-backup.service')
 

	
 
    assert service_file.is_file
 
    assert service_file.user == 'root'
 
    assert service_file.group == 'root'
 
    assert service_file.mode == 0o644
 
    assert "EnvironmentFile=-/etc/default/ssh-backup" in service_file.content
 
    assert "EnvironmentFile=-/etc/default/ssh-backup" in service_file.content_string
 

	
 

	
 
def test_backup_ssh_server_service(host):
 
    """
 
    Tests if the backup SSH server service is running and listening on correct
 
    port.
roles/backup_server/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -17,7 +17,7 @@ def test_firewall_configuration(host):
 
        firewall_config = host.file('/etc/ferm/conf.d/40-backup.conf')
 

	
 
        assert firewall_config.is_file
 
        assert firewall_config.user == 'root'
 
        assert firewall_config.group == 'root'
 
        assert firewall_config.mode == 0o640
 
        assert firewall_config.content == "\n"
 
        assert firewall_config.content_string == "\n"
roles/backup_server/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -108,22 +108,22 @@ def test_backup_client_authorized_keys(host):
 

	
 
        client1_user_authorized_keys = host.file(os.path.join(client1_user.home, '.ssh', 'authorized_keys'))
 
        assert client1_user_authorized_keys.is_file
 
        assert client1_user_authorized_keys.user == 'root'
 
        assert client1_user_authorized_keys.group == 'bak-client1_backup'
 
        assert client1_user_authorized_keys.mode == 0o640
 
        assert client1_user_authorized_keys.content == open('tests/data/ssh/client1.pub', 'r').read()
 
        assert client1_user_authorized_keys.content_string == open('tests/data/ssh/client1.pub', 'r').read()
 

	
 
        client2_user = host.user('bak-client2-backup')
 

	
 
        client2_user_authorized_keys = host.file(os.path.join(client2_user.home, '.ssh', 'authorized_keys'))
 
        assert client2_user_authorized_keys.is_file
 
        assert client2_user_authorized_keys.user == 'root'
 
        assert client2_user_authorized_keys.group == 'bak-client2-backup'
 
        assert client2_user_authorized_keys.mode == 0o640
 
        assert client2_user_authorized_keys.content == open('tests/data/ssh/client2.pub', 'r').read()
 
        assert client2_user_authorized_keys.content_string == open('tests/data/ssh/client2.pub', 'r').read()
 

	
 

	
 
def test_firewall_configuration(host):
 
    """
 
    Tests if the firewall configuration file has been deployed correctly.
 
    """
 
@@ -133,13 +133,13 @@ def test_firewall_configuration(host):
 
        firewall_config = host.file('/etc/ferm/conf.d/40-backup.conf')
 

	
 
        assert firewall_config.is_file
 
        assert firewall_config.user == 'root'
 
        assert firewall_config.group == 'root'
 
        assert firewall_config.mode == 0o640
 
        assert 'saddr ( 10.31.127.1 10.31.127.3) @subchain "backup_in" {' in firewall_config.content
 
        assert 'saddr ( 10.31.127.1 10.31.127.3) @subchain "backup_in" {' in firewall_config.content_string
 

	
 

	
 
@pytest.mark.usefixtures("prepare_ssh_client_private_key_permissions")
 
def test_regular_ssh_server_inaccessible(host):
 
    """
 
    Tests if the default SSH server is inaccessible for the backup client system
roles/bootstrap/molecule/default/tests/test_default.py
Show inline comments
 
@@ -45,7 +45,7 @@ def test_sudo_configuration(host):
 
        sudo_config = host.file('/etc/sudoers.d/ansible')
 

	
 
        assert sudo_config.is_file
 
        assert sudo_config.user == 'root'
 
        assert sudo_config.group == 'root'
 
        assert sudo_config.mode == 0o640
 
        assert sudo_config.content == 'ansible ALL=(ALL:ALL) NOPASSWD:ALL\n'
 
        assert sudo_config.content_string == 'ansible ALL=(ALL:ALL) NOPASSWD:ALL\n'
roles/bootstrap/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -15,19 +15,19 @@ def test_authorized_keys(host):
 
    with host.sudo():
 

	
 
        ssh_key = open(os.path.expanduser('~/.ssh/id_rsa.pub'), 'read').read().strip()
 
        authorized_keys = host.file('/home/ansible/.ssh/authorized_keys')
 

	
 
        assert authorized_keys.is_file
 
        assert ssh_key in authorized_keys.content
 
        assert ssh_key in authorized_keys.content_string
 

	
 

	
 
def test_root_authorized_keys(host):
 
    """
 
    Tests if Ansible key been removed from root's authorized keys.
 
    """
 

	
 
    with host.sudo():
 

	
 
        ssh_key = open(os.path.expanduser('~/.ssh/id_rsa.pub'), 'read').read().strip()
 

	
 
        assert ssh_key not in host.file('/root/.ssh/authorized_keys').content
 
        assert ssh_key not in host.file('/root/.ssh/authorized_keys').content_string
roles/bootstrap/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -15,19 +15,19 @@ def test_authorized_keys(host):
 
    with host.sudo():
 

	
 
        ssh_key = open('tests/data/ansible_key.pub', 'read').read().strip()
 
        authorized_keys = host.file('/home/ansible/.ssh/authorized_keys')
 

	
 
        assert authorized_keys.is_file
 
        assert ssh_key in authorized_keys.content
 
        assert ssh_key in authorized_keys.content_string
 

	
 

	
 
def test_root_authorised_keys(host):
 
    """
 
    Tests if Ansible key been removed from root's authorized keys.
 
    """
 

	
 
    with host.sudo():
 

	
 
        ssh_key = open('tests/data/ansible_key.pub', 'read').read().strip()
 

	
 
        assert ssh_key not in host.file('/root/.ssh/authorized_keys').content
 
        assert ssh_key not in host.file('/root/.ssh/authorized_keys').content_string
roles/common/molecule/default/tests/test_default.py
Show inline comments
 
@@ -126,35 +126,35 @@ def test_installed_packages(host):
 

	
 
def test_root_remote_login_disabled(host):
 
    """
 
    Tests if SSH server has been configured to prevent remote root logins.
 
    """
 

	
 
    assert 'PermitRootLogin no' in host.file('/etc/ssh/sshd_config').content
 
    assert 'PermitRootLogin no' in host.file('/etc/ssh/sshd_config').content_string
 

	
 

	
 
def test_remote_login_via_password_disabled(host):
 
    """
 
    Tests if SSH server has been configured to disable password-based
 
    authentication.
 
    """
 

	
 
    assert 'PasswordAuthentication no' in host.file('/etc/ssh/sshd_config').content
 
    assert 'PasswordAuthentication no' in host.file('/etc/ssh/sshd_config').content_string
 

	
 

	
 
def test_ferm_service_configuration(host):
 

	
 
    ferm_service_config = host.file('/etc/default/ferm')
 

	
 
    assert ferm_service_config.is_file
 
    assert ferm_service_config.user == 'root'
 
    assert ferm_service_config.group == 'root'
 
    assert ferm_service_config.mode == 0o644
 
    assert 'FAST=yes' in ferm_service_config.content
 
    assert 'CACHE=no' in ferm_service_config.content
 
    assert 'ENABLED="yes"' in ferm_service_config.content
 
    assert 'FAST=yes' in ferm_service_config.content_string
 
    assert 'CACHE=no' in ferm_service_config.content_string
 
    assert 'ENABLED="yes"' in ferm_service_config.content_string
 

	
 

	
 
def test_ferm_configuration_directory(host):
 
    """
 
    Tests creation of ferm configuration directory.
 
    """
 
@@ -177,13 +177,13 @@ def test_ferm_configuration(host):
 

	
 
        ferm_configuration = host.file('/etc/ferm/ferm.conf')
 
        assert ferm_configuration.is_file
 
        assert ferm_configuration.user == 'root'
 
        assert ferm_configuration.group == 'root'
 
        assert ferm_configuration.mode == 0o640
 
        assert "@include '/etc/ferm/conf.d/';" in ferm_configuration.content
 
        assert "@include '/etc/ferm/conf.d/';" in ferm_configuration.content_string
 

	
 
        ferm_base = host.file('/etc/ferm/conf.d/00-base.conf')
 
        assert ferm_base.is_file
 
        assert ferm_base.user == 'root'
 
        assert ferm_base.group == 'root'
 
        assert ferm_base.mode == 0o640
 
@@ -228,13 +228,13 @@ def test_check_certificate_crontab(host):
 
    check_certificate_crontab = host.file('/etc/cron.d/check_certificate')
 

	
 
    assert check_certificate_crontab.is_file
 
    assert check_certificate_crontab.user == 'root'
 
    assert check_certificate_crontab.group == 'root'
 
    assert check_certificate_crontab.mode == 0o644
 
    assert "0 0 * * * nobody /usr/local/bin/check_certificate.sh -q expiration" in check_certificate_crontab.content
 
    assert "0 0 * * * nobody /usr/local/bin/check_certificate.sh -q expiration" in check_certificate_crontab.content_string
 

	
 

	
 
@pytest.mark.parametrize('virtualenv_activate_path', [
 
    '/var/lib/pipreqcheck/virtualenv/bin/activate',
 
    '/var/lib/pipreqcheck/virtualenv-py3/bin/activate',
 
])
 
@@ -366,14 +366,14 @@ def test_pipreqcheck_crontab(host, crontab_path, virtualenv_path):
 
    crontab = host.file(crontab_path)
 

	
 
    assert crontab.is_file
 
    assert crontab.user == 'root'
 
    assert crontab.group == 'root'
 
    assert crontab.mode == 0o644
 
    assert "MAILTO=root" in crontab.content
 
    assert virtualenv_path in crontab.content.split(" ")
 
    assert "MAILTO=root" in crontab.content_string
 
    assert virtualenv_path in crontab.content_string.split(" ")
 

	
 

	
 
@pytest.mark.parametrize('python_path, expected_major_version', [
 
    ('/var/lib/pipreqcheck/virtualenv/bin/python', '2'),
 
    ('/var/lib/pipreqcheck/virtualenv-py3/bin/python', '3'),
 
])
roles/common/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -23,14 +23,14 @@ def test_bash_prompt_content(host):
 
    Tests if bash prompt configuration file has not colouring and ID information
 
    contained within.
 
    """
 

	
 
    bash_prompt = host.file('/etc/profile.d/bash_prompt.sh')
 

	
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\[\\033[0m\\]\\u@\\h:\\w\\$ \\[\\033[0m\\]'" in bash_prompt.content
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$ '" in bash_prompt.content
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\[\\033[0m\\]\\u@\\h:\\w\\$ \\[\\033[0m\\]'" in bash_prompt.content_string
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\u@\\h:\\w\\$ '" in bash_prompt.content_string
 

	
 

	
 
def test_ssh_login_mechanisms(host):
 
    """
 
    Tests available SSH login mechanisms (should be just public key).
 
    """
 
@@ -67,13 +67,13 @@ def test_ferm_base_rules(host):
 
    Test if base ferm configuration has been deployed correctly (content-wise).
 
    """
 

	
 
    with host.sudo():
 
        ferm_base = host.file('/etc/ferm/conf.d/00-base.conf')
 

	
 
        assert "mod hashlimit hashlimit 3/second hashlimit-burst 9" in ferm_base.content
 
        assert "mod hashlimit hashlimit 3/second hashlimit-burst 9" in ferm_base.content_string
 

	
 
        iptables = host.command('iptables-save')
 

	
 
        assert iptables.rc == 0
 
        assert "-A flood -p icmp -m icmp --icmp-type 8 -m hashlimit --hashlimit-upto 3/sec --hashlimit-burst 9 " \
 
            "--hashlimit-mode srcip --hashlimit-name icmp -j RETURN" in iptables.stdout
roles/common/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -29,14 +29,14 @@ def test_bash_prompt_content(host):
 
    Tests that custom bash prompt has been configured correctly with specified
 
    colour and prompt.
 
    """
 

	
 
    config = host.file('/etc/profile.d/bash_prompt.sh')
 

	
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\[\\033[0;36m\\]\\u@\\h[test]:\\w\\$ \\[\\033[0m\\]'" in config.content
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\u@\\h[test]:\\w\\$ '" in config.content
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\[\\033[0;36m\\]\\u@\\h[test]:\\w\\$ \\[\\033[0m\\]'" in config.content_string
 
    assert "export PS1='\\[\\e]0;\\u@\\h: \\w\\a\\]${debian_chroot:+($debian_chroot)}\\u@\\h[test]:\\w\\$ '" in config.content_string
 

	
 

	
 
def test_common_installed_packages_common(host):
 
    """
 
    Tests that user-provided common packages have been installed.
 
    """
 
@@ -75,13 +75,13 @@ def test_emacs_electric_indent_mode(host):
 
    emacs_config = host.file('/etc/emacs/site-start.d/01disable-electric-indent-mode.el')
 

	
 
    assert emacs_config.is_file
 
    assert emacs_config.user == 'root'
 
    assert emacs_config.group == 'root'
 
    assert emacs_config.mode == 0o644
 
    assert "(electric-indent-mode -1)" in emacs_config.content
 
    assert "(electric-indent-mode -1)" in emacs_config.content_string
 

	
 

	
 
def test_os_groups(host):
 
    """
 
    Tests if user-supplied system groups have been created correctly.
 
    """
 
@@ -126,24 +126,24 @@ def test_os_users(host):
 
        assert user2.group == 'user2'
 
        assert sorted(user2.groups) == sorted(['group1', 'group2', 'user2'])
 
        assert user2.shell == '/bin/bash'
 
        assert user2.password == '$6$wdXOQiMe09ugh0$VRIph2XA2QQyEYlAlH7zT4TPACDUalf/4FKpqG9JRHfKxANTcTug2ANCt450htcs0LikJfHLWofLP54jraFU61'
 

	
 
        user2_authorized_keys = host.file(os.path.join(user2.home, '.ssh', 'authorized_keys'))
 
        assert open('tests/data/ssh/clientkey1.pub', 'r').read().strip() in user2_authorized_keys.content
 
        assert open('tests/data/ssh/clientkey2.pub', 'r').read().strip() in user2_authorized_keys.content
 
        assert open('tests/data/ssh/clientkey1.pub', 'r').read().strip() in user2_authorized_keys.content_string
 
        assert open('tests/data/ssh/clientkey2.pub', 'r').read().strip() in user2_authorized_keys.content_string
 

	
 
        user3 = host.user('user3')
 
        assert user3.uid == 2002
 
        assert user3.group == 'user3'
 
        assert sorted(user3.groups) == sorted(['group3', 'user3'])
 
        assert user3.shell == '/bin/bash'
 
        assert user3.password == '$6$nmx.21uLqT$9LrUqNUgUwIM.l0KFKgr2.kDEwe2lo7IbBIhnG70AGW7GTFdWBUFnGAxH15YxikTXhDJD/uxd.NNgojEOjRvx1'
 

	
 
        user3_authorized_keys = host.file(os.path.join(user3.home, '.ssh', 'authorized_keys'))
 
        assert open('tests/data/ssh/clientkey3.pub', 'r').read().strip() in user3_authorized_keys.content
 
        assert open('tests/data/ssh/clientkey3.pub', 'r').read().strip() in user3_authorized_keys.content_string
 

	
 

	
 
def test_authorized_keys_login(host):
 
    """
 
    Tests if authorized SSH keys for user-provided system users have been set-up
 
    correctly.
 
@@ -214,13 +214,13 @@ def test_ferm_base_rules(host):
 
    user-provided rate-limiting.
 
    """
 

	
 
    with host.sudo():
 
        ferm_base = host.file('/etc/ferm/conf.d/00-base.conf')
 

	
 
        assert "mod hashlimit hashlimit 5/second hashlimit-burst 5" in ferm_base.content
 
        assert "mod hashlimit hashlimit 5/second hashlimit-burst 5" in ferm_base.content_string
 

	
 
        iptables = host.command('iptables-save')
 

	
 
        assert iptables.rc == 0
 
        assert "-A flood -p icmp -m icmp --icmp-type 8 -m hashlimit --hashlimit-upto 5/sec --hashlimit-burst 5 " \
 
            "--hashlimit-mode srcip --hashlimit-name icmp -j RETURN" in iptables.stdout
 
@@ -259,21 +259,21 @@ def test_backup_configuration(host):
 
    """
 

	
 
    with host.sudo():
 

	
 
        common = host.file('/etc/duply/main/patterns/common')
 
        assert common.is_file
 
        assert "/var/log" in common.content.split("\n")
 
        assert "/etc/shadow" in common.content.split("\n")
 
        assert "/var/mail" in common.content.split("\n")
 
        assert "/var/spool/cron" in common.content.split("\n")
 
        assert "/var/log" in common.content_string.split("\n")
 
        assert "/etc/shadow" in common.content_string.split("\n")
 
        assert "/var/mail" in common.content_string.split("\n")
 
        assert "/var/spool/cron" in common.content_string.split("\n")
 

	
 
        common_extra = host.file('/etc/duply/main/patterns/common_extra')
 
        assert common_extra.is_file
 
        assert "/home/user1" in common_extra.content.split("\n")
 
        assert "/home/user2" in common_extra.content.split("\n")
 
        assert "/home/user1" in common_extra.content_string.split("\n")
 
        assert "/home/user2" in common_extra.content_string.split("\n")
 

	
 

	
 
def test_ntp_software_installed(host):
 
    """
 
    Tests if NTP packages are installed.
 
    """
 
@@ -287,13 +287,13 @@ def test_ntp_server_configuration(host):
 
    Tests if NTP server has been correctly configured.
 
    """
 

	
 
    with host.sudo():
 

	
 
        # Read the configuration file.
 
        configuration = host.file("/etc/ntp.conf").content.split("\n")
 
        configuration = host.file("/etc/ntp.conf").content_string.split("\n")
 

	
 
        # Extract only the relevant sections of files (exculde empty
 
        # lines and comments).
 
        configuration = [c.strip() for c in configuration if re.match(r'^\s*(|#.*)$', c) is None]
 

	
 
        # Ensure correct servers have been configured in the pool.
roles/database/molecule/default/tests/test_backup.py
Show inline comments
 
@@ -34,13 +34,13 @@ def test_backup_script_file(host):
 
        script = host.file('/etc/duply/main/pre.d/dump_testdb.sh')
 

	
 
        assert script.is_file
 
        assert script.user == 'root'
 
        assert script.group == 'root'
 
        assert script.mode == 0o700
 
        assert "/usr/bin/mysqldump \"testdb\" > \"/srv/backup/mariadb/testdb.sql\"" in script.content
 
        assert "/usr/bin/mysqldump \"testdb\" > \"/srv/backup/mariadb/testdb.sql\"" in script.content_string
 

	
 

	
 
def test_backup_run(host):
 
    """
 
    Tests if backup runs correctly, and if restore will included the backed-up
 
    database.
 
@@ -54,14 +54,14 @@ def test_backup_run(host):
 

	
 
        backup_run = host.run('duply main backup')
 
        assert backup_run.rc == 0
 

	
 
        database_dump = host.file('/srv/backup/mariadb/testdb.sql')
 
        assert database_dump.is_file
 
        assert 'Database: testdb' in database_dump.content
 
        assert 'Database: testdb' in database_dump.content_string
 

	
 
        restore_run = host.run('duply main restore /root/restore')
 
        assert restore_run.rc == 0
 

	
 
        restored_database_dump = host.file('/root/restore/srv/backup/mariadb/testdb.sql')
 
        assert restored_database_dump.is_file
 
        assert restored_database_dump.content == database_dump.content
 
        assert restored_database_dump.content_string == database_dump.content_string
roles/database_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -52,14 +52,14 @@ def test_root_my_cnf(host):
 
        my_cnf = host.file('/root/.my.cnf')
 

	
 
        assert my_cnf.is_file
 
        assert my_cnf.user == 'root'
 
        assert my_cnf.group == 'root'
 
        assert my_cnf.mode == 0o400
 
        assert "user=root" in my_cnf.content
 
        assert "password=root_password" in my_cnf.content
 
        assert "user=root" in my_cnf.content_string
 
        assert "password=root_password" in my_cnf.content_string
 

	
 

	
 
def test_root_my_cnf_login(host):
 
    """
 
    Tets if the database server root login works using just the my.cnf
 
    configuration file.
roles/ldap_client/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -11,7 +11,7 @@ def test_ldap_configuration_file_content(host):
 
    """
 
    Tests if LDAP configuration file has correct content
 
    """
 

	
 
    config = host.file('/etc/ldap/ldap.conf')
 

	
 
    assert config.content == ""
 
    assert config.content_string == ""
roles/ldap_client/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -21,7 +21,7 @@ URI ldaps://ldap-server/
 
# Base entry
 
BASE dc=local
 
"""
 

	
 
    config = host.file('/etc/ldap/ldap.conf')
 

	
 
    assert config.content == expected_content
 
    assert config.content_string == expected_content
roles/ldap_server/molecule/default/tests/test_backup.py
Show inline comments
 
@@ -51,14 +51,14 @@ def test_backup(host):
 

	
 
        backup_run = host.run('duply main backup')
 
        assert backup_run.rc == 0
 

	
 
        database_dump = host.file('/srv/backup/slapd.bak')
 
        assert database_dump.is_file
 
        assert 'dn: dc=local' in database_dump.content
 
        assert 'dn: dc=local' in database_dump.content_string
 

	
 
        restore_run = host.run('duply main restore /root/restore')
 
        assert restore_run.rc == 0
 

	
 
        restored_database_dump = host.file('/root/restore/srv/backup/slapd.bak')
 
        assert restored_database_dump.is_file
 
        assert restored_database_dump.content == database_dump.content
 
        assert restored_database_dump.content_string == database_dump.content_string
roles/ldap_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -58,13 +58,13 @@ def test_syslog_configuration(host):
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 

	
 
    with host.sudo():
 
        log = host.file('/var/log/slapd.log')
 
        assert log.is_file
 
        assert 'slapd' in log.content
 
        assert 'slapd' in log.content_string
 

	
 

	
 
def test_log_rotation_configuration(host):
 
    """
 
    Tests if log rotation configuration file has been deployed correctly and has
 
    valid syntax.
roles/ldap_server/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -46,13 +46,13 @@ def test_ldap_tls_private_key_file(host):
 
        key = host.file('/etc/ssl/private/%s_ldap.key' % inventory_hostname)
 

	
 
        assert key.is_file
 
        assert key.user == 'root'
 
        assert key.group == 'openldap'
 
        assert key.mode == 0o640
 
        assert key.content == open('tests/data/x509/%s_ldap.key' % inventory_hostname).read()
 
        assert key.content_string == open('tests/data/x509/%s_ldap.key' % inventory_hostname).read()
 

	
 

	
 
def test_ldap_tls_certificate_file(host):
 
    """
 
    Tests if the TLS certificate has been deployed correctly.
 
    """
 
@@ -64,13 +64,13 @@ def test_ldap_tls_certificate_file(host):
 
        cert = host.file('/etc/ssl/certs/%s_ldap.pem' % inventory_hostname)
 

	
 
        assert cert.is_file
 
        assert cert.user == 'root'
 
        assert cert.group == 'root'
 
        assert cert.mode == 0o644
 
        assert cert.content == open('tests/data/x509/%s_ldap.pem' % inventory_hostname).read()
 
        assert cert.content_string == open('tests/data/x509/%s_ldap.pem' % inventory_hostname).read()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -81,13 +81,13 @@ def test_certificate_validity_check_configuration(host):
 
    config = host.file('/etc/check_certificate/%s_ldap.conf' % inventory_hostname)
 

	
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_ldap.pem" % inventory_hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_ldap.pem" % inventory_hostname
 

	
 

	
 
def test_tls_configuration(host):
 
    """
 
    Tests if the TLS has been configured correctly and works.
 
    """
roles/ldap_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -46,13 +46,13 @@ def test_ldap_tls_private_key_file(host):
 
        key = host.file('/etc/ssl/private/%s_ldap.key' % inventory_hostname)
 

	
 
        assert key.is_file
 
        assert key.user == 'root'
 
        assert key.group == 'openldap'
 
        assert key.mode == 0o640
 
        assert key.content == open('tests/data/x509/parameters-optional.key.pem').read()
 
        assert key.content_string == open('tests/data/x509/parameters-optional.key.pem').read()
 

	
 

	
 
def test_ldap_tls_certificate_file(host):
 
    """
 
    Tests if the TLS certificate has been deployed correctly.
 
    """
 
@@ -64,13 +64,13 @@ def test_ldap_tls_certificate_file(host):
 
        cert = host.file('/etc/ssl/certs/%s_ldap.pem' % inventory_hostname)
 

	
 
        assert cert.is_file
 
        assert cert.user == 'root'
 
        assert cert.group == 'root'
 
        assert cert.mode == 0o644
 
        assert cert.content == open('tests/data/x509/parameters-optional.cert.pem').read()
 
        assert cert.content_string == open('tests/data/x509/parameters-optional.cert.pem').read()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -81,13 +81,13 @@ def test_certificate_validity_check_configuration(host):
 
    config = host.file('/etc/check_certificate/%s_ldap.conf' % inventory_hostname)
 

	
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_ldap.pem" % inventory_hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_ldap.pem" % inventory_hostname
 

	
 

	
 
def test_tls_configuration(host):
 
    """
 
    Tests if the TLS has been configured correctly and works.
 
    """
roles/mail_forwarder/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -13,42 +13,42 @@ def test_smtp_relay_truststore_file(host):
 
    """
 
    Tests if SMTP relay truststore has correct content.
 
    """
 

	
 
    truststore = host.file('/etc/ssl/certs/smtp_relay_truststore.pem')
 

	
 
    assert truststore.content == open("tests/data/x509/truststore.pem", "r").read().rstrip()
 
    assert truststore.content_string == open("tests/data/x509/truststore.pem", "r").read().rstrip()
 

	
 

	
 
def test_smtp_mailname(host):
 
    """
 
    Tests if SMTP mailname configuration file has correct content.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    mailname = host.file('/etc/mailname')
 

	
 
    assert mailname.content == hostname
 
    assert mailname.content_string == hostname
 

	
 

	
 
def test_postfix_main_cf_file_content(host):
 
    """
 
    Tests if the Postfix main configuration file content is correct.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 
    config = host.file('/etc/postfix/main.cf')
 
    config_lines = config.content.split("\n")
 
    config_lines = config.content_string.split("\n")
 

	
 
    assert "myhostname = %s" % hostname in config_lines
 
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
 
    assert "relayhost = " in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" in config_lines
 
    assert "smtp_tls_security_level" not in config.content
 
    assert "smtp_tls_CAfile" not in config.content
 
    assert "smtp_tls_security_level" not in config.content_string
 
    assert "smtp_tls_CAfile" not in config.content_string
 
    assert "smtp_host_lookup = dns, native" in config_lines
 

	
 

	
 
def test_direct_mail_sending(host):
 
    """
 
    Tests if mails are sent correctly directly without relay if relay has not
 
@@ -64,7 +64,7 @@ def test_direct_mail_sending(host):
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        # Pattern used to verify the mail was sent directly on default port.
 
        pattern = r"%s: to=<root@domain1>, relay=domain1\[[^]]*\]:25.*status=sent" % message_id
 

	
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
roles/mail_forwarder/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -13,35 +13,35 @@ def test_smtp_relay_truststore_file(host):
 
    """
 
    Tests if SMTP relay truststore has correct content.
 
    """
 

	
 
    truststore = host.file('/etc/ssl/certs/smtp_relay_truststore.pem')
 

	
 
    assert truststore.content == open("tests/data/x509/ca.cert.pem", "r").read().rstrip()
 
    assert truststore.content_string == open("tests/data/x509/ca.cert.pem", "r").read().rstrip()
 

	
 

	
 
def test_smtp_mailname(host):
 
    """
 
    Tests if SMTP mailname has been configured correctly.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    mailname = host.file('/etc/mailname')
 

	
 
    assert mailname.content == "%s" % hostname
 
    assert mailname.content_string == "%s" % hostname
 

	
 

	
 
def test_postfix_main_cf_file_content(host):
 
    """
 
    Tests if the Postfix main configuration file content is correct.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 
    config = host.file('/etc/postfix/main.cf')
 
    config_lines = config.content.split("\n")
 
    config_lines = config.content_string.split("\n")
 

	
 
    assert "myhostname = %s" % hostname in config_lines
 
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
 
    assert "relayhost = mail-server:27" in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" in config_lines
 
    assert "smtp_tls_security_level=verify" in config_lines
 
@@ -64,14 +64,14 @@ def test_local_aliases(host):
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        pattern1 = "%s: to=<root@%s>, orig_to=<root@localhost>.*status=sent" % (message_id, hostname)
 
        pattern2 = "%s: to=<testuser@%s>, orig_to=<root@localhost>.*status=sent" % (message_id, hostname)
 

	
 
        assert re.search(pattern1, mail_log.content) is not None
 
        assert re.search(pattern2, mail_log.content) is not None
 
        assert re.search(pattern1, mail_log.content_string) is not None
 
        assert re.search(pattern2, mail_log.content_string) is not None
 

	
 

	
 
def test_relay_mail_sending(host):
 
    """
 
    Tests if mails are sent correctly via relay if relay has been configured.
 
    """
 
@@ -86,13 +86,13 @@ def test_relay_mail_sending(host):
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        # Pattern used to verify the mail was sent over relay on designated
 
        # port.
 
        pattern = r"%s: to=<root@domain1>, relay=mail-server\[[^]]*\]:27.*status=sent" % message_id
 

	
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_tls_enforced_towards_relay_mail_server(host):
 
    """
 
    Tests if TLS verification is enfoced towards the relay mail server.
 
    """
 
@@ -122,7 +122,7 @@ def test_tls_enforced_towards_relay_mail_server(host):
 
        time.sleep(5)
 

	
 
        with host.sudo():
 
            mail_log = host.file('/var/log/mail.log')
 
            pattern = r"%s: to=<root@domain1>, relay=domain1.*status=deferred \(Server certificate not verified\)" % message_id
 

	
 
            assert re.search(pattern, mail_log.content) is not None
 
            assert re.search(pattern, mail_log.content_string) is not None
roles/mail_forwarder/molecule/default/tests/test_smtp_relay_host_port.py
Show inline comments
 
@@ -14,13 +14,13 @@ def test_postfix_main_cf_file_content(host):
 
    """
 
    Tests if the Postfix main configuration file content is correct.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 
    config = host.file('/etc/postfix/main.cf')
 
    config_lines = config.content.split("\n")
 
    config_lines = config.content_string.split("\n")
 

	
 
    assert "myhostname = %s" % hostname in config_lines
 
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
 
    assert "relayhost = mail-server" in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" in config_lines
 
    assert "smtp_tls_security_level=verify" in config_lines
 
@@ -42,7 +42,7 @@ def test_relay_mail_sending(host):
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        # Pattern used to verify the mail was sent over relay on default port.
 
        pattern = r"%s: to=<root@domain1>, relay=mail-server\[[^]]*\]:25.*status=sent" % message_id
 

	
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
roles/mail_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -110,20 +110,20 @@ def test_ldap_tls_truststore_file(host):
 

	
 
    tls_file = host.file('/etc/ssl/certs/mail_ldap_tls_truststore.pem')
 
    assert tls_file.is_file
 
    assert tls_file.user == 'root'
 
    assert tls_file.group == 'root'
 
    assert tls_file.mode == 0o644
 
    assert tls_file.content == open("tests/data/x509/ca.cert.pem", "r").read().rstrip()
 
    assert tls_file.content_string == open("tests/data/x509/ca.cert.pem", "r").read().rstrip()
 

	
 
    tls_file = host.file('/var/spool/postfix/etc/ssl/certs/mail_ldap_tls_truststore.pem')
 
    assert tls_file.is_file
 
    assert tls_file.user == 'root'
 
    assert tls_file.group == 'root'
 
    assert tls_file.mode == 0o644
 
    assert tls_file.content == open("tests/data/x509/ca.cert.pem", "r").read().rstrip()
 
    assert tls_file.content_string == open("tests/data/x509/ca.cert.pem", "r").read().rstrip()
 

	
 

	
 
def test_mailname_file(host):
 
    """
 
    Tests the system mail name file permissions.
 
    """
 
@@ -240,23 +240,23 @@ def test_postfix_delivery_to_dovecot(host):
 
    send = host.run('swaks --header %s --suppress-data --to john.doe@domain1 --server %s', "Message-Id: <%s>" % message_id, hostname)
 
    assert send.rc == 0
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        pattern = r"dovecot: lda\(john.doe@domain1\): msgid=<%s>: saved mail to INBOX" % message_id
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_dovecot_system_authentication_is_disabled(host):
 
    """
 
    Tests if Dovecot system-based authentication has been disabled.
 
    """
 

	
 
    config = host.file("/etc/dovecot/conf.d/10-auth.conf")
 

	
 
    assert "!include auth-system.conf.ext" not in config.content
 
    assert "!include auth-system.conf.ext" not in config.content_string
 

	
 

	
 
def test_dovecot_overrides_configuration_file(host):
 
    """
 
    Tests if Dovecot configuration file with overrides has been deployed and has
 
    correct permissions.
roles/mail_server/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -18,34 +18,34 @@ def test_smtp_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_smtp.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/%s_smtp.key" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s_smtp.key" % hostname, "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_smtp.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/%s_smtp.pem" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s_smtp.pem" % hostname, "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_imap.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/%s_imap.key" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s_imap.key" % hostname, "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_imap.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/%s_imap.pem" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s_imap.pem" % hostname, "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -55,42 +55,42 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/%s_smtp.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_smtp.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_smtp.pem" % hostname
 

	
 
    config = host.file('/etc/check_certificate/%s_imap.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_imap.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_imap.pem" % hostname
 

	
 

	
 
def test_mailname_file_content(host):
 
    """
 
    Tests the system mail name file content.
 
    """
 

	
 
    mailname = host.file('/etc/mailname')
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    assert mailname.content == hostname
 
    assert mailname.content_string == hostname
 

	
 

	
 
def test_postfix_main_cf_file_content(host):
 
    """
 
    Tests if the Postfix main configuration file content is correct.
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    config = host.file('/etc/postfix/main.cf')
 
    config_lines = config.content.split("\n")
 
    config_lines = config.content_string.split("\n")
 

	
 
    assert "myhostname = %s" % hostname in config_lines
 
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128" in config_lines
 
    assert "smtpd_tls_cert_file = /etc/ssl/certs/%s_smtp.pem" % hostname in config_lines
 
    assert "smtpd_tls_key_file = /etc/ssl/private/%s_smtp.key" % hostname in config_lines
roles/mail_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -21,34 +21,34 @@ def test_smtp_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_smtp.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_smtp.key.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_smtp.key.pem", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_smtp.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_smtp.cert.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_smtp.cert.pem", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_imap.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_imap.key.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_imap.key.pem", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_imap.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_imap.cert.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_imap.cert.pem", "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -58,44 +58,44 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/%s_smtp.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_smtp.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_smtp.pem" % hostname
 

	
 
    config = host.file('/etc/check_certificate/%s_imap.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_imap.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_imap.pem" % hostname
 

	
 

	
 
def test_mailname_file_content(host):
 
    """
 
    Tests the system mail name file content.
 
    """
 

	
 
    mailname = host.file('/etc/mailname')
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    assert mailname.content == hostname
 
    assert mailname.content_string == hostname
 

	
 

	
 
def test_postfix_main_cf_file_content(host):
 
    """
 
    Tests if the Postfix main configuration file content is correct.
 
    """
 

	
 
    allow_relay_from_ip = "10.31.127.22"
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    config = host.file('/etc/postfix/main.cf')
 
    config_lines = config.content.split("\n")
 
    config_lines = config.content_string.split("\n")
 

	
 
    assert "myhostname = %s" % hostname in config_lines
 
    assert "mydestination = %s, %s, localhost.localdomain, localhost" % (hostname, hostname) in config_lines
 
    assert "mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 %s" % allow_relay_from_ip in config_lines
 
    assert "smtpd_tls_cert_file = /etc/ssl/certs/%s_smtp.pem" % hostname in config_lines
 
    assert "smtpd_tls_key_file = /etc/ssl/private/%s_smtp.key" % hostname in config_lines
 
@@ -115,13 +115,13 @@ def test_local_aliases(host):
 
    time.sleep(1)
 
    assert send.rc == 0
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 
        pattern = r"dovecot: lda\(john.doe@domain1\): msgid=<%s>: saved mail to INBOX" % message_id
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_dovecot_mailbox_directories(host):
 
    """
 
    Tests if mailbox directories are created correctly.
 
    """
roles/php_website/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -100,13 +100,13 @@ def test_forward_file(host):
 

	
 
        config = host.file('/var/www/parameters-mandatory/.forward')
 
        assert config.is_file
 
        assert config.user == 'root'
 
        assert config.group == 'web-parameters-mandatory'
 
        assert config.mode == 0o640
 
        assert config.content == "root\n"
 
        assert config.content_string == "root\n"
 

	
 

	
 
def test_mail_forwarding(host):
 
    """
 
    Tests if mail forwarding works as expected.
 
    """
 
@@ -122,17 +122,17 @@ def test_mail_forwarding(host):
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 

	
 
        # First extract message ID of forwarded mail.
 
        pattern = r"%s: to=<web-parameters-mandatory@localhost>.*status=sent \(forwarded as ([^)]*)\)" % original_queue_id
 
        forward_queue_id = re.search(pattern, mail_log.content).group(1)
 
        forward_queue_id = re.search(pattern, mail_log.content_string).group(1)
 

	
 
        # Now try to determine where the forward ended-up at.
 
        pattern = "%s: to=<vagrant@%s>, orig_to=<web-parameters-mandatory@localhost>.*status=sent" % (forward_queue_id, hostname)
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_php_fpm_configuration_file(host):
 
    """
 
    Tests if PHP FPM configuration file has been correctly deployed.
 
    """
 
@@ -157,20 +157,20 @@ def test_nginx_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/parameters-mandatory_https.key')
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/parameters-mandatory_https.key", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-mandatory_https.key", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/parameters-mandatory_https.pem')
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/parameters-mandatory_https.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-mandatory_https.pem", "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -178,13 +178,13 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/parameters-mandatory_https.conf')
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/parameters-mandatory_https.pem"
 
    assert config.content_string == "/etc/ssl/certs/parameters-mandatory_https.pem"
 

	
 

	
 
def test_vhost_file(host):
 
    """
 
    Tests permissions of vhost configuration file.
 
    """
roles/php_website/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -100,13 +100,13 @@ def test_forward_file(host):
 

	
 
        config = host.file('/var/www/parameters-optional.local/.forward')
 
        assert config.is_file
 
        assert config.user == 'root'
 
        assert config.group == 'web-parameters-optional_local'
 
        assert config.mode == 0o640
 
        assert config.content == "user\n"
 
        assert config.content_string == "user\n"
 

	
 

	
 
def test_mail_forwarding(host):
 
    """
 
    Tests if mail forwarding works as expected.
 
    """
 
@@ -122,17 +122,17 @@ def test_mail_forwarding(host):
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 

	
 
        # First extract message ID of forwarded mail.
 
        pattern = r"%s: to=<web-parameters-optional_local@localhost>.*status=sent \(forwarded as ([^)]*)\)" % message_id
 
        message_id = re.search(pattern, mail_log.content).group(1)
 
        message_id = re.search(pattern, mail_log.content_string).group(1)
 

	
 
        # Now try to determine where the forward ended-up at.
 
        pattern = "%s: to=<user@%s>, orig_to=<web-parameters-optional_local@localhost>.*status=sent" % (message_id, hostname)
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
def test_installed_packages(host):
 
    """
 
    Tests if additional packages are installed.
 
    """
 
@@ -151,20 +151,20 @@ def test_nginx_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/parameters-optional.local_https.key')
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/parameters-optional.local_https.key.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional.local_https.key.pem", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/parameters-optional.local_https.pem')
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/parameters-optional.local_https.cert.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional.local_https.cert.pem", "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -172,13 +172,13 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/parameters-optional.local_https.conf')
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/parameters-optional.local_https.pem"
 
    assert config.content_string == "/etc/ssl/certs/parameters-optional.local_https.pem"
 

	
 

	
 
def test_vhost_file(host):
 
    """
 
    Tests permissions of vhost configuration file.
 
    """
roles/preseed/molecule/default/tests/test_parameters_mandatory.py
Show inline comments
 
@@ -50,13 +50,13 @@ def test_preseed_configuration_file_content(host):
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    with host.sudo():
 
        preseed_file = host.file(os.path.join("/tmp/molecule/preseed/default/inventory", "preseed_files", "%s.cfg" % hostname))
 
        preseed_file_content = preseed_file.content_string
 
        preseed_file_content = preseed_file.content_string_string
 
        ssh_public_key = open(os.path.join(os.path.expanduser("~"), ".ssh", "id_rsa.pub")).read().strip()
 

	
 
    assert "d-i debian-installer/language string en" in preseed_file_content
 
    assert "d-i debian-installer/country string SE" in preseed_file_content
 
    assert "d-i debian-installer/locale string en_US.UTF-8" in preseed_file_content
 
    assert "d-i keyboard-configuration/xkb-keymap select us" in preseed_file_content
roles/preseed/molecule/default/tests/test_parameters_optional.py
Show inline comments
 
@@ -45,13 +45,13 @@ def test_preseed_configuration_file_content(host):
 
    """
 

	
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    with host.sudo():
 
        preseed_file = host.file(os.path.join(PRESEED_DIRECTORY, "%s.cfg" % hostname))
 
        preseed_file_content = preseed_file.content_string
 
        preseed_file_content = preseed_file.content_string_string
 
        ssh_public_key = "CUSTOMKEY"
 

	
 
    assert "d-i debian-installer/language string sr" in preseed_file_content
 
    assert "d-i debian-installer/country string RS" in preseed_file_content
 
    assert "d-i debian-installer/locale string en_UK.UTF-8" in preseed_file_content
 
    assert "d-i keyboard-configuration/xkb-keymap select sv" in preseed_file_content
roles/preseed/molecule/default/tests/test_parameters_optional_with_overrides.py
Show inline comments
 
@@ -29,13 +29,13 @@ def test_preseed_configuration_file_content_host_without_overrides(host):
 
    """
 

	
 
    hostname = 'parameters-mandatory-stretch64'
 

	
 
    with host.sudo():
 
        preseed_file = host.file(os.path.join(PRESEED_DIRECTORY, "%s.cfg" % hostname))
 
        preseed_file_content = preseed_file.content_string
 
        preseed_file_content = preseed_file.content_string_string
 
        ssh_public_key = "CUSTOMKEY"
 

	
 
    assert "d-i debian-installer/language string en" in preseed_file_content
 
    assert "d-i debian-installer/country string SE" in preseed_file_content
 
    assert "d-i debian-installer/locale string en_US.UTF-8" in preseed_file_content
 
    assert "d-i keyboard-configuration/xkb-keymap select us" in preseed_file_content
 
@@ -61,13 +61,13 @@ def test_preseed_configuration_file_content_host_with_overrides(host):
 
    """
 

	
 
    hostname = 'parameters-optional-with-overrides-stretch64'
 

	
 
    with host.sudo():
 
        preseed_file = host.file(os.path.join(PRESEED_DIRECTORY, "%s.cfg" % hostname))
 
        preseed_file_content = preseed_file.content_string
 
        preseed_file_content = preseed_file.content_string_string
 
        ssh_public_key = "CUSTOMKEY"
 

	
 
    assert "d-i debian-installer/language string sr" in preseed_file_content
 
    assert "d-i debian-installer/country string RS" in preseed_file_content
 
    assert "d-i debian-installer/locale string en_UK.UTF-8" in preseed_file_content
 
    assert "d-i keyboard-configuration/xkb-keymap select sv" in preseed_file_content
roles/web_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -32,13 +32,13 @@ def test_nginx_user(host):
 
def test_default_tls_configuration_removed(host):
 
    """
 
    Tests if TLS configuration has been removed from the main (default)
 
    configuration file.
 
    """
 

	
 
    assert 'ssl_protocols' not in host.file('/etc/nginx/nginx.conf').content
 
    assert 'ssl_protocols' not in host.file('/etc/nginx/nginx.conf').content_string
 

	
 

	
 
def test_nginx_configuration_verification_script(host):
 
    """
 
    Tests if script used for verifying Nginx configuration is deployed
 
    correctly.
 
@@ -184,13 +184,13 @@ def test_socket_directories(host, application_type, tmpfiles_d_path):
 

	
 
    config = host.file(tmpfiles_d_path)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == tmpfiles_d_content
 
    assert config.content_string == tmpfiles_d_content
 

	
 

	
 
def test_php_fpm_service_overrides(host, php_info):
 
    """
 
    Tests if overrides for PHP-FPM service are deployed correctly.
 
    """
 
@@ -210,13 +210,13 @@ def test_php_fpm_service_overrides(host, php_info):
 

	
 
def test_php_timezone_configuration(host, php_info):
 
    """
 
    Tests if PHP timezone configuration has been set correctly.
 
    """
 

	
 
    server_timezone = host.file("/etc/timezone").content.strip()
 
    server_timezone = host.file("/etc/timezone").content_string.strip()
 

	
 
    config = host.file('%s/cli/conf.d/30-timezone.ini' % php_info.base_config_dir)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
roles/web_server/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -18,20 +18,20 @@ def test_nginx_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_https.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/%s_https.key" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s_https.key" % hostname, "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_https.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/%s_https.pem" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s_https.pem" % hostname, "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -41,13 +41,13 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/%s_https.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_https.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_https.pem" % hostname
 

	
 

	
 
def test_tls_configuration(host):
 
    """
 
    Tests if the TLS has been configured correctly and works.
 
    """
roles/web_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -18,20 +18,20 @@ def test_nginx_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_https.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_https.key.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_https.key.pem", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_https.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_https.cert.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_https.cert.pem", "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -41,13 +41,13 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/%s_https.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_https.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_https.pem" % hostname
 

	
 

	
 
def test_tls_configuration(host):
 
    """
 
    Tests if the TLS has been configured correctly and works.
 
    """
roles/wsgi_website/molecule/default/tests/test_default.py
Show inline comments
 
@@ -116,13 +116,13 @@ def test_environment_profile_configuration(host, profile_file, expected_group, e
 

	
 
        config = host.file(profile_file)
 
        assert config.is_file
 
        assert config.user == 'root'
 
        assert config.group == expected_group
 
        assert config.mode == 0o640
 
        assert config.content == expected_content
 
        assert config.content_string == expected_content
 

	
 

	
 
@pytest.mark.parametrize("admin_user, expected_virtualenv_path", [
 
    ('admin-parameters-mandatory', '/var/www/parameters-mandatory/virtualenv\n'),
 
    ('admin-parameters-optional_local', '/var/www/parameters-optional.local/virtualenv\nMy environment variable\n'),
 
    ('admin-parameters-paste-req', '/var/www/parameters-paste-req/virtualenv\n'),
 
@@ -190,13 +190,13 @@ def test_forward_file(host, forward_file, expected_group, expected_content):
 
        config = host.file(forward_file)
 

	
 
        assert config.is_file
 
        assert config.user == 'root'
 
        assert config.group == expected_group
 
        assert config.mode == 0o640
 
        assert config.content == expected_content
 
        assert config.content_string == expected_content
 

	
 

	
 
@pytest.mark.parametrize("original_destination, expected_destination_user", [
 
    ('web-parameters-mandatory@localhost', 'vagrant'),
 
    ('web-parameters-optional_local@localhost', 'user'),
 
    ('web-parameters-paste-req@localhost', 'vagrant'),
 
@@ -217,17 +217,17 @@ def test_mail_forwarding(host, original_destination, expected_destination_user):
 

	
 
    with host.sudo():
 
        mail_log = host.file('/var/log/mail.log')
 

	
 
        # First extract message ID of forwarded mail.
 
        pattern = r"%s: to=<%s>.*status=sent \(forwarded as ([^)]*)\)" % (original_queue_id, original_destination)
 
        forward_queue_id = re.search(pattern, mail_log.content).group(1)
 
        forward_queue_id = re.search(pattern, mail_log.content_string).group(1)
 

	
 
        # Now try to determine where the forward ended-up at.
 
        pattern = "%s: to=<%s@%s>, orig_to=<%s>.*status=sent" % (forward_queue_id, expected_destination_user, hostname, original_destination)
 
        assert re.search(pattern, mail_log.content) is not None
 
        assert re.search(pattern, mail_log.content_string) is not None
 

	
 

	
 
@pytest.mark.parametrize("virtualenv_dir, expected_owner, expected_group", [
 
    ('/var/www/parameters-mandatory/virtualenv', 'admin-parameters-mandatory', 'web-parameters-mandatory'),
 
    ('/var/www/parameters-optional.local/virtualenv', 'admin-parameters-optional_local', 'web-parameters-optional_local'),
 
    ('/var/www/parameters-paste-req/virtualenv', 'admin-parameters-paste-req', 'web-parameters-paste-req'),
 
@@ -369,14 +369,14 @@ def test_systemd_socket_configuration_file(host, config_file, expected_website_n
 

	
 
    config = host.file(config_file)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert "Socket for website %s" % expected_website_name in config.content
 
    assert "ListenStream=%s" % expected_socket_file_path in config.content
 
    assert "Socket for website %s" % expected_website_name in config.content_string
 
    assert "ListenStream=%s" % expected_socket_file_path in config.content_string
 

	
 

	
 
@pytest.mark.parametrize("socket_file_path", [
 
    '/run/wsgi/parameters-mandatory.sock',
 
    '/run/wsgi/parameters-optional.local.sock',
 
    '/run/wsgi/parameters-paste-req.sock',
 
@@ -410,13 +410,13 @@ def test_systemd_service_configuration_file(host, service_file, expected_fqdn):
 

	
 
    config = host.file(service_file)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert expected_fqdn in config.content
 
    assert expected_fqdn in config.content_string
 

	
 

	
 
@pytest.mark.parametrize("service_name", [
 
    'parameters-mandatory',
 
    'parameters-optional.local',
 
    'parameters-paste-req',
 
@@ -468,20 +468,20 @@ def test_nginx_tls_files(host, private_key_path, certificate_path, expected_priv
 

	
 
        tls_file = host.file(private_key_path)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open(expected_private_key, "r").read().rstrip()
 
        assert tls_file.content_string == open(expected_private_key, "r").read().rstrip()
 

	
 
        tls_file = host.file(certificate_path)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open(expected_certificate, "r").read().rstrip()
 
        assert tls_file.content_string == open(expected_certificate, "r").read().rstrip()
 

	
 

	
 
@pytest.mark.parametrize("config_file_path, expected_content", [
 
    ('/etc/check_certificate/parameters-mandatory_https.conf', '/etc/ssl/certs/parameters-mandatory_https.pem'),
 
    ('/etc/check_certificate/parameters-optional.local_https.conf', '/etc/ssl/certs/parameters-optional.local_https.pem'),
 
    ('/etc/check_certificate/parameters-paste-req_https.conf', '/etc/ssl/certs/parameters-paste-req_https.pem'),
 
@@ -494,13 +494,13 @@ def test_certificate_validity_check_configuration(host, config_file_path, expect
 

	
 
    config = host.file(config_file_path)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == expected_content
 
    assert config.content_string == expected_content
 

	
 

	
 
@pytest.mark.parametrize("config_file", [
 
    '/etc/nginx/sites-available/parameters-mandatory',
 
    '/etc/nginx/sites-available/parameters-optional.local',
 
    '/etc/nginx/sites-available/parameters-paste-req',
roles/wsgi_website/molecule/default/tests/test_parameters_paste_req.py
Show inline comments
 
@@ -21,20 +21,20 @@ def test_wsgi_requirements_upgrade_checks(host):
 

	
 
        config = host.file('/etc/pip_check_requirements_upgrades/parameters-paste-req/wsgi_requirements.in')
 
        assert config.is_file
 
        assert config.user == 'root'
 
        assert config.group == 'pipreqcheck'
 
        assert config.mode == 0o640
 
        assert config.content == "gunicorn\nfutures\n"
 
        assert config.content_string == "gunicorn\nfutures\n"
 

	
 
        config = host.file('/etc/pip_check_requirements_upgrades/parameters-paste-req/wsgi_requirements.txt')
 
        assert config.is_file
 
        assert config.user == 'root'
 
        assert config.group == 'pipreqcheck'
 
        assert config.mode == 0o640
 
        assert config.content == "futures==3.1.0\ngunicorn==19.7.0\n"
 
        assert config.content_string == "futures==3.1.0\ngunicorn==19.7.0\n"
 

	
 

	
 
def test_gunicorn_requirements_installation_file(host):
 
    """
 
    Tests if requirements file for installing Gunicorn has been deployed
 
    correctly.
 
@@ -44,13 +44,13 @@ def test_gunicorn_requirements_installation_file(host):
 

	
 
        requirements = host.file('/var/www/parameters-paste-req/.wsgi_requirements.txt')
 
        assert requirements.is_file
 
        assert requirements.user == 'admin-parameters-paste-req'
 
        assert requirements.group == 'web-parameters-paste-req'
 
        assert requirements.mode == 0o640
 
        assert requirements.content == "futures==3.1.0\ngunicorn==19.7.0\n"
 
        assert requirements.content_string == "futures==3.1.0\ngunicorn==19.7.0\n"
 

	
 

	
 
def test_index_page(host):
 
    """
 
    Tests if index page is served correctly. This covers:
 

	
roles/xmpp_server/molecule/default/tests/test_default.py
Show inline comments
 
@@ -40,13 +40,13 @@ def test_prosody_repository(host):
 
    expected_content = "deb http://packages.prosody.im/debian %s main\n" % distribution_release
 

	
 
    assert repository.is_file
 
    assert repository.user == 'root'
 
    assert repository.group == 'root'
 
    assert repository.mode == 0o644
 
    assert repository.content == expected_content
 
    assert repository.content_string == expected_content
 

	
 

	
 
def test_prosody_user(host):
 
    """
 
    Tests if Prosody user has been set-up correctly to access TLS material.
 
    """
 
@@ -76,14 +76,14 @@ def test_prosody_mod_auth_ldap(host):
 
    module = host.file('/usr/local/lib/prosody/modules/mod_auth_ldap.lua')
 

	
 
    assert module.is_file
 
    assert module.user == 'root'
 
    assert module.group == 'root'
 
    assert module.mode == 0o644
 
    assert 'module:provides("auth", provider);' in module.content
 
    assert 'mod_auth_ldap' in module.content
 
    assert 'module:provides("auth", provider);' in module.content_string
 
    assert 'mod_auth_ldap' in module.content_string
 

	
 

	
 
def test_prosody_configuration_file(host):
 
    """
 
    Tests if Prosody configuration file has correct permissions.
 
    """
roles/xmpp_server/molecule/default/tests/test_mandatory.py
Show inline comments
 
@@ -19,20 +19,20 @@ def test_prosody_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/%s.domain1_xmpp.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'prosody'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/%s.domain1_xmpp.key" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s.domain1_xmpp.key" % hostname, "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s.domain1_xmpp.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/%s.domain1_xmpp.pem" % hostname, "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/%s.domain1_xmpp.pem" % hostname, "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -42,13 +42,13 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/%s.domain1_xmpp.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s.domain1_xmpp.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s.domain1_xmpp.pem" % hostname
 

	
 

	
 
def test_prosody_configuration_file_content(host):
 
    """
 
    Tests if Prosody configuration file has correct content.
 
    """
 
@@ -56,26 +56,26 @@ def test_prosody_configuration_file_content(host):
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    with host.sudo():
 

	
 
        config = host.file('/etc/prosody/prosody.cfg.lua')
 

	
 
        assert "admins = { \"john.doe@domain1\",  }" in config.content
 
        assert "key = \"/etc/ssl/private/%s.domain1_xmpp.key\";" % hostname in config.content
 
        assert "certificate = \"/etc/ssl/certs/%s.domain1_xmpp.pem\";" % hostname in config.content
 
        assert "ldap_server = \"ldap-server\"" in config.content
 
        assert "ldap_rootdn = \"cn=prosody,ou=services,dc=local\"" in config.content
 
        assert "ldap_password = \"prosodypassword\"" in config.content
 
        assert "ldap_filter = \"(&(mail=$user@$host)(memberOf=cn=xmpp,ou=groups,dc=local))\"" in config.content
 
        assert "ldap_base = \"ou=people,dc=local\"" in config.content
 
        assert "admins = { \"john.doe@domain1\",  }" in config.content_string
 
        assert "key = \"/etc/ssl/private/%s.domain1_xmpp.key\";" % hostname in config.content_string
 
        assert "certificate = \"/etc/ssl/certs/%s.domain1_xmpp.pem\";" % hostname in config.content_string
 
        assert "ldap_server = \"ldap-server\"" in config.content_string
 
        assert "ldap_rootdn = \"cn=prosody,ou=services,dc=local\"" in config.content_string
 
        assert "ldap_password = \"prosodypassword\"" in config.content_string
 
        assert "ldap_filter = \"(&(mail=$user@$host)(memberOf=cn=xmpp,ou=groups,dc=local))\"" in config.content_string
 
        assert "ldap_base = \"ou=people,dc=local\"" in config.content_string
 

	
 
        assert """VirtualHost "domain1"
 
Component "conference.domain1" "muc"
 
  restrict_room_creation = "local"
 
Component "proxy.domain1" "proxy65"
 
  proxy65_acl = { "domain1" }""" in config.content
 
  proxy65_acl = { "domain1" }""" in config.content_string
 

	
 

	
 
def test_correct_prosody_package_installed(host):
 
    """
 
    Tests if correct Prosody package has been installed.
 
    """
roles/xmpp_server/molecule/default/tests/test_optional.py
Show inline comments
 
@@ -19,20 +19,20 @@ def test_prosody_tls_files(host):
 

	
 
        tls_file = host.file('/etc/ssl/private/%s_xmpp.key' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'prosody'
 
        assert tls_file.mode == 0o640
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_xmpp.key.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_xmpp.key.pem", "r").read().rstrip()
 

	
 
        tls_file = host.file('/etc/ssl/certs/%s_xmpp.pem' % hostname)
 
        assert tls_file.is_file
 
        assert tls_file.user == 'root'
 
        assert tls_file.group == 'root'
 
        assert tls_file.mode == 0o644
 
        assert tls_file.content == open("tests/data/x509/parameters-optional_xmpp.cert.pem", "r").read().rstrip()
 
        assert tls_file.content_string == open("tests/data/x509/parameters-optional_xmpp.cert.pem", "r").read().rstrip()
 

	
 

	
 
def test_certificate_validity_check_configuration(host):
 
    """
 
    Tests if certificate validity check configuration file has been deployed
 
    correctly.
 
@@ -42,13 +42,13 @@ def test_certificate_validity_check_configuration(host):
 

	
 
    config = host.file('/etc/check_certificate/%s_xmpp.conf' % hostname)
 
    assert config.is_file
 
    assert config.user == 'root'
 
    assert config.group == 'root'
 
    assert config.mode == 0o644
 
    assert config.content == "/etc/ssl/certs/%s_xmpp.pem" % hostname
 
    assert config.content_string == "/etc/ssl/certs/%s_xmpp.pem" % hostname
 

	
 

	
 
def test_prosody_configuration_file_content(host):
 
    """
 
    Tests if Prosody configuration file has correct content.
 
    """
 
@@ -56,32 +56,32 @@ def test_prosody_configuration_file_content(host):
 
    hostname = host.run('hostname').stdout.strip()
 

	
 
    with host.sudo():
 

	
 
        config = host.file('/etc/prosody/prosody.cfg.lua')
 

	
 
        assert "admins = { \"jane.doe@domain2\", \"mick.doe@domain3\",  }" in config.content
 
        assert "key = \"/etc/ssl/private/%s_xmpp.key\";" % hostname in config.content
 
        assert "certificate = \"/etc/ssl/certs/%s_xmpp.pem\";" % hostname in config.content
 
        assert "ldap_server = \"ldap-server\"" in config.content
 
        assert "ldap_rootdn = \"cn=prosody,ou=services,dc=local\"" in config.content
 
        assert "ldap_password = \"prosodypassword\"" in config.content
 
        assert "ldap_filter = \"(&(mail=$user@$host)(memberOf=cn=xmpp,ou=groups,dc=local))\"" in config.content
 
        assert "ldap_base = \"ou=people,dc=local\"" in config.content
 
        assert "admins = { \"jane.doe@domain2\", \"mick.doe@domain3\",  }" in config.content_string
 
        assert "key = \"/etc/ssl/private/%s_xmpp.key\";" % hostname in config.content_string
 
        assert "certificate = \"/etc/ssl/certs/%s_xmpp.pem\";" % hostname in config.content_string
 
        assert "ldap_server = \"ldap-server\"" in config.content_string
 
        assert "ldap_rootdn = \"cn=prosody,ou=services,dc=local\"" in config.content_string
 
        assert "ldap_password = \"prosodypassword\"" in config.content_string
 
        assert "ldap_filter = \"(&(mail=$user@$host)(memberOf=cn=xmpp,ou=groups,dc=local))\"" in config.content_string
 
        assert "ldap_base = \"ou=people,dc=local\"" in config.content_string
 

	
 
        assert """VirtualHost "domain2"
 
Component "conference.domain2" "muc"
 
  restrict_room_creation = "local"
 
Component "proxy.domain2" "proxy65"
 
  proxy65_acl = { "domain2" }""" in config.content
 
  proxy65_acl = { "domain2" }""" in config.content_string
 

	
 
        assert """VirtualHost "domain3"
 
Component "conference.domain3" "muc"
 
  restrict_room_creation = "local"
 
Component "proxy.domain3" "proxy65"
 
  proxy65_acl = { "domain3" }""" in config.content
 
  proxy65_acl = { "domain3" }""" in config.content_string
 

	
 

	
 
def test_correct_prosody_package_installed(host):
 
    """
 
    Tests if correct Prosody package has been installed.
 
    """
0 comments (0 inline, 0 general)