|
@@ -1,6 +1,8 @@
|
|
|
from __future__ import absolute_import
|
|
|
|
|
|
-import mock
|
|
|
+# TODO(dcramer): this heavily inspired by pytest-selenium, and it's possible
|
|
|
+# we could simply inherit from the plugin at this point
|
|
|
+
|
|
|
import os
|
|
|
import pytest
|
|
|
import signal
|
|
@@ -110,156 +112,23 @@ class Browser(object):
|
|
|
))
|
|
|
|
|
|
|
|
|
-def pytest_configure(config):
|
|
|
- # HACK: Only needed for testing!
|
|
|
- os.environ.setdefault('_SENTRY_SKIP_CONFIGURATION', '1')
|
|
|
-
|
|
|
- os.environ.setdefault('RECAPTCHA_TESTING', 'True')
|
|
|
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sentry.conf.server')
|
|
|
-
|
|
|
- if not settings.configured:
|
|
|
- # only configure the db if its not already done
|
|
|
- test_db = os.environ.get('DB', 'postgres')
|
|
|
- if test_db == 'mysql':
|
|
|
- settings.DATABASES['default'].update({
|
|
|
- 'ENGINE': 'django.db.backends.mysql',
|
|
|
- 'NAME': 'sentry',
|
|
|
- 'USER': 'root',
|
|
|
- 'HOST': '127.0.0.1',
|
|
|
- })
|
|
|
- # mysql requires running full migration all the time
|
|
|
- settings.SOUTH_TESTS_MIGRATE = True
|
|
|
- elif test_db == 'postgres':
|
|
|
- settings.DATABASES['default'].update({
|
|
|
- 'ENGINE': 'sentry.db.postgres',
|
|
|
- 'USER': 'postgres',
|
|
|
- 'NAME': 'sentry',
|
|
|
- })
|
|
|
- # postgres requires running full migration all the time
|
|
|
- # since it has to install stored functions which come from
|
|
|
- # an actual migration.
|
|
|
- settings.SOUTH_TESTS_MIGRATE = True
|
|
|
- elif test_db == 'sqlite':
|
|
|
- settings.DATABASES['default'].update({
|
|
|
- 'ENGINE': 'django.db.backends.sqlite3',
|
|
|
- 'NAME': ':memory:',
|
|
|
- })
|
|
|
- settings.SOUTH_TESTS_MIGRATE = os.environ.get('SENTRY_SOUTH_TESTS_MIGRATE', '1') == '1'
|
|
|
- else:
|
|
|
- raise RuntimeError('oops, wrong database: %r' % test_db)
|
|
|
-
|
|
|
- settings.TEMPLATE_DEBUG = True
|
|
|
-
|
|
|
- # Disable static compiling in tests
|
|
|
- settings.STATIC_BUNDLES = {}
|
|
|
-
|
|
|
- # override a few things with our test specifics
|
|
|
- settings.INSTALLED_APPS = tuple(settings.INSTALLED_APPS) + (
|
|
|
- 'tests',
|
|
|
- )
|
|
|
- # Need a predictable key for tests that involve checking signatures
|
|
|
- settings.SENTRY_PUBLIC = False
|
|
|
-
|
|
|
- if not settings.SENTRY_CACHE:
|
|
|
- settings.SENTRY_CACHE = 'sentry.cache.django.DjangoCache'
|
|
|
- settings.SENTRY_CACHE_OPTIONS = {}
|
|
|
-
|
|
|
- # This speeds up the tests considerably, pbkdf2 is by design, slow.
|
|
|
- settings.PASSWORD_HASHERS = [
|
|
|
- 'django.contrib.auth.hashers.MD5PasswordHasher',
|
|
|
- ]
|
|
|
-
|
|
|
- # Replace real sudo middleware with our mock sudo middleware
|
|
|
- # to assert that the user is always in sudo mode
|
|
|
- middleware = list(settings.MIDDLEWARE_CLASSES)
|
|
|
- sudo = middleware.index('sentry.middleware.sudo.SudoMiddleware')
|
|
|
- middleware[sudo] = 'sentry.testutils.middleware.SudoMiddleware'
|
|
|
- settings.MIDDLEWARE_CLASSES = tuple(middleware)
|
|
|
-
|
|
|
- # enable draft features
|
|
|
- settings.SENTRY_OPTIONS['mail.enable-replies'] = True
|
|
|
-
|
|
|
- settings.SENTRY_ALLOW_ORIGIN = '*'
|
|
|
-
|
|
|
- settings.SENTRY_TSDB = 'sentry.tsdb.inmemory.InMemoryTSDB'
|
|
|
- settings.SENTRY_TSDB_OPTIONS = {}
|
|
|
-
|
|
|
- settings.RECAPTCHA_PUBLIC_KEY = 'a' * 40
|
|
|
- settings.RECAPTCHA_PRIVATE_KEY = 'b' * 40
|
|
|
-
|
|
|
- settings.BROKER_BACKEND = 'memory'
|
|
|
- settings.BROKER_URL = None
|
|
|
- settings.CELERY_ALWAYS_EAGER = False
|
|
|
- settings.CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
|
|
|
-
|
|
|
- settings.DEBUG_VIEWS = True
|
|
|
-
|
|
|
- settings.DISABLE_RAVEN = True
|
|
|
-
|
|
|
- settings.CACHES = {
|
|
|
- 'default': {
|
|
|
- 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if not hasattr(settings, 'SENTRY_OPTIONS'):
|
|
|
- settings.SENTRY_OPTIONS = {}
|
|
|
-
|
|
|
- settings.SENTRY_OPTIONS.update({
|
|
|
- 'redis.clusters': {
|
|
|
- 'default': {
|
|
|
- 'hosts': {
|
|
|
- 0: {
|
|
|
- 'db': 9,
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- 'mail.backend': 'django.core.mail.backends.locmem.EmailBackend',
|
|
|
- 'system.url-prefix': 'http://testserver',
|
|
|
- })
|
|
|
+def pytest_addoption(parser):
|
|
|
+ parser.addini('selenium_driver',
|
|
|
+ help='selenium driver (phantomjs or firefox)')
|
|
|
|
|
|
- # django mail uses socket.getfqdn which doesn't play nice if our
|
|
|
- # networking isn't stable
|
|
|
- patcher = mock.patch('socket.getfqdn', return_value='localhost')
|
|
|
- patcher.start()
|
|
|
+ group = parser.getgroup('selenium', 'selenium')
|
|
|
+ group._addoption('--selenium-driver',
|
|
|
+ dest='selenium_driver',
|
|
|
+ help='selenium driver (phantomjs or firefox)')
|
|
|
|
|
|
- from sentry.runner.initializer import (
|
|
|
- bootstrap_options, configure_structlog, initialize_receivers, fix_south,
|
|
|
- bind_cache_to_option_store)
|
|
|
|
|
|
- bootstrap_options(settings)
|
|
|
- configure_structlog()
|
|
|
- fix_south(settings)
|
|
|
-
|
|
|
- bind_cache_to_option_store()
|
|
|
-
|
|
|
- initialize_receivers()
|
|
|
-
|
|
|
- from sentry.utils.redis import clusters
|
|
|
-
|
|
|
- with clusters.get('default').all() as client:
|
|
|
- client.flushdb()
|
|
|
-
|
|
|
- # force celery registration
|
|
|
- from sentry.celery import app # NOQA
|
|
|
-
|
|
|
- # disable DISALLOWED_IPS
|
|
|
- from sentry import http
|
|
|
- http.DISALLOWED_IPS = set()
|
|
|
-
|
|
|
-
|
|
|
-def pytest_runtest_teardown(item):
|
|
|
- from sentry.app import tsdb
|
|
|
- tsdb.flush()
|
|
|
-
|
|
|
- from sentry.utils.redis import clusters
|
|
|
-
|
|
|
- with clusters.get('default').all() as client:
|
|
|
- client.flushdb()
|
|
|
+def pytest_configure(config):
|
|
|
+ if hasattr(config, 'slaveinput'):
|
|
|
+ return # xdist slave
|
|
|
|
|
|
- from celery.task.control import discard_all
|
|
|
- discard_all()
|
|
|
+ config.option.selenium_driver = config.getoption('selenium_driver') or \
|
|
|
+ config.getini('selenium_driver') or \
|
|
|
+ os.getenv('SELENIUM_DRIVER')
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='session')
|
|
@@ -281,13 +150,19 @@ def percy(request):
|
|
|
|
|
|
@pytest.fixture(scope='function')
|
|
|
def browser(request, percy, live_server):
|
|
|
- phantomjs_path = os.path.join(
|
|
|
- settings.NODE_MODULES_ROOT,
|
|
|
- 'phantomjs-prebuilt',
|
|
|
- 'bin',
|
|
|
- 'phantomjs',
|
|
|
- )
|
|
|
- driver = webdriver.PhantomJS(executable_path=phantomjs_path)
|
|
|
+ driver_type = request.config.getoption('selenium_driver')
|
|
|
+ if driver_type == 'firefox':
|
|
|
+ driver = webdriver.Firefox()
|
|
|
+ elif driver_type == 'phantomjs':
|
|
|
+ phantomjs_path = os.path.join(
|
|
|
+ settings.NODE_MODULES_ROOT,
|
|
|
+ 'phantomjs-prebuilt',
|
|
|
+ 'bin',
|
|
|
+ 'phantomjs',
|
|
|
+ )
|
|
|
+ driver = webdriver.PhantomJS(executable_path=phantomjs_path)
|
|
|
+ else:
|
|
|
+ raise pytest.UsageError('--driver must be specified')
|
|
|
|
|
|
def fin():
|
|
|
# Teardown Selenium.
|
|
@@ -296,7 +171,8 @@ def browser(request, percy, live_server):
|
|
|
except Exception:
|
|
|
pass
|
|
|
# TODO: remove this when fixed in: https://github.com/seleniumhq/selenium/issues/767
|
|
|
- driver.service.process.send_signal(signal.SIGTERM)
|
|
|
+ if hasattr(driver, 'service'):
|
|
|
+ driver.service.process.send_signal(signal.SIGTERM)
|
|
|
driver.quit()
|
|
|
|
|
|
request.node._driver = driver
|
|
@@ -314,6 +190,13 @@ def browser(request, percy, live_server):
|
|
|
return driver
|
|
|
|
|
|
|
|
|
+@pytest.fixture(scope='session', autouse=True)
|
|
|
+def _environment(request):
|
|
|
+ config = request.config
|
|
|
+ # add environment details to the pytest-html plugin
|
|
|
+ config._environment.append(('Driver', config.option.selenium_driver))
|
|
|
+
|
|
|
+
|
|
|
@pytest.mark.tryfirst
|
|
|
def pytest_runtest_makereport(item, call, __multicall__):
|
|
|
report = __multicall__.execute()
|