Skip to content

Commit

Permalink
Log queries during upgrade tests, and compare indexes
Browse files Browse the repository at this point in the history
Note that this fails: none of the changes or schedulers indexes exist
after upgrade with SQLite (Which is the only DB that the upgrade tests
use).  Hand verification shows that they do exist with MySQL and
Postgres.
  • Loading branch information
djmitche committed Nov 29, 2011
1 parent 2aa97b8 commit 9bdc51d
Showing 1 changed file with 65 additions and 35 deletions.
100 changes: 65 additions & 35 deletions master/buildbot/test/integration/test_upgrade.py
Expand Up @@ -22,11 +22,12 @@
from twisted.internet import defer
from twisted.trial import unittest
import sqlalchemy as sa
from sqlalchemy.engine import reflection
import migrate
import migrate.versioning.api
from migrate.versioning import schemadiff
from buildbot.db import connector
from buildbot.test.util import change_import, db, dirs
from buildbot.test.util import change_import, db, dirs, querylog
from buildbot.test.fake import fakemaster

# monkey-patch for "compare_model_to_db gets confused by sqlite_sequence",
Expand Down Expand Up @@ -64,26 +65,35 @@ class UpgradeTestMixin(object):
def setUpUpgradeTest(self):
self.basedir = None

tarball = util.sibpath(__file__, self.source_tarball)
if not os.path.exists(tarball):
raise unittest.SkipTest(
"'%s' not found (normal when not building from Git)" % tarball)

tf = tarfile.open(tarball)
prefixes = set()
for inf in tf:
tf.extract(inf)
prefixes.add(inf.name.split('/', 1)[0])
# (note that tf.extractall isn't available in py2.4)

# get the top-level dir from the tarball
assert len(prefixes) == 1, "tarball has multiple top-level dirs!"
self.basedir = prefixes.pop()
if self.source_tarball:
tarball = util.sibpath(__file__, self.source_tarball)
if not os.path.exists(tarball):
raise unittest.SkipTest(
"'%s' not found (normal when not building from Git)"
% tarball)

tf = tarfile.open(tarball)
prefixes = set()
for inf in tf:
tf.extract(inf)
prefixes.add(inf.name.split('/', 1)[0])
# (note that tf.extractall isn't available in py2.4)

# get the top-level dir from the tarball
assert len(prefixes) == 1, "tarball has multiple top-level dirs!"
self.basedir = prefixes.pop()
else:
os.makedirs("basedir")
self.basedir = os.path.abspath("basedir")

master = fakemaster.make_master()
master.config.db['db_url'] = self.db_url
self.db = connector.DBConnector(master, self.basedir)
return self.db.setup(check_version=False)
d = self.db.setup(check_version=False)
@d.addCallback
def setup_logging(_):
querylog.log_from_engine(self.db.pool.engine)
return d

def tearDownUpgradeTest(self):
if self.basedir:
Expand All @@ -109,11 +119,46 @@ def assertModelMatches(self):
self.patch(schemadiff, 'getDiffOfModelAgainstDatabase',
getDiffMonkeyPatch)
def comp(engine):
# get a fresh model/metadata
return migrate.versioning.api.compare_model_to_db(
# use compare_model_to_db, which gets everything but foreign
# keys and indexes
diff = migrate.versioning.api.compare_model_to_db(
engine,
self.db.model.repo_path,
self.db.model.metadata)
if diff:
return diff

# check indexes manually
insp = reflection.Inspector.from_engine(engine)
# unique, name, column_names
diff = []
for tbl in self.db.model.metadata.sorted_tables:
exp = sorted([
dict(name=idx.name,
unique=1 if idx.unique else 0,
column_names=[ c.name for c in idx.columns ])
for idx in tbl.indexes ])
got = sorted(insp.get_indexes(tbl.name))
if exp != got:
got_names = set([ idx['name'] for idx in got ])
exp_names = set([ idx['name'] for idx in exp ])
for name in got_names - exp_names:
diff.append("got unexpected index %s on table %s"
% (name, tbl.name))
for name in exp_names - got_names:
diff.append("missing index %s on table %s"
% (name, tbl.name))
got_info = dict( (idx['name'],idx) for idx in got )
exp_info = dict( (idx['name'],idx) for idx in exp )
for name in got_names & exp_names:
if got_info[name] != exp_info[name]:
diff.append(
"index %s on table %s differs: got %s; exp %s"
% (name, tbl.name, got_info[name],
exp_info[name]))
if diff:
return "\n".join(diff)

d = self.db.pool.do_with_engine(comp)

# older sqlites cause failures in reflection, which manifest as a
Expand All @@ -125,6 +170,7 @@ def catch_TypeError(f):
raise unittest.SkipTest("model comparison skipped: bugs in schema "
"reflection on this sqlite version")
d.addErrback(catch_TypeError)

def check(diff):
if diff:
self.fail(str(diff))
Expand All @@ -146,22 +192,6 @@ class UpgradeTestEmpty(dirs.DirsMixin,
db.RealDatabaseMixin,
unittest.TestCase):

def setUp(self):
self.basedir = os.path.abspath("basedir")
self.setUpDirs('basedir')
d = self.setUpRealDatabase()
def make_dbc(_):
master = fakemaster.make_master()
self.db = connector.DBConnector(master, self.basedir)
master.config.db['db_url'] = self.db_url
self.db.setup(check_version=False)
d.addCallback(make_dbc)
return d

def tearDown(self):
self.tearDownDirs()
return self.tearDownRealDatabase()

def test_emptydb_modelmatches(self):
d = self.db.model.upgrade()
d.addCallback(lambda r : self.assertModelMatches())
Expand Down

0 comments on commit 9bdc51d

Please sign in to comment.