def test__masterDeactivated(self): yield self.master.db.insertTestData([ fakedb.Master(id=22, active=0), fakedb.Scheduler(id=13, name='some:scheduler'), fakedb.SchedulerMaster(schedulerid=13, masterid=22), fakedb.Scheduler(id=14, name='other:scheduler'), fakedb.SchedulerMaster(schedulerid=14, masterid=22), ]) yield self.rtype._masterDeactivated(22) self.master.db.schedulers.assertSchedulerMaster(13, None) self.master.db.schedulers.assertSchedulerMaster(14, None)
def setUp(self): self.setUpEndpoint() self.db.insertTestData([ fakedb.Master(id=22, active=0), fakedb.Master(id=33, active=1), fakedb.Scheduler(id=13, name='some:scheduler'), fakedb.SchedulerMaster(schedulerid=13, masterid=None), fakedb.Scheduler(id=14, name='other:scheduler'), fakedb.SchedulerMaster(schedulerid=14, masterid=22), fakedb.Scheduler(id=15, name='another:scheduler'), fakedb.SchedulerMaster(schedulerid=15, masterid=33), ])
def test_schedulerEnable(self): SOMETIME = 1348971992 yield self.master.db.insertTestData([ fakedb.Master(id=22, active=0, last_active=SOMETIME), fakedb.Scheduler(id=13, name='some:scheduler'), fakedb.SchedulerMaster(schedulerid=13, masterid=22), ]) yield self.rtype.schedulerEnable(13, False) self.master.mq.assertProductions([(('schedulers', '13', 'updated'), { 'enabled': False, 'master': { 'active': False, 'last_active': fakedb._mkdt(SOMETIME), 'masterid': 22, 'name': u'some:master' }, 'name': u'some:scheduler', 'schedulerid': 13 })]) yield self.rtype.schedulerEnable(13, True) self.master.mq.assertProductions([(('schedulers', '13', 'updated'), { 'enabled': True, 'master': { 'active': False, 'last_active': fakedb._mkdt(SOMETIME), 'masterid': 22, 'name': u'some:master' }, 'name': u'some:scheduler', 'schedulerid': 13 })])
def test_pruneChanges(self): yield self.insertTestData([ fakedb.Scheduler(id=29), fakedb.SourceStamp(id=234, branch='aa'), fakedb.SourceStamp(id=235, branch='bb'), fakedb.Change(changeid=11), fakedb.Change(changeid=12, sourcestampid=234), fakedb.SchedulerChange(schedulerid=29, changeid=12), ] + self.change13_rows + [ fakedb.SchedulerChange(schedulerid=29, changeid=13), ] + self.change14_rows + [ fakedb.SchedulerChange(schedulerid=29, changeid=14), fakedb.Change(changeid=15, sourcestampid=235), ]) # pruning with a horizon of 2 should delete changes 11, 12 and 13 yield self.db.changes.pruneChanges(2) def thd(conn): results = {} for tbl_name in ('scheduler_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], 'change_files': [14], 'change_properties': [], 'changes': [14, 15], }) yield self.db.pool.do(thd)
def test_getState_bad(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=10, state='{ 99notjs0n }') ]) d.addCallback(lambda _ : self.db.schedulers.getState(10)) def check(state): self.assertEqual(state, {}) d.addCallback(check) return d
def test_getState_good(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=10, state='{ "foo":"bar" }') ]) d.addCallback(lambda _ : self.db.schedulers.getState(10)) def check(state): self.assertEqual(state, dict(foo="bar")) d.addCallback(check) return d
def test_getSchedulerId_first_time(self): d = self.insertTestData([ fakedb.Scheduler(name='distractor', class_name='Weekly', schedulerid=992, state='{"foo": "bar"}') ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Nightly')) d.addCallback(lambda schid : self.checkScheduler(schid, 'mysched', 'Nightly', '{}')) return d
def test_setState_unJSON(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=99, state='{}') ]) d.addCallback(lambda _ : self.db.schedulers.setState(99, mock.Mock())) def cb(_): self.fail("should have raised a failure") def eb(f): f.trap(TypeError) d.addCallbacks(cb, eb) return d
def test_getSchedulerId_upgrade(self): d = self.insertTestData([ fakedb.Scheduler(name='mysched', class_name='', schedulerid=992) ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Hourly')) def check(schid): self.assertEqual(schid, 992) # class has been filled in return self.checkScheduler(992, 'mysched', 'Hourly') d.addCallback(check) return d
def test_getSchedulerId_existing(self): d = self.insertTestData([ fakedb.Scheduler(name='mysched', class_name='Nightly', schedulerid=992, state='{"foo": "bar"}') ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Nightly')) def check(schid): self.assertEqual(schid, 992) return self.checkScheduler(992, 'mysched', 'Nightly', '{"foo": "bar"}') d.addCallback(check) return d
def test_setState(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=99, state='{}') ]) d.addCallback(lambda _ : self.db.schedulers.setState(99, dict(abc="def"))) def check(state): def thd(conn): r = conn.execute(self.db.model.schedulers.select()) rows = r.fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].schedulerid, 99) self.assertEqual(json.loads(rows[0].state), dict(abc="def")) return self.db.pool.do(thd) d.addCallback(check) return d
def test_setMasterState_false_deletes_links(self): yield self.insertTestData([ fakedb.Master(id=7, name='some:master', active=1, last_active=OTHERTIME), fakedb.Scheduler(id=21), fakedb.SchedulerMaster(schedulerid=21, masterid=7), ]) deactivated = yield self.db.masters.setMasterState( masterid=7, active=False, _reactor=self.reactor) self.assertTrue(deactivated) # check that the scheduler_masters row was deleted def thd(conn): tbl = self.db.model.scheduler_masters self.assertEqual(conn.execute(tbl.select()).fetchall(), []) yield self.db.pool.do(thd)
def test_pruneChanges(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=29), fakedb.SourceStamp(id=234), fakedb.Change(changeid=11), fakedb.Change(changeid=12), fakedb.SchedulerChange(schedulerid=29, changeid=12), fakedb.SourceStampChange(sourcestampid=234, changeid=12), ] + self.change13_rows + [ fakedb.SchedulerChange(schedulerid=29, changeid=13), ] + self.change14_rows + [ fakedb.SchedulerChange(schedulerid=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_links', 'change_properties', 'changes'): tbl = self.db.model.metadata.tables[tbl_name] r = conn.execute(sa.select([tbl.c.changeid])) results[tbl_name] = sorted([ r[0] for r in r.fetchall() ]) self.assertEqual(results, { 'scheduler_changes': [14], 'sourcestamp_changes': [15], 'change_files': [14], 'change_links': [], 'change_properties': [], 'changes': [14, 15], }) return self.db.pool.do(thd) d.addCallback(check) return d
class Tests(interfaces.InterfaceTests): # test data ss92 = fakedb.SourceStamp(id=92) change3 = fakedb.Change(changeid=3) change4 = fakedb.Change(changeid=4) change5 = fakedb.Change(changeid=5) change6 = fakedb.Change(changeid=6, branch='sql') scheduler24 = fakedb.Scheduler(id=24, name='schname') master13 = fakedb.Master(id=13, name='m1', active=1) scheduler24master = fakedb.SchedulerMaster(schedulerid=24, masterid=13) scheduler25 = fakedb.Scheduler(id=25, name='schname2') master14 = fakedb.Master(id=14, name='m2', active=0) scheduler25master = fakedb.SchedulerMaster(schedulerid=25, masterid=14) # tests def test_signature_classifyChanges(self): @self.assertArgSpecMatches(self.db.schedulers.classifyChanges) def classifyChanges(self, schedulerid, classifications): pass @defer.inlineCallbacks def test_classifyChanges(self): yield self.insertTestData( [self.ss92, self.change3, self.change4, self.scheduler24]) yield self.db.schedulers.classifyChanges(24, {3: False, 4: True}) res = yield self.db.schedulers.getChangeClassifications(24) self.assertEqual(res, {3: False, 4: True}) @defer.inlineCallbacks def test_classifyChanges_again(self): # test reclassifying changes, which may happen during some timing # conditions. It's important that this test uses multiple changes, # only one of which already exists yield self.insertTestData([ self.ss92, self.change3, self.change4, self.change5, self.change6, self.scheduler24, fakedb.SchedulerChange(schedulerid=24, changeid=5, important=0), ]) yield self.db.schedulers.classifyChanges(24, { 3: True, 4: False, 5: True, 6: False }) res = yield self.db.schedulers.getChangeClassifications(24) self.assertEqual(res, {3: True, 4: False, 5: True, 6: False}) def test_signature_flushChangeClassifications(self): @self.assertArgSpecMatches( self.db.schedulers.flushChangeClassifications) def flushChangeClassifications(self, schedulerid, less_than=None): pass @defer.inlineCallbacks def test_flushChangeClassifications(self): yield self.insertTestData([ self.ss92, self.change3, self.change4, self.change5, self.scheduler24 ]) yield self.addClassifications(24, (3, 1), (4, 0), (5, 1)) res = yield self.db.schedulers.getChangeClassifications(24) self.assertEqual(res, {3: True, 4: False, 5: True}) yield self.db.schedulers.flushChangeClassifications(24) res = yield self.db.schedulers.getChangeClassifications(24) self.assertEqual(res, {}) @defer.inlineCallbacks def test_flushChangeClassifications_less_than(self): yield self.insertTestData([ self.ss92, self.change3, self.change4, self.change5, self.scheduler24 ]) yield self.addClassifications(24, (3, 1), (4, 0), (5, 1)) yield self.db.schedulers.flushChangeClassifications(24, less_than=5) res = yield self.db.schedulers.getChangeClassifications(24) self.assertEqual(res, {5: True}) def test_signature_getChangeClassifications(self): @self.assertArgSpecMatches(self.db.schedulers.getChangeClassifications) def getChangeClassifications(self, schedulerid, branch=-1, repository=-1, project=-1, codebase=-1): pass @defer.inlineCallbacks def test_getChangeClassifications(self): yield self.insertTestData([ self.ss92, self.change3, self.change4, self.change5, self.change6, self.scheduler24 ]) yield self.addClassifications(24, (3, 1), (4, 0), (5, 1), (6, 1)) res = yield self.db.schedulers.getChangeClassifications(24) self.assertEqual(res, {3: True, 4: False, 5: True, 6: True}) @defer.inlineCallbacks def test_getChangeClassifications_branch(self): yield self.insertTestData([ self.ss92, self.change3, self.change4, self.change5, self.change6, self.scheduler24 ]) yield self.addClassifications(24, (3, 1), (4, 0), (5, 1), (6, 1)) res = yield self.db.schedulers.getChangeClassifications(24, branch='sql') self.assertEqual(res, {6: True}) def test_signature_findSchedulerId(self): @self.assertArgSpecMatches(self.db.schedulers.findSchedulerId) def findSchedulerId(self, name): pass @defer.inlineCallbacks def test_findSchedulerId_new(self): id = yield self.db.schedulers.findSchedulerId('schname') sch = yield self.db.schedulers.getScheduler(id) self.assertEqual(sch['name'], 'schname') @defer.inlineCallbacks def test_findSchedulerId_existing(self): id = yield self.db.schedulers.findSchedulerId('schname') id2 = yield self.db.schedulers.findSchedulerId('schname') self.assertEqual(id, id2) def test_signature_setSchedulerMaster(self): @self.assertArgSpecMatches(self.db.schedulers.setSchedulerMaster) def setSchedulerMaster(self, schedulerid, masterid): pass @defer.inlineCallbacks def test_setSchedulerMaster_fresh(self): yield self.insertTestData([self.scheduler24, self.master13]) yield self.db.schedulers.setSchedulerMaster(24, 13) sch = yield self.db.schedulers.getScheduler(24) self.assertEqual(sch['masterid'], 13) def test_setSchedulerMaster_inactive_but_linked(self): d = self.insertTestData([ self.master13, self.scheduler25, self.master14, self.scheduler25master, ]) d.addCallback(lambda _: self.db.schedulers.setSchedulerMaster(25, 13)) self.assertFailure(d, schedulers.SchedulerAlreadyClaimedError) return d def test_setSchedulerMaster_active(self): d = self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, ]) d.addCallback(lambda _: self.db.schedulers.setSchedulerMaster(24, 14)) self.assertFailure(d, schedulers.SchedulerAlreadyClaimedError) return d @defer.inlineCallbacks def test_setSchedulerMaster_None(self): yield self.insertTestData([ self.scheduler25, self.master14, self.scheduler25master, ]) yield self.db.schedulers.setSchedulerMaster(25, None) sch = yield self.db.schedulers.getScheduler(25) self.assertEqual(sch['masterid'], None) @defer.inlineCallbacks def test_setSchedulerMaster_None_unowned(self): yield self.insertTestData([self.scheduler25]) yield self.db.schedulers.setSchedulerMaster(25, None) sch = yield self.db.schedulers.getScheduler(25) self.assertEqual(sch['masterid'], None) def test_signature_getScheduler(self): @self.assertArgSpecMatches(self.db.schedulers.getScheduler) def getScheduler(self, schedulerid): pass @defer.inlineCallbacks def test_getScheduler(self): yield self.insertTestData([self.scheduler24]) sch = yield self.db.schedulers.getScheduler(24) validation.verifyDbDict(self, 'schedulerdict', sch) self.assertEqual(sch, dict(id=24, name='schname', masterid=None)) @defer.inlineCallbacks def test_getScheduler_missing(self): sch = yield self.db.schedulers.getScheduler(24) self.assertEqual(sch, None) @defer.inlineCallbacks def test_getScheduler_active(self): yield self.insertTestData( [self.scheduler24, self.master13, self.scheduler24master]) sch = yield self.db.schedulers.getScheduler(24) validation.verifyDbDict(self, 'schedulerdict', sch) self.assertEqual(sch, dict(id=24, name='schname', masterid=13)) @defer.inlineCallbacks def test_getScheduler_inactive_but_linked(self): yield self.insertTestData( [self.scheduler25, self.master14, self.scheduler25master]) sch = yield self.db.schedulers.getScheduler(25) validation.verifyDbDict(self, 'schedulerdict', sch) self.assertEqual(sch, dict(id=25, name='schname2', masterid=14)) # row exists, but marked inactive def test_signature_getSchedulers(self): @self.assertArgSpecMatches(self.db.schedulers.getSchedulers) def getSchedulers(self, active=None, masterid=None): pass @defer.inlineCallbacks def test_getSchedulers(self): yield self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, self.scheduler25, ]) schlist = yield self.db.schedulers.getSchedulers() [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual( sorted(schlist), sorted([ dict(id=24, name='schname', masterid=13), dict(id=25, name='schname2', masterid=None), ])) @defer.inlineCallbacks def test_getSchedulers_masterid(self): yield self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, self.scheduler25, ]) schlist = yield self.db.schedulers.getSchedulers(masterid=13) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual(sorted(schlist), sorted([ dict(id=24, name='schname', masterid=13), ])) @defer.inlineCallbacks def test_getSchedulers_active(self): yield self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, self.scheduler25 ]) schlist = yield self.db.schedulers.getSchedulers(active=True) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual(sorted(schlist), sorted([ dict(id=24, name='schname', masterid=13), ])) @defer.inlineCallbacks def test_getSchedulers_active_masterid(self): yield self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, self.scheduler25 ]) schlist = yield self.db.schedulers.getSchedulers(active=True, masterid=13) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual(sorted(schlist), sorted([ dict(id=24, name='schname', masterid=13), ])) schlist = yield self.db.schedulers.getSchedulers(active=True, masterid=14) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual(sorted(schlist), []) @defer.inlineCallbacks def test_getSchedulers_inactive(self): yield self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, self.scheduler25 ]) schlist = yield self.db.schedulers.getSchedulers(active=False) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual( sorted(schlist), sorted([ dict(id=25, name='schname2', masterid=None), ])) @defer.inlineCallbacks def test_getSchedulers_inactive_masterid(self): yield self.insertTestData([ self.scheduler24, self.master13, self.scheduler24master, self.scheduler25 ]) schlist = yield self.db.schedulers.getSchedulers(active=False, masterid=13) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual(sorted(schlist), []) schlist = yield self.db.schedulers.getSchedulers(active=False, masterid=14) [ validation.verifyDbDict(self, 'schedulerdict', sch) for sch in schlist ] self.assertEqual(sorted(schlist), []) # always returns [] by spec!
def attachScheduler(self, scheduler, objectid, schedulerid, overrideBuildsetMethods=False, createBuilderDB=False): """Set up a scheduler with a fake master and db; sets self.sched, and sets the master's basedir to the absolute path of 'basedir' in the test directory. If C{overrideBuildsetMethods} is true, then all of the addBuildsetForXxx methods are overridden to simply append the method name and arguments to self.addBuildsetCalls. These overridden methods return buildsets starting with 500 and buildrequest IDs starting with 100. For C{addBuildsetForSourceStamp}, this also overrides DB API methods C{addSourceStamp} and C{addSourceStampSet}, and uses that information to generate C{addBuildsetForSourceStamp} results. @returns: scheduler """ scheduler.objectid = objectid # set up a fake master db = self.db = self.master.db self.mq = self.master.mq scheduler.setServiceParent(self.master) rows = [fakedb.Object(id=objectid, name=scheduler.name, class_name='SomeScheduler'), fakedb.Scheduler(id=schedulerid, name=scheduler.name), ] if createBuilderDB is True: rows.extend([fakedb.Builder(name=bname) for bname in scheduler.builderNames]) db.insertTestData(rows) if overrideBuildsetMethods: for method in ( 'addBuildsetForSourceStampsWithDefaults', 'addBuildsetForChanges', 'addBuildsetForSourceStamps'): actual = getattr(scheduler, method) fake = getattr(self, 'fake_%s' % method) self.assertArgSpecMatches(actual, fake) setattr(scheduler, method, fake) self.addBuildsetCalls = [] self._bsidGenerator = iter(range(500, 999)) self._bridGenerator = iter(range(100, 999)) # temporarily override the sourcestamp and sourcestampset methods self.addedSourceStamps = [] self.addedSourceStampSets = [] def fake_addSourceStamp(**kwargs): self.assertEqual(kwargs['sourcestampsetid'], 400 + len(self.addedSourceStampSets) - 1) self.addedSourceStamps.append(kwargs) return defer.succeed(300 + len(self.addedSourceStamps) - 1) self.db.sourcestamps.addSourceStamp = fake_addSourceStamp def fake_addSourceStampSet(): self.addedSourceStampSets.append([]) return defer.succeed(400 + len(self.addedSourceStampSets) - 1) self.db.sourcestamps.addSourceStampSet = fake_addSourceStampSet # patch methods to detect a failure to upcall the activate and # deactivate methods .. unless we're testing BaseScheduler def patch(meth): oldMethod = getattr(scheduler, meth) @defer.inlineCallbacks def newMethod(): self._parentMethodCalled = False rv = yield defer.maybeDeferred(oldMethod) self.assertTrue(self._parentMethodCalled, "'%s' did not call its parent" % meth) defer.returnValue(rv) setattr(scheduler, meth, newMethod) oldParent = getattr(base.BaseScheduler, meth) def newParent(self_): self._parentMethodCalled = True return oldParent(self_) self.patch(base.BaseScheduler, meth, newParent) if scheduler.__class__.activate != base.BaseScheduler.activate: patch('activate') if scheduler.__class__.deactivate != base.BaseScheduler.deactivate: patch('deactivate') self.sched = scheduler return scheduler
class TestSchedulersConnectorComponent( connector_component.ConnectorComponentMixin, unittest.TestCase): def setUp(self): d = self.setUpConnectorComponent( table_names=['changes', 'schedulers', 'scheduler_changes' ]) def finish_setup(_): self.db.schedulers = \ schedulers.SchedulersConnectorComponent(self.db) d.addCallback(finish_setup) return d def tearDown(self): return self.tearDownConnectorComponent() def checkScheduler(self, schedulerid, name, class_name): def thd(conn): q = self.db.model.schedulers.select( whereclause=(self.db.model.schedulers.c.schedulerid == schedulerid)) for row in conn.execute(q): self.assertEqual([ row.schedulerid, row.name, row.class_name], [ schedulerid, name, class_name]) return self.db.pool.do(thd) # test data change3 = fakedb.Change(changeid=3) change4 = fakedb.Change(changeid=4) change5 = fakedb.Change(changeid=5) change6 = fakedb.Change(changeid=6, branch='sql') scheduler24 = fakedb.Scheduler(schedulerid=24) def addClassifications(self, _, schedulerid, *classifications): def thd(conn): q = self.db.model.scheduler_changes.insert() conn.execute(q, [ dict(changeid=c[0], schedulerid=schedulerid, important=c[1]) for c in classifications ]) return self.db.pool.do(thd) # tests def test_classifyChanges(self): d = self.insertTestData([ self.change3, self.change4, self.scheduler24 ]) d.addCallback(lambda _ : self.db.schedulers.classifyChanges(24, { 3 : False, 4: True })) def check(_): def thd(conn): sch_chgs_tbl = self.db.model.scheduler_changes q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid) r = conn.execute(q) rows = [ (row.schedulerid, row.changeid, row.important) for row in r.fetchall() ] self.assertEqual(rows, [ (24, 3, 0), (24, 4, 1) ]) return self.db.pool.do(thd) d.addCallback(check) return d def test_classifyChanges_again(self): # test reclassifying changes, which may happen during some timing # conditions d = self.insertTestData([ self.change3, self.scheduler24, fakedb.SchedulerChange(schedulerid=24, changeid=3, important=0), ]) d.addCallback(lambda _ : self.db.schedulers.classifyChanges(24, { 3 : True })) def check(_): def thd(conn): sch_chgs_tbl = self.db.model.scheduler_changes q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid) r = conn.execute(q) rows = [ (row.schedulerid, row.changeid, row.important) for row in r.fetchall() ] self.assertEqual(rows, [ (24, 3, 1) ]) return self.db.pool.do(thd) d.addCallback(check) return d def test_flushChangeClassifications(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1)) d.addCallback(lambda _ : self.db.schedulers.flushChangeClassifications(24)) def check(_): def thd(conn): q = self.db.model.scheduler_changes.select() rows = conn.execute(q).fetchall() self.assertEqual(rows, []) return self.db.pool.do(thd) d.addCallback(check) return d def test_flushChangeClassifications_less_than(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1)) d.addCallback(lambda _ : self.db.schedulers.flushChangeClassifications(24, less_than=5)) def check(_): def thd(conn): q = self.db.model.scheduler_changes.select() rows = conn.execute(q).fetchall() self.assertEqual([ (r.changeid, r.important) for r in rows], [ (5, 1) ]) return self.db.pool.do(thd) d.addCallback(check) return d def test_getChangeClassifications(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.change6, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1), (6, 1)) d.addCallback(lambda _ : self.db.schedulers.getChangeClassifications(24)) def check(cls): self.assertEqual(cls, { 3 : True, 4 : False, 5 : True, 6: True }) d.addCallback(check) return d def test_getChangeClassifications_branch(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.change6, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1), (6, 1)) d.addCallback(lambda _ : self.db.schedulers.getChangeClassifications(24, branch='sql')) def check(cls): self.assertEqual(cls, { 6 : True }) d.addCallback(check) return d def test_getSchedulerId_first_time(self): d = self.insertTestData([ fakedb.Scheduler(name='distractor', class_name='Weekly', schedulerid=992) ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Nightly')) d.addCallback(lambda schid : self.checkScheduler(schid, 'mysched', 'Nightly')) return d def test_getSchedulerId_existing(self): d = self.insertTestData([ fakedb.Scheduler(name='mysched', class_name='Nightly', schedulerid=992) ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Nightly')) def check(schid): self.assertEqual(schid, 992) return self.checkScheduler(992, 'mysched', 'Nightly') d.addCallback(check) return d def test_getSchedulerId_upgrade(self): d = self.insertTestData([ fakedb.Scheduler(name='mysched', class_name='', schedulerid=992) ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Hourly')) def check(schid): self.assertEqual(schid, 992) # class has been filled in return self.checkScheduler(992, 'mysched', 'Hourly') d.addCallback(check) return d
class TestSchedulersConnectorComponent( connector_component.ConnectorComponentMixin, unittest.TestCase): def setUp(self): d = self.setUpConnectorComponent( table_names=['changes', 'schedulers', 'scheduler_changes' ]) def finish_setup(_): self.db.schedulers = \ schedulers.SchedulersConnectorComponent(self.db) d.addCallback(finish_setup) return d def tearDown(self): return self.tearDownConnectorComponent() def checkScheduler(self, schedulerid, name, class_name, state): def thd(conn): q = self.db.model.schedulers.select( whereclause=(self.db.model.schedulers.c.schedulerid == schedulerid)) for row in conn.execute(q): self.assertEqual([ row.schedulerid, row.name, row.class_name, row.state ], [ schedulerid, name, class_name, state ]) return self.db.pool.do(thd) # test data change3 = fakedb.Change(changeid=3) change4 = fakedb.Change(changeid=4) change5 = fakedb.Change(changeid=5) change6 = fakedb.Change(changeid=6, branch='sql') scheduler24 = fakedb.Scheduler(schedulerid=24) def addClassifications(self, _, schedulerid, *classifications): def thd(conn): q = self.db.model.scheduler_changes.insert() conn.execute(q, [ dict(changeid=c[0], schedulerid=schedulerid, important=c[1]) for c in classifications ]) return self.db.pool.do(thd) # tests def test_getState_good(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=10, state='{ "foo":"bar" }') ]) d.addCallback(lambda _ : self.db.schedulers.getState(10)) def check(state): self.assertEqual(state, dict(foo="bar")) d.addCallback(check) return d def test_getState_bad(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=10, state='{ 99notjs0n }') ]) d.addCallback(lambda _ : self.db.schedulers.getState(10)) def check(state): self.assertEqual(state, {}) d.addCallback(check) return d def test_getState_missing(self): d = defer.succeed(None) d.addCallback(lambda _ : self.db.schedulers.getState(10)) def check(state): self.assertEqual(state, {}) d.addCallback(check) return d def test_setState(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=99, state='{}') ]) d.addCallback(lambda _ : self.db.schedulers.setState(99, dict(abc="def"))) def check(state): def thd(conn): r = conn.execute(self.db.model.schedulers.select()) rows = r.fetchall() self.assertEqual(len(rows), 1) self.assertEqual(rows[0].schedulerid, 99) self.assertEqual(json.loads(rows[0].state), dict(abc="def")) return self.db.pool.do(thd) d.addCallback(check) return d def test_setState_unJSON(self): d = self.insertTestData([ fakedb.Scheduler(schedulerid=99, state='{}') ]) d.addCallback(lambda _ : self.db.schedulers.setState(99, mock.Mock())) def cb(_): self.fail("should have raised a failure") def eb(f): f.trap(TypeError) d.addCallbacks(cb, eb) return d def test_classifyChanges(self): d = self.insertTestData([ self.change3, self.change4, self.scheduler24 ]) d.addCallback(lambda _ : self.db.schedulers.classifyChanges(24, { 3 : False, 4: True })) def check(_): def thd(conn): sch_chgs_tbl = self.db.model.scheduler_changes q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid) r = conn.execute(q) rows = [ (row.schedulerid, row.changeid, row.important) for row in r.fetchall() ] self.assertEqual(rows, [ (24, 3, 0), (24, 4, 1) ]) return self.db.pool.do(thd) d.addCallback(check) return d def test_classifyChanges_again(self): # test reclassifying changes, which may happen during some timing # conditions d = self.insertTestData([ self.change3, self.scheduler24, fakedb.SchedulerChange(schedulerid=24, changeid=3, important=0), ]) d.addCallback(lambda _ : self.db.schedulers.classifyChanges(24, { 3 : True })) def check(_): def thd(conn): sch_chgs_tbl = self.db.model.scheduler_changes q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid) r = conn.execute(q) rows = [ (row.schedulerid, row.changeid, row.important) for row in r.fetchall() ] self.assertEqual(rows, [ (24, 3, 1) ]) return self.db.pool.do(thd) d.addCallback(check) return d def test_flushChangeClassifications(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1)) d.addCallback(lambda _ : self.db.schedulers.flushChangeClassifications(24)) def check(_): def thd(conn): q = self.db.model.scheduler_changes.select() rows = conn.execute(q).fetchall() self.assertEqual(rows, []) return self.db.pool.do(thd) d.addCallback(check) return d def test_flushChangeClassifications_less_than(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1)) d.addCallback(lambda _ : self.db.schedulers.flushChangeClassifications(24, less_than=5)) def check(_): def thd(conn): q = self.db.model.scheduler_changes.select() rows = conn.execute(q).fetchall() self.assertEqual([ (r.changeid, r.important) for r in rows], [ (5, 1) ]) return self.db.pool.do(thd) d.addCallback(check) return d def test_getChangeClassifications(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.change6, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1), (6, 1)) d.addCallback(lambda _ : self.db.schedulers.getChangeClassifications(24)) def check(cls): self.assertEqual(cls, { 3 : True, 4 : False, 5 : True, 6: True }) d.addCallback(check) return d def test_getChangeClassifications_branch(self): d = self.insertTestData([ self.change3, self.change4, self.change5, self.change6, self.scheduler24 ]) d.addCallback(self.addClassifications, 24, (3, 1), (4, 0), (5, 1), (6, 1)) d.addCallback(lambda _ : self.db.schedulers.getChangeClassifications(24, branch='sql')) def check(cls): self.assertEqual(cls, { 6 : True }) d.addCallback(check) return d def test_getSchedulerId_first_time(self): d = self.insertTestData([ fakedb.Scheduler(name='distractor', class_name='Weekly', schedulerid=992, state='{"foo": "bar"}') ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Nightly')) d.addCallback(lambda schid : self.checkScheduler(schid, 'mysched', 'Nightly', '{}')) return d def test_getSchedulerId_existing(self): d = self.insertTestData([ fakedb.Scheduler(name='mysched', class_name='Nightly', schedulerid=992, state='{"foo": "bar"}') ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Nightly')) def check(schid): self.assertEqual(schid, 992) return self.checkScheduler(992, 'mysched', 'Nightly', '{"foo": "bar"}') d.addCallback(check) return d def test_getSchedulerId_upgrade(self): d = self.insertTestData([ fakedb.Scheduler(name='mysched', class_name='', schedulerid=992, state='{}') ]) d.addCallback(lambda _ : self.db.schedulers.getSchedulerId('mysched', 'Hourly')) def check(schid): self.assertEqual(schid, 992) # class has been filled in return self.checkScheduler(992, 'mysched', 'Hourly', '{}') d.addCallback(check) return d