aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--docs/development/installation.rst46
-rw-r--r--patchwork/tests/browser.py176
-rw-r--r--patchwork/tests/test_user_browser.py41
-rw-r--r--tools/docker/Dockerfile9
-rwxr-xr-xtools/docker/entrypoint.sh14
-rw-r--r--tox.ini3
7 files changed, 17 insertions, 273 deletions
diff --git a/.travis.yml b/.travis.yml
index 7e871da..6cb983f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,7 +22,6 @@ env:
- PW_TEST_DB_TYPE=mysql PW_TEST_DB_USER=root
global:
- PW_TEST_DB_PASS=""
- - PW_SKIP_BROWSER_TESTS=yes
before_script:
- mysql -e 'create database patchwork character set utf8;'
diff --git a/docs/development/installation.rst b/docs/development/installation.rst
index a1bee1d..f2ed0f2 100644
--- a/docs/development/installation.rst
+++ b/docs/development/installation.rst
@@ -41,7 +41,8 @@ To run a shell within this environment, run:
$ docker-compose run --rm web --shell
-To run `django-manage` commands, such as `createsuperuser` or `migrate`, run:
+To run ``django-manage`` commands, such as ``createsuperuser`` or ``migrate``,
+run:
.. code-block:: shell
@@ -53,48 +54,17 @@ To access the SQL command-line client, run:
$ docker-compose run --rm web python manage.py dbshell
-To run unit tests, excluding Selenium UI interaction tests, using only the
-package versions installed during container initialization, run:
-
-.. code-block:: shell
-
- $ docker-compose run --rm web --quick-test
-
-To run the same against all supported versions of Django (via tox), run:
-
-.. code-block:: shell
-
- $ docker-compose run --rm web --quick-tox
-
-To run specific tox targets or tests, pass arguments to the above:
+To run unit tests against the system Python packages, run:
.. code-block:: shell
- $ docker-compose run --rm web --quick-tox -e py27-django18 \
- patchwork.tests.test_bundles
+ $ docker-compose run --rm web python manage.py test
-To run all tests, including Selenium UI interaction tests, using only the
-package versions installed container initialization, run:
-
-.. code-block:: shell
-
- $ docker-compose run --rm web --test
-
-To run the same against all supported versions of Django (via tox), run:
-
-.. code-block:: shell
-
- $ docker-compose run --rm web --tox
-
-To run all tests, including Selenium UI interaction tests in non-headless mode,
-run:
+To run unit tests for multiple versions using ``tox``, run:
.. code-block:: shell
- $ docker run -it --rm -v (pwd):/home/patchwork/patchwork/ \
- --link patchwork_db_1:db -p 8000:8000 \
- -v /tmp/.X11-unix:/tmp/.X11-unix \
- -e PW_TEST_DB_HOST=db -e DISPLAY patchwork_web bash
+ $ docker-compose run --rm web tox
To reset the database before any of these commands, add ``--reset`` to the
command line after ``web`` and before any other arguments. Conversely, to
@@ -102,8 +72,8 @@ backup the database at any stage, run:
.. code-block:: shell
- $ docker exec DATABASECONTAINER /usr/bin/mysqldump -u DATABASEUSER \
- --password=DATABASEPASSWORD DATABASE > backup.sql
+ $ docker exec DATABASECONTAINER /usr/bin/mysqldump -u DATABASEUSER \
+ --password=DATABASEPASSWORD DATABASE > backup.sql
where ``DATABASECONTAINER`` is found by ``docker ps -a`` and the other settings
are the same as those defined in ``patchwork/settings/dev.py``. To restore this
diff --git a/patchwork/tests/browser.py b/patchwork/tests/browser.py
deleted file mode 100644
index 1939def..0000000
--- a/patchwork/tests/browser.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Patchwork - automated patch tracking system
-# Copyright (C) 2015 Intel Corporation
-#
-# This file is part of the Patchwork package.
-#
-# Patchwork is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# Patchwork is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Patchwork; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-import errno
-import os
-import time
-
-from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-from selenium.common.exceptions import (
- NoSuchElementException, StaleElementReferenceException,
- TimeoutException)
-from selenium import webdriver
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.webdriver.chrome.options import Options
-
-
-class Wait(WebDriverWait):
-
- """Subclass of WebDriverWait.
-
- Includes a predetermined timeout and poll frequency. Also deals with a
- wider variety of exceptions.
- """
- _TIMEOUT = 10
- _POLL_FREQUENCY = 0.5
-
- def __init__(self, driver):
- super(Wait, self).__init__(driver, self._TIMEOUT, self._POLL_FREQUENCY)
-
- def until(self, method, message=''):
- """Call method with driver until it returns True."""
- end_time = time.time() + self._timeout
-
- while True:
- try:
- value = method(self._driver)
- if value:
- return value
- except NoSuchElementException:
- pass
- except StaleElementReferenceException:
- pass
-
- time.sleep(self._poll)
- if(time.time() > end_time):
- break
-
- raise TimeoutException(message)
-
- def until_not(self, method, message=''):
- """Call method with driver until it returns True."""
- end_time = time.time() + self._timeout
- while(True):
- try:
- value = method(self._driver)
- if not value:
- return value
- except NoSuchElementException:
- return True
- except StaleElementReferenceException:
- pass
-
- time.sleep(self._poll)
- if(time.time() > end_time):
- break
-
- raise TimeoutException(message)
-
-
-def mkdir(path):
- try:
- os.makedirs(path)
- except OSError as error:
- if error.errno == errno.EEXIST and os.path.isdir(path):
- pass
- else:
- raise
-
-
-class SeleniumTestCase(StaticLiveServerTestCase):
- # TODO(stephenfin): This should handle non-UNIX paths
- _SCREENSHOT_DIR = os.path.dirname(__file__) + '/../../selenium_screenshots'
-
- def setUp(self):
- self.skip = os.getenv('PW_SKIP_BROWSER_TESTS', None)
- if self.skip:
- self.skipTest('Disabled by environment variable')
-
- super(SeleniumTestCase, self).setUp()
-
- self.browser = os.getenv('SELENIUM_BROWSER', 'chrome')
- if self.browser == 'firefox':
- self.selenium = webdriver.Firefox()
- if self.browser == 'chrome':
- chrome_options = Options()
- # chrome's aggressive sandboxing doesn't work well with
- # docker so disable the sandbox. We're only looking at our
- # own site so it should be safe enough
- chrome_options.add_argument("--no-sandbox")
- self.selenium = webdriver.Chrome(
- service_args=['--verbose', '--log-path=selenium.log'],
- chrome_options=chrome_options
- )
-
- mkdir(self._SCREENSHOT_DIR)
- self._screenshot_number = 1
-
- def tearDown(self):
- self.selenium.quit()
- super(SeleniumTestCase, self).tearDown()
-
- def screenshot(self):
- name = '%s_%d.png' % (self._testMethodName, self._screenshot_number)
- path = os.path.join(self._SCREENSHOT_DIR, name)
- self.selenium.get_screenshot_as_file(path)
- self._screenshot_number += 1
-
- def get(self, relative_url):
- self.selenium.get('%s%s' % (self.live_server_url, relative_url))
- self.screenshot()
-
- def find(self, selector):
- return self.selenium.find_element_by_css_selector(selector)
-
- def focused_element(self):
- return self.selenium.switch_to.active_element
-
- def wait_until_present(self, name):
- def is_present(driver):
- return driver.find_element_by_name(name)
- msg = "An element named '%s' should be on the page" % name
- element = Wait(self.selenium).until(is_present, msg)
- self.screenshot()
- return element
-
- def wait_until_visible(self, selector):
- def is_visible(driver):
- return self.find(selector).is_displayed()
- msg = "The element matching '%s' should be visible" % selector
- Wait(self.selenium).until(is_visible, msg)
- self.screenshot()
- return self.find(selector)
-
- def wait_until_focused(self, selector):
- def is_focused(driver):
- return self.find(selector) == self.focused_element()
- msg = "The element matching '%s' should be focused" % selector
- Wait(self.selenium).until(is_focused, msg)
- self.screenshot()
- return self.find(selector)
-
- def enter_text(self, name, value):
- field = self.wait_until_present(name)
- field.send_keys(value)
- return field
-
- def click(self, selector):
- element = self.wait_until_visible(selector)
- element.click()
- return element
diff --git a/patchwork/tests/test_user_browser.py b/patchwork/tests/test_user_browser.py
deleted file mode 100644
index ad4143f..0000000
--- a/patchwork/tests/test_user_browser.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Patchwork - automated patch tracking system
-# Copyright (C) 2015 Intel Corporation
-#
-# This file is part of the Patchwork package.
-#
-# Patchwork is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# Patchwork is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Patchwork; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-from patchwork.compat import reverse
-from patchwork.tests.browser import SeleniumTestCase
-from patchwork.tests.utils import create_user
-
-
-class LoginTestCase(SeleniumTestCase):
-
- def setUp(self):
- super(LoginTestCase, self).setUp()
- self.user = create_user()
-
- def test_default_focus(self):
- self.get(reverse('auth_login'))
- self.wait_until_focused('#id_username')
-
- def test_login(self):
- self.get(reverse('auth_login'))
- self.enter_text('username', self.user.username)
- self.enter_text('password', self.user.username)
- self.click('input[value="Login"]')
- dropdown = self.wait_until_visible('a.dropdown-toggle strong')
- self.assertEqual(dropdown.text, self.user.username)
diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile
index 31b2aae..68a62e1 100644
--- a/tools/docker/Dockerfile
+++ b/tools/docker/Dockerfile
@@ -13,8 +13,8 @@ ENV DEBIAN_FRONTEND noninteractive
ENV PYTHONUNBUFFERED 1
# System
-# trusty and findutils is for python3.4
-# xenial is for python3.5
+# trusty and findutils is for python3.4; xenial is for python3.5
+# TODO(stephenfin): Are curl, unzip required?
COPY tools/docker/trusty.list /etc/apt/sources.list.d/trusty.list
COPY tools/docker/xenial.list /etc/apt/sources.list.d/xenial.list
RUN apt-get update -qq && \
@@ -22,9 +22,8 @@ RUN apt-get update -qq && \
python-dev python-pip python-setuptools python-wheel \
python3.5-dev python3-pip python3-setuptools python3-wheel \
python3.4-dev findutils=4.4.2-7 python3.6-dev \
- libmysqlclient-dev mysql-client curl unzip xvfb chromium-chromedriver \
- chromium-browser build-essential git postgresql-client tzdata && \
- ln -s /usr/lib/chromium-browser/chromedriver /usr/bin/
+ libmysqlclient-dev mysql-client curl unzip build-essential \
+ git postgresql-client tzdata
# User
RUN useradd --uid=$UID --create-home patchwork
diff --git a/tools/docker/entrypoint.sh b/tools/docker/entrypoint.sh
index 4a89978..997b876 100755
--- a/tools/docker/entrypoint.sh
+++ b/tools/docker/entrypoint.sh
@@ -106,26 +106,20 @@ elif ! test_database; then
reset_data
fi
+# TODO(stephenfin): Deprecated the --test, --tox, --quick-test and --quick-tox
+# flags in a future release
if [ $# -eq 0 ]; then
# we probably ran with --reset and nothing else
# just exit cleanly
exit 0
elif [ "$1" == "--shell" ]; then
exec bash
-elif [ "$1" == "--quick-test" ]; then
+elif [ "$1" == "--test" ] || [ "$1" == "--quick-test" ]; then
shift
- export PW_SKIP_BROWSER_TESTS=yes
python3 manage.py test $@
-elif [ "$1" == "--test" ]; then
+elif [ "$1" == "--tox" ] || [ "$1" == "--quick-tox" ]; then
shift
- xvfb-run --server-args='-screen 0, 1024x768x16' python3 manage.py test $@
-elif [ "$1" == "--quick-tox" ]; then
- shift
- export PW_SKIP_BROWSER_TESTS=yes
tox $@
-elif [ "$1" == "--tox" ]; then
- shift
- xvfb-run --server-args='-screen 0, 1024x768x16' tox $@
else # run whatever CMD is set to
$@
fi
diff --git a/tox.ini b/tox.ini
index a7c6dfc..a64d958 100644
--- a/tox.ini
+++ b/tox.ini
@@ -20,8 +20,7 @@ setenv =
passenv =
http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY
PW_TEST_DB_TYPE PW_TEST_DB_USER PW_TEST_DB_PASS PW_TEST_DB_HOST
- PW_TEST_DB_PORT DISPLAY SELENIUM_BROWSER PW_SKIP_BROWSER_TESTS
- DISPLAY HOME XAUTHORITY
+ PW_TEST_DB_PORT
commands =
python -Wonce {toxinidir}/manage.py test --noinput '{posargs:patchwork}'