-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d83ab66
commit fa228dc
Showing
15 changed files
with
577 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
[run] | ||
branch = True | ||
source = pytest_docker | ||
|
||
[paths] | ||
source = | ||
src/pytest_docker | ||
.tox/*/lib/python*/site-packages/pytest_docker | ||
.tox/pypy*/site-packages/pytest_docker | ||
.tox/*/site-packages/pytest_docker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
*~ | ||
*.pyc | ||
/.coverage | ||
/.cache/ | ||
/.tox/ | ||
/htmlcov/ | ||
/pytest_docker.egg-info/ | ||
/src/pytest_docker.egg-info/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
sudo: required | ||
services: | ||
- docker | ||
|
||
language: python | ||
|
||
python: | ||
- "2.7" | ||
- "3.5" | ||
|
||
before_install: | ||
- pip --version | ||
- docker --version | ||
- docker-compose --version | ||
|
||
install: | ||
- pip install tox | ||
- pip install coveralls | ||
|
||
before_script: | ||
# Pre-cache images to prevent timeout in service availability checks. | ||
- docker-compose -f tests/docker-compose.yml pull | ||
- docker-compose -f tests/docker-compose.yml build | ||
|
||
script: | ||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then tox -e py27; fi | ||
- if [[ $TRAVIS_PYTHON_VERSION == '3.5' ]]; then tox -e py35; fi | ||
|
||
after_script: | ||
# Always leave a clean slate. | ||
- docker-compose -f tests/docker-compose.yml down | ||
|
||
after_success: | ||
- coveralls |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
from setuptools import ( | ||
find_packages, | ||
setup, | ||
) | ||
|
||
|
||
setup( | ||
name='pytest-docker', | ||
url='https://github.com/AndreLouisCaron/pytest-docker', | ||
version='0.0.0', | ||
license='MIT', | ||
maintainer='Andre Caron', | ||
maintainer_email='andre.l.caron@gmail.com', | ||
classifiers=[ | ||
'Framework :: Pytest', | ||
'Development Status :: 3 - Alpha', | ||
'License :: OSI Approved :: MIT License', | ||
'Programming Language :: Python', | ||
'Programming Language :: Python :: 2.7', | ||
'Programming Language :: Python :: 3.5', | ||
'Topic :: Utilities', | ||
'Intended Audience :: Developers', | ||
'Operating System :: Unix', | ||
'Operating System :: POSIX', | ||
'Operating System :: Microsoft :: Windows', | ||
], | ||
keywords=[ | ||
'docker', | ||
'docker-compose', | ||
'pytest', | ||
], | ||
packages=find_packages(where='src'), | ||
package_dir={ | ||
'': 'src', | ||
}, | ||
entry_points={ | ||
'pytest11': [ | ||
'docker = pytest_docker', | ||
], | ||
}, | ||
install_requires=[ | ||
'attrs>=16,<17', | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
import attr | ||
import os | ||
import pytest | ||
import re | ||
import subprocess | ||
import time | ||
import timeit | ||
|
||
|
||
def execute(command, success_codes=(0,)): | ||
"""Run a shell command.""" | ||
try: | ||
output = subprocess.check_output( | ||
command, stderr=subprocess.STDOUT, shell=True, | ||
) | ||
status = 0 | ||
except subprocess.CalledProcessError as error: | ||
output = error.output | ||
status = error.returncode | ||
command = error.cmd | ||
output = output.decode('utf-8') | ||
if status not in success_codes: | ||
raise Exception( | ||
'Command %r returned %d: """%s""".' % (command, status, output) | ||
) | ||
return output | ||
|
||
|
||
@pytest.fixture(scope='session') | ||
def docker_ip(): | ||
"""Determine IP address for TCP connections to Docker containers.""" | ||
|
||
# When talking to the Docker daemon via a UNIX socket, route all TCP | ||
# traffic to docker containers via the TCP loopback interface. | ||
docker_host = os.environ.get('DOCKER_HOST', '').strip() | ||
if not docker_host: | ||
return '127.0.0.1' | ||
|
||
match = re.match('^tcp://(.+?):\d+$', docker_host) | ||
if not match: | ||
raise ValueError( | ||
'Invalid value for DOCKER_HOST: "%s".' % (docker_host,) | ||
) | ||
return match.group(1) | ||
|
||
|
||
@attr.s(frozen=True) | ||
class Services(object): | ||
""".""" | ||
|
||
_compose_file = attr.ib() | ||
_services = attr.ib(init=False, default=attr.Factory(dict)) | ||
|
||
def port_for(self, service, port): | ||
"""Get the effective bind port for a service.""" | ||
|
||
# Lookup in the cache. | ||
cache = self._services.get(service, {}).get(port, None) | ||
if cache is not None: | ||
return cache | ||
|
||
output = execute('docker-compose -f "%s" port %s %d' % ( | ||
self._compose_file, service, port, | ||
)) | ||
endpoint = output.strip() | ||
if not endpoint: | ||
raise ValueError( | ||
'Could not detect port for "%s:%d".' % (service, port) | ||
) | ||
|
||
# Usually, the IP address here is 0.0.0.0, so we don't use it. | ||
match = int(endpoint.split(':', 1)[1]) | ||
|
||
# Store it in cache in case we request it multiple times. | ||
self._services.setdefault(service, {})[port] = match | ||
|
||
return match | ||
|
||
def wait_until_responsive(self, check, timeout, pause, | ||
clock=timeit.default_timer): | ||
"""Wait until a service is responsive.""" | ||
|
||
ref = clock() | ||
now = ref | ||
while (now - ref) < timeout: | ||
if check(): | ||
return | ||
time.sleep(pause) | ||
now = clock() | ||
|
||
raise Exception( | ||
'Timeout reached while waiting on service!' | ||
) | ||
|
||
|
||
@pytest.fixture(scope='session') | ||
def docker_compose_file(): | ||
""".""" | ||
return 'docker-compose.yml' | ||
|
||
|
||
@pytest.fixture(scope='session') | ||
def docker_services(docker_compose_file): | ||
"""Ensure all Docker-based services are up and running.""" | ||
|
||
# Spawn containers. | ||
execute('docker-compose -f "%s" up -d' % (docker_compose_file,)) | ||
|
||
# Let test(s) run. | ||
yield Services(compose_file=docker_compose_file) | ||
|
||
# Clean up. | ||
execute('docker-compose -f "%s" down' % (docker_compose_file,)) | ||
|
||
|
||
__all__ = ( | ||
'docker_compose_file', | ||
'docker_ip', | ||
'docker_services', | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
import os.path | ||
import pytest | ||
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__)) | ||
|
||
|
||
@pytest.fixture(scope='session') | ||
def docker_compose_file(): | ||
return os.path.join(HERE, 'docker-compose.yml') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
FROM python:3.6-alpine | ||
|
||
CMD [ "python", "-m", "http.server", "80" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
hello: | ||
build: "./containers/hello" | ||
ports: | ||
- "80" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
coverage | ||
docutils | ||
flake8 | ||
mock | ||
pytest | ||
requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
from pytest_docker import docker_compose_file | ||
|
||
|
||
def test_docker_compose_file(): | ||
docker_compose_file() == 'docker-compose.yml' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
import mock | ||
import pytest | ||
|
||
from pytest_docker import docker_ip | ||
|
||
|
||
def test_docker_ip_native(): | ||
environ = {} | ||
with mock.patch('os.environ', environ): | ||
assert docker_ip() == '127.0.0.1' | ||
|
||
|
||
def test_docker_ip_remote(): | ||
environ = { | ||
'DOCKER_HOST': 'tcp://1.2.3.4:2376', | ||
} | ||
with mock.patch('os.environ', environ): | ||
assert docker_ip() == '1.2.3.4' | ||
|
||
|
||
@pytest.mark.parametrize('docker_host', [ | ||
'http://1.2.3.4:2376', | ||
]) | ||
def test_docker_ip_remote_invalid(docker_host): | ||
environ = { | ||
'DOCKER_HOST': docker_host, | ||
} | ||
with mock.patch('os.environ', environ): | ||
with pytest.raises(ValueError) as exc: | ||
print(docker_ip()) | ||
assert str(exc.value) == ( | ||
'Invalid value for DOCKER_HOST: "%s".' % (docker_host,) | ||
) |
Oops, something went wrong.