示例#1
0
 def test_getWorker_multiple_connections(self):
     yield self.insertTestData(self.baseRows + [
         # the worker is connected to two masters at once.
         # weird, but the DB should represent it.
         fakedb.Worker(id=32, name='two'),
         fakedb.ConnectedWorker(workerid=32, masterid=10),
         fakedb.ConnectedWorker(workerid=32, masterid=11),
         fakedb.BuilderMaster(id=24, builderid=20, masterid=10),
         fakedb.BuilderMaster(id=25, builderid=20, masterid=11),
         fakedb.ConfiguredWorker(workerid=32, buildermasterid=24),
         fakedb.ConfiguredWorker(workerid=32, buildermasterid=25),
     ])
     workerdict = yield self.db.workers.getWorker(workerid=32)
     validation.verifyDbDict(self, 'workerdict', workerdict)
     self.assertEqual(
         workerdict,
         dict(id=32,
              name='two',
              workerinfo={'a': 'b'},
              paused=False,
              graceful=False,
              connected_to=[10, 11],
              configured_on=[
                  {
                      'builderid': 20,
                      'masterid': 10
                  },
                  {
                      'builderid': 20,
                      'masterid': 11
                  },
              ]))
示例#2
0
    def test_workerDisconnected(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows + [
            fakedb.ConnectedWorker(id=888, workerid=self.W1_ID, masterid=10),
            fakedb.ConnectedWorker(id=889, workerid=self.W1_ID, masterid=11),
        ])
        yield self.db.workers.workerDisconnected(workerid=self.W1_ID,
                                                 masterid=11)

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(w['connected_to'], [10])
示例#3
0
 def test_command_list_workers_online(self):
     self.setup_multi_builders()
     # Also set the connectedness:
     self.master.db.insertTestData(
         [fakedb.ConnectedWorker(id=113, masterid=13, workerid=1)])
     yield self.do_test_command('list', args='all workers')
     self.assertEqual(len(self.sent), 1)
     self.assertNotIn('linux1 [disconnected]', self.sent[0])
     self.assertIn('linux2 [disconnected]', self.sent[0])
示例#4
0
    def test_workerConnected_already_connected(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows + [
            fakedb.ConnectedWorker(id=888, workerid=self.W1_ID, masterid=11),
        ])
        yield self.db.workers.workerConnected(workerid=self.W1_ID,
                                              masterid=11,
                                              workerinfo={})

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(w['connected_to'], [11])
示例#5
0
    def test_command_list_builders_connected(self):
        self.setup_multi_builders()
        # Also set the connectedness:
        self.master.db.insertTestData(
            [fakedb.ConnectedWorker(id=113, masterid=13, workerid=1)])

        yield self.do_test_command('list', args='all builders')
        self.assertEqual(len(self.sent), 1)
        self.assertIn(f'{self.BUILDER_NAMES[0]} [offline]', self.sent[0])
        self.assertNotIn(f'{self.BUILDER_NAMES[1]} [offline]', self.sent[0])
示例#6
0
 def test_command_last(self):
     self.setupSomeBuilds()
     self.setup_multi_builders()
     # Also set the connectedness:
     self.master.db.insertTestData(
         [fakedb.ConnectedWorker(id=113, masterid=13, workerid=2)])
     yield self.do_test_command('last')
     self.assertEqual(len(self.sent), 1)
     sent = self.sub_seconds(self.sent)
     self.assertIn(
         '`builder1`: last build completed successfully (N seconds ago)',
         sent)
示例#7
0
 def test_command_status_online(self):
     # we are online and we have some finished builds
     self.setup_multi_builders()
     self.master.db.insertTestData([
         fakedb.ConfiguredWorker(id=14012, workerid=1,
                                 buildermasterid=4013),
         fakedb.ConnectedWorker(id=114, masterid=13, workerid=1)
     ])
     self.setupSomeBuilds()
     self.master.db.builds.finishBuild(buildid=13, results=FAILURE)
     self.master.db.builds.finishBuild(buildid=15, results=SUCCESS)
     self.master.db.builds.finishBuild(buildid=16, results=FAILURE)
     yield self.do_test_command('status')
示例#8
0
 def test_getWorker_connected_not_configured(self):
     yield self.insertTestData(self.baseRows + [
         # the worker is connected to this master, but not configured.
         # weird, but the DB should represent it.
         fakedb.Worker(id=32, name='two'),
         fakedb.ConnectedWorker(workerid=32, masterid=11),
     ])
     workerdict = yield self.db.workers.getWorker(workerid=32)
     validation.verifyDbDict(self, 'workerdict', workerdict)
     self.assertEqual(
         workerdict,
         dict(id=32,
              name='two',
              workerinfo={'a': 'b'},
              paused=False,
              graceful=False,
              connected_to=[11],
              configured_on=[]))
示例#9
0
 def test_getWorker_connected(self):
     yield self.insertTestData(self.baseRows + [
         fakedb.BuilderMaster(id=12, builderid=20, masterid=10),
         fakedb.ConfiguredWorker(workerid=30, buildermasterid=12),
         fakedb.ConnectedWorker(workerid=30, masterid=10),
     ])
     workerdict = yield self.db.workers.getWorker(workerid=30)
     validation.verifyDbDict(self, 'workerdict', workerdict)
     self.assertEqual(
         workerdict,
         dict(id=30,
              name='zero',
              workerinfo={'a': 'b'},
              paused=False,
              graceful=False,
              configured_on=[{
                  'masterid': 10,
                  'builderid': 20
              }],
              connected_to=[10]))
示例#10
0
testData = [
    fakedb.Builder(id=40, name='b1'),
    fakedb.Builder(id=41, name='b2'),
    fakedb.Master(id=13),
    fakedb.Master(id=14),
    fakedb.BuilderMaster(id=4013, builderid=40, masterid=13),
    fakedb.BuilderMaster(id=4014, builderid=40, masterid=14),
    fakedb.BuilderMaster(id=4113, builderid=41, masterid=13),

    fakedb.Worker(id=1, name='linux', info={}),
    fakedb.ConfiguredWorker(id=14013,
                            workerid=1, buildermasterid=4013),
    fakedb.ConfiguredWorker(id=14014,
                            workerid=1, buildermasterid=4014),
    fakedb.ConnectedWorker(id=113, masterid=13, workerid=1),

    fakedb.Worker(id=2, name='windows', info={"a": "b"}),
    fakedb.ConfiguredWorker(id=24013,
                            workerid=2, buildermasterid=4013),
    fakedb.ConfiguredWorker(id=24014,
                            workerid=2, buildermasterid=4014),
    fakedb.ConfiguredWorker(id=24113,
                            workerid=2, buildermasterid=4113),
    fakedb.ConnectedWorker(id=214, masterid=14, workerid=2),
]


def configuredOnKey(worker):
    return (worker.get('masterid', 0),
            worker.get('builderid', 0))
示例#11
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    baseRows = [
        fakedb.Master(id=10, name='m10'),
        fakedb.Master(id=11, name='m11'),
        fakedb.Builder(id=20, name='a'),
        fakedb.Builder(id=21, name='b'),
        fakedb.Builder(id=22, name='c'),
        fakedb.Worker(id=30, name='zero'),
        fakedb.Worker(id=31, name='one'),
    ]

    multipleMasters = [
        fakedb.BuilderMaster(id=12, builderid=20, masterid=10),
        fakedb.BuilderMaster(id=13, builderid=21, masterid=10),
        fakedb.BuilderMaster(id=14, builderid=20, masterid=11),
        fakedb.BuilderMaster(id=15, builderid=22, masterid=11),
        fakedb.BuilderMaster(id=16, builderid=22, masterid=10),
        fakedb.ConfiguredWorker(id=3012, workerid=30, buildermasterid=12),
        fakedb.ConfiguredWorker(id=3013, workerid=30, buildermasterid=13),
        fakedb.ConfiguredWorker(id=3014, workerid=30, buildermasterid=14),
        fakedb.ConfiguredWorker(id=3114, workerid=31, buildermasterid=14),
        fakedb.ConfiguredWorker(id=3115, workerid=31, buildermasterid=15),
        fakedb.ConnectedWorker(id=3010, workerid=30, masterid=10),
        fakedb.ConnectedWorker(id=3111, workerid=31, masterid=11),
    ]

    # sample worker data, with id's avoiding the postgres id sequence

    BOGUS_NAME = 'bogus'

    W1_NAME, W1_ID, W1_INFO = 'w1', 100, {'a': 1}
    worker1_rows = [
        fakedb.Worker(id=W1_ID, name=W1_NAME, info=W1_INFO),
    ]

    W2_NAME, W2_ID, W2_INFO = 'w2', 200, {'a': 1, 'b': 2}
    worker2_rows = [
        fakedb.Worker(id=W2_ID, name=W2_NAME, info=W2_INFO),
    ]

    # tests

    def test_signature_findWorkerId(self):
        @self.assertArgSpecMatches(self.db.workers.findWorkerId)
        def findWorkerId(self, name):
            pass

    def test_signature_getWorker(self):
        @self.assertArgSpecMatches(self.db.workers.getWorker)
        def getWorker(self,
                      workerid=None,
                      name=None,
                      masterid=None,
                      builderid=None):
            pass

    def test_signature_getWorkers(self):
        @self.assertArgSpecMatches(self.db.workers.getWorkers)
        def getWorkers(self,
                       masterid=None,
                       builderid=None,
                       paused=None,
                       graceful=None):
            pass

    def test_signature_workerConnected(self):
        @self.assertArgSpecMatches(self.db.workers.workerConnected)
        def workerConnected(self, workerid, masterid, workerinfo):
            pass

    def test_signature_workerDisconnected(self):
        @self.assertArgSpecMatches(self.db.workers.workerDisconnected)
        def workerDisconnected(self, workerid, masterid):
            pass

    def test_signature_workerConfigured(self):
        @self.assertArgSpecMatches(self.db.workers.workerConfigured)
        def workerConfigured(self, workerid, masterid, builderids):
            pass

    def test_signature_deconfigureAllWorkersForMaster(self):
        @self.assertArgSpecMatches(
            self.db.workers.deconfigureAllWorkersForMaster)
        def deconfigureAllWorkersForMaster(self, masterid):
            pass

    def test_signature_setWorkerState(self):
        @self.assertArgSpecMatches(self.db.workers.setWorkerState)
        def setWorkerState(self, workerid, paused, graceful):
            pass

    @defer.inlineCallbacks
    def test_findWorkerId_insert(self):
        id = yield self.db.workers.findWorkerId(name="xyz")
        worker = yield self.db.workers.getWorker(workerid=id)
        self.assertEqual(worker['name'], 'xyz')
        self.assertEqual(worker['workerinfo'], {})

    @defer.inlineCallbacks
    def test_findWorkerId_existing(self):
        yield self.insertTestData(self.baseRows)
        id = yield self.db.workers.findWorkerId(name="one")
        self.assertEqual(id, 31)

    @defer.inlineCallbacks
    def test_getWorker_no_such(self):
        yield self.insertTestData(self.baseRows)
        workerdict = yield self.db.workers.getWorker(workerid=99)
        self.assertEqual(workerdict, None)

    @defer.inlineCallbacks
    def test_getWorker_by_name_no_such(self):
        yield self.insertTestData(self.baseRows)
        workerdict = yield self.db.workers.getWorker(name='NOSUCH')
        self.assertEqual(workerdict, None)

    @defer.inlineCallbacks
    def test_getWorker_not_configured(self):
        yield self.insertTestData(self.baseRows)
        workerdict = yield self.db.workers.getWorker(workerid=30)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 connected_to=[],
                 configured_on=[]))

    @defer.inlineCallbacks
    def test_getWorker_connected_not_configured(self):
        yield self.insertTestData(self.baseRows + [
            # the worker is connected to this master, but not configured.
            # weird, but the DB should represent it.
            fakedb.Worker(id=32, name='two'),
            fakedb.ConnectedWorker(workerid=32, masterid=11),
        ])
        workerdict = yield self.db.workers.getWorker(workerid=32)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=32,
                 name='two',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 connected_to=[11],
                 configured_on=[]))

    @defer.inlineCallbacks
    def test_getWorker_multiple_connections(self):
        yield self.insertTestData(self.baseRows + [
            # the worker is connected to two masters at once.
            # weird, but the DB should represent it.
            fakedb.Worker(id=32, name='two'),
            fakedb.ConnectedWorker(workerid=32, masterid=10),
            fakedb.ConnectedWorker(workerid=32, masterid=11),
            fakedb.BuilderMaster(id=24, builderid=20, masterid=10),
            fakedb.BuilderMaster(id=25, builderid=20, masterid=11),
            fakedb.ConfiguredWorker(workerid=32, buildermasterid=24),
            fakedb.ConfiguredWorker(workerid=32, buildermasterid=25),
        ])
        workerdict = yield self.db.workers.getWorker(workerid=32)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=32,
                 name='two',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 connected_to=[10, 11],
                 configured_on=[
                     {
                         'builderid': 20,
                         'masterid': 10
                     },
                     {
                         'builderid': 20,
                         'masterid': 11
                     },
                 ]))

    @defer.inlineCallbacks
    def test_getWorker_by_name_not_configured(self):
        yield self.insertTestData(self.baseRows)
        workerdict = yield self.db.workers.getWorker(name='zero')
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 connected_to=[],
                 configured_on=[]))

    @defer.inlineCallbacks
    def test_getWorker_not_connected(self):
        yield self.insertTestData(self.baseRows + [
            fakedb.BuilderMaster(id=12, builderid=20, masterid=10),
            fakedb.ConfiguredWorker(workerid=30, buildermasterid=12),
        ])
        workerdict = yield self.db.workers.getWorker(workerid=30)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=[{
                     'masterid': 10,
                     'builderid': 20
                 }],
                 connected_to=[]))

    @defer.inlineCallbacks
    def test_getWorker_connected(self):
        yield self.insertTestData(self.baseRows + [
            fakedb.BuilderMaster(id=12, builderid=20, masterid=10),
            fakedb.ConfiguredWorker(workerid=30, buildermasterid=12),
            fakedb.ConnectedWorker(workerid=30, masterid=10),
        ])
        workerdict = yield self.db.workers.getWorker(workerid=30)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=[{
                     'masterid': 10,
                     'builderid': 20
                 }],
                 connected_to=[10]))

    @defer.inlineCallbacks
    def test_getWorker_with_multiple_masters(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdict = yield self.db.workers.getWorker(workerid=30)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                             key=configuredOnKey)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=sorted([
                     {
                         'masterid': 10,
                         'builderid': 20
                     },
                     {
                         'masterid': 10,
                         'builderid': 21
                     },
                     {
                         'masterid': 11,
                         'builderid': 20
                     },
                 ],
                                      key=configuredOnKey),
                 connected_to=[10]))

    @defer.inlineCallbacks
    def test_getWorker_with_multiple_masters_builderid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdict = yield self.db.workers.getWorker(workerid=30, builderid=20)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                             key=configuredOnKey)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=sorted([
                     {
                         'masterid': 10,
                         'builderid': 20
                     },
                     {
                         'masterid': 11,
                         'builderid': 20
                     },
                 ],
                                      key=configuredOnKey),
                 connected_to=[10]))

    @defer.inlineCallbacks
    def test_getWorker_with_multiple_masters_masterid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdict = yield self.db.workers.getWorker(workerid=30, masterid=11)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=[
                     {
                         'masterid': 11,
                         'builderid': 20
                     },
                 ],
                 connected_to=[]))

    @defer.inlineCallbacks
    def test_getWorker_with_multiple_masters_builderid_masterid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdict = yield self.db.workers.getWorker(workerid=30,
                                                     builderid=20,
                                                     masterid=11)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=[
                     {
                         'masterid': 11,
                         'builderid': 20
                     },
                 ],
                 connected_to=[]))

    @defer.inlineCallbacks
    def test_getWorker_by_name_with_multiple_masters_builderid_masterid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdict = yield self.db.workers.getWorker(name='zero',
                                                     builderid=20,
                                                     masterid=11)
        validation.verifyDbDict(self, 'workerdict', workerdict)
        self.assertEqual(
            workerdict,
            dict(id=30,
                 name='zero',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=False,
                 configured_on=[
                     {
                         'masterid': 11,
                         'builderid': 20
                     },
                 ],
                 connected_to=[]))

    @defer.inlineCallbacks
    def test_getWorkers_no_config(self):
        yield self.insertTestData(self.baseRows)
        workerdicts = yield self.db.workers.getWorkers()
        [
            validation.verifyDbDict(self, 'workerdict', workerdict)
            for workerdict in workerdicts
        ]
        self.assertEqual(
            sorted(workerdicts, key=workerKey),
            sorted([
                dict(id=30,
                     name='zero',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=[],
                     connected_to=[]),
                dict(id=31,
                     name='one',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=[],
                     connected_to=[]),
            ],
                   key=workerKey))

    @defer.inlineCallbacks
    def test_getWorkers_with_config(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdicts = yield self.db.workers.getWorkers()
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                                 key=configuredOnKey)
        self.assertEqual(
            sorted(workerdicts, key=workerKey),
            sorted([
                dict(id=30,
                     name='zero',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 10,
                             'builderid': 20
                         },
                         {
                             'masterid': 10,
                             'builderid': 21
                         },
                         {
                             'masterid': 11,
                             'builderid': 20
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[10]),
                dict(id=31,
                     name='one',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 11,
                             'builderid': 20
                         },
                         {
                             'masterid': 11,
                             'builderid': 22
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[11]),
            ],
                   key=workerKey))

    @defer.inlineCallbacks
    def test_getWorkers_empty(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdicts = yield self.db.workers.getWorkers(masterid=11,
                                                       builderid=21)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                                 key=configuredOnKey)
        self.assertEqual(sorted(workerdicts, key=workerKey), [])

    @defer.inlineCallbacks
    def test_getWorkers_with_config_builderid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdicts = yield self.db.workers.getWorkers(builderid=20)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                                 key=configuredOnKey)
        self.assertEqual(
            sorted(workerdicts, key=workerKey),
            sorted([
                dict(id=30,
                     name='zero',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 10,
                             'builderid': 20
                         },
                         {
                             'masterid': 11,
                             'builderid': 20
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[10]),
                dict(id=31,
                     name='one',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 11,
                             'builderid': 20
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[11]),
            ],
                   key=workerKey))

    @defer.inlineCallbacks
    def test_getWorkers_with_config_masterid_10(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdicts = yield self.db.workers.getWorkers(masterid=10)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                                 key=configuredOnKey)
        self.assertEqual(
            sorted(workerdicts, key=workerKey),
            sorted([
                dict(id=30,
                     name='zero',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 10,
                             'builderid': 20
                         },
                         {
                             'masterid': 10,
                             'builderid': 21
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[10]),
            ],
                   key=workerKey))

    @defer.inlineCallbacks
    def test_getWorkers_with_config_masterid_11(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdicts = yield self.db.workers.getWorkers(masterid=11)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                                 key=configuredOnKey)
        self.assertEqual(
            sorted(workerdicts, key=workerKey),
            sorted([
                dict(id=30,
                     name='zero',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 11,
                             'builderid': 20
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[]),
                dict(id=31,
                     name='one',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 11,
                             'builderid': 20
                         },
                         {
                             'masterid': 11,
                             'builderid': 22
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[11]),
            ],
                   key=workerKey))

    @defer.inlineCallbacks
    def test_getWorkers_with_config_masterid_11_builderid_22(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        workerdicts = yield self.db.workers.getWorkers(masterid=11,
                                                       builderid=22)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = sorted(workerdict['configured_on'],
                                                 key=configuredOnKey)
        self.assertEqual(
            sorted(workerdicts, key=workerKey),
            sorted([
                dict(id=31,
                     name='one',
                     workerinfo={'a': 'b'},
                     paused=False,
                     graceful=False,
                     configured_on=sorted([
                         {
                             'masterid': 11,
                             'builderid': 22
                         },
                     ],
                                          key=configuredOnKey),
                     connected_to=[11]),
            ],
                   key=workerKey))

    @defer.inlineCallbacks
    def test_getWorkers_with_paused(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        yield self.db.workers.setWorkerState(31, paused=True, graceful=False)
        workerdicts = yield self.db.workers.getWorkers(paused=True)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = []
        self.assertEqual(workerdicts, [
            dict(id=31,
                 name='one',
                 workerinfo={'a': 'b'},
                 paused=True,
                 graceful=False,
                 configured_on=[],
                 connected_to=[11]),
        ])

    @defer.inlineCallbacks
    def test_getWorkers_with_graceful(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        yield self.db.workers.setWorkerState(31, paused=False, graceful=True)
        workerdicts = yield self.db.workers.getWorkers(graceful=True)
        for workerdict in workerdicts:
            validation.verifyDbDict(self, 'workerdict', workerdict)
            workerdict['configured_on'] = []
        self.assertEqual(workerdicts, [
            dict(id=31,
                 name='one',
                 workerinfo={'a': 'b'},
                 paused=False,
                 graceful=True,
                 configured_on=[],
                 connected_to=[11]),
        ])

    @defer.inlineCallbacks
    def test_workerConnected_existing(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows)

        NEW_INFO = {'other': [1, 2, 3]}

        yield self.db.workers.workerConnected(workerid=self.W1_ID,
                                              masterid=11,
                                              workerinfo=NEW_INFO)

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(
            w, {
                'id': self.W1_ID,
                'name': self.W1_NAME,
                'workerinfo': NEW_INFO,
                'paused': False,
                'graceful': False,
                'configured_on': [],
                'connected_to': [11]
            })

    @defer.inlineCallbacks
    def test_workerConnected_already_connected(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows + [
            fakedb.ConnectedWorker(id=888, workerid=self.W1_ID, masterid=11),
        ])
        yield self.db.workers.workerConnected(workerid=self.W1_ID,
                                              masterid=11,
                                              workerinfo={})

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(w['connected_to'], [11])

    @defer.inlineCallbacks
    def test_workerDisconnected(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows + [
            fakedb.ConnectedWorker(id=888, workerid=self.W1_ID, masterid=10),
            fakedb.ConnectedWorker(id=889, workerid=self.W1_ID, masterid=11),
        ])
        yield self.db.workers.workerDisconnected(workerid=self.W1_ID,
                                                 masterid=11)

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(w['connected_to'], [10])

    @defer.inlineCallbacks
    def test_workerDisconnected_already_disconnected(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows)
        yield self.db.workers.workerDisconnected(workerid=self.W1_ID,
                                                 masterid=11)

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(w['connected_to'], [])

    @defer.inlineCallbacks
    def test_setWorkerState_existing(self):
        yield self.insertTestData(self.baseRows + self.worker1_rows)

        yield self.db.workers.setWorkerState(workerid=self.W1_ID,
                                             paused=False,
                                             graceful=True)

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(
            w, {
                'id': self.W1_ID,
                'name': self.W1_NAME,
                'workerinfo': self.W1_INFO,
                'paused': False,
                'graceful': True,
                'configured_on': [],
                'connected_to': []
            })

        yield self.db.workers.setWorkerState(workerid=self.W1_ID,
                                             paused=True,
                                             graceful=False)

        w = yield self.db.workers.getWorker(self.W1_ID)
        self.assertEqual(
            w, {
                'id': self.W1_ID,
                'name': self.W1_NAME,
                'workerinfo': self.W1_INFO,
                'paused': True,
                'graceful': False,
                'configured_on': [],
                'connected_to': []
            })

    @defer.inlineCallbacks
    def test_workerConfigured(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        # should remove builder 21, and add 22
        yield self.db.workers.deconfigureAllWorkersForMaster(masterid=10)

        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=10,
                                               builderids=[20, 22])

        w = yield self.db.workers.getWorker(30)
        self.assertEqual(
            sorted(w['configured_on'], key=configuredOnKey),
            sorted([{
                'builderid': 20,
                'masterid': 11
            }, {
                'builderid': 20,
                'masterid': 10
            }, {
                'builderid': 22,
                'masterid': 10
            }],
                   key=configuredOnKey))

    @defer.inlineCallbacks
    def test_workerConfiguredTwice(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        # should remove builder 21, and add 22
        yield self.db.workers.deconfigureAllWorkersForMaster(masterid=10)

        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=10,
                                               builderids=[20, 22])

        # configure again (should eat the duplicate insertion errors)
        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=10,
                                               builderids=[20, 21, 22])

        w = yield self.db.workers.getWorker(30)
        x1 = sorted(w['configured_on'], key=configuredOnKey)
        x2 = sorted([{
            'builderid': 20,
            'masterid': 11
        }, {
            'builderid': 20,
            'masterid': 10
        }, {
            'builderid': 21,
            'masterid': 10
        }, {
            'builderid': 22,
            'masterid': 10
        }],
                    key=configuredOnKey)
        self.assertEqual(x1, x2)

    @defer.inlineCallbacks
    def test_workerReConfigured(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        # should remove builder 21, and add 22
        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=10,
                                               builderids=[20, 22])

        w = yield self.db.workers.getWorker(30)
        w['configured_on'] = sorted(w['configured_on'], key=configuredOnKey)
        self.assertEqual(
            w['configured_on'],
            sorted([{
                'builderid': 20,
                'masterid': 11
            }, {
                'builderid': 20,
                'masterid': 10
            }, {
                'builderid': 22,
                'masterid': 10
            }],
                   key=configuredOnKey))

    @defer.inlineCallbacks
    def test_workerReConfigured_should_not_affect_other_worker(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        # should remove all the builders in master 11
        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=11,
                                               builderids=[])

        w = yield self.db.workers.getWorker(30)
        x1 = sorted(w['configured_on'], key=configuredOnKey)
        x2 = sorted([{
            'builderid': 20,
            'masterid': 10
        }, {
            'builderid': 21,
            'masterid': 10
        }],
                    key=configuredOnKey)
        self.assertEqual(x1, x2)

        # ensure worker 31 is not affected (see GitHub issue#3392)
        w = yield self.db.workers.getWorker(31)
        x1 = sorted(w['configured_on'], key=configuredOnKey)
        x2 = sorted([{
            'builderid': 20,
            'masterid': 11
        }, {
            'builderid': 22,
            'masterid': 11
        }],
                    key=configuredOnKey)
        self.assertEqual(x1, x2)

    @defer.inlineCallbacks
    def test_workerUnconfigured(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        # should remove all builders from master 10
        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=10,
                                               builderids=[])

        w = yield self.db.workers.getWorker(30)
        w['configured_on'] = sorted(w['configured_on'], key=configuredOnKey)
        expected = sorted([{
            'builderid': 20,
            'masterid': 11
        }],
                          key=configuredOnKey)
        self.assertEqual(w['configured_on'], expected)

    @defer.inlineCallbacks
    def test_nothingConfigured(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        # should remove builder 21, and add 22
        yield self.db.workers.deconfigureAllWorkersForMaster(masterid=10)
        yield self.db.workers.workerConfigured(workerid=30,
                                               masterid=10,
                                               builderids=[])

        # should only keep builder for master 11
        w = yield self.db.workers.getWorker(30)
        self.assertEqual(sorted(w['configured_on']),
                         sorted([{
                             'builderid': 20,
                             'masterid': 11
                         }]))

    @defer.inlineCallbacks
    def test_deconfiguredAllWorkers(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)

        res = yield self.db.workers.getWorkers(masterid=11)
        self.assertEqual(len(res), 2)

        # should remove all worker configured for masterid 11
        yield self.db.workers.deconfigureAllWorkersForMaster(masterid=11)

        res = yield self.db.workers.getWorkers(masterid=11)
        self.assertEqual(len(res), 0)