import re import time import testinfra.utils.ansible_runner testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( '.molecule/ansible_inventory.yml').get_hosts('all') def test_website_group(host): """ Tests if website group has been created correctly. """ group = host.group('web-parameters-paste-req') assert group.exists assert group.gid == 5002 def test_website_admin_user(host): """ Tests if website administrator user has been created correctly. """ user = host.user('admin-parameters-paste-req') assert user.exists assert user.uid == 5002 assert user.group == 'web-parameters-paste-req' assert user.groups == ['web-parameters-paste-req'] assert user.shell == '/bin/bash' assert user.home == '/var/www/parameters-paste-req' def test_website_admin_home(host): """ Tests if permissions on website admin home directory are correct. """ home = host.file('/var/www/parameters-paste-req') assert home.is_directory assert home.user == 'admin-parameters-paste-req' assert home.group == 'web-parameters-paste-req' assert home.mode == 0o750 def test_home_profile_directory(host): """ Tests if profile directory has been set-up correctly for the website administrator/application user. """ with host.sudo(): directory = host.file('/var/www/parameters-paste-req/.profile.d') assert directory.is_directory assert directory.user == 'admin-parameters-paste-req' assert directory.group == 'web-parameters-paste-req' assert directory.mode == 0o750 def test_virtualenv_profile_configuration(host): """ Tests if profile configuration file for auto-activation of virtual environment has been deployed correctly. """ with host.sudo(): config = host.file('/var/www/parameters-paste-req/.profile.d/virtualenv.sh') assert config.is_file assert config.user == 'root' assert config.group == 'web-parameters-paste-req' assert config.mode == 0o640 def test_profile_configuration(host): """ Tests if profile configuration is behaving correctly (setting appropriate vars via login shell). """ env = host.run("sudo -i -u admin-parameters-paste-req printenv VIRTUAL_ENV MY_ENV_VAR") assert env.stdout == "/var/www/parameters-paste-req/virtualenv" def test_website_application_user(host): """ Tests if website application user has been created correctly. """ user = host.user('web-parameters-paste-req') assert user.exists assert user.uid == 998 assert user.group == 'web-parameters-paste-req' assert user.groups == ['web-parameters-paste-req'] assert user.shell == '/bin/sh' assert user.home == '/var/www/parameters-paste-req' with host.sudo(): umask = host.run("su -l web-parameters-paste-req -c 'bash -c umask'") assert umask.stdout == '0007' def test_nginx_user(host): """ Tests if web server user has been added to website group. """ user = host.user('www-data') assert 'web-parameters-paste-req' in user.groups def test_forward_file(host): """ Tests if the forward file has correct permissions and content. """ with host.sudo(): config = host.file('/var/www/parameters-paste-req/.forward') assert config.is_file assert config.user == 'root' assert config.group == 'web-parameters-paste-req' assert config.mode == 0o640 assert config.content == "root" def test_mail_forwarding(host): """ Tests if mail forwarding works as expected. """ hostname = host.run('hostname').stdout send = host.run('swaks --suppress-data --to web-parameters-paste-req@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 host.sudo(): mail_log = host.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, hostname) assert re.search(pattern, mail_log.content) is not None def test_python_virtualenv_created(host): """ Tests if Python virtual environment has been created correctly. """ with host.sudo(): virtualenv = host.file("/var/www/parameters-paste-req/virtualenv") assert virtualenv.is_directory assert virtualenv.user == 'admin-parameters-paste-req' assert virtualenv.group == 'web-parameters-paste-req' assert virtualenv.mode == 0o2750 virtualenv_activate = host.file("/var/www/parameters-paste-req/virtualenv/bin/activate") assert virtualenv_activate.is_file assert virtualenv_activate.user == 'admin-parameters-paste-req' assert virtualenv_activate.group == 'web-parameters-paste-req' assert virtualenv_activate.mode == 0o644 def test_python_virtualenv_project_directory_config(host): """ Tests if project directory configuration within virtualenv is set-up correctly. """ with host.sudo(): project = host.file("/var/www/parameters-paste-req/virtualenv/.project") assert project.is_file assert project.user == 'admin-parameters-paste-req' assert project.group == 'web-parameters-paste-req' assert project.mode == 0o640 def test_python_virtualenv_wrapper_script(host): """ Tests if Python virtualenv wrapper script is functioning correctly. """ with host.sudo(): wrapper = host.file("/var/www/parameters-paste-req/virtualenv/bin/exec") assert wrapper.is_file assert wrapper.user == 'admin-parameters-paste-req' assert wrapper.group == 'web-parameters-paste-req' assert wrapper.mode == 0o750 command = host.run("sudo -u admin-parameters-paste-req /var/www/parameters-paste-req/virtualenv/bin/exec python -c 'import gunicorn'") assert command.rc == 0 def test_virtualenv_packages(host): """ Tests if correct packages are installed in virtualenv. """ packages = host.run("sudo -u admin-parameters-paste-req /var/www/parameters-paste-req/virtualenv/bin/pip freeze") assert sorted(packages.stdout.lower().split("\n")) == sorted("""Flask==0.12.2 Jinja2==2.9.6 MarkupSafe==1.0 Paste==2.0.3 PasteDeploy==1.5.2 PasteScript==2.0.2 Werkzeug==0.12.2 argparse==1.2.1 click==6.7 futures==3.1.0 gunicorn==19.7.0 itsdangerous==0.24 six==1.10.0 wsgiref==0.1.2""".lower().split("\n")) def test_wsgi_requirements_upgrade_checks(host): """ Tests if Python requirements files for upgrade checks are set-up correctly. """ with host.sudo(): directory = host.file('/etc/pip_check_requirements_upgrades/parameters-paste-req') assert directory.is_directory assert directory.user == 'root' assert directory.group == 'pipreqcheck' assert directory.mode == 0o750 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" 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" def test_gunicorn_requirements_installation_file(host): """ Tests if requirements file for installing Gunicorn has been deployed correctly. """ with host.sudo(): 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" def test_index_page(host): """ Tests if index page is served correctly. This covers: - Basic WSGI application operation. - Handling of environment variables. - Handling of proxy headers. """ page = host.run('curl -H "Accept-Encoding: plain" https://parameters-paste-req/') assert page.rc == 0 assert "This is the WSGI application at parameters-paste-req." in page.stdout assert "Requested URL was: https://parameters-paste-req/" in page.stdout assert "MY_ENV_VAR: None" in page.stdout assert "Accept-Encoding: plain" in page.stdout def test_static_file_serving(host): """ Tests serving of static files. """ page = host.run('curl https://parameters-paste-req/static/static_file.txt') assert page.rc == 0 assert "This is the WSGI application at parameters-paste-req." in page.stdout assert "Requested URL was: https://parameters-paste-req/static/static_file.txt" in page.stdout page = host.run('curl https://parameters-paste-req/media/media_file.txt') assert page.rc == 0 assert "This is the WSGI application at parameters-paste-req." in page.stdout assert "Requested URL was: https://parameters-paste-req/media/media_file.txt" in page.stdout