##// END OF EJS Templates
fix(tests): fixed db migration tests after introduction of RC_TEST flag
super-admin -
r5351:adc169b4 default
parent child Browse files
Show More
@@ -1,91 +1,91 b''
1 # Copyright (C) 2010-2023 RhodeCode GmbH
1 # Copyright (C) 2010-2023 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 import os
19 import os
20 import datetime
20 import datetime
21 import collections
21 import collections
22 import logging
22 import logging
23
23
24
24
25 now = datetime.datetime.now()
25 now = datetime.datetime.now()
26 now = now.strftime("%Y-%m-%d %H:%M:%S") + '.' + f"{int(now.microsecond/1000):03d}"
26 now = now.strftime("%Y-%m-%d %H:%M:%S") + '.' + f"{int(now.microsecond/1000):03d}"
27
27
28 log = logging.getLogger(__name__)
28 log = logging.getLogger(__name__)
29 log.debug(f'{now} Starting RhodeCode imports...')
29 log.debug(f'{now} Starting RhodeCode imports...')
30
30
31
31
32 VERSION = tuple(open(os.path.join(
32 VERSION = tuple(open(os.path.join(
33 os.path.dirname(__file__), 'VERSION')).read().split('.'))
33 os.path.dirname(__file__), 'VERSION')).read().split('.'))
34
34
35 BACKENDS = collections.OrderedDict()
35 BACKENDS = collections.OrderedDict()
36
36
37 BACKENDS['hg'] = 'Mercurial repository'
37 BACKENDS['hg'] = 'Mercurial repository'
38 BACKENDS['git'] = 'Git repository'
38 BACKENDS['git'] = 'Git repository'
39 BACKENDS['svn'] = 'Subversion repository'
39 BACKENDS['svn'] = 'Subversion repository'
40
40
41
41
42 CELERY_ENABLED = False
42 CELERY_ENABLED = False
43 CELERY_EAGER = False
43 CELERY_EAGER = False
44
44
45 # link to config for pyramid
45 # link to config for pyramid
46 CONFIG = {}
46 CONFIG = {}
47
47
48
48
49 class ConfigGet:
49 class ConfigGet:
50 NotGiven = object()
50 NotGiven = object()
51
51
52 def _get_val_or_missing(self, key, missing):
52 def _get_val_or_missing(self, key, missing):
53 if key not in CONFIG:
53 if key not in CONFIG:
54 if missing == self.NotGiven:
54 if missing == self.NotGiven:
55 return missing
55 return missing
56 # we don't get key, we don't get missing value, return nothing similar as config.get(key)
56 # we don't get key, we don't get missing value, return nothing similar as config.get(key)
57 return None
57 return None
58 else:
58 else:
59 val = CONFIG[key]
59 val = CONFIG[key]
60 return val
60 return val
61
61
62 def get_str(self, key, missing=NotGiven):
62 def get_str(self, key, missing=NotGiven):
63 from rhodecode.lib.str_utils import safe_str
63 from rhodecode.lib.str_utils import safe_str
64 val = self._get_val_or_missing(key, missing)
64 val = self._get_val_or_missing(key, missing)
65 return safe_str(val)
65 return safe_str(val)
66
66
67 def get_int(self, key, missing=NotGiven):
67 def get_int(self, key, missing=NotGiven):
68 from rhodecode.lib.str_utils import safe_int
68 from rhodecode.lib.str_utils import safe_int
69 val = self._get_val_or_missing(key, missing)
69 val = self._get_val_or_missing(key, missing)
70 return safe_int(val)
70 return safe_int(val)
71
71
72 def get_bool(self, key, missing=NotGiven):
72 def get_bool(self, key, missing=NotGiven):
73 from rhodecode.lib.type_utils import str2bool
73 from rhodecode.lib.type_utils import str2bool
74 val = self._get_val_or_missing(key, missing)
74 val = self._get_val_or_missing(key, missing)
75 return str2bool(val)
75 return str2bool(val)
76
76
77 # Populated with the settings dictionary from application init in
77 # Populated with the settings dictionary from application init in
78 # rhodecode.conf.environment.load_pyramid_environment
78 # rhodecode.conf.environment.load_pyramid_environment
79 PYRAMID_SETTINGS = {}
79 PYRAMID_SETTINGS = {}
80
80
81 # Linked module for extensions
81 # Linked module for extensions
82 EXTENSIONS = {}
82 EXTENSIONS = {}
83
83
84 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
84 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
85 __dbversion__ = 114 # defines current db version for migrations
85 __dbversion__ = 114 # defines current db version for migrations
86 __license__ = 'AGPLv3, and Commercial License'
86 __license__ = 'AGPLv3, and Commercial License'
87 __author__ = 'RhodeCode GmbH'
87 __author__ = 'RhodeCode GmbH'
88 __url__ = 'https://code.rhodecode.com'
88 __url__ = 'https://code.rhodecode.com'
89
89
90 is_test = os.getenv('RC_TEST')
90 is_test = os.getenv('RC_TEST', '0') == '1'
91 disable_error_handler = False
91 disable_error_handler = False
@@ -1,287 +1,290 b''
1
1
2 # Copyright (C) 2010-2023 RhodeCode GmbH
2 # Copyright (C) 2010-2023 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 from subprocess import Popen, PIPE
20 from subprocess import Popen, PIPE
21 import os
21 import os
22 import sys
22 import sys
23 import tempfile
23 import tempfile
24
24
25 import pytest
25 import pytest
26 from sqlalchemy.engine import url
26 from sqlalchemy.engine import url
27
27
28 from rhodecode.lib.str_utils import safe_str, safe_bytes
28 from rhodecode.lib.str_utils import safe_str, safe_bytes
29 from rhodecode.tests.fixture import TestINI
29 from rhodecode.tests.fixture import TestINI
30
30
31
31
32 def _get_dbs_from_metafunc(metafunc):
32 def _get_dbs_from_metafunc(metafunc):
33 dbs_mark = metafunc.definition.get_closest_marker('dbs')
33 dbs_mark = metafunc.definition.get_closest_marker('dbs')
34
34
35 if dbs_mark:
35 if dbs_mark:
36 # Supported backends by this test function, created from pytest.mark.dbs
36 # Supported backends by this test function, created from pytest.mark.dbs
37 backends = dbs_mark.args
37 backends = dbs_mark.args
38 else:
38 else:
39 backends = metafunc.config.getoption('--dbs')
39 backends = metafunc.config.getoption('--dbs')
40 return backends
40 return backends
41
41
42
42
43 def pytest_generate_tests(metafunc):
43 def pytest_generate_tests(metafunc):
44 # Support test generation based on --dbs parameter
44 # Support test generation based on --dbs parameter
45 if 'db_backend' in metafunc.fixturenames:
45 if 'db_backend' in metafunc.fixturenames:
46 requested_backends = set(metafunc.config.getoption('--dbs'))
46 requested_backends = set(metafunc.config.getoption('--dbs'))
47 backends = _get_dbs_from_metafunc(metafunc)
47 backends = _get_dbs_from_metafunc(metafunc)
48 backends = requested_backends.intersection(backends)
48 backends = requested_backends.intersection(backends)
49 # TODO: johbo: Disabling a backend did not work out with
49 # TODO: johbo: Disabling a backend did not work out with
50 # parametrization, find better way to achieve this.
50 # parametrization, find better way to achieve this.
51 if not backends:
51 if not backends:
52 metafunc.function._skip = True
52 metafunc.function._skip = True
53 metafunc.parametrize('db_backend_name', backends)
53 metafunc.parametrize('db_backend_name', backends)
54
54
55
55
56 def pytest_collection_modifyitems(session, config, items):
56 def pytest_collection_modifyitems(session, config, items):
57 remaining = [
57 remaining = [
58 i for i in items if not getattr(i.obj, '_skip', False)]
58 i for i in items if not getattr(i.obj, '_skip', False)]
59 items[:] = remaining
59 items[:] = remaining
60
60
61
61
62 @pytest.fixture()
62 @pytest.fixture()
63 def db_backend(
63 def db_backend(
64 request, db_backend_name, ini_config, tmpdir_factory):
64 request, db_backend_name, ini_config, tmpdir_factory):
65 basetemp = tmpdir_factory.getbasetemp().strpath
65 basetemp = tmpdir_factory.getbasetemp().strpath
66 klass = _get_backend(db_backend_name)
66 klass = _get_backend(db_backend_name)
67
67
68 option_name = '--{}-connection-string'.format(db_backend_name)
68 option_name = '--{}-connection-string'.format(db_backend_name)
69 connection_string = request.config.getoption(option_name) or None
69 connection_string = request.config.getoption(option_name) or None
70
70
71 return klass(
71 return klass(
72 config_file=ini_config, basetemp=basetemp,
72 config_file=ini_config, basetemp=basetemp,
73 connection_string=connection_string)
73 connection_string=connection_string)
74
74
75
75
76 def _get_backend(backend_type):
76 def _get_backend(backend_type):
77 return {
77 return {
78 'sqlite': SQLiteDBBackend,
78 'sqlite': SQLiteDBBackend,
79 'postgres': PostgresDBBackend,
79 'postgres': PostgresDBBackend,
80 'mysql': MySQLDBBackend,
80 'mysql': MySQLDBBackend,
81 '': EmptyDBBackend
81 '': EmptyDBBackend
82 }[backend_type]
82 }[backend_type]
83
83
84
84
85 class DBBackend(object):
85 class DBBackend(object):
86 _store = os.path.dirname(os.path.abspath(__file__))
86 _store = os.path.dirname(os.path.abspath(__file__))
87 _type = None
87 _type = None
88 _base_ini_config = [{'app:main': {'vcs.start_server': 'false',
88 _base_ini_config = [{'app:main': {'vcs.start_server': 'false',
89 'startup.import_repos': 'false'}}]
89 'startup.import_repos': 'false'}}]
90 _db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}]
90 _db_url = [{'app:main': {'sqlalchemy.db1.url': ''}}]
91 _base_db_name = 'rhodecode_test_db_backend'
91 _base_db_name = 'rhodecode_test_db_backend'
92 std_env = {'RC_TEST': '0'}
92
93
93 def __init__(
94 def __init__(
94 self, config_file, db_name=None, basetemp=None,
95 self, config_file, db_name=None, basetemp=None,
95 connection_string=None):
96 connection_string=None):
96
97
97 from rhodecode.lib.vcs.backends.hg import largefiles_store
98 from rhodecode.lib.vcs.backends.hg import largefiles_store
98 from rhodecode.lib.vcs.backends.git import lfs_store
99 from rhodecode.lib.vcs.backends.git import lfs_store
99
100
100 self.fixture_store = os.path.join(self._store, self._type)
101 self.fixture_store = os.path.join(self._store, self._type)
101 self.db_name = db_name or self._base_db_name
102 self.db_name = db_name or self._base_db_name
102 self._base_ini_file = config_file
103 self._base_ini_file = config_file
103 self.stderr = ''
104 self.stderr = ''
104 self.stdout = ''
105 self.stdout = ''
105 self._basetemp = basetemp or tempfile.gettempdir()
106 self._basetemp = basetemp or tempfile.gettempdir()
106 self._repos_location = os.path.join(self._basetemp, 'rc_test_repos')
107 self._repos_location = os.path.join(self._basetemp, 'rc_test_repos')
107 self._repos_hg_largefiles_store = largefiles_store(self._basetemp)
108 self._repos_hg_largefiles_store = largefiles_store(self._basetemp)
108 self._repos_git_lfs_store = lfs_store(self._basetemp)
109 self._repos_git_lfs_store = lfs_store(self._basetemp)
109 self.connection_string = connection_string
110 self.connection_string = connection_string
110
111
111 @property
112 @property
112 def connection_string(self):
113 def connection_string(self):
113 return self._connection_string
114 return self._connection_string
114
115
115 @connection_string.setter
116 @connection_string.setter
116 def connection_string(self, new_connection_string):
117 def connection_string(self, new_connection_string):
117 if not new_connection_string:
118 if not new_connection_string:
118 new_connection_string = self.get_default_connection_string()
119 new_connection_string = self.get_default_connection_string()
119 else:
120 else:
120 new_connection_string = new_connection_string.format(
121 new_connection_string = new_connection_string.format(
121 db_name=self.db_name)
122 db_name=self.db_name)
122 url_parts = url.make_url(new_connection_string)
123 url_parts = url.make_url(new_connection_string)
123 self._connection_string = new_connection_string
124 self._connection_string = new_connection_string
124 self.user = url_parts.username
125 self.user = url_parts.username
125 self.password = url_parts.password
126 self.password = url_parts.password
126 self.host = url_parts.host
127 self.host = url_parts.host
127
128
128 def get_default_connection_string(self):
129 def get_default_connection_string(self):
129 raise NotImplementedError('default connection_string is required.')
130 raise NotImplementedError('default connection_string is required.')
130
131
131 def execute(self, cmd, env=None, *args):
132 def execute(self, cmd, env=None, *args):
132 """
133 """
133 Runs command on the system with given ``args``.
134 Runs command on the system with given ``args``.
134 """
135 """
135
136
136 command = cmd + ' ' + ' '.join(args)
137 command = cmd + ' ' + ' '.join(args)
137 sys.stdout.write(command)
138 sys.stdout.write(f'CMD: {command}')
138
139
139 # Tell Python to use UTF-8 encoding out stdout
140 # Tell Python to use UTF-8 encoding out stdout
140 _env = os.environ.copy()
141 _env = os.environ.copy()
141 _env['PYTHONIOENCODING'] = 'UTF-8'
142 _env['PYTHONIOENCODING'] = 'UTF-8'
143 _env.update(self.std_env)
142 if env:
144 if env:
143 _env.update(env)
145 _env.update(env)
146
144 self.p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, env=_env)
147 self.p = Popen(command, shell=True, stdout=PIPE, stderr=PIPE, env=_env)
145 self.stdout, self.stderr = self.p.communicate()
148 self.stdout, self.stderr = self.p.communicate()
146 stdout_str = safe_str(self.stdout)
149 stdout_str = safe_str(self.stdout)
147 sys.stdout.write(f'COMMAND:{command}\n')
150 sys.stdout.write(f'COMMAND:{command}\n')
148 sys.stdout.write(stdout_str)
151 sys.stdout.write(stdout_str)
149 return self.stdout, self.stderr
152 return self.stdout, self.stderr
150
153
151 def assert_returncode_success(self):
154 def assert_returncode_success(self):
152 from rich import print as pprint
155 from rich import print as pprint
153 if not self.p.returncode == 0:
156 if not self.p.returncode == 0:
154 pprint(safe_str(self.stderr))
157 pprint(safe_str(self.stderr))
155 raise AssertionError(f'non 0 retcode:{self.p.returncode}')
158 raise AssertionError(f'non 0 retcode:{self.p.returncode}')
156
159
157 def assert_correct_output(self, stdout, version):
160 def assert_correct_output(self, stdout, version):
158 assert b'UPGRADE FOR STEP %b COMPLETED' % safe_bytes(version) in stdout
161 assert b'UPGRADE FOR STEP %b COMPLETED' % safe_bytes(version) in stdout
159
162
160 def setup_rhodecode_db(self, ini_params=None, env=None):
163 def setup_rhodecode_db(self, ini_params=None, env=None):
161 if not ini_params:
164 if not ini_params:
162 ini_params = self._base_ini_config
165 ini_params = self._base_ini_config
163
166
164 ini_params.extend(self._db_url)
167 ini_params.extend(self._db_url)
165 with TestINI(self._base_ini_file, ini_params,
168 with TestINI(self._base_ini_file, ini_params,
166 self._type, destroy=True) as _ini_file:
169 self._type, destroy=True) as _ini_file:
167
170
168 if not os.path.isdir(self._repos_location):
171 if not os.path.isdir(self._repos_location):
169 os.makedirs(self._repos_location)
172 os.makedirs(self._repos_location)
170 if not os.path.isdir(self._repos_hg_largefiles_store):
173 if not os.path.isdir(self._repos_hg_largefiles_store):
171 os.makedirs(self._repos_hg_largefiles_store)
174 os.makedirs(self._repos_hg_largefiles_store)
172 if not os.path.isdir(self._repos_git_lfs_store):
175 if not os.path.isdir(self._repos_git_lfs_store):
173 os.makedirs(self._repos_git_lfs_store)
176 os.makedirs(self._repos_git_lfs_store)
174
177
175 return self.execute(
178 return self.execute(
176 "rc-setup-app {0} --user=marcink "
179 "rc-setup-app {0} --user=marcink "
177 "--email=marcin@rhodeocode.com --password={1} "
180 "--email=marcin@rhodeocode.com --password={1} "
178 "--repos={2} --force-yes".format(
181 "--repos={2} --force-yes".format(
179 _ini_file, 'qweqwe', self._repos_location), env=env)
182 _ini_file, 'qweqwe', self._repos_location), env=env)
180
183
181 def upgrade_database(self, ini_params=None):
184 def upgrade_database(self, ini_params=None):
182 if not ini_params:
185 if not ini_params:
183 ini_params = self._base_ini_config
186 ini_params = self._base_ini_config
184 ini_params.extend(self._db_url)
187 ini_params.extend(self._db_url)
185
188
186 test_ini = TestINI(
189 test_ini = TestINI(
187 self._base_ini_file, ini_params, self._type, destroy=True)
190 self._base_ini_file, ini_params, self._type, destroy=True)
188 with test_ini as ini_file:
191 with test_ini as ini_file:
189 if not os.path.isdir(self._repos_location):
192 if not os.path.isdir(self._repos_location):
190 os.makedirs(self._repos_location)
193 os.makedirs(self._repos_location)
191
194
192 return self.execute(
195 return self.execute(
193 "rc-upgrade-db {0} --force-yes".format(ini_file))
196 "rc-upgrade-db {0} --force-yes".format(ini_file))
194
197
195 def setup_db(self):
198 def setup_db(self):
196 raise NotImplementedError
199 raise NotImplementedError
197
200
198 def teardown_db(self):
201 def teardown_db(self):
199 raise NotImplementedError
202 raise NotImplementedError
200
203
201 def import_dump(self, dumpname):
204 def import_dump(self, dumpname):
202 raise NotImplementedError
205 raise NotImplementedError
203
206
204
207
205 class EmptyDBBackend(DBBackend):
208 class EmptyDBBackend(DBBackend):
206 _type = ''
209 _type = ''
207
210
208 def setup_db(self):
211 def setup_db(self):
209 pass
212 pass
210
213
211 def teardown_db(self):
214 def teardown_db(self):
212 pass
215 pass
213
216
214 def import_dump(self, dumpname):
217 def import_dump(self, dumpname):
215 pass
218 pass
216
219
217 def assert_returncode_success(self):
220 def assert_returncode_success(self):
218 assert True
221 assert True
219
222
220
223
221 class SQLiteDBBackend(DBBackend):
224 class SQLiteDBBackend(DBBackend):
222 _type = 'sqlite'
225 _type = 'sqlite'
223
226
224 def get_default_connection_string(self):
227 def get_default_connection_string(self):
225 return 'sqlite:///{}/{}.sqlite'.format(self._basetemp, self.db_name)
228 return 'sqlite:///{}/{}.sqlite'.format(self._basetemp, self.db_name)
226
229
227 def setup_db(self):
230 def setup_db(self):
228 # dump schema for tests
231 # dump schema for tests
229 # cp -v $TEST_DB_NAME
232 # cp -v $TEST_DB_NAME
230 self._db_url = [{'app:main': {
233 self._db_url = [{'app:main': {
231 'sqlalchemy.db1.url': self.connection_string}}]
234 'sqlalchemy.db1.url': self.connection_string}}]
232
235
233 def import_dump(self, dumpname):
236 def import_dump(self, dumpname):
234 dump = os.path.join(self.fixture_store, dumpname)
237 dump = os.path.join(self.fixture_store, dumpname)
235 target = os.path.join(self._basetemp, '{0.db_name}.sqlite'.format(self))
238 target = os.path.join(self._basetemp, '{0.db_name}.sqlite'.format(self))
236 return self.execute(f'cp -v {dump} {target}')
239 return self.execute(f'cp -v {dump} {target}')
237
240
238 def teardown_db(self):
241 def teardown_db(self):
239 target_db = os.path.join(self._basetemp, self.db_name)
242 target_db = os.path.join(self._basetemp, self.db_name)
240 return self.execute(f"rm -rf {target_db}.sqlite")
243 return self.execute(f"rm -rf {target_db}.sqlite")
241
244
242
245
243 class MySQLDBBackend(DBBackend):
246 class MySQLDBBackend(DBBackend):
244 _type = 'mysql'
247 _type = 'mysql'
245
248
246 def get_default_connection_string(self):
249 def get_default_connection_string(self):
247 return 'mysql://root:qweqwe@127.0.0.1/{}'.format(self.db_name)
250 return 'mysql://root:qweqwe@127.0.0.1/{}'.format(self.db_name)
248
251
249 def setup_db(self):
252 def setup_db(self):
250 # dump schema for tests
253 # dump schema for tests
251 # mysqldump -uroot -pqweqwe $TEST_DB_NAME
254 # mysqldump -uroot -pqweqwe $TEST_DB_NAME
252 self._db_url = [{'app:main': {
255 self._db_url = [{'app:main': {
253 'sqlalchemy.db1.url': self.connection_string}}]
256 'sqlalchemy.db1.url': self.connection_string}}]
254 return self.execute("mysql -v -u{} -p{} -e 'create database '{}';'".format(
257 return self.execute("mysql -v -u{} -p{} -e 'create database '{}';'".format(
255 self.user, self.password, self.db_name))
258 self.user, self.password, self.db_name))
256
259
257 def import_dump(self, dumpname):
260 def import_dump(self, dumpname):
258 dump = os.path.join(self.fixture_store, dumpname)
261 dump = os.path.join(self.fixture_store, dumpname)
259 return self.execute("mysql -u{} -p{} {} < {}".format(
262 return self.execute("mysql -u{} -p{} {} < {}".format(
260 self.user, self.password, self.db_name, dump))
263 self.user, self.password, self.db_name, dump))
261
264
262 def teardown_db(self):
265 def teardown_db(self):
263 return self.execute("mysql -v -u{} -p{} -e 'drop database '{}';'".format(
266 return self.execute("mysql -v -u{} -p{} -e 'drop database '{}';'".format(
264 self.user, self.password, self.db_name))
267 self.user, self.password, self.db_name))
265
268
266
269
267 class PostgresDBBackend(DBBackend):
270 class PostgresDBBackend(DBBackend):
268 _type = 'postgres'
271 _type = 'postgres'
269
272
270 def get_default_connection_string(self):
273 def get_default_connection_string(self):
271 return 'postgresql://postgres:qweqwe@localhost/{}'.format(self.db_name)
274 return 'postgresql://postgres:qweqwe@localhost/{}'.format(self.db_name)
272
275
273 def setup_db(self):
276 def setup_db(self):
274 # dump schema for tests
277 # dump schema for tests
275 # pg_dump -U postgres -h localhost $TEST_DB_NAME
278 # pg_dump -U postgres -h localhost $TEST_DB_NAME
276 self._db_url = [{'app:main': {'sqlalchemy.db1.url': self.connection_string}}]
279 self._db_url = [{'app:main': {'sqlalchemy.db1.url': self.connection_string}}]
277 cmd = f"PGPASSWORD={self.password} psql -U {self.user} -h localhost -c 'create database '{self.db_name}';'"
280 cmd = f"PGPASSWORD={self.password} psql -U {self.user} -h localhost -c 'create database '{self.db_name}';'"
278 return self.execute(cmd)
281 return self.execute(cmd)
279
282
280 def teardown_db(self):
283 def teardown_db(self):
281 cmd = f"PGPASSWORD={self.password} psql -U {self.user} -h localhost -c 'drop database if exists '{self.db_name}';'"
284 cmd = f"PGPASSWORD={self.password} psql -U {self.user} -h localhost -c 'drop database if exists '{self.db_name}';'"
282 return self.execute(cmd)
285 return self.execute(cmd)
283
286
284 def import_dump(self, dumpname):
287 def import_dump(self, dumpname):
285 dump = os.path.join(self.fixture_store, dumpname)
288 dump = os.path.join(self.fixture_store, dumpname)
286 cmd = f"PGPASSWORD={self.password} psql -U {self.user} -h localhost -d {self.db_name} -1 -f {dump}"
289 cmd = f"PGPASSWORD={self.password} psql -U {self.user} -h localhost -d {self.db_name} -1 -f {dump}"
287 return self.execute(cmd)
290 return self.execute(cmd)
General Comments 0
You need to be logged in to leave comments. Login now