Skip to content

Commit d312b25

Browse files
committed
Use Docker to test external storages
1 parent 2d5f600 commit d312b25

File tree

5 files changed

+149
-31
lines changed

5 files changed

+149
-31
lines changed

.travis.yml

Lines changed: 7 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,10 +16,13 @@ install:
1216
- pip install aiohttp
1317
- pip install aioredis
1418
- pip install cryptography
19+
- pip install docker-py
20+
- pip install pymemcache
1521
- pip install pynacl
1622
- pip install pytest
1723
- pip install pytest-aiohttp
1824
- pip install pytest-cov
25+
- pip install redis
1926
- pip install codecov
2027
- pip install aiomcache
2128
- python setup.py develop

requirements-dev.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@ pep257==0.7.0
55
-e .
66
aioredis==0.3.4
77
cryptography==2.1.3
8+
docker-py==1.10.6
9+
pymemcache==1.4.3
810
pynacl==1.2.0
911
pytest-aiohttp==0.1.3
1012
pytest-cov==2.5.1
13+
redis==2.10.6
1114
aiohttp==2.3.2
1215
multidict==3.3.2
1316
chardet==3.0.4

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 redis as redisdb
7+
import time
8+
import uuid
9+
from docker import Client as DockerClient
10+
from pymemcache.client.base import Client
11+
12+
13+
@pytest.yield_fixture
14+
def loop(request):
15+
loop = asyncio.new_event_loop()
16+
asyncio.set_event_loop(None)
17+
18+
yield loop
19+
20+
if not loop._closed:
21+
loop.call_soon(loop.stop)
22+
loop.run_forever()
23+
loop.close()
24+
gc.collect()
25+
asyncio.set_event_loop(None)
26+
27+
28+
@pytest.fixture(scope='session')
29+
def session_id():
30+
'''Unique session identifier, random string.'''
31+
return str(uuid.uuid4())
32+
33+
34+
@pytest.fixture(scope='session')
35+
def docker():
36+
return DockerClient(version='auto')
37+
38+
39+
def pytest_addoption(parser):
40+
parser.addoption("--no-pull", action="store_true", default=False,
41+
help="Don't perform docker images pulling")
42+
43+
44+
@pytest.yield_fixture(scope='session')
45+
def redis_server(docker, session_id, request):
46+
if not request.config.option.no_pull:
47+
docker.pull('redis:{}'.format('latest'))
48+
container = docker.create_container(
49+
image='redis:{}'.format('latest'),
50+
name='redis-test-server-{}-{}'.format('latest', session_id),
51+
ports=[6379],
52+
detach=True,
53+
)
54+
docker.start(container=container['Id'])
55+
inspection = docker.inspect_container(container['Id'])
56+
host = inspection['NetworkSettings']['IPAddress']
57+
delay = 0.001
58+
for i in range(100):
59+
try:
60+
conn = redisdb.StrictRedis(host=host, port=6379, db=0)
61+
conn.set('foo', 'bar')
62+
break
63+
except redisdb.exceptions.ConnectionError 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.yield_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.yield_fixture(scope='session')
100+
def memcached_server(docker, session_id, 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+
client = Client((host, 11211))
116+
client.set('foo', '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.yield_fixture
136+
def memcached(loop, memcached_params):
137+
conn = aiomcache.Client(**memcached_params, loop=loop)
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)