From patchwork Tue Apr 24 21:05:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephen Finucane X-Patchwork-Id: 903875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40Vwsg52DMz9s06 for ; Wed, 25 Apr 2018 07:08:23 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=that.guru Authentication-Results: ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=that.guru header.i=@that.guru header.b="ns6AOB+G"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40Vwsg2ZrzzF24G for ; Wed, 25 Apr 2018 07:08:23 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=that.guru Authentication-Results: lists.ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=that.guru header.i=@that.guru header.b="ns6AOB+G"; dkim-atps=neutral X-Original-To: patchwork@lists.ozlabs.org Delivered-To: patchwork@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=none (mailfrom) smtp.mailfrom=that.guru (client-ip=23.83.222.38; helo=common.ash.relay.mailchannels.net; envelope-from=stephen@that.guru; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=that.guru Authentication-Results: lists.ozlabs.org; dkim=fail reason="key not found in DNS" (0-bit key; unprotected) header.d=that.guru header.i=@that.guru header.b="ns6AOB+G"; dkim-atps=neutral Received: from common.ash.relay.mailchannels.net (common.ash.relay.mailchannels.net [23.83.222.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40Vwq645Y7zF24D for ; Wed, 25 Apr 2018 07:06:09 +1000 (AEST) X-Sender-Id: 5xi41l16bi|x-authuser|stephen@that.guru Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 86541281449; Tue, 24 Apr 2018 21:05:59 +0000 (UTC) Received: from one.mxroute.com (unknown [100.96.15.28]) (Authenticated sender: 5xi41l16bi) by relay.mailchannels.net (Postfix) with ESMTPA id F0838281493; Tue, 24 Apr 2018 21:05:58 +0000 (UTC) X-Sender-Id: 5xi41l16bi|x-authuser|stephen@that.guru Received: from one.mxroute.com (one-outgoing.mxroute.com [172.19.51.240]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.14.1); Tue, 24 Apr 2018 21:05:59 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: 5xi41l16bi|x-authuser|stephen@that.guru X-MailChannels-Auth-Id: 5xi41l16bi X-Army-Irritate: 63564df90fcf3688_1524603959421_2860656692 X-MC-Loop-Signature: 1524603959421:3625954119 X-MC-Ingress-Time: 1524603959420 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=that.guru; s=default; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=hE0SvPqRtlokoHV2jFPavpCQTm25+69iAXphy1A9M3I=; b=ns6AOB+Gjau5NSOUDD5nC9L76b zOygSaLrzlNqrJNF6thhBOQaB/FcBTOk01skVED8dW5gXaOtpMomQYFfWMSO6rCiJ8b3ZH7s49R6m dPJVRRD4myjsCfWaobbLxb+9SqgHdkuILlZSGqW4Wfu7s5Dv221BwsYyON42HeP70f+bS3KGAMmjm JpdKQX79DM3A76aAVS0AEu/K+HGyd/b86Le2TKIZfuSyAaZUfiulteoW4PGDzITmYRuAzArpuvUaa bQp18zCzIEkx+iTfY3wXEvVVdvqNfdNO8P3cmQ2dmFvUf6RGygmYLnCphYD5BUiyrhZUka0MaM5+J VA/VVqRw==; From: Stephen Finucane To: patchwork@lists.ozlabs.org Subject: [PATCH 2/6] tests: Remove Selenium tests Date: Tue, 24 Apr 2018 22:05:37 +0100 Message-Id: <20180424210541.6060-3-stephen@that.guru> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180424210541.6060-1-stephen@that.guru> References: <20180424210541.6060-1-stephen@that.guru> X-AuthUser: stephen@that.guru X-BeenThere: patchwork@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Patchwork development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: patchwork-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Patchwork" These were added quite some time ago in order to allow some level of UI testing. However, I've personally never used them, they're not used by the CI, and no one has shown any desire in extending them in their time here. It is time to bid these tests adieu. Removing these allows us to remove a whole load of wiring that existed just to enable these. Some of this, like the '--quick-tox' option for the Dockerfile, is retained so we don't need to use different commands for various versions of Patchwork, but the majority is just stripped out. Signed-off-by: Stephen Finucane Cc: Daniel Axtens --- .travis.yml | 1 - docs/development/installation.rst | 46 ++------- patchwork/tests/browser.py | 176 ----------------------------------- patchwork/tests/test_user_browser.py | 41 -------- tools/docker/Dockerfile | 9 +- tools/docker/entrypoint.sh | 14 +-- tox.ini | 3 +- 7 files changed, 17 insertions(+), 273 deletions(-) delete mode 100644 patchwork/tests/browser.py delete mode 100644 patchwork/tests/test_user_browser.py diff --git a/.travis.yml b/.travis.yml index 7e871da8..6cb983f3 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 a1bee1d1..f2ed0f2d 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 1939defb..00000000 --- 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 ad4143fc..00000000 --- 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 31b2aaee..68a62e15 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 4a899781..997b8763 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 a7c6dfc6..a64d9587 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}'