2
# -*- coding: utf-8 -*-
8
from migrate.versioning import exceptions, version, repository
9
from migrate.versioning.script import *
10
from migrate.versioning.util import *
12
from migrate.tests import fixture
13
from migrate.tests.fixture.models import tmp_sql_table
16
class TestBaseScript(fixture.Pathed):
19
"""Testing all basic BaseScript operations"""
20
# verify / source / run
22
open(src, 'w').close()
23
bscript = BaseScript(src)
24
BaseScript.verify(src)
25
self.assertEqual(bscript.source(), '')
26
self.assertRaises(NotImplementedError, bscript.run, 'foobar')
29
class TestPyScript(fixture.Pathed, fixture.DB):
31
def test_create(self):
32
"""We can create a migration script"""
34
# Creating a file that doesn't exist should succeed
36
self.assert_(os.path.exists(path))
37
# Created file should be a valid script (If not, raises an error)
39
# Can't create it again: it already exists
40
self.assertRaises(exceptions.PathFoundError,self.cls.create,path)
42
@fixture.usedb(supported='sqlite')
44
script_path = self.tmp_py()
45
pyscript = PythonScript.create(script_path)
46
pyscript.run(self.engine, 1)
47
pyscript.run(self.engine, -1)
49
self.assertRaises(exceptions.ScriptError, pyscript.run, self.engine, 0)
50
self.assertRaises(exceptions.ScriptError, pyscript._func, 'foobar')
53
os.remove(script_path + 'c')
55
# test deprecated upgrade/downgrade with no arguments
56
contents = open(script_path, 'r').read()
57
f = open(script_path, 'w')
58
f.write(contents.replace("upgrade(migrate_engine)", "upgrade()"))
61
pyscript = PythonScript(script_path)
62
pyscript._module = None
64
pyscript.run(self.engine, 1)
65
pyscript.run(self.engine, -1)
66
except exceptions.ScriptError:
71
def test_verify_notfound(self):
72
"""Correctly verify a python migration script: nonexistant file"""
74
self.assertFalse(os.path.exists(path))
76
self.assertRaises(exceptions.InvalidScriptError,self.cls.verify,path)
77
self.assertRaises(exceptions.InvalidScriptError,self.cls,path)
79
def test_verify_invalidpy(self):
80
"""Correctly verify a python migration script: invalid python file"""
86
self.assertRaises(Exception,self.cls.verify_module,path)
87
# script isn't verified on creation, but on module reference
89
self.assertRaises(Exception,(lambda x: x.module),py)
91
def test_verify_nofuncs(self):
92
"""Correctly verify a python migration script: valid python file; no upgrade func"""
96
f.write("def zergling():\n\tprint 'rush'")
98
self.assertRaises(exceptions.InvalidScriptError, self.cls.verify_module, path)
99
# script isn't verified on creation, but on module reference
101
self.assertRaises(exceptions.InvalidScriptError,(lambda x: x.module),py)
103
@fixture.usedb(supported='sqlite')
104
def test_preview_sql(self):
105
"""Preview SQL abstract from ORM layer (sqlite)"""
110
from migrate import *
111
from sqlalchemy import *
113
metadata = MetaData()
115
UserGroup = Table('Link', metadata,
116
Column('link1ID', Integer),
117
Column('link2ID', Integer),
118
UniqueConstraint('link1ID', 'link2ID'))
120
def upgrade(migrate_engine):
121
metadata.create_all(migrate_engine)
126
pyscript = self.cls(path)
127
SQL = pyscript.preview_sql(self.url, 1)
128
self.assertEqualsIgnoreWhitespace("""
132
UNIQUE ("link1ID", "link2ID"))
134
# TODO: test: No SQL should be executed!
136
def test_verify_success(self):
137
"""Correctly verify a python migration script: success"""
139
# Succeeds after creating
140
self.cls.create(path)
141
self.cls.verify(path)
143
# test for PythonScript.make_update_script_for_model
146
def test_make_update_script_for_model(self):
147
"""Construct script source from differences of two models"""
149
self.setup_model_params()
150
self.write_file(self.first_model_path, self.base_source)
151
self.write_file(self.second_model_path, self.base_source + self.model_source)
153
source_script = self.pyscript.make_update_script_for_model(
155
oldmodel=load_model('testmodel_first:meta'),
156
model=load_model('testmodel_second:meta'),
157
repository=self.repo_path,
160
self.assertTrue('User.create()' in source_script)
161
self.assertTrue('User.drop()' in source_script)
164
#def test_make_update_script_for_model_equals(self):
165
# """Try to make update script from two identical models"""
167
# self.setup_model_params()
168
# self.write_file(self.first_model_path, self.base_source + self.model_source)
169
# self.write_file(self.second_model_path, self.base_source + self.model_source)
171
# source_script = self.pyscript.make_update_script_for_model(
172
# engine=self.engine,
173
# oldmodel=load_model('testmodel_first:meta'),
174
# model=load_model('testmodel_second:meta'),
175
# repository=self.repo_path,
178
# self.assertFalse('User.create()' in source_script)
179
# self.assertFalse('User.drop()' in source_script)
181
def setup_model_params(self):
182
self.script_path = self.tmp_py()
183
self.repo_path = self.tmp()
184
self.first_model_path = os.path.join(self.temp_usable_dir, 'testmodel_first.py')
185
self.second_model_path = os.path.join(self.temp_usable_dir, 'testmodel_second.py')
187
self.base_source = """from sqlalchemy import *\nmeta = MetaData()\n"""
188
self.model_source = """
189
User = Table('User', meta,
190
Column('id', Integer, primary_key=True),
191
Column('login', Unicode(40)),
192
Column('passwd', String(40)),
195
self.repo = repository.Repository.create(self.repo_path, 'repo')
196
self.pyscript = PythonScript.create(self.script_path)
198
def write_file(self, path, contents):
204
class TestSqlScript(fixture.Pathed, fixture.DB):
207
def test_error(self):
208
"""Test if exception is raised on wrong script source"""
212
f.write("""foobar""")
215
sqls = SqlScript(src)
216
self.assertRaises(Exception, sqls.run, self.engine)
219
def test_success(self):
220
"""Test sucessful SQL execution"""
221
# cleanup and prepare python script
222
tmp_sql_table.metadata.drop_all(self.engine, checkfirst=True)
223
script_path = self.tmp_py()
224
pyscript = PythonScript.create(script_path)
226
# populate python script
227
contents = open(script_path, 'r').read()
228
contents = contents.replace("pass", "tmp_sql_table.create(migrate_engine)")
229
contents = 'from migrate.tests.fixture.models import tmp_sql_table\n' + contents
230
f = open(script_path, 'w')
234
# write SQL script from python script preview
235
pyscript = PythonScript(script_path)
238
f.write(pyscript.preview_sql(self.url, 1))
242
sqls = SqlScript(src)
243
sqls.run(self.engine, executemany=False)
244
tmp_sql_table.metadata.drop_all(self.engine, checkfirst=True)