def test_addBuildsetForSourceStamp_combine_change_properties(self): sched = self.makeScheduler() self.master.db.insertTestData([ fakedb.SourceStamp(id=98, branch='stable'), fakedb.Change(changeid=25, sourcestampid=98, branch='stable'), fakedb.ChangeProperty(changeid=25, property_name='color', property_value='["pink","Change"]'), ]) bsid, brids = yield sched.addBuildsetForSourceStamps(reason='whynot', waited_for=False, sourcestamps=[98]) self.assertEqual((bsid, brids), self.exp_bsid_brids) self.master.data.updates.addBuildset.assert_called_with( waited_for=False, builderids=[1, 2], external_idstring=None, properties={ 'scheduler': ('testsched', 'Scheduler'), 'color': ('pink', 'Change') }, reason='whynot', scheduler='testsched', sourcestamps=[98])
def test_addBuildsetForSourceStamp_list_of_renderable_builderNames(self): names = ['a', 'b', properties.Interpolate('%(prop:extra_builder)s')] sched = self.makeScheduler(name='n', builderNames=names) self.master.db.insertTestData([ fakedb.Builder(id=1, name='a'), fakedb.Builder(id=2, name='b'), fakedb.Builder(id=3, name='c'), fakedb.SourceStamp(id=98, branch='stable'), fakedb.Change(changeid=25, sourcestampid=98, branch='stable'), fakedb.ChangeProperty(changeid=25, property_name='extra_builder', property_value='["c","Change"]'), ]) bsid, brids = yield sched.addBuildsetForSourceStamps(reason=u'whynot', waited_for=False, sourcestamps=[98]) self.assertEqual((bsid, brids), self.exp_bsid_brids) self.master.data.updates.addBuildset.assert_called_with( waited_for=False, builderids=[1, 2, 3], external_idstring=None, properties={ u'scheduler': (u'n', u'Scheduler'), u'extra_builder': (u'c', u'Change')}, reason=u'whynot', scheduler=u'n', sourcestamps=[98])
def test_bogus_row_jsoned_list(self): yield self.insertTestData([ fakedb.SourceStamp(id=10), fakedb.ChangeProperty(changeid=13, property_name='devel', property_value='[1, 2]'), fakedb.Change(changeid=13, sourcestampid=10), ]) c = yield self.db.changes.getChange(13) self.assertEqual(c['properties'], dict(devel=([1, 2], 'Change')))
def test_bogus_row_jsoned_list(self): d = self.insertTestData([ fakedb.ChangeProperty(changeid=13, property_name='devel', property_value='[1, 2]'), fakedb.Change(changeid=13), ]) def get13(_): return self.db.changes.getChange(13) d.addCallback(get13) def check13(c): self.assertEqual(c['properties'], dict(devel=([1, 2], 'Change'))) d.addCallback(check13) return d
def test_bogus_row_no_source(self): d = self.insertTestData([ fakedb.SourceStamp(id=10), fakedb.ChangeProperty(changeid=13, property_name='devel', property_value='"no source"'), fakedb.Change(changeid=13, sourcestampid=10), ]) @d.addCallback def get13(_): return self.db.changes.getChange(13) @d.addCallback def check13(c): self.assertEqual(c['properties'], dict(devel=('no source', 'Change'))) return d
def test_getPropertiesFromDb(self): d = self.insertTestData([ fakedb.Change(changeid=13), fakedb.ChangeProperty(changeid=13, property_name='foo', property_value='"my prop"'), fakedb.SourceStamp(id=23), fakedb.Buildset(id=33, sourcestampid=23), fakedb.BuildsetProperty(buildsetid=33, property_name='bar', property_value='["other prop", "BS"]'), ]) def do_test(_): cprops = self.dbc.get_properties_from_db("change_properties", "changeid", 13) bprops = self.dbc.get_properties_from_db("buildset_properties", "buildsetid", 33) self.assertEqual(cprops.asList() + bprops.asList(), [('foo', 'my prop', 'Change'), ('bar', 'other prop', 'BS')]) d.addCallback(do_test) return d
class Change(unittest.TestCase): change23_rows = [ fakedb.Change(changeid=23, author="dustin", comments="fix whitespace", branch="warnerdb", revision="deadbeef", when_timestamp=266738404, revlink='http://warner/0e92a098b', category='devel', repository='git://warner', codebase='mainapp', project='Buildbot'), fakedb.ChangeFile(changeid=23, filename='master/README.txt'), fakedb.ChangeFile(changeid=23, filename='worker/README.txt'), fakedb.ChangeProperty(changeid=23, property_name='notest', property_value='["no","Change"]'), fakedb.ChangeUser(changeid=23, uid=27), ] def setUp(self): self.master = fakemaster.make_master(testcase=self, wantDb=True) self.change23 = changes.Change( **dict( # using **dict(..) forces kwargs category='devel', repository=u'git://warner', codebase=u'mainapp', who=u'dustin', when=266738404, comments=u'fix whitespace', project=u'Buildbot', branch=u'warnerdb', revlink=u'http://warner/0e92a098b', properties={'notest': "no"}, files=[u'master/README.txt', u'worker/README.txt'], revision=u'deadbeef')) self.change23.number = 23 @defer.inlineCallbacks def test_fromChdict(self): # get a real honest-to-goodness chdict from the fake db yield self.master.db.insertTestData(self.change23_rows) chdict = yield self.master.db.changes.getChange(23) exp = self.change23 got = yield changes.Change.fromChdict(self.master, chdict) # compare ok = True ok = ok and got.number == exp.number ok = ok and got.who == exp.who ok = ok and sorted(got.files) == sorted(exp.files) ok = ok and got.comments == exp.comments ok = ok and got.revision == exp.revision ok = ok and got.when == exp.when ok = ok and got.branch == exp.branch ok = ok and got.category == exp.category ok = ok and got.revlink == exp.revlink ok = ok and got.properties == exp.properties ok = ok and got.repository == exp.repository ok = ok and got.codebase == exp.codebase ok = ok and got.project == exp.project if not ok: def printable(c): return pprint.pformat(c.__dict__) self.fail("changes do not match; expected\n%s\ngot\n%s" % (printable(exp), printable(got))) def test_str(self): string = str(self.change23) self.assertTrue(re.match(r"Change\(.*\)", string), string) def test_asText(self): text = self.change23.asText() self.assertTrue( re.match( textwrap.dedent(u'''\ Files: master/README.txt worker/README.txt On: git://warner For: Buildbot At: .* Changed By: dustin Comments: fix whitespaceProperties:. notest: no '''), text), text) def test_asDict(self): dict = self.change23.asDict() self.assertIn('1978', dict['at']) # timezone-sensitive del dict['at'] self.assertEqual( dict, { 'branch': u'warnerdb', 'category': u'devel', 'codebase': u'mainapp', 'comments': u'fix whitespace', 'files': [{ 'name': u'master/README.txt' }, { 'name': u'worker/README.txt' }], 'number': 23, 'project': u'Buildbot', 'properties': [('notest', 'no', 'Change')], 'repository': u'git://warner', 'rev': u'deadbeef', 'revision': u'deadbeef', 'revlink': u'http://warner/0e92a098b', 'when': 266738404, 'who': u'dustin' }) def test_getShortAuthor(self): self.assertEqual(self.change23.getShortAuthor(), 'dustin') def test_getTime(self): # careful, or timezones will hurt here self.assertIn('Jun 1978', self.change23.getTime()) def test_getTimes(self): self.assertEqual(self.change23.getTimes(), (266738404, None)) def test_getText(self): self.change23.who = 'nasty < nasty' # test the html escaping (ugh!) self.assertEqual(self.change23.getText(), ['nasty < nasty']) def test_getLogs(self): self.assertEqual(self.change23.getLogs(), {})
class Tests(interfaces.InterfaceTests): # common sample data change13_rows = [ fakedb.SourceStamp(id=92, branch="thirteen"), fakedb.Change(changeid=13, author="dustin", comments="fix spelling", branch="master", revision="deadbeef", when_timestamp=266738400, revlink=None, category=None, repository='', codebase='', project='', sourcestampid=92), fakedb.ChangeFile(changeid=13, filename='master/README.txt'), fakedb.ChangeFile(changeid=13, filename='worker/README.txt'), fakedb.ChangeProperty(changeid=13, property_name='notest', property_value='["no","Change"]'), ] change14_rows = [ fakedb.SourceStamp(id=233, branch="fourteen"), fakedb.Change(changeid=14, author="warner", comments="fix whitespace", branch="warnerdb", revision="0e92a098b", when_timestamp=266738404, revlink='http://warner/0e92a098b', category='devel', repository='git://warner', codebase='mainapp', project='Buildbot', sourcestampid=233), fakedb.ChangeFile(changeid=14, filename='master/buildbot/__init__.py'), ] change14_dict = { 'changeid': 14, 'parent_changeids': [], 'author': u'warner', 'branch': u'warnerdb', 'category': u'devel', 'comments': u'fix whitespace', 'files': [u'master/buildbot/__init__.py'], 'project': u'Buildbot', 'properties': {}, 'repository': u'git://warner', 'codebase': u'mainapp', 'revision': u'0e92a098b', 'revlink': u'http://warner/0e92a098b', 'when_timestamp': epoch2datetime(266738404), 'sourcestampid': 233, } # tests def test_signature_addChange(self): @self.assertArgSpecMatches(self.db.changes.addChange) def addChange(self, author=None, files=None, comments=None, is_dir=None, revision=None, when_timestamp=None, branch=None, category=None, revlink='', properties=None, repository='', codebase='', project='', uid=None): pass def test_signature_getChange(self): @self.assertArgSpecMatches(self.db.changes.getChange) def getChange(self, key, no_cache=False): pass @defer.inlineCallbacks def test_addChange_getChange(self): clock = task.Clock() clock.advance(SOMETIME) changeid = yield self.db.changes.addChange( author=u'dustin', files=[], comments=u'fix spelling', revision=u'2d6caa52', when_timestamp=epoch2datetime(OTHERTIME), branch=u'master', category=None, revlink=None, properties={}, repository=u'repo://', codebase=u'cb', project=u'proj', _reactor=clock) chdict = yield self.db.changes.getChange(changeid) validation.verifyDbDict(self, 'chdict', chdict) chdict = chdict.copy() ss = yield self.db.sourcestamps.getSourceStamp(chdict['sourcestampid']) chdict['sourcestampid'] = ss self.assertEqual( chdict, { 'author': u'dustin', 'branch': u'master', 'category': None, 'changeid': changeid, 'parent_changeids': [], 'codebase': u'cb', 'comments': u'fix spelling', 'files': [], 'project': u'proj', 'properties': {}, 'repository': u'repo://', 'revision': u'2d6caa52', 'revlink': None, 'sourcestampid': { 'branch': u'master', 'codebase': u'cb', 'patch_author': None, 'patch_body': None, 'patch_comment': None, 'patch_level': None, 'patch_subdir': None, 'patchid': None, 'project': u'proj', 'repository': u'repo://', 'revision': u'2d6caa52', 'created_at': epoch2datetime(SOMETIME), 'ssid': ss['ssid'], }, 'when_timestamp': epoch2datetime(OTHERTIME), }) @defer.inlineCallbacks def test_addChange_withParent(self): yield self.insertTestData(self.change14_rows) clock = task.Clock() clock.advance(SOMETIME) changeid = yield self.db.changes.addChange( author=u'delanne', files=[], comments=u'child of changeid14', revision=u'50adad56', when_timestamp=epoch2datetime(OTHERTIME), branch=u'warnerdb', category=u'devel', revlink=None, properties={}, repository=u'git://warner', codebase=u'mainapp', project=u'Buildbot', _reactor=clock) chdict = yield self.db.changes.getChange(changeid) validation.verifyDbDict(self, 'chdict', chdict) chdict = chdict.copy() ss = yield self.db.sourcestamps.getSourceStamp(chdict['sourcestampid']) chdict['sourcestampid'] = ss self.assertEqual( chdict, { 'author': u'delanne', 'branch': u'warnerdb', 'category': u'devel', 'changeid': changeid, 'parent_changeids': [14], 'codebase': u'mainapp', 'comments': u'child of changeid14', 'files': [], 'project': u'Buildbot', 'properties': {}, 'repository': u'git://warner', 'revision': u'50adad56', 'revlink': None, 'sourcestampid': { 'branch': u'warnerdb', 'codebase': u'mainapp', 'created_at': epoch2datetime(SOMETIME), 'patch_author': None, 'patch_body': None, 'patch_comment': None, 'patch_level': None, 'patch_subdir': None, 'patchid': None, 'project': u'Buildbot', 'repository': u'git://warner', 'revision': u'50adad56', 'ssid': ss['ssid'] }, 'when_timestamp': epoch2datetime(OTHERTIME), }) def test_getChange_chdict(self): d = self.insertTestData(self.change14_rows) def get14(_): return self.db.changes.getChange(14) d.addCallback(get14) def check14(chdict): validation.verifyDbDict(self, 'chdict', chdict) self.assertEqual(chdict, self.change14_dict) d.addCallback(check14) return d def test_getChange_missing(self): d = defer.succeed(None) def get14(_): return self.db.changes.getChange(14) d.addCallback(get14) def check14(chdict): self.failUnless(chdict is None) d.addCallback(check14) return d def test_signature_getChangeUids(self): @self.assertArgSpecMatches(self.db.changes.getChangeUids) def getChangeUids(self, changeid): pass def test_getChangeUids_missing(self): d = self.db.changes.getChangeUids(1) def check(res): self.assertEqual(res, []) d.addCallback(check) return d def test_getChangeUids_found(self): d = self.insertTestData(self.change14_rows + [ fakedb.SourceStamp(id=92), fakedb.User(uid=1), fakedb.ChangeUser(changeid=14, uid=1), ]) d.addCallback(lambda _: self.db.changes.getChangeUids(14)) def check(res): self.assertEqual(res, [1]) d.addCallback(check) return d def test_getChangeUids_multi(self): d = self.insertTestData(self.change14_rows + self.change13_rows + [ fakedb.User(uid=1, identifier="one"), fakedb.User(uid=2, identifier="two"), fakedb.User(uid=99, identifier="nooo"), fakedb.ChangeUser(changeid=14, uid=1), fakedb.ChangeUser(changeid=14, uid=2), fakedb.ChangeUser(changeid=13, uid=99), # not selected ]) d.addCallback(lambda _: self.db.changes.getChangeUids(14)) def check(res): self.assertEqual(sorted(res), [1, 2]) d.addCallback(check) return d def test_signature_getRecentChanges(self): @self.assertArgSpecMatches(self.db.changes.getRecentChanges) def getRecentChanges(self, count): pass def test_signature_getChanges(self): @self.assertArgSpecMatches(self.db.changes.getChanges) def getChanges(self): pass def insert7Changes(self): return self.insertTestData([ fakedb.SourceStamp(id=922), fakedb.Change(changeid=8, sourcestampid=922), fakedb.Change(changeid=9, sourcestampid=922), fakedb.Change(changeid=10, sourcestampid=922), fakedb.Change(changeid=11, sourcestampid=922), fakedb.Change(changeid=12, sourcestampid=922), ] + self.change13_rows + self.change14_rows) def test_getRecentChanges_subset(self): d = self.insert7Changes() d.addCallback(lambda _: self.db.changes.getRecentChanges(5)) def check(changes): changeids = [c['changeid'] for c in changes] self.assertEqual(changeids, [10, 11, 12, 13, 14]) d.addCallback(check) return d def test_getChangesCount(self): d = self.insert7Changes() d.addCallback(lambda _: self.db.changes.getChangesCount()) def check(n): self.assertEqual(n, 7) d.addCallback(check) return d def test_getChangesHugeCount(self): d = self.insertTestData([ fakedb.SourceStamp(id=92), ] + [fakedb.Change(changeid=i) for i in range(2, 102)]) d.addCallback(lambda _: self.db.changes.getChangesCount()) def check(n): self.assertEqual(n, 100) d.addCallback(check) return d def test_getRecentChanges_empty(self): d = defer.succeed(None) d.addCallback(lambda _: self.db.changes.getRecentChanges(5)) def check(changes): changeids = [c['changeid'] for c in changes] self.assertEqual(changeids, []) d.addCallback(check) d.addCallback(lambda _: self.db.changes.getChanges()) d.addCallback(check) return d def test_getRecentChanges_missing(self): d = self.insertTestData(self.change13_rows + self.change14_rows) d.addCallback(lambda _: self.db.changes.getRecentChanges(5)) def check(changes): # requested all, but only got 2 # sort by changeid, since we assert on change 13 at index 0 changes.sort(key=lambda c: c['changeid']) changeids = [c['changeid'] for c in changes] self.assertEqual(changeids, [13, 14]) # double-check that they have .files, etc. self.assertEqual( sorted(changes[0]['files']), sorted(['master/README.txt', 'worker/README.txt'])) self.assertEqual(changes[0]['properties'], {'notest': ('no', 'Change')}) d.addCallback(check) d.addCallback(lambda _: self.db.changes.getChanges()) d.addCallback(check) return d def test_signature_getLatestChangeid(self): @self.assertArgSpecMatches(self.db.changes.getLatestChangeid) def getLatestChangeid(self): pass def test_getLatestChangeid(self): d = self.insertTestData(self.change13_rows) def get(_): return self.db.changes.getLatestChangeid() d.addCallback(get) def check(changeid): self.assertEqual(changeid, 13) d.addCallback(check) return d def test_getLatestChangeid_empty(self): d = defer.succeed(None) def get(_): return self.db.changes.getLatestChangeid() d.addCallback(get) def check(changeid): self.assertEqual(changeid, None) d.addCallback(check) return d def test_signature_getParentChangeIds(self): @self.assertArgSpecMatches(self.db.changes.getParentChangeIds) def getParentChangeIds(self, branch, repository, project, codebase): pass def test_getParentChangeIds(self): d = self.insertTestData(self.change14_rows + self.change13_rows) def getParent(_): return self.db.changes.getParentChangeIds( branch='warnerdb', repository='git://warner', project='Buildbot', codebase='mainapp') d.addCallback(getParent) def check(changeid): self.assertEqual(changeid, [14]) d.addCallback(check) return d
class TestChangesConnectorComponent( connector_component.ConnectorComponentMixin, unittest.TestCase): def setUp(self): d = self.setUpConnectorComponent( table_names=['changes', 'change_files', 'change_properties', 'scheduler_changes', 'objects', 'sourcestampsets', 'sourcestamps', 'sourcestamp_changes', 'patches', 'change_users', 'users']) def finish_setup(_): self.db.changes = changes.ChangesConnectorComponent(self.db) d.addCallback(finish_setup) return d def tearDown(self): return self.tearDownConnectorComponent() # common sample data change13_rows = [ fakedb.Change(changeid=13, author="dustin", comments="fix spelling", is_dir=0, branch="master", revision="deadbeef", when_timestamp=266738400, revlink=None, category=None, repository='', codebase='', project=''), fakedb.ChangeFile(changeid=13, filename='master/README.txt'), fakedb.ChangeFile(changeid=13, filename='slave/README.txt'), fakedb.ChangeProperty(changeid=13, property_name='notest', property_value='["no","Change"]'), ] change14_rows = [ fakedb.Change(changeid=14, author="warner", comments="fix whitespace", is_dir=0, branch="warnerdb", revision="0e92a098b", when_timestamp=266738404, revlink='http://warner/0e92a098b', category='devel', repository='git://warner', codebase='mainapp', project='Buildbot'), fakedb.ChangeFile(changeid=14, filename='master/buildbot/__init__.py'), ] change14_dict = { 'changeid': 14, 'author': u'warner', 'branch': u'warnerdb', 'category': u'devel', 'comments': u'fix whitespace', 'files': [u'master/buildbot/__init__.py'], 'is_dir': 0, 'project': u'Buildbot', 'properties': {}, 'repository': u'git://warner', 'codebase': u'mainapp', 'revision': u'0e92a098b', 'revlink': u'http://warner/0e92a098b', 'when_timestamp': epoch2datetime(266738404), } def change14(self): c = Change(**dict( category='devel', isdir=0, repository=u'git://warner', codebase=u'mainapp', who=u'warner', when=266738404, comments=u'fix whitespace', project=u'Buildbot', branch=u'warnerdb', revlink=u'http://warner/0e92a098b', properties={}, files=[u'master/buildbot/__init__.py'], revision=u'0e92a098b')) c.number = 14 return c # assertions def assertChangesEqual(self, ca, cb): ok = True ok = ok and ca.number == cb.number ok = ok and ca.who == cb.who ok = ok and sorted(ca.files) == sorted(cb.files) ok = ok and ca.comments == cb.comments ok = ok and bool(ca.isdir) == bool(cb.isdir) ok = ok and ca.revision == cb.revision ok = ok and ca.when == cb.when ok = ok and ca.branch == cb.branch ok = ok and ca.category == cb.category ok = ok and ca.revlink == cb.revlink ok = ok and ca.properties == cb.properties ok = ok and ca.repository == cb.repository ok = ok and ca.codebase == cb.codebase ok = ok and ca.project == cb.project if not ok: def printable(c): return pprint.pformat(c.__dict__) self.fail("changes do not match; expected\n%s\ngot\n%s" % (printable(ca), printable(cb))) # tests def test_getChange(self): d = self.insertTestData(self.change14_rows) def get14(_): return self.db.changes.getChange(14) d.addCallback(get14) def check14(chdict): self.assertEqual(chdict, self.change14_dict) d.addCallback(check14) return d def test_Change_fromChdict_with_chdict(self): # test that the chdict getChange returns works with Change.fromChdict d = Change.fromChdict(mock.Mock(), self.change14_dict) def check(c): self.assertChangesEqual(c, self.change14()) d.addCallback(check) return d def test_getChange_missing(self): d = defer.succeed(None) def get14(_): return self.db.changes.getChange(14) d.addCallback(get14) def check14(chdict): self.failUnless(chdict is None) d.addCallback(check14) return d def test_getLatestChangeid(self): d = self.insertTestData(self.change13_rows) def get(_): return self.db.changes.getLatestChangeid() d.addCallback(get) def check(changeid): self.assertEqual(changeid, 13) d.addCallback(check) return d def test_getLatestChangeid_empty(self): d = defer.succeed(None) def get(_): return self.db.changes.getLatestChangeid() d.addCallback(get) def check(changeid): self.assertEqual(changeid, None) d.addCallback(check) return d def test_addChange(self): d = self.db.changes.addChange( author=u'dustin', files=[u'master/LICENSING.txt', u'slave/LICENSING.txt'], comments=u'fix spelling', is_dir=0, revision=u'2d6caa52', when_timestamp=epoch2datetime(266738400), branch=u'master', category=None, revlink=None, properties={u'platform': (u'linux', 'Change')}, repository=u'', codebase=u'', project=u'') # check all of the columns of the four relevant tables def check_change(changeid): def thd(conn): self.assertEqual(changeid, 1) r = conn.execute(self.db.model.changes.select()) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].changeid, changeid) self.assertEqual(r[0].author, 'dustin') self.assertEqual(r[0].comments, 'fix spelling') self.assertFalse(r[0].is_dir) self.assertEqual(r[0].branch, 'master') self.assertEqual(r[0].revision, '2d6caa52') self.assertEqual(r[0].when_timestamp, 266738400) self.assertEqual(r[0].category, None) self.assertEqual(r[0].repository, '') self.assertEqual(r[0].codebase, '') self.assertEqual(r[0].project, '') return self.db.pool.do(thd) d.addCallback(check_change) def check_change_files(_): def thd(conn): query = self.db.model.change_files.select() query.where(self.db.model.change_files.c.changeid == 1) query.order_by(self.db.model.change_files.c.filename) r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 2) self.assertEqual(r[0].filename, 'master/LICENSING.txt') self.assertEqual(r[1].filename, 'slave/LICENSING.txt') return self.db.pool.do(thd) d.addCallback(check_change_files) def check_change_properties(_): def thd(conn): query = self.db.model.change_properties.select() query.where(self.db.model.change_properties.c.changeid == 1) query.order_by(self.db.model.change_properties.c.property_name) r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].property_name, 'platform') self.assertEqual(r[0].property_value, '["linux", "Change"]') return self.db.pool.do(thd) d.addCallback(check_change_properties) def check_change_users(_): def thd(conn): query = self.db.model.change_users.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 0) return self.db.pool.do(thd) d.addCallback(check_change_users) return d def test_addChange_when_timestamp_None(self): clock = task.Clock() clock.advance(1239898353) d = self.db.changes.addChange( author=u'dustin', files=[], comments=u'fix spelling', is_dir=0, revision=u'2d6caa52', when_timestamp=None, branch=u'master', category=None, revlink=None, properties={}, repository=u'', codebase=u'', project=u'', _reactor=clock) # check all of the columns of the four relevant tables def check_change(changeid): def thd(conn): r = conn.execute(self.db.model.changes.select()) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].changeid, changeid) self.assertEqual(r[0].when_timestamp, 1239898353) return self.db.pool.do(thd) d.addCallback(check_change) def check_change_files(_): def thd(conn): query = self.db.model.change_files.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 0) return self.db.pool.do(thd) d.addCallback(check_change_files) def check_change_properties(_): def thd(conn): query = self.db.model.change_properties.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 0) return self.db.pool.do(thd) d.addCallback(check_change_properties) def check_change_users(_): def thd(conn): query = self.db.model.change_users.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 0) return self.db.pool.do(thd) d.addCallback(check_change_users) return d def test_addChange_with_uid(self): d = self.insertTestData([ fakedb.User(uid=1, identifier="one"), ]) d.addCallback(lambda _: self.db.changes.addChange( author=u'dustin', files=[], comments=u'fix spelling', is_dir=0, revision=u'2d6caa52', when_timestamp=epoch2datetime(1239898353), branch=u'master', category=None, revlink=None, properties={}, repository=u'', codebase=u'', project=u'', uid=1)) # check all of the columns of the five relevant tables def check_change(changeid): def thd(conn): r = conn.execute(self.db.model.changes.select()) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].changeid, changeid) self.assertEqual(r[0].when_timestamp, 1239898353) return self.db.pool.do(thd) d.addCallback(check_change) def check_change_files(_): def thd(conn): query = self.db.model.change_files.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 0) return self.db.pool.do(thd) d.addCallback(check_change_files) def check_change_properties(_): def thd(conn): query = self.db.model.change_properties.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 0) return self.db.pool.do(thd) d.addCallback(check_change_properties) def check_change_users(_): def thd(conn): query = self.db.model.change_users.select() r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].changeid, 1) self.assertEqual(r[0].uid, 1) return self.db.pool.do(thd) d.addCallback(check_change_users) return d def test_getChangeUids_missing(self): d = self.db.changes.getChangeUids(1) def check(res): self.assertEqual(res, []) d.addCallback(check) return d def test_getChangeUids_found(self): d = self.insertTestData(self.change14_rows + [ fakedb.User(uid=1), fakedb.ChangeUser(changeid=14, uid=1), ]) d.addCallback(lambda _: self.db.changes.getChangeUids(14)) def check(res): self.assertEqual(res, [1]) d.addCallback(check) return d def test_getChangeUids_multi(self): d = self.insertTestData(self.change14_rows + self.change13_rows + [ fakedb.User(uid=1, identifier="one"), fakedb.User(uid=2, identifier="two"), fakedb.User(uid=99, identifier="nooo"), fakedb.ChangeUser(changeid=14, uid=1), fakedb.ChangeUser(changeid=14, uid=2), fakedb.ChangeUser(changeid=13, uid=99), # not selected ]) d.addCallback(lambda _: self.db.changes.getChangeUids(14)) def check(res): self.assertEqual(sorted(res), [1, 2]) d.addCallback(check) return d def test_pruneChanges(self): d = self.insertTestData( [ fakedb.Object(id=29), fakedb.SourceStamp(id=234), fakedb.Change(changeid=11), fakedb.Change(changeid=12), fakedb.SchedulerChange(objectid=29, changeid=12), fakedb.SourceStampChange(sourcestampid=234, changeid=12), ] + self.change13_rows + [ fakedb.SchedulerChange(objectid=29, changeid=13), ] + self.change14_rows + [ fakedb.SchedulerChange(objectid=29, changeid=14), fakedb.Change(changeid=15), fakedb.SourceStampChange(sourcestampid=234, changeid=15), ] ) # pruning with a horizon of 2 should delete changes 11, 12 and 13 d.addCallback(lambda _: self.db.changes.pruneChanges(2)) def check(_): def thd(conn): results = {} for tbl_name in ('scheduler_changes', 'sourcestamp_changes', 'change_files', 'change_properties', 'changes'): tbl = self.db.model.metadata.tables[tbl_name] res = conn.execute(sa.select([tbl.c.changeid])) results[tbl_name] = sorted([row[0] for row in res.fetchall()]) self.assertEqual(results, { 'scheduler_changes': [14], 'sourcestamp_changes': [15], 'change_files': [14], 'change_properties': [], 'changes': [14, 15], }) return self.db.pool.do(thd) d.addCallback(check) return d def test_pruneChanges_lots(self): d = self.insertTestData([ fakedb.Change(changeid=n) for n in xrange(1, 151) ]) d.addCallback(lambda _: self.db.changes.pruneChanges(1)) def check(_): def thd(conn): results = {} for tbl_name in ('scheduler_changes', 'sourcestamp_changes', 'change_files', 'change_properties', 'changes'): tbl = self.db.model.metadata.tables[tbl_name] res = conn.execute(sa.select([tbl.c.changeid])) results[tbl_name] = len([row for row in res.fetchall()]) self.assertEqual(results, { 'scheduler_changes': 0, 'sourcestamp_changes': 0, 'change_files': 0, 'change_properties': 0, 'changes': 1, }) return self.db.pool.do(thd) d.addCallback(check) return d def test_pruneChanges_None(self): d = self.insertTestData(self.change13_rows) d.addCallback(lambda _: self.db.changes.pruneChanges(None)) def check(_): def thd(conn): tbl = self.db.model.changes res = conn.execute(tbl.select()) self.assertEqual([row.changeid for row in res.fetchall()], [13]) return self.db.pool.do(thd) d.addCallback(check) return d def test_getRecentChanges_subset(self): d = self.insertTestData([ fakedb.Change(changeid=8), fakedb.Change(changeid=9), fakedb.Change(changeid=10), fakedb.Change(changeid=11), fakedb.Change(changeid=12), ] + self.change13_rows + self.change14_rows) d.addCallback(lambda _: self.db.changes.getRecentChanges(5)) def check(changes): changeids = [c['changeid'] for c in changes] self.assertEqual(changeids, [10, 11, 12, 13, 14]) d.addCallback(check) return d def test_getRecentChanges_empty(self): d = defer.succeed(None) d.addCallback(lambda _: self.db.changes.getRecentChanges(5)) def check(changes): changeids = [c['changeid'] for c in changes] self.assertEqual(changeids, []) d.addCallback(check) return d def test_getRecentChanges_missing(self): d = self.insertTestData(self.change13_rows + self.change14_rows) d.addCallback(lambda _: self.db.changes.getRecentChanges(5)) def check(changes): # requested 5, but only got 2 changeids = [c['changeid'] for c in changes] self.assertEqual(changeids, [13, 14]) # double-check that they have .files, etc. self.assertEqual(sorted(changes[0]['files']), sorted(['master/README.txt', 'slave/README.txt'])) self.assertEqual(changes[0]['properties'], {'notest': ('no', 'Change')}) d.addCallback(check) return d
class TestChangesConnectorComponent( connector_component.ConnectorComponentMixin, unittest.TestCase): def setUp(self): d = self.setUpConnectorComponent(table_names=[ 'changes', 'change_links', 'change_files', 'change_properties', 'scheduler_changes', 'schedulers', 'sourcestamps', 'sourcestamp_changes', 'patches' ]) def finish_setup(_): self.db.changes = changes.ChangesConnectorComponent(self.db) d.addCallback(finish_setup) return d def tearDown(self): return self.tearDownConnectorComponent() # common sample data change13_rows = [ fakedb.Change(changeid=13, author="dustin", comments="fix spelling", is_dir=0, branch="master", revision="deadbeef", when_timestamp=266738400, revlink=None, category=None, repository='', project=''), fakedb.ChangeLink(changeid=13, link='http://buildbot.net'), fakedb.ChangeLink(changeid=13, link='http://sf.net/projects/buildbot'), fakedb.ChangeFile(changeid=13, filename='master/README.txt'), fakedb.ChangeFile(changeid=13, filename='slave/README.txt'), fakedb.ChangeProperty(changeid=13, property_name='notest', property_value='"no"'), ] def change13(self): c = Change(**dict( category=None, isdir=0, repository=u'', links=[u'http://buildbot.net', u'http://sf.net/projects/buildbot'], who=u'dustin', when=266738400, comments=u'fix spelling', project=u'', branch=u'master', revlink=None, properties={u'notest': u'no'}, files=[u'master/README.txt', u'slave/README.txt'], revision=u'deadbeef')) c.number = 13 return c change14_rows = [ fakedb.Change(changeid=14, author="warner", comments="fix whitespace", is_dir=0, branch="warnerdb", revision="0e92a098b", when_timestamp=266738404, revlink='http://warner/0e92a098b', category='devel', repository='git://warner', project='Buildbot'), fakedb.ChangeFile(changeid=14, filename='master/buildbot/__init__.py'), ] def change14(self): c = Change(**dict(category='devel', isdir=0, repository=u'git://warner', links=[], who=u'warner', when=266738404, comments=u'fix whitespace', project=u'Buildbot', branch=u'warnerdb', revlink=u'http://warner/0e92a098b', properties={}, files=[u'master/buildbot/__init__.py'], revision=u'0e92a098b')) c.number = 14 return c # assertions def assertChangesEqual(self, a, b): if len(a) != len(b): ok = False else: ok = True for i in xrange(len(a)): ca = a[i] cb = b[i] ok = ok and ca.number == cb.number ok = ok and ca.who == cb.who ok = ok and sorted(ca.files) == sorted(cb.files) ok = ok and ca.comments == cb.comments ok = ok and bool(ca.isdir) == bool(cb.isdir) ok = ok and sorted(ca.links) == sorted(cb.links) ok = ok and ca.revision == cb.revision ok = ok and ca.when == cb.when ok = ok and ca.branch == cb.branch ok = ok and ca.category == cb.category ok = ok and ca.revlink == cb.revlink ok = ok and ca.properties == cb.properties ok = ok and ca.repository == cb.repository ok = ok and ca.project == cb.project if not ok: break if not ok: def printable(clist): return pprint.pformat([c.__dict__ for c in clist]) self.fail("changes do not match; expected\n%s\ngot\n%s" % (printable(a), printable(b))) # tests def test_getChangeInstance(self): d = self.insertTestData(self.change14_rows) def get14(_): return self.db.changes.getChangeInstance(14) d.addCallback(get14) def check14(c): self.assertChangesEqual([c], [self.change14()]) d.addCallback(check14) return d def test_getChangeInstance_missing(self): d = defer.succeed(None) def get14(_): return self.db.changes.getChangeInstance(14) d.addCallback(get14) def check14(c): self.failUnless(c is None) d.addCallback(check14) return d def test_getLatestChangeid(self): d = self.insertTestData(self.change13_rows) def get(_): return self.db.changes.getLatestChangeid() d.addCallback(get) def check(changeid): self.assertEqual(changeid, 13) d.addCallback(check) return d def test_getLatestChangeid_empty(self): d = defer.succeed(None) def get(_): return self.db.changes.getLatestChangeid() d.addCallback(get) def check(changeid): self.assertEqual(changeid, None) d.addCallback(check) return d def test_addChange(self): d = self.db.changes.addChange( who=u'dustin', files=[u'master/LICENSING.txt', u'slave/LICENSING.txt'], comments=u'fix spelling', isdir=0, links=[u'http://slashdot.org', u'http://wired.com/g'], revision=u'2d6caa52ab39fbac83cee03dcf2ccb7e41eaad86', when=266738400, branch=u'master', category=None, revlink=None, properties={u'platform': u'linux'}, repository=u'', project=u'') # check all of the columns of the four relevant tables def check_change(change): self.assertEqual(change.number, 1) self.assertEqual(change.who, 'dustin') self.assertEqual( sorted(change.files), sorted([u'master/LICENSING.txt', u'slave/LICENSING.txt'])) self.assertEqual(change.comments, 'fix spelling') self.assertFalse(change.isdir) self.assertEqual( sorted(change.links), sorted([u'http://slashdot.org', u'http://wired.com/g'])) self.assertEqual(change.revision, '2d6caa52ab39fbac83cee03dcf2ccb7e41eaad86') self.assertEqual(change.when, 266738400) self.assertEqual(change.category, None) self.assertEqual(change.revlink, None) self.assertEqual(change.properties.asList(), [('platform', 'linux', 'Change')]) self.assertEqual(change.repository, '') self.assertEqual(change.project, '') def thd(conn): r = conn.execute(self.db.model.changes.select()) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].changeid, 1) self.assertEqual(r[0].author, 'dustin') self.assertEqual(r[0].comments, 'fix spelling') self.assertFalse(r[0].is_dir) self.assertEqual(r[0].branch, 'master') self.assertEqual(r[0].revision, '2d6caa52ab39fbac83cee03dcf2ccb7e41eaad86') self.assertEqual(r[0].when_timestamp, 266738400) self.assertEqual(r[0].category, None) self.assertEqual(r[0].repository, '') self.assertEqual(r[0].project, '') return self.db.pool.do(thd) d.addCallback(check_change) def check_change_links(_): def thd(conn): query = self.db.model.change_links.select() query.where(self.db.model.change_links.c.changeid == 1) query.order_by([self.db.model.change_links.c.link]) r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 2) self.assertEqual(r[0].link, 'http://slashdot.org') self.assertEqual(r[1].link, 'http://wired.com/g') return self.db.pool.do(thd) d.addCallback(check_change_links) def check_change_files(_): def thd(conn): query = self.db.model.change_files.select() query.where(self.db.model.change_files.c.changeid == 1) query.order_by([self.db.model.change_files.c.filename]) r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 2) self.assertEqual(r[0].filename, 'master/LICENSING.txt') self.assertEqual(r[1].filename, 'slave/LICENSING.txt') return self.db.pool.do(thd) d.addCallback(check_change_files) def check_change_properties(_): def thd(conn): query = self.db.model.change_properties.select() query.where(self.db.model.change_properties.c.changeid == 1) query.order_by( [self.db.model.change_properties.c.property_name]) r = conn.execute(query) r = r.fetchall() self.assertEqual(len(r), 1) self.assertEqual(r[0].property_name, 'platform') self.assertEqual(r[0].property_value, '"linux"') # JSON-encoded return self.db.pool.do(thd) d.addCallback(check_change_properties) return d def test_prune_changes(self): self.db.changes.changeHorizon = 1 # prune_changes prunes from a lot of tables # TODO: add data to them to check! d = self.insertTestData(self.change13_rows + self.change14_rows) d.addCallback(lambda _: self.db.changes._prune_changes(14)) def check(_): def thd(conn): changes_tbl = self.db.model.changes r = conn.execute(sa.select([changes_tbl.c.changeid])) self.assertEqual([r.changeid for r in r.fetchall()], [14]) return self.db.pool.do(thd) d.addCallback(check) return d def test_getRecentChangeInstances_subset(self): d = self.insertTestData([ fakedb.Change(changeid=8), fakedb.Change(changeid=9), fakedb.Change(changeid=10), fakedb.Change(changeid=11), fakedb.Change(changeid=12), ] + self.change13_rows + self.change14_rows) d.addCallback(lambda _: self.db.changes.getRecentChangeInstances(5)) def check(changes): changeids = [c.number for c in changes] self.assertEqual(changeids, [10, 11, 12, 13, 14]) d.addCallback(check) return d def test_getRecentChangeInstances_empty(self): d = defer.succeed(None) d.addCallback(lambda _: self.db.changes.getRecentChangeInstances(5)) def check(changes): changeids = [c.number for c in changes] self.assertEqual(changeids, []) d.addCallback(check) return d def test_getRecentChangeInstances_missing(self): d = self.insertTestData(self.change13_rows + self.change14_rows) d.addCallback(lambda _: self.db.changes.getRecentChangeInstances(5)) def check(changes): # requested 5, but only got 2 changeids = [c.number for c in changes] self.assertEqual(changeids, [13, 14]) # double-check that they have .files, etc. self.assertEqual(sorted(changes[0].files), sorted(['master/README.txt', 'slave/README.txt'])) self.assertEqual( sorted(changes[0].links), sorted( ['http://buildbot.net', 'http://sf.net/projects/buildbot'])) self.assertEqual(changes[0].properties.asList(), [('notest', 'no', 'Change')]) d.addCallback(check) return d
class Change(unittest.TestCase): change23_rows = [ fakedb.Change(changeid=23, author="dustin", comments="fix whitespace", is_dir=0, branch="warnerdb", revision="deadbeef", when_timestamp=266738404, revlink='http://warner/0e92a098b', category='devel', repository='git://warner', codebase='mainapp', project='Buildbot'), fakedb.ChangeFile(changeid=23, filename='master/README.txt'), fakedb.ChangeFile(changeid=23, filename='slave/README.txt'), fakedb.ChangeProperty(changeid=23, property_name='notest', property_value='["no","Change"]'), fakedb.ChangeUser(changeid=23, uid=27), ] def setUp(self): self.change23 = changes.Change( **dict( # using **dict(..) forces kwargs category='devel', isdir=0, repository=u'git://warner', codebase=u'mainapp', who=u'dustin', when=266738404, comments=u'fix whitespace', project=u'Buildbot', branch=u'warnerdb', revlink=u'http://warner/0e92a098b', properties={'notest': "no"}, files=[u'master/README.txt', u'slave/README.txt'], revision=u'deadbeef')) self.change23.number = 23 def test_str(self): string = str(self.change23) self.assertTrue(re.match(r"Change\(.*\)", string), string) def test_asText(self): text = self.change23.asText() self.assertTrue( re.match( textwrap.dedent(u'''\ Files: master/README.txt slave/README.txt On: git://warner For: Buildbot At: .* Changed By: dustin Comments: fix whitespaceProperties: notest: no '''), text), text) def test_asDict(self): dict = self.change23.asDict() self.assertIn('1978', dict['at']) # timezone-sensitive del dict['at'] self.assertEqual( dict, { 'branch': u'warnerdb', 'category': u'devel', 'codebase': u'mainapp', 'comments': u'fix whitespace', 'files': [{ 'name': u'master/README.txt' }, { 'name': u'slave/README.txt' }], 'number': 23, 'project': u'Buildbot', 'properties': [('notest', 'no', 'Change')], 'repository': u'git://warner', 'rev': u'deadbeef', 'revision': u'deadbeef', 'revlink': u'http://warner/0e92a098b', 'when': 266738404, 'who': u'dustin' }) def test_getShortAuthor(self): self.assertEqual(self.change23.getShortAuthor(), 'dustin') def test_getTime(self): # careful, or timezones will hurt here self.assertIn('Jun 1978', self.change23.getTime()) def test_getTimes(self): self.assertEqual(self.change23.getTimes(), (266738404, None)) def test_getText(self): self.change23.who = 'nasty < nasty' # test the html escaping (ugh!) self.assertEqual(self.change23.getText(), ['nasty < nasty']) def test_getLogs(self): self.assertEqual(self.change23.getLogs(), {})