import re import time import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( '.molecule/ansible_inventory').get_hosts('all') def test_website_group(Group): """ Tests if website group has been created correctly. """ group = Group('web-parameters-optional_local') assert group.exists assert group.gid == 5001 def test_website_admin_user(User): """ Tests if website administrator user has been created correctly. """ user = User('admin-parameters-optional_local') assert user.exists assert user.uid == 5000 assert user.group == 'web-parameters-optional_local' assert user.groups == ['web-parameters-optional_local'] assert user.shell == '/bin/bash' assert user.home == '/var/www/parameters-optional.local' def test_website_admin_home(File, Sudo): """ Tests if permissions on website admin home directory are correct. """ home = File('/var/www/parameters-optional.local') assert home.is_directory assert home.user == 'admin-parameters-optional_local' assert home.group == 'web-parameters-optional_local' assert home.mode == 0o750 def test_home_profile_directory(File, Sudo): """ Tests if profile directory has been set-up correctly for the website administrator/application user. """ with Sudo(): directory = File('/var/www/parameters-optional.local/.profile.d') assert directory.is_directory assert directory.user == 'admin-parameters-optional_local' assert directory.group == 'web-parameters-optional_local' assert directory.mode == 0o750 def test_virtualenv_profile_configuration(File, Sudo): """ Tests if profile configuration file for auto-activation of virtual environment has been deployed correctly. """ with Sudo(): config = File('/var/www/parameters-optional.local/.profile.d/virtualenv.sh') assert config.is_file assert config.user == 'root' assert config.group == 'web-parameters-optional_local' assert config.mode == 0o640 def test_environment_profile_configuration(File, Sudo): """ Tests if profile configuration file for setting-up environment variables has been deployed correctly. """ with Sudo(): config = File('/var/www/parameters-optional.local/.profile.d/environment.sh') assert config.is_file assert config.user == 'root' assert config.group == 'web-parameters-optional_local' assert config.mode == 0o640 assert config.content == "export MY_ENV_VAR='My environment variable'" def test_profile_configuration(Command): """ Tests if profile configuration is behaving correctly (setting appropriate vars via login shell). """ env = Command("sudo -i -u admin-parameters-optional_local printenv VIRTUAL_ENV MY_ENV_VAR") assert env.stdout == "/var/www/parameters-optional.local/virtualenv\nMy environment variable" def test_website_application_user(Command, Sudo, User): """ Tests if website application user has been created correctly. """ user = User('web-parameters-optional_local') assert user.exists assert user.uid == 5001 assert user.group == 'web-parameters-optional_local' assert user.groups == ['web-parameters-optional_local'] assert user.shell == '/bin/sh' assert user.home == '/var/www/parameters-optional.local' with Sudo(): umask = Command("su -l web-parameters-optional_local -c 'bash -c umask'") assert umask.stdout == '0007' def test_nginx_user(User): """ Tests if web server user has been added to website group. """ user = User('www-data') assert 'web-parameters-optional_local' in user.groups def test_forward_file(File, Sudo): """ Tests if the forward file has correct permissions and content. """ with Sudo(): config = 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" def test_mail_forwarding(Command, File, Sudo): """ Tests if mail forwarding works as expected. """ send = Command('swaks --suppress-data --to web-parameters-optional_local@localhost') assert send.rc == 0 message_id = re.search('Ok: queued as (.*)', send.stdout).group(1) # Sleep for a couple of seconds so the mail can get delivered. time.sleep(5) with Sudo(): mail_log = File('/var/log/mail.log') # First extract message ID of forwarded mail. pattern = "%s: to=.*status=sent \(forwarded as ([^)]*)\)" % message_id message_id = re.search(pattern, mail_log.content).group(1) # Now try to determine where the forward ended-up at. pattern = "%s: to=, orig_to=.*status=sent" % message_id assert re.search(pattern, mail_log.content) is not None def test_installed_packages(Package): """ Tests if additional packages are installed. """ assert Package('libmariadb-client-lgpl-dev-compat').is_installed assert Package('global').is_installed def test_mariadb_compat_symlink(File): """ Tests if compatibility symlink is set-up for mysql_config binary if libmariadb-client-lgpl-dev-compat is installed. """ link = File('/usr/bin/mysql_config') assert link.is_symlink assert link.linked_to == "/usr/bin/mariadb_config" def test_python_virtualenv_created(File, Sudo): """ Tests if Python virtual environment has been created correctly. """ with Sudo(): virtualenv = File("/var/www/parameters-optional.local/virtualenv") assert virtualenv.is_directory assert virtualenv.user == 'admin-parameters-optional_local' assert virtualenv.group == 'web-parameters-optional_local' assert virtualenv.mode == 0o2750 virtualenv_activate = File("/var/www/parameters-optional.local/virtualenv/bin/activate") assert virtualenv_activate.is_file assert virtualenv_activate.user == 'admin-parameters-optional_local' assert virtualenv_activate.group == 'web-parameters-optional_local' assert virtualenv_activate.mode == 0o644 def test_python_virtualenv_project_directory_config(File, Sudo): """ Tests if project directory configuration within virtualenv is set-up correctly. """ with Sudo(): project = File("/var/www/parameters-optional.local/virtualenv/.project") assert project.is_file assert project.user == 'admin-parameters-optional_local' assert project.group == 'web-parameters-optional_local' assert project.mode == 0o640 def test_python_virtualenv_wrapper_script(Command, File, Sudo): """ Tests if Python virtualenv wrapper script is functioning correctly. """ with Sudo(): wrapper = File("/var/www/parameters-optional.local/virtualenv/bin/exec") assert wrapper.is_file assert wrapper.user == 'admin-parameters-optional_local' assert wrapper.group == 'web-parameters-optional_local' assert wrapper.mode == 0o750 command = Command("sudo -u admin-parameters-optional_local /var/www/parameters-optional.local/virtualenv/bin/exec python -c 'import gunicorn'") assert command.rc == 0 def test_virtualenv_packages(Command): """ Tests if correct packages are installed in virtualenv. """ packages = Command("sudo -u admin-parameters-optional_local /var/www/parameters-optional.local/virtualenv/bin/pip freeze") assert sorted(packages.stdout.lower().split("\n")) == sorted("""Pygments==2.2.0 argparse==1.2.1 dnspython==1.15.0 docopt==0.6.2 futures==3.1.0 gunicorn==19.7.0 jedi==0.10.2 prompt-toolkit==1.0.15 ptpython==0.41 six==1.10.0 wcwidth==0.1.7 wsgiref==0.1.2""".lower().split("\n")) def test_wsgi_requirements_upgrade_checks(File, Sudo): """ Tests if Python requirements files for upgrade checks are set-up correctly. """ with Sudo(): directory = File('/etc/pip_check_requirements_upgrades/parameters-optional.local') assert not directory.exists def test_systemd_socket_configuration_file(File): """ Tests if systemd socket configuration file has been set-up correctly. """ config = File("/etc/systemd/system/parameters-optional.local.socket") assert config.is_file assert config.user == 'root' assert config.group == 'root' assert config.mode == 0o644 assert "Socket for website parameters-optional.local" in config.content assert "ListenStream=/run/wsgi/parameters-optional.local.sock" in config.content def test_systemd_socket(File, Socket, Sudo): """ Tests if systemd socket has correct permissions and is available. """ with Sudo(): socket_file = File("/run/wsgi/parameters-optional.local.sock") assert socket_file.is_socket assert socket_file.user == 'www-data' assert socket_file.group == 'www-data' assert socket_file.mode == 0o660 socket = Socket("unix:///run/wsgi/parameters-optional.local.sock") assert socket.is_listening def test_systemd_service_configuration_file(File): """ Tests if systemd service configuration file has been set-up correctly. """ config = File("/etc/systemd/system/parameters-optional.local.service") assert config.is_file assert config.user == 'root' assert config.group == 'root' assert config.mode == 0o644 assert "parameters-optional.local" in config.content def test_systemd_service(Service): """ Tests if the systemd service is enabled at boot and running. """ service = Service('parameters-optional.local') assert service.is_enabled assert service.is_running def test_static_file_directory(File, Sudo): """ Tests if directory for serving static files has been created correctly. """ with Sudo(): directory = File('/var/www/parameters-optional.local/htdocs') assert directory.is_directory assert directory.user == 'admin-parameters-optional_local' assert directory.group == 'web-parameters-optional_local' assert directory.mode == 0o2750 def test_nginx_tls_files(File, Sudo): """ Tests if TLS private key and certificate have been deployed correctly. """ with Sudo(): tls_file = 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() tls_file = 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() def test_certificate_validity_check_configuration(File): """ Tests if certificate validity check configuration file has been deployed correctly. """ config = 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" def test_vhost_file(File): """ Tests permissions of vhost configuration file. """ config = File('/etc/nginx/sites-available/parameters-optional.local') assert config.is_file assert config.user == 'root' assert config.group == 'root' assert config.mode == 0o640 def test_website_enabled(File): """ Tests if website has been enabled. """ config = File('/etc/nginx/sites-enabled/parameters-optional.local') assert config.is_symlink assert config.linked_to == '/etc/nginx/sites-available/parameters-optional.local' def test_https_enforcement(Command): """ Tests if HTTPS is (not) being enforced. """ https_enforcement = Command('curl -I http://parameters-optional.local/') assert https_enforcement.rc == 0 assert 'HTTP/1.1 200 OK' in https_enforcement.stdout assert 'HTTP/1.1 301 Moved Permanently' not in https_enforcement.stdout assert 'Location: https://parameters-optional/' not in https_enforcement.stdout https_enforcement = Command('curl -I https://parameters-optional.local/') assert https_enforcement.rc == 0 assert 'Strict-Transport-Security' not in https_enforcement.stdout def test_index_page(Command): """ Tests if index page is served correctly. This covers: - Basic WSGI application operation. - Handling of environment variables. - Handling of proxy headers. """ page = Command('curl -H "Accept-Encoding: plain" https://parameters-optional.local/') assert page.rc == 0 assert "This is the WSGI application at parameters-optional.local." in page.stdout assert "Requested URL was: https://parameters-optional.local/" in page.stdout assert "MY_ENV_VAR: My environment variable" in page.stdout assert "Accept-Encoding: None" in page.stdout def test_static_file_serving(Command): """ Tests serving of static files. """ page = Command('curl https://parameters-optional.local/static/static_file.txt') assert page.rc == 0 assert page.stdout == open("tests/data/static_file.txt", 'r').read().rstrip() page = Command('curl https://parameters-optional.local/media/media_file.txt') assert page.rc == 0 assert page.stdout == open("tests/data/media_file.txt", 'r').read().rstrip() def test_additional_nginx_config(Command): """ Tests if additional Nginx configuration directives are properly deployed. """ page = Command('curl https://parameters-optional.local/static/missing_static_file.txt') assert page.rc == 0 assert "Requested URL was: https://parameters-optional.local/my/own/error/page" def test_environment_indicator(Command): """ Tests if environment indicator is applied correctly. """ page = Command('curl https://parameters-optional.local/') assert page.rc == 0 assert "
parameters-optional
" in page.stdout def test_nginx_rewrite_config(Command): """ Tests if Nginx rewrite configuration is deployed correctly. """ page = Command('curl https://parameters-optional.local/rewrite1/some/path') assert page.rc == 0 assert "Requested URL was: https://parameters-optional.local/rewritten1/" in page.stdout page = Command('curl https://parameters-optional.local/rewrite2/some/other/path') assert page.rc == 0 assert "Requested URL was: https://parameters-optional.local/rewritten2/some/other/path" in page.stdout