Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for py2 and remove testtools #279

Merged
merged 2 commits into from
Apr 30, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 4 additions & 25 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,46 +1,25 @@
sudo: false
dist: xenial
language: python
services:
# For Gnocchi
- docker
install:
- |
if [ "$TOXENV" == "gnocchi" ]; then
docker pull gnocchixyz/ci-tools:latest
else
pip install tox
fi
- pip install tox
script:
- |
case "$TOXENV" in
gnocchi)
docker run -v ~/.cache/pip:/home/tester/.cache/pip -v $(pwd):/home/tester/src gnocchixyz/ci-tools:latest tox -e ${TOXENV}
;;
*)
tox
;;
esac
- tox
matrix:
include:
- env: TOXENV=py27
- env: TOXENV=pep8
- env: TOXENV=py27-pytest
- env: TOXENV=gnocchi
- python: 3.7
env: TOXENV=placement
- python: pypy
env: TOXENV=pypy
dist: trusty
- python: pypy3
env: TOXENV=pypy3
dist: trusty
- python: 3.5
env: TOXENV=py35
- python: 3.6
env: TOXENV=py36
- python: 3.7
env: TOXENV=py37
- python: 3.8
env: TOXENV=py38
- python: 3.5
env: TOXENV=py35-pytest
- python: 3.6
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ looks like this::
See the docs_ for more details on the many features and formats for
setting request headers and bodies and evaluating responses.

Gabbi is tested with Python 2.7, 3.5, 3.6, 3.7 and pypy.
Gabbi is tested with Python 3.5, 3.6, 3.7 and pypy3.

Tests can be run using `unittest`_ style test runners, `pytest`_
or from the command line with a `gabbi-run`_ script.
@@ -84,7 +84,7 @@ Gabbi is set up to be developed and tested using `tox`_ (installed via
are in the directories ``gabbi/tests/gabbits_*`` and loaded by the file
``gabbi/test_*.py``), you call ``tox``::

tox -epep8,py27,py34
tox -epep8,py37

If you have the dependencies installed (or a warmed up
virtualenv) you can run the tests by hand and exit on the first
@@ -95,7 +95,7 @@ failure::
Testing can be limited to individual modules by specifying them
after the tox invocation::

tox -epep8,py27,py34 -- test_driver test_handlers
tox -epep8,py37 -- test_driver test_handlers

If you wish to avoid running tests that connect to internet hosts,
set ``GABBI_SKIP_NETWORK`` to ``True``.
10 changes: 0 additions & 10 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
@@ -111,8 +111,6 @@ As a Python package, gabbi is typically installed via pip::

pip install gabbi

(both Python 2 and Python 3 are supported)

You might want to create a virtual environment; an isolated context for
Python packages, keeping gabbi cleany separated from the rest of your
system.
@@ -124,14 +122,6 @@ Python 3 comes with a built-in tool to create virtual environments::

pip install gabbi

Alternatively, with Python 2 we can use `virtualenv`_::

pip install virtualenv
virtualenv venv
. venv/bin/activate

pip install gabbi

This way we can later use ``deactivate`` and safely remove the ``venv``
directory, thus erasing any trace of gabbi from the system.

11 changes: 11 additions & 0 deletions docs/source/release.rst
Original file line number Diff line number Diff line change
@@ -5,6 +5,17 @@ These are informal release notes for gabbi since version 1.0.0,
highlighting major features and changes. For more detail see
the `commit logs`_ on GitHub.

2.0.0
-----

* Drop support for Python 2. If you need Python 2 support, use an older version.
* Stop using ``testtools`` and ``fixtures``. These two modules present several
difficulties and their maintenance situation suggests those difficulties
will not be resolved. Since Python 2 support is being removed, the need for
the modules can be removed as well without losing functionality. "Inner
fixtures" that use the ``fixtures.Fixture`` interface should continue to
work.

1.49.0
------

2 changes: 1 addition & 1 deletion gabbi/__init__.py
Original file line number Diff line number Diff line change
@@ -12,4 +12,4 @@
# under the License.
"""See gabbi.driver and gabbbi.case."""

__version__ = '1.49.0'
__version__ = '2.0.0'
27 changes: 14 additions & 13 deletions gabbi/case.py
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""A single HTTP request represented as a subclass of ``testtools.TestCase``
"""A single HTTP request represented as a subclass of ``unittest.TestCase``

The test case encapsulates the request headers and body and expected
response headers and body. When the test is run an HTTP request is
@@ -24,13 +24,12 @@
import re
import sys
import time
import unittest
from unittest import result as unitresult

import six
from six.moves import http_cookies
from six.moves.urllib import parse as urlparse
import testtools
from testtools import testcase
import wsgi_intercept

from gabbi import __version__
@@ -82,15 +81,9 @@ def wrapper(self):
try:
func(self)
except Exception:
if hasattr(testcase, '_ExpectedFailure'):
raise testcase._ExpectedFailure(sys.exc_info())
else:
self._addExpectedFailure(self.result, sys.exc_info())
self._addExpectedFailure(self.result, sys.exc_info())
else:
if hasattr(self, '_addUnexpectedSuccess'):
self._addUnexpectedSuccess(self.result)
else:
raise testcase._UnexpectedSuccess
self._addUnexpectedSuccess(self.result)
else:
func(self)
return wrapper
@@ -101,7 +94,7 @@ def _is_complex_type(data):
return isinstance(data, list) or isinstance(data, dict)


class HTTPTestCase(testtools.TestCase):
class HTTPTestCase(unittest.TestCase):
"""Encapsulate a single HTTP request as a TestCase.

If the test is a member of a sequence of requests, ensure that prior
@@ -114,15 +107,23 @@ class HTTPTestCase(testtools.TestCase):
base_test = copy.copy(BASE_TEST)

def setUp(self):
self._fixture_cleanups = []
if not self.has_run:
super(HTTPTestCase, self).setUp()
for fixture in self.inner_fixtures:
self.useFixture(fixture())
f = fixture()
f.setUp()
# add fixture to front of list so we unwind them FILO in
# tearDown
self._fixture_cleanups.insert(0, f)

def tearDown(self):
if not self.has_run:
super(HTTPTestCase, self).tearDown()
self.has_run = True
# Clean up an inner fixtures.
for fixture in self._fixture_cleanups:
fixture.cleanUp()

def run(self, result=None):
"""Store the current result handler on this test."""
3 changes: 2 additions & 1 deletion gabbi/driver.py
Original file line number Diff line number Diff line change
@@ -65,6 +65,8 @@ def build_tests(path, loader, host=None, port=8001, intercept=None,
:param require_ssl: If ``True``, make all tests default to using SSL.
:param inner_fixtures: A list of ``Fixtures`` to use with each
individual test request.
:type inner_fixtures: List of classes with setUp and cleanUp methods to
be used as fixtures.
:param verbose: If ``True`` or ``'all'``, make tests verbose by default
``'headers'`` and ``'body'`` are also accepted.
:param use_prior_test: If ``True``, uses prior test to create ordered
@@ -74,7 +76,6 @@ def build_tests(path, loader, host=None, port=8001, intercept=None,
:param cert_validate: If ``False`` ssl server certificate will be ignored,
further it will not be validated if provided
(set cert_reqs=CERT_NONE to the Http object)
:type inner_fixtures: List of fixtures.Fixture classes.
:rtype: TestSuite containing multiple TestSuites (one for each YAML file).
"""

2 changes: 1 addition & 1 deletion gabbi/suite.py
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ def run(self, result, debug=False):
# the entire suite is skipped, and the result stream told
# we're done. If there are no tests (an empty suite) the
# exception is re-raised.
except Exception as exc:
except Exception:
if self._tests:
result.addError(self._tests[0], sys.exc_info())
for test in self._tests:
3 changes: 2 additions & 1 deletion gabbi/suitemaker.py
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@

import copy
import functools
import unittest

from gabbi import case
from gabbi.exception import GabbiFormatError
@@ -90,7 +91,7 @@ def make_one_test(self, test_dict, prior_test):
test_method_name = 'test_request'
test_method = getattr(case.HTTPTestCase, test_method_name)

@case.testcase.skipIf(self.host == '', 'No host configured')
@unittest.skipIf(self.host == '', 'No host configured')
@functools.wraps(test_method)
def do_test(*args, **kwargs):
return test_method(*args, **kwargs)
8 changes: 2 additions & 6 deletions gabbi/tests/test_inner_fixture.py
Original file line number Diff line number Diff line change
@@ -18,8 +18,6 @@
import os
import sys

import fixtures

from gabbi import driver
# TODO(cdent): test_pytest allows pytest to see the tests this module
# produces. Without it, the generator will not run. It is a todo because
@@ -45,16 +43,14 @@ def stop_fixture(self):
assert COUNT_OUTER == 1


class InnerFixture(fixtures.Fixture):
class InnerFixture(object):
"""Test that setUp is called 3 times."""

def setUp(self):
super(InnerFixture, self).setUp()
global COUNT_INNER
COUNT_INNER += 1

def cleanUp(self, raise_first=True):
super(InnerFixture, self).cleanUp()
def cleanUp(self):
assert 1 <= COUNT_INNER <= 3


1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -7,4 +7,3 @@ certifi
jsonpath-rw-ext>=1.0.0
wsgi-intercept>=1.8.1
colorama
testtools
2 changes: 0 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -13,8 +13,6 @@ classifier =
License :: OSI Approved :: Apache Software License
Operating System :: POSIX
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
24 changes: 4 additions & 20 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tox]
minversion = 3.1.1
skipsdist = True
envlist = py27,py35,py36,py37,pypy,pep8,limit,failskip,docs,py37-prefix,py37-limit,py37-failskip,py27-pytest,py35-pytest,py36-pytest,py37-pytest
envlist = py35,py36,py37,py38,pypy3,pep8,limit,failskip,docs,py37-prefix,py37-limit,py37-failskip,py35-pytest,py36-pytest,py37-pytest

[testenv]
deps = -r{toxinidir}/requirements.txt
@@ -19,9 +19,6 @@ deps = -r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands = {posargs}

[testenv:py27-pytest]
commands = py.test gabbi

[testenv:py35-pytest]
commands = py.test gabbi

@@ -40,19 +37,14 @@ deps = hacking
commands =
flake8

[testenv:limit]
commands = {toxinidir}/test-limit.sh

[testenv:failskip]
commands = {toxinidir}/test-failskip.sh

[testenv:py37-limit]
commands = {toxinidir}/test-limit.sh

[testenv:py37-failskip]
commands = {toxinidir}/test-failskip.sh

[testenv:cover]
basepython = python3
setenv =
{[testenv]setenv}
PYTHON=coverage run --source gabbi --parallel-mode
@@ -66,23 +58,15 @@ commands =
coverage report

[testenv:pytest-cov]
basepython = python3
commands = py.test --cov=gabbi gabbi/tests --cov-config .coveragerc --cov-report html

[testenv:gnocchi]
basepython = python2.7
deps = -egit+https://github.com/gnocchixyz/gnocchi#egg=gnocchi
tox
changedir = {envdir}/src/gnocchi
commands = tox -e py27-postgresql-file --notest # ensure a virtualenv is built
{envdir}/src/gnocchi/.tox/py27-postgresql-file/bin/pip install -U {toxinidir} # install gabbi
tox -e py27-postgresql-file gabbi

[testenv:placement]
basepython = python3.7
deps = tox
commands = -mkdir {envdir}/src
-rm -r {envdir}/src/*
bash -c "curl https://tarballs.openstack.org/placement/placement-master.tar.gz | tar -C {envdir}/src -zx --strip-components 1 -f - "
bash -c "curl -L https://tarballs.opendev.org/openstack/placement/placement-master.tar.gz | tar -C {envdir}/src -zx --strip-components 1 -f - "
tox -c {envdir}/src -e functional-py37 --notest # ensure a virtualenv is built
# nova shares tox envs so it's just luck that we know the tox dir is different from name
{envdir}/src/.tox/py37/bin/pip install -U {toxinidir} # install gabbi