Skip to content

Commit e3defa3

Browse files
committed
Rework tests to run against an etcd cluster
A new utility class `EtcdCluster` is added to manage the lifecycle of a etcd cluster run in containers. This class replaces the methods in `docker_cli` and `etcd_go_cli`. A set of fixtures(`etcd_cluster`, `etcd_cluster_ssl`, `client` and `io_client` manages the lifecycle of the test resources. All the tests are set to run using the `BaseClient`'s `endpoint` parameter, additional tests have been added to test `host` and `port`.
1 parent 4b1de04 commit e3defa3

20 files changed

+372
-597
lines changed

requirements_dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ m2r==0.2.1
1919
codecov>=1.4.0
2020
codacy-coverage==1.3.11
2121
twine==1.13.0
22+
docker==3.7.0

tests/conftest.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from etcd3.client import Client
2+
from etcd3 import AioClient
3+
import pytest
4+
from .etcd_cluster import EtcdTestCluster
5+
6+
7+
@pytest.fixture(scope='session')
8+
def etcd_cluster(request):
9+
# function_name = request.function.__name__
10+
# function_name = re.sub(r"[^a-zA-Z0-9]+", "", function_name)
11+
cluster = EtcdTestCluster(ident='cleartext', size=3)
12+
13+
def fin():
14+
cluster.down()
15+
request.addfinalizer(fin)
16+
cluster.up()
17+
18+
return cluster
19+
20+
21+
@pytest.fixture(scope='session')
22+
def etcd_cluster_ssl(request):
23+
# function_name = request.function.__name__
24+
# function_name = re.sub(r"[^a-zA-Z0-9]+", "", function_name)
25+
cluster = EtcdTestCluster(ident='ssl', size=3, ssl=True)
26+
27+
def fin():
28+
cluster.down()
29+
request.addfinalizer(fin)
30+
cluster.up()
31+
32+
return cluster
33+
34+
35+
@pytest.fixture(scope='module')
36+
def client(etcd_cluster):
37+
"""
38+
init Etcd3Client, close its connection-pool when teardown
39+
"""
40+
# _, p, _ = docker_run_etcd_main()
41+
c = Client(endpoints=etcd_cluster.get_endpoints(),
42+
protocol='https' if etcd_cluster.ssl else 'http')
43+
yield c
44+
c.close()
45+
46+
47+
@pytest.fixture
48+
def clear(etcd_cluster):
49+
def _clear():
50+
etcd_cluster.etcdctl('del --from-key ""')
51+
return _clear
52+
53+
54+
@pytest.fixture
55+
async def aio_client(event_loop, request, etcd_cluster):
56+
"""
57+
init Etcd3Client, close its connection-pool when teardown
58+
"""
59+
60+
c = AioClient(endpoints=etcd_cluster.get_endpoints(),
61+
protocol='https' if etcd_cluster.ssl else 'http')
62+
63+
def teardown():
64+
async def _t():
65+
await c.close()
66+
67+
event_loop.run_until_complete(_t())
68+
event_loop._close()
69+
70+
request.addfinalizer(teardown)
71+
return c
72+
73+
74+
def teardown_auth(etcd_cluster): # pragma: no cover
75+
"""
76+
disable auth, delete all users and roles
77+
"""
78+
etcd_cluster.etcdctl('--user root:root auth disable')
79+
etcd_cluster.etcdctl('--user root:changed auth disable')
80+
for i in (etcd_cluster.etcdctl('role list') or '').splitlines():
81+
etcd_cluster.etcdctl('role delete %s' % i)
82+
for i in (etcd_cluster.etcdctl('user list') or '').splitlines():
83+
etcd_cluster.etcdctl('user delete %s' % i)
84+
85+
86+
def enable_auth(etcd_cluster): # pragma: no cover
87+
etcd_cluster.etcdctl('user add root:root')
88+
etcd_cluster.etcdctl('role add root')
89+
etcd_cluster.etcdctl('user grant root root')
90+
etcd_cluster.etcdctl('auth enable')

tests/docker_cli.py

Lines changed: 0 additions & 149 deletions
This file was deleted.

tests/envs.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
import logging
22
import os
3-
from six.moves.urllib_parse import urlparse
43

54
logging.basicConfig(format='%(name)s %(levelname)s - %(message)s')
65
log = logging.getLogger()
76
log.setLevel(logging.DEBUG)
87
handler = logging.StreamHandler()
98
log.addHandler(handler)
109

11-
ETCD_ENDPOINT = os.getenv('ETCD_ENDPOINT') or 'http://localhost:2379'
12-
_url = urlparse(ETCD_ENDPOINT)
10+
ETCD_VER = os.getenv('ETCD_VER') or 'v3.3.0'
1311

14-
protocol = _url.scheme
12+
ETCD_IMG = 'quay.io/coreos/etcd:' + ETCD_VER
1513

16-
host, port = _url.netloc.split(':')
14+
DOCKER_PUBLISH_HOST = '127.0.0.1'
1715

18-
ETCD_VER = os.getenv('ETCD_VER') or 'v3.3.0'
1916

20-
ETCD_IMG = 'quay.io/coreos/etcd:' + ETCD_VER
17+
CERTS_DIR = os.path.join(os.path.dirname(__file__), 'certs')
18+
CA_PATH = os.path.join(CERTS_DIR, 'ca.pem')
19+
CERT_PATH = os.path.join(CERTS_DIR, 'client.pem')
20+
KEY_PATH = os.path.join(CERTS_DIR, 'client-key.pem')
21+
SERVER_CA_PATH = '/certs/ca.pem'
22+
SERVER_CERT_PATH = '/certs/server.pem'
23+
SERVER_KEY_PATH = '/certs/server-key.pem'
24+
25+
NO_DOCKER_SERVICE = True
26+
try: # pragma: no cover
27+
import docker # noqa
28+
NO_DOCKER_SERVICE = False
29+
except ImportError as e: # pragma: no cover
30+
print("docker library not found")
31+
print(e)

0 commit comments

Comments
 (0)