Skip to content

Commit 8ec4677

Browse files
Convert test_connection to pytest.
1 parent 7481cc6 commit 8ec4677

File tree

6 files changed

+424
-234
lines changed

6 files changed

+424
-234
lines changed

LNX-docker-compose.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ services:
8989
pip install --user nose nose-cov
9090
pip install -e .
9191
pip list --format=freeze | grep datajoint
92-
nosetests -vsw tests --with-coverage --cover-package=datajoint
92+
pytest -sv --cov-report term-missing --cov=datajoint tests
93+
nosetests -vsw tests_old --with-coverage --cover-package=datajoint
9394
# ports:
9495
# - "8888:8888"
9596
user: ${HOST_UID}:anaconda

tests/__init__.py

Lines changed: 46 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,69 @@
1-
"""
2-
Package for testing datajoint. Setup fixture will be run
3-
to ensure that proper database connection and access privilege
4-
exists. The content of the test database will be destroyed
5-
after the test.
6-
"""
7-
8-
import logging
9-
from os import environ, remove
101
import datajoint as dj
112
from distutils.version import LooseVersion
3+
import pytest
124
import os
13-
from pathlib import Path
14-
import minio
15-
import urllib3
16-
import certifi
17-
import shutil
18-
from datajoint.utils import parse_sql
19-
20-
__author__ = "Edgar Walker, Fabian Sinz, Dimitri Yatsenko, Raphael Guzman"
21-
22-
# turn on verbose logging
23-
logging.basicConfig(level=logging.DEBUG)
245

25-
__all__ = ["__author__", "PREFIX", "CONN_INFO"]
26-
27-
# Connection for testing
28-
CONN_INFO = dict(
29-
host=environ.get("DJ_TEST_HOST", "fakeservices.datajoint.io"),
30-
user=environ.get("DJ_TEST_USER", "datajoint"),
31-
password=environ.get("DJ_TEST_PASSWORD", "datajoint"),
32-
)
6+
PREFIX = "djtest"
337

348
CONN_INFO_ROOT = dict(
35-
host=environ.get("DJ_HOST", "fakeservices.datajoint.io"),
36-
user=environ.get("DJ_USER", "root"),
37-
password=environ.get("DJ_PASS", "simple"),
38-
)
39-
40-
S3_CONN_INFO = dict(
41-
endpoint=environ.get("S3_ENDPOINT", "fakeservices.datajoint.io"),
42-
access_key=environ.get("S3_ACCESS_KEY", "datajoint"),
43-
secret_key=environ.get("S3_SECRET_KEY", "datajoint"),
44-
bucket=environ.get("S3_BUCKET", "datajoint.test"),
45-
)
46-
47-
# Prefix for all databases used during testing
48-
PREFIX = environ.get("DJ_TEST_DB_PREFIX", "djtest")
49-
conn_root = dj.conn(**CONN_INFO_ROOT)
50-
51-
# Initialize httpClient with relevant timeout.
52-
httpClient = urllib3.PoolManager(
53-
timeout=30,
54-
cert_reqs="CERT_REQUIRED",
55-
ca_certs=certifi.where(),
56-
retries=urllib3.Retry(
57-
total=3, backoff_factor=0.2, status_forcelist=[500, 502, 503, 504]
58-
),
59-
)
60-
61-
# Initialize minioClient with an endpoint and access/secret keys.
62-
minioClient = minio.Minio(
63-
S3_CONN_INFO["endpoint"],
64-
access_key=S3_CONN_INFO["access_key"],
65-
secret_key=S3_CONN_INFO["secret_key"],
66-
secure=True,
67-
http_client=httpClient,
9+
host=os.getenv("DJ_HOST"),
10+
user=os.getenv("DJ_USER"),
11+
password=os.getenv("DJ_PASS"),
6812
)
6913

7014

71-
def setup_package():
72-
"""
73-
Package-level unit test setup
74-
Turns off safemode
75-
"""
15+
@pytest.fixture
16+
def connection_root():
17+
"""Root user database connection."""
7618
dj.config["safemode"] = False
19+
connection = dj.Connection(
20+
host=os.getenv("DJ_HOST"),
21+
user=os.getenv("DJ_USER"),
22+
password=os.getenv("DJ_PASS"),
23+
)
24+
yield connection
25+
dj.config["safemode"] = True
26+
connection.close()
27+
28+
29+
@pytest.fixture
30+
def connection_test(connection_root):
31+
"""Test user database connection."""
32+
database = f"{PREFIX}%%"
33+
credentials = dict(
34+
host=os.getenv("DJ_HOST"), user="datajoint", password="datajoint"
35+
)
36+
permission = "ALL PRIVILEGES"
7737

7838
# Create MySQL users
79-
if LooseVersion(conn_root.query("select @@version;").fetchone()[0]) >= LooseVersion(
80-
"8.0.0"
81-
):
39+
if LooseVersion(
40+
connection_root.query("select @@version;").fetchone()[0]
41+
) >= LooseVersion("8.0.0"):
8242
# create user if necessary on mysql8
83-
conn_root.query(
43+
connection_root.query(
44+
f"""
45+
CREATE USER IF NOT EXISTS '{credentials["user"]}'@'%%'
46+
IDENTIFIED BY '{credentials["password"]}';
8447
"""
85-
CREATE USER IF NOT EXISTS 'datajoint'@'%%'
86-
IDENTIFIED BY 'datajoint';
87-
"""
8848
)
89-
conn_root.query(
49+
connection_root.query(
50+
f"""
51+
GRANT {permission} ON `{database}`.*
52+
TO '{credentials["user"]}'@'%%';
9053
"""
91-
CREATE USER IF NOT EXISTS 'djview'@'%%'
92-
IDENTIFIED BY 'djview';
93-
"""
9454
)
95-
conn_root.query(
96-
"""
97-
CREATE USER IF NOT EXISTS 'djssl'@'%%'
98-
IDENTIFIED BY 'djssl'
99-
REQUIRE SSL;
100-
"""
101-
)
102-
conn_root.query("GRANT ALL PRIVILEGES ON `djtest%%`.* TO 'datajoint'@'%%';")
103-
conn_root.query("GRANT SELECT ON `djtest%%`.* TO 'djview'@'%%';")
104-
conn_root.query("GRANT SELECT ON `djtest%%`.* TO 'djssl'@'%%';")
10555
else:
10656
# grant permissions. For MySQL 5.7 this also automatically creates user
10757
# if not exists
108-
conn_root.query(
109-
"""
110-
GRANT ALL PRIVILEGES ON `djtest%%`.* TO 'datajoint'@'%%'
111-
IDENTIFIED BY 'datajoint';
58+
connection_root.query(
59+
f"""
60+
GRANT {permission} ON `{database}`.*
61+
TO '{credentials["user"]}'@'%%'
62+
IDENTIFIED BY '{credentials["password"]}';
11263
"""
11364
)
114-
conn_root.query(
115-
"GRANT SELECT ON `djtest%%`.* TO 'djview'@'%%' IDENTIFIED BY 'djview';"
116-
)
117-
conn_root.query(
118-
"""
119-
GRANT SELECT ON `djtest%%`.* TO 'djssl'@'%%'
120-
IDENTIFIED BY 'djssl'
121-
REQUIRE SSL;
122-
"""
123-
)
124-
125-
region = "us-east-1"
126-
# Add S3
127-
try:
128-
minioClient.make_bucket(S3_CONN_INFO["bucket"], location=region)
129-
except minio.error.S3Error as e:
130-
if e.code != "BucketAlreadyOwnedByYou":
131-
raise e
132-
133-
134-
def teardown_package():
135-
"""
136-
Package-level unit test teardown.
137-
Removes all databases with name starting with PREFIX.
138-
To deal with possible foreign key constraints, it will unset
139-
and then later reset FOREIGN_KEY_CHECKS flag
140-
"""
141-
conn_root.query("SET FOREIGN_KEY_CHECKS=0")
142-
cur = conn_root.query('SHOW DATABASES LIKE "{}\_%%"'.format(PREFIX))
143-
for db in cur.fetchall():
144-
conn_root.query("DROP DATABASE `{}`".format(db[0]))
145-
conn_root.query("SET FOREIGN_KEY_CHECKS=1")
146-
if os.path.exists("dj_local_conf.json"):
147-
remove("dj_local_conf.json")
148-
149-
# Remove created users
150-
conn_root.query("DROP USER `datajoint`")
151-
conn_root.query("DROP USER `djview`")
152-
conn_root.query("DROP USER `djssl`")
15365

154-
# Remove S3
155-
objs = list(minioClient.list_objects(S3_CONN_INFO["bucket"], recursive=True))
156-
objs = [
157-
minioClient.remove_object(S3_CONN_INFO["bucket"], o.object_name.encode("utf-8"))
158-
for o in objs
159-
]
160-
minioClient.remove_bucket(S3_CONN_INFO["bucket"])
66+
connection = dj.Connection(**credentials)
67+
yield connection
68+
connection_root.query(f"""DROP USER `{credentials["user"]}`""")
69+
connection.close()

tests/schemas/connection.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import datajoint as dj
2+
from .. import PREFIX, connection_test
3+
import pytest
4+
5+
6+
@pytest.fixture
7+
def schema(connection_test):
8+
schema = dj.Schema(PREFIX + "_transactions", locals(), connection=connection_test)
9+
yield schema
10+
schema.drop()
11+
12+
13+
@pytest.fixture
14+
def Subjects(schema):
15+
@schema
16+
class Subjects(dj.Manual):
17+
definition = """
18+
#Basic subject
19+
subject_id : int # unique subject id
20+
---
21+
real_id : varchar(40) # real-world name
22+
species = "mouse" : enum('mouse', 'monkey', 'human') # species
23+
"""
24+
25+
yield Subjects
26+
Subjects.drop()

0 commit comments

Comments
 (0)