Skip to content

Commit e859ac7

Browse files
authored
Merge pull request #229 from panagiks/master
Use Docker to test external storages
2 parents 2d5f600 + cf6ef26 commit e859ac7

File tree

5 files changed

+145
-31
lines changed

5 files changed

+145
-31
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
language: python
2+
3+
services:
4+
- docker
5+
26
python:
37
- 3.4.3
48
- 3.5
@@ -12,6 +16,7 @@ install:
1216
- pip install aiohttp
1317
- pip install aioredis
1418
- pip install cryptography
19+
- pip install docker-py
1520
- pip install pynacl
1621
- pip install pytest
1722
- pip install pytest-aiohttp

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pep257==0.7.0
55
-e .
66
aioredis==0.3.4
77
cryptography==2.1.3
8+
docker-py==1.10.6
89
pynacl==1.2.0
910
pytest-aiohttp==0.1.3
1011
pytest-cov==2.5.1

tests/conftest.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import aiomcache
2+
import aioredis
3+
import asyncio
4+
import gc
5+
import pytest
6+
import time
7+
import uuid
8+
from docker import Client as DockerClient
9+
10+
11+
@pytest.fixture(scope='session')
12+
def loop(request):
13+
loop = asyncio.new_event_loop()
14+
asyncio.set_event_loop(None)
15+
16+
yield loop
17+
18+
if not loop._closed:
19+
loop.call_soon(loop.stop)
20+
loop.run_forever()
21+
loop.close()
22+
gc.collect()
23+
asyncio.set_event_loop(None)
24+
25+
26+
@pytest.fixture(scope='session')
27+
def session_id():
28+
"""Unique session identifier, random string."""
29+
return str(uuid.uuid4())
30+
31+
32+
@pytest.fixture(scope='session')
33+
def docker():
34+
return DockerClient(version='auto')
35+
36+
37+
def pytest_addoption(parser):
38+
parser.addoption("--no-pull", action="store_true", default=False,
39+
help="Don't perform docker images pulling")
40+
41+
42+
@pytest.fixture(scope='session')
43+
def redis_server(docker, session_id, loop, request):
44+
if not request.config.option.no_pull:
45+
docker.pull('redis:{}'.format('latest'))
46+
container = docker.create_container(
47+
image='redis:{}'.format('latest'),
48+
name='redis-test-server-{}-{}'.format('latest', session_id),
49+
ports=[6379],
50+
detach=True,
51+
)
52+
docker.start(container=container['Id'])
53+
inspection = docker.inspect_container(container['Id'])
54+
host = inspection['NetworkSettings']['IPAddress']
55+
delay = 0.001
56+
for i in range(100):
57+
try:
58+
conn = loop.run_until_complete(
59+
aioredis.create_connection((host, 6379), loop=loop)
60+
)
61+
loop.run_until_complete(conn.execute('SET', 'foo', 'bar'))
62+
break
63+
except ConnectionRefusedError as e:
64+
time.sleep(delay)
65+
delay *= 2
66+
else:
67+
pytest.fail("Cannot start redis server")
68+
container['redis_params'] = dict(address=(host, 6379))
69+
yield container
70+
71+
docker.kill(container=container['Id'])
72+
docker.remove_container(container['Id'])
73+
74+
75+
@pytest.fixture
76+
def redis_params(redis_server):
77+
return dict(**redis_server['redis_params'])
78+
79+
80+
@pytest.fixture
81+
def redis(loop, redis_params):
82+
pool = None
83+
84+
@asyncio.coroutine
85+
def start(*args, no_loop=False, **kwargs):
86+
nonlocal pool
87+
params = redis_params.copy()
88+
params.update(kwargs)
89+
useloop = None if no_loop else loop
90+
pool = yield from aioredis.create_pool(loop=useloop, **params)
91+
return pool
92+
93+
loop.run_until_complete(start())
94+
yield pool
95+
if pool is not None:
96+
loop.run_until_complete(pool.clear())
97+
98+
99+
@pytest.fixture(scope='session')
100+
def memcached_server(docker, session_id, loop, request):
101+
if not request.config.option.no_pull:
102+
docker.pull('memcached:{}'.format('latest'))
103+
container = docker.create_container(
104+
image='memcached:{}'.format('latest'),
105+
name='memcached-test-server-{}-{}'.format('latest', session_id),
106+
ports=[11211],
107+
detach=True,
108+
)
109+
docker.start(container=container['Id'])
110+
inspection = docker.inspect_container(container['Id'])
111+
host = inspection['NetworkSettings']['IPAddress']
112+
delay = 0.001
113+
for i in range(100):
114+
try:
115+
conn = aiomcache.Client(host, 11211, loop=loop)
116+
loop.run_until_complete(conn.set(b'foo', b'bar'))
117+
break
118+
except ConnectionRefusedError as e:
119+
time.sleep(delay)
120+
delay *= 2
121+
else:
122+
pytest.fail("Cannot start memcached server")
123+
container['memcached_params'] = dict(host=host, port=11211)
124+
yield container
125+
126+
docker.kill(container=container['Id'])
127+
docker.remove_container(container['Id'])
128+
129+
130+
@pytest.fixture
131+
def memcached_params(memcached_server):
132+
return dict(**memcached_server['memcached_params'])
133+
134+
135+
@pytest.fixture
136+
def memcached(loop, memcached_params):
137+
conn = aiomcache.Client(loop=loop, **memcached_params)
138+
yield conn
139+
conn.close()

tests/test_memcached_storage.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
11
import asyncio
22
import json
33
import uuid
4-
import aiomcache
54
import time
6-
import pytest
75

86
from aiohttp import web
97
from aiohttp_session import Session, session_middleware, get_session
108
from aiohttp_session.memcached_storage import MemcachedStorage
119

1210

13-
@pytest.yield_fixture
14-
def memcached(loop):
15-
conn = aiomcache.Client("127.0.0.1", 11211, loop=loop)
16-
yield conn
17-
conn.close()
18-
19-
2011
def create_app(loop, handler, memcached, max_age=None,
2112
key_factory=lambda: uuid.uuid4().hex):
2213
middleware = session_middleware(

tests/test_redis_storage.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,13 @@
11
import asyncio
22
import json
33
import uuid
4-
import aioredis
54
import time
6-
import pytest
75

86
from aiohttp import web
97
from aiohttp_session import Session, session_middleware, get_session
108
from aiohttp_session.redis_storage import RedisStorage
119

1210

13-
@pytest.yield_fixture
14-
def redis(request, loop):
15-
pool = None
16-
17-
@asyncio.coroutine
18-
def start():
19-
nonlocal pool
20-
pool = yield from aioredis.create_pool(('localhost', 6379),
21-
minsize=5,
22-
maxsize=10,
23-
loop=loop)
24-
25-
request.addfinalizer(lambda: pool.close())
26-
27-
loop.run_until_complete(start())
28-
yield pool
29-
if pool is not None:
30-
loop.run_until_complete(pool.clear())
31-
32-
3311
def create_app(loop, handler, redis, max_age=None,
3412
key_factory=lambda: uuid.uuid4().hex):
3513
middleware = session_middleware(

0 commit comments

Comments
 (0)