Skip to content

Commit 9423966

Browse files
Merge pull request #641 from guzman-raphael/ext-migrate-test
Add test cases for external blob migration 0.11 to 0.12
2 parents 7cbf35e + 379eb84 commit 9423966

17 files changed

+465
-8
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,8 @@ build/
1818
./tests/.coverage
1919
./tests/dj-store/*
2020
*.log
21+
*.env
22+
LNX-docker-compose.yml
23+
notebooks/*
24+
test.dockerfile
25+
__main__.py

.travis.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ sudo: required
22
dist: xenial
33
language: python
44
env:
5-
- DJ_TEST_HOST="127.0.0.1" DJ_TEST_USER="datajoint" DJ_TEST_PASSWORD="datajoint" DJ_HOST="127.0.0.1" DJ_USER="root" DJ_PASS="" S3_ENDPOINT="127.0.0.1:9000" S3_ACCESS_KEY="datajoint" S3_SECRET_KEY="datajoint" S3_BUCKET="datajoint-test"
5+
- DJ_TEST_HOST="127.0.0.1" DJ_TEST_USER="datajoint" DJ_TEST_PASSWORD="datajoint" DJ_HOST="127.0.0.1" DJ_USER="root" DJ_PASS="" S3_ACCESS_KEY="datajoint" S3_SECRET_KEY="datajoint"
66
python:
77
- "3.4"
88
- "3.5"
@@ -16,8 +16,6 @@ before_install:
1616
- docker pull minio/minio
1717
- docker run -d -p 9000:9000 -e "MINIO_ACCESS_KEY=$S3_ACCESS_KEY" -e "MINIO_SECRET_KEY=$S3_SECRET_KEY" minio/minio server /data
1818
- sleep 120
19-
- docker pull minio/mc
20-
- docker run --network="host" --entrypoint=/bin/sh minio/mc -c "mc config host add dj-s3 http://$S3_ENDPOINT $S3_ACCESS_KEY $S3_SECRET_KEY;mc mb $S3_BUCKET;mc policy download $S3_BUCKET;exit 0;"
2119
- sudo apt-get install -y libblas-dev liblapack-dev libatlas-dev gfortran
2220
- sudo apt-get install -y graphviz graphviz-dev pkg-config
2321
- mysql --version

datajoint/utils.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,19 @@ def safe_copy(src, dest, overwrite=False):
9595
temp_file = dest + '.copying'
9696
shutil.copyfile(src, temp_file)
9797
os.rename(temp_file, dest)
98+
99+
100+
def parse_sql(filepath):
101+
DELIMITER = ';'
102+
statement = []
103+
with open(filepath, 'rt') as f:
104+
for line in f:
105+
line = line.strip()
106+
if not line.startswith('--') and len(line) > 1:
107+
if line.startswith('DELIMITER'):
108+
DELIMITER = line.split()[1]
109+
else:
110+
statement.append(line)
111+
if line.endswith(DELIMITER):
112+
yield ' '.join(statement)
113+
statement = []

tests/__init__.py

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@
99
from os import environ, remove
1010
import datajoint as dj
1111
from distutils.version import LooseVersion
12+
import os
13+
from pathlib import Path
14+
from minio import Minio
15+
import urllib3
16+
import certifi
17+
import shutil
18+
from datajoint.utils import parse_sql
1219

13-
__author__ = 'Edgar Walker, Fabian Sinz, Dimitri Yatsenko'
20+
__author__ = 'Edgar Walker, Fabian Sinz, Dimitri Yatsenko, Raphael Guzman'
1421

1522
# turn on verbose logging
1623
logging.basicConfig(level=logging.DEBUG)
@@ -61,7 +68,7 @@
6168
conn_root.query(
6269
"GRANT SELECT ON `djtest%%`.* TO 'djssl'@'%%';")
6370
else:
64-
# grant permissions. For mysql5.6/5.7 this also automatically creates user
71+
# grant permissions. For mysql5.6/5.7 this also automatically creates user
6572
# if not exists
6673
conn_root.query("""
6774
GRANT ALL PRIVILEGES ON `djtest%%`.* TO 'datajoint'@'%%'
@@ -76,6 +83,25 @@
7683
REQUIRE SSL;
7784
""")
7885

86+
# Initialize httpClient with relevant timeout.
87+
httpClient = urllib3.PoolManager(
88+
timeout=30,
89+
cert_reqs='CERT_REQUIRED',
90+
ca_certs=certifi.where(),
91+
retries=urllib3.Retry(
92+
total=3,
93+
backoff_factor=0.2,
94+
status_forcelist=[500, 502, 503, 504]
95+
)
96+
)
97+
98+
# Initialize minioClient with an endpoint and access/secret keys.
99+
minioClient = Minio(S3_CONN_INFO['endpoint'],
100+
access_key=S3_CONN_INFO['access_key'],
101+
secret_key=S3_CONN_INFO['secret_key'],
102+
secure=False,
103+
http_client=httpClient)
104+
79105

80106
def setup_package():
81107
"""
@@ -84,6 +110,44 @@ def setup_package():
84110
"""
85111
dj.config['safemode'] = False
86112

113+
# Add old MySQL
114+
source = os.path.dirname(os.path.realpath(__file__)) + \
115+
"/external-legacy-data"
116+
db_name = "djtest_blob_migrate"
117+
db_file = "v0_11.sql"
118+
conn_root.query("""
119+
CREATE DATABASE {};
120+
""".format(db_name))
121+
122+
statements = parse_sql('{}/{}'.format(source, db_file))
123+
for s in statements:
124+
conn_root.query(s)
125+
126+
# Add old S3
127+
source = os.path.dirname(os.path.realpath(__file__)) + \
128+
"/external-legacy-data/s3"
129+
bucket = "migrate-test"
130+
region = "us-east-1"
131+
minioClient.make_bucket(bucket, location=region)
132+
133+
pathlist = Path(source).glob('**/*')
134+
for path in pathlist:
135+
if os.path.isfile(str(path)) and ".sql" not in str(path):
136+
minioClient.fput_object(
137+
bucket, os.path.relpath(
138+
str(path),
139+
'{}/{}'.format(source, bucket)
140+
), str(path))
141+
142+
# Add S3
143+
minioClient.make_bucket("datajoint-test", location=region)
144+
145+
# Add old File Content
146+
shutil.copytree(
147+
os.path.dirname(os.path.realpath(__file__)) +
148+
"/external-legacy-data/file/temp",
149+
os.path.expanduser('~/temp'))
150+
87151

88152
def teardown_package():
89153
"""
@@ -99,3 +163,21 @@ def teardown_package():
99163
conn.query('DROP DATABASE `{}`'.format(db[0]))
100164
conn.query('SET FOREIGN_KEY_CHECKS=1')
101165
remove("dj_local_conf.json")
166+
167+
# Remove old S3
168+
bucket = "migrate-test"
169+
objs = list(minioClient.list_objects_v2(
170+
bucket, recursive=True))
171+
objs = [minioClient.remove_object(bucket,
172+
o.object_name.encode('utf-8')) for o in objs]
173+
minioClient.remove_bucket(bucket)
174+
175+
# Remove S3
176+
bucket = "datajoint-test"
177+
objs = list(minioClient.list_objects_v2(bucket, recursive=True))
178+
objs = [minioClient.remove_object(bucket,
179+
o.object_name.encode('utf-8')) for o in objs]
180+
minioClient.remove_bucket(bucket)
181+
182+
# Remove old File Content
183+
shutil.rmtree(os.path.expanduser('~/temp'))

tests/external-legacy-data/v0_11.sql

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
USE djtest_blob_migrate;
2+
-- MySQL dump 10.13 Distrib 5.7.26, for Linux (x86_64)
3+
--
4+
-- Host: localhost Database: djtest_blob_migrate
5+
-- ------------------------------------------------------
6+
-- Server version 5.7.26
7+
8+
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
9+
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
10+
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
11+
/*!40101 SET NAMES utf8 */;
12+
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
13+
/*!40103 SET TIME_ZONE='+00:00' */;
14+
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
15+
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
16+
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
17+
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
18+
19+
--
20+
-- Table structure for table `~external`
21+
--
22+
23+
DROP TABLE IF EXISTS `~external`;
24+
/*!40101 SET @saved_cs_client = @@character_set_client */;
25+
/*!40101 SET character_set_client = utf8 */;
26+
CREATE TABLE `~external` (
27+
`hash` char(51) NOT NULL COMMENT 'the hash of stored object + store name',
28+
`size` bigint(20) unsigned NOT NULL COMMENT 'size of object in bytes',
29+
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'automatic timestamp',
30+
PRIMARY KEY (`hash`)
31+
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='external storage tracking';
32+
/*!40101 SET character_set_client = @saved_cs_client */;
33+
34+
--
35+
-- Dumping data for table `~external`
36+
--
37+
38+
LOCK TABLES `~external` WRITE;
39+
/*!40000 ALTER TABLE `~external` DISABLE KEYS */;
40+
INSERT INTO `~external` VALUES ('e46pnXQW9GaCKbL3WxV1crGHeGqcE0OLInM_TTwAFfwlocal',237,'2019-07-31 17:55:01'),('FoRROa2LWM6_wx0RIQ0J-LVvgm256cqDQfJa066HoTEshared',37,'2019-07-31 17:55:01'),('NmWj002gtKUkt9GIBwzn6Iw3x6h7ovlX_FfELbfjwRQshared',53,'2019-07-31 17:55:01'),('Ue9c89gKVZD7xPOcHd5Lz6mARJQ50xT1G5cTTX4h0L0shared',53,'2019-07-31 17:55:01'),('_3A03zPqfVhbn0rhlOJYGNivFJ4uqYuHaeQBA-V8PKA',237,'2019-07-31 17:55:01'),('_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94',40,'2019-07-31 17:55:01'),('_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94local',40,'2019-07-31 17:55:01');
41+
/*!40000 ALTER TABLE `~external` ENABLE KEYS */;
42+
UNLOCK TABLES;
43+
44+
--
45+
-- Table structure for table `~log`
46+
--
47+
48+
DROP TABLE IF EXISTS `~log`;
49+
/*!40101 SET @saved_cs_client = @@character_set_client */;
50+
/*!40101 SET character_set_client = utf8 */;
51+
CREATE TABLE `~log` (
52+
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
53+
`version` varchar(12) NOT NULL COMMENT 'datajoint version',
54+
`user` varchar(255) NOT NULL COMMENT 'user@host',
55+
`host` varchar(255) NOT NULL DEFAULT '' COMMENT 'system hostname',
56+
`event` varchar(255) NOT NULL DEFAULT '' COMMENT 'custom message',
57+
PRIMARY KEY (`timestamp`)
58+
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='event logging table for `djtest_blob_migrate`';
59+
/*!40101 SET character_set_client = @saved_cs_client */;
60+
61+
--
62+
-- Dumping data for table `~log`
63+
--
64+
65+
LOCK TABLES `~log` WRITE;
66+
/*!40000 ALTER TABLE `~log` DISABLE KEYS */;
67+
INSERT INTO `~log` VALUES ('2019-07-31 17:54:49','0.11.1py','[email protected]','297df05ab17c','Declared `djtest_blob_migrate`.`~log`'),('2019-07-31 17:54:54','0.11.1py','[email protected]','297df05ab17c','Declared `djtest_blob_migrate`.`~external`'),('2019-07-31 17:54:55','0.11.1py','[email protected]','297df05ab17c','Declared `djtest_blob_migrate`.`b`');
68+
/*!40000 ALTER TABLE `~log` ENABLE KEYS */;
69+
UNLOCK TABLES;
70+
71+
--
72+
-- Table structure for table `a`
73+
--
74+
75+
DROP TABLE IF EXISTS `a`;
76+
/*!40101 SET @saved_cs_client = @@character_set_client */;
77+
/*!40101 SET character_set_client = utf8 */;
78+
CREATE TABLE `a` (
79+
`id` int(11) NOT NULL,
80+
`blob_external` char(51) NOT NULL COMMENT ':external:uses S3',
81+
`blob_share` char(51) NOT NULL COMMENT ':external-shared:uses S3',
82+
PRIMARY KEY (`id`),
83+
KEY `blob_external` (`blob_external`),
84+
KEY `blob_share` (`blob_share`),
85+
CONSTRAINT `a_ibfk_1` FOREIGN KEY (`blob_external`) REFERENCES `~external` (`hash`),
86+
CONSTRAINT `a_ibfk_2` FOREIGN KEY (`blob_share`) REFERENCES `~external` (`hash`)
87+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
88+
/*!40101 SET character_set_client = @saved_cs_client */;
89+
90+
--
91+
-- Dumping data for table `a`
92+
--
93+
94+
LOCK TABLES `a` WRITE;
95+
/*!40000 ALTER TABLE `a` DISABLE KEYS */;
96+
INSERT INTO `a` VALUES (0,'_3A03zPqfVhbn0rhlOJYGNivFJ4uqYuHaeQBA-V8PKA','NmWj002gtKUkt9GIBwzn6Iw3x6h7ovlX_FfELbfjwRQshared'),(1,'_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94','FoRROa2LWM6_wx0RIQ0J-LVvgm256cqDQfJa066HoTEshared');
97+
/*!40000 ALTER TABLE `a` ENABLE KEYS */;
98+
UNLOCK TABLES;
99+
100+
--
101+
-- Table structure for table `b`
102+
--
103+
104+
DROP TABLE IF EXISTS `b`;
105+
/*!40101 SET @saved_cs_client = @@character_set_client */;
106+
/*!40101 SET character_set_client = utf8 */;
107+
CREATE TABLE `b` (
108+
`id` int(11) NOT NULL,
109+
`blob_local` char(51) NOT NULL COMMENT ':external-local:uses files',
110+
`blob_share` char(51) NOT NULL COMMENT ':external-shared:uses S3',
111+
PRIMARY KEY (`id`),
112+
KEY `blob_local` (`blob_local`),
113+
KEY `blob_share` (`blob_share`),
114+
CONSTRAINT `b_ibfk_1` FOREIGN KEY (`blob_local`) REFERENCES `~external` (`hash`),
115+
CONSTRAINT `b_ibfk_2` FOREIGN KEY (`blob_share`) REFERENCES `~external` (`hash`)
116+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
117+
/*!40101 SET character_set_client = @saved_cs_client */;
118+
119+
--
120+
-- Dumping data for table `b`
121+
--
122+
123+
LOCK TABLES `b` WRITE;
124+
/*!40000 ALTER TABLE `b` DISABLE KEYS */;
125+
INSERT INTO `b` VALUES (0,'e46pnXQW9GaCKbL3WxV1crGHeGqcE0OLInM_TTwAFfwlocal','Ue9c89gKVZD7xPOcHd5Lz6mARJQ50xT1G5cTTX4h0L0shared'),(1,'_Fhi2GUBB0fgxcSP2q-isgncIUTdgGK7ivHiySAU_94local','FoRROa2LWM6_wx0RIQ0J-LVvgm256cqDQfJa066HoTEshared');
126+
/*!40000 ALTER TABLE `b` ENABLE KEYS */;
127+
UNLOCK TABLES;
128+
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
129+
130+
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
131+
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
132+
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
133+
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
134+
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
135+
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
136+
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
137+
138+
-- Dump completed on 2019-07-31 18:16:40

tests/schema_external.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
schema = dj.schema(PREFIX + '_extern', connection=dj.conn(**CONN_INFO))
1212

1313

14-
dj.config['stores'] = {
14+
stores_config = {
1515

1616
'raw': dict(
1717
protocol='file',
@@ -40,6 +40,8 @@
4040
subfolding=(2, 4))
4141
}
4242

43+
dj.config['stores'] = stores_config
44+
4345
dj.config['cache'] = tempfile.mkdtemp()
4446

4547

0 commit comments

Comments
 (0)