Example #1
0
 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)
Example #2
0
 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),
     ])
Example #3
0
 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
     })])
Example #4
0
    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)
Example #5
0
 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
Example #6
0
 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
Example #7
0
 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
Example #8
0
 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
Example #9
0
 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
Example #10
0
 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
Example #11
0
 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
Example #12
0
    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)
Example #13
0
    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
Example #14
0
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!
Example #15
0
    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
Example #16
0
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
Example #17
0
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