Beispiel #1
0
    def setupStep(self,
                  step,
                  sourcestampsInBuild=None,
                  gotRevisionsInBuild=None,
                  *args,
                  **kwargs):
        sourcestamps = sourcestampsInBuild or []
        got_revisions = gotRevisionsInBuild or {}

        steps.BuildStepMixin.setupStep(self, step, *args, **kwargs)

        # This step reaches deeply into a number of parts of Buildbot.  That
        # should be fixed!

        # set up a buildmaster that knows about two fake schedulers, a and b
        m = self.master
        m.db.checkForeignKeys = True
        self.build.builder.botmaster = m.botmaster
        m.status = master.Status()
        m.status.setServiceParent(m)
        m.config.buildbotURL = "baseurl/"
        m.scheduler_manager = FakeSchedulerManager()

        self.scheduler_a = a = FakeTriggerable(name='a')
        self.scheduler_b = b = FakeTriggerable(name='b')
        m.scheduler_manager.namedServices = dict(a=a, b=b)

        a.brids = {77: 11}
        b.brids = {78: 22}

        make_fake_br = lambda brid, builderid: fakedb.BuildRequest(
            id=brid, buildsetid=BRID_TO_BSID(brid), builderid=builderid)
        make_fake_build = lambda brid: fakedb.Build(buildrequestid=brid,
                                                    id=BRID_TO_BID(brid),
                                                    number=
                                                    BRID_TO_BUILD_NUMBER(brid),
                                                    masterid=9,
                                                    workerid=13)

        m.db.insertTestData([
            fakedb.Builder(id=77, name='A'),
            fakedb.Builder(id=78, name='B'),
            fakedb.Master(id=9),
            fakedb.Buildset(id=2022),
            fakedb.Buildset(id=2011),
            fakedb.Worker(id=13, name="some:worker"),
            make_fake_br(11, 77),
            make_fake_br(22, 78),
            make_fake_build(11),
            make_fake_build(22),
        ])

        def getAllSourceStamps():
            return sourcestamps

        self.build.getAllSourceStamps = getAllSourceStamps

        def getAllGotRevisions():
            return got_revisions

        self.step.getAllGotRevisions = getAllGotRevisions

        self.exp_add_sourcestamp = None
        self.exp_a_trigger = None
        self.exp_b_trigger = None
        self.exp_added_urls = []
Beispiel #2
0
class Tests(interfaces.InterfaceTests):

    backgroundData = [
        fakedb.Worker(id=47, name='linux'),
        fakedb.Buildset(id=20),
        fakedb.Builder(id=88, name='b1'),
        fakedb.BuildRequest(id=41, buildsetid=20, builderid=88),
        fakedb.Master(id=88),
        fakedb.Build(id=30,
                     buildrequestid=41,
                     number=7,
                     masterid=88,
                     builderid=88,
                     workerid=47),
        fakedb.Step(id=101, buildid=30, number=1, name='one'),
        fakedb.Step(id=102, buildid=30, number=2, name='two'),
    ]

    testLogLines = [
        fakedb.Log(id=201,
                   stepid=101,
                   name=u'stdio',
                   slug=u'stdio',
                   complete=0,
                   num_lines=7,
                   type=u's'),
        fakedb.LogChunk(logid=201,
                        first_line=0,
                        last_line=1,
                        compressed=0,
                        content=textwrap.dedent("""\
                    line zero
                    line 1""" + "x" * 200)),
        fakedb.LogChunk(logid=201,
                        first_line=2,
                        last_line=4,
                        compressed=0,
                        content=textwrap.dedent("""\
                    line TWO

                    line 2**2""")),
        fakedb.LogChunk(logid=201,
                        first_line=5,
                        last_line=5,
                        compressed=0,
                        content="another line"),
        fakedb.LogChunk(logid=201,
                        first_line=6,
                        last_line=6,
                        compressed=0,
                        content="yet another line"),
    ]
    bug3101Content = base64.b64decode("""
        PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0
        9PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpbU0tJUFBFRF0Kbm90IGEgd2luMz
        IgcGxhdGZvcm0KCmJ1aWxkc2xhdmUudGVzdC51bml0LnRlc3RfcnVucHJvY2Vzcy5UZ
        XN0UnVuUHJvY2Vzcy50ZXN0UGlwZVN0cmluZwotLS0tLS0tLS0tLS0tLS0tLS0tLS0t
        LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0
        tLS0tLS0tClJhbiAyNjcgdGVzdHMgaW4gNS4zNzhzCgpQQVNTRUQgKHNraXBzPTEsIH
        N1Y2Nlc3Nlcz0yNjYpCnByb2dyYW0gZmluaXNoZWQgd2l0aCBleGl0IGNvZGUgMAplb
        GFwc2VkVGltZT04LjI0NTcwMg==""")

    bug3101Rows = [
        fakedb.Log(id=1470,
                   stepid=101,
                   name=u'problems',
                   slug=u'problems',
                   complete=1,
                   num_lines=11,
                   type=u't'),
        fakedb.LogChunk(logid=1470,
                        first_line=0,
                        last_line=10,
                        compressed=0,
                        content=bug3101Content),
    ]

    @defer.inlineCallbacks
    def checkTestLogLines(self):
        expLines = [
            'line zero', 'line 1' + "x" * 200, 'line TWO', '', 'line 2**2',
            'another line', 'yet another line'
        ]
        for first_line in range(0, 7):
            for last_line in range(first_line, 7):
                got_lines = yield self.db.logs.getLogLines(
                    201, first_line, last_line)
                self.assertEqual(
                    got_lines,
                    "\n".join(expLines[first_line:last_line + 1] + [""]))
        # check overflow
        self.assertEqual((yield self.db.logs.getLogLines(201, 5, 20)),
                         "\n".join(expLines[5:7] + [""]))

    # signature tests

    def test_signature_getLog(self):
        @self.assertArgSpecMatches(self.db.logs.getLog)
        def getLog(self, logid):
            pass

    def test_signature_getLogBySlug(self):
        @self.assertArgSpecMatches(self.db.logs.getLogBySlug)
        def getLogBySlug(self, stepid, slug):
            pass

    def test_signature_getLogs(self):
        @self.assertArgSpecMatches(self.db.logs.getLogs)
        def getLogs(self, stepid=None):
            pass

    def test_signature_getLogLines(self):
        @self.assertArgSpecMatches(self.db.logs.getLogLines)
        def getLogLines(self, logid, first_line, last_line):
            pass

    def test_signature_addLog(self):
        @self.assertArgSpecMatches(self.db.logs.addLog)
        def addLog(self, stepid, name, slug, type):
            pass

    def test_signature_appendLog(self):
        @self.assertArgSpecMatches(self.db.logs.appendLog)
        def appendLog(self, logid, content):
            pass

    def test_signature_finishLog(self):
        @self.assertArgSpecMatches(self.db.logs.finishLog)
        def finishLog(self, logid):
            pass

    def test_signature_compressLog(self):
        @self.assertArgSpecMatches(self.db.logs.compressLog)
        def compressLog(self, logid):
            pass

    # method tests

    @defer.inlineCallbacks
    def test_getLog(self):
        yield self.insertTestData(self.backgroundData + [
            fakedb.Log(id=201,
                       stepid=101,
                       name=u'stdio',
                       slug=u'stdio',
                       complete=0,
                       num_lines=200,
                       type=u's'),
        ])
        logdict = yield self.db.logs.getLog(201)
        validation.verifyDbDict(self, 'logdict', logdict)
        self.assertEqual(
            logdict, {
                'id': 201,
                'stepid': 101,
                'name': u'stdio',
                'slug': u'stdio',
                'complete': False,
                'num_lines': 200,
                'type': 's',
            })

    @defer.inlineCallbacks
    def test_getLog_missing(self):
        logdict = yield self.db.logs.getLog(201)
        self.assertEqual(logdict, None)

    @defer.inlineCallbacks
    def test_getLogBySlug(self):
        yield self.insertTestData(self.backgroundData + [
            fakedb.Log(id=201,
                       stepid=101,
                       name=u'stdio',
                       slug=u'stdio',
                       complete=0,
                       num_lines=200,
                       type=u's'),
            fakedb.Log(id=202,
                       stepid=101,
                       name=u'dbg.log',
                       slug=u'dbg_log',
                       complete=1,
                       num_lines=200,
                       type=u's'),
        ])
        logdict = yield self.db.logs.getLogBySlug(101, u'dbg_log')
        validation.verifyDbDict(self, 'logdict', logdict)
        self.assertEqual(logdict['id'], 202)

    @defer.inlineCallbacks
    def test_getLogBySlug_missing(self):
        yield self.insertTestData(self.backgroundData + [
            fakedb.Log(id=201,
                       stepid=101,
                       name=u'stdio',
                       slug=u'stdio',
                       complete=0,
                       num_lines=200,
                       type=u's'),
        ])
        logdict = yield self.db.logs.getLogBySlug(102, u'stdio')
        self.assertEqual(logdict, None)

    @defer.inlineCallbacks
    def test_getLogs(self):
        yield self.insertTestData(self.backgroundData + [
            fakedb.Log(id=201,
                       stepid=101,
                       name=u'stdio',
                       slug=u'stdio',
                       complete=0,
                       num_lines=200,
                       type=u's'),
            fakedb.Log(id=202,
                       stepid=101,
                       name=u'dbg.log',
                       slug=u'dbg_log',
                       complete=1,
                       num_lines=300,
                       type=u't'),
            fakedb.Log(id=203,
                       stepid=102,
                       name=u'stdio',
                       slug=u'stdio',
                       complete=0,
                       num_lines=200,
                       type=u's'),
        ])
        logdicts = yield self.db.logs.getLogs(101)
        for logdict in logdicts:
            validation.verifyDbDict(self, 'logdict', logdict)
        self.assertEqual(sorted([ld['id'] for ld in logdicts]), [201, 202])

    @defer.inlineCallbacks
    def test_getLogLines(self):
        yield self.insertTestData(self.backgroundData + self.testLogLines)
        yield self.checkTestLogLines()

        # check line number reversal
        self.assertEqual((yield self.db.logs.getLogLines(201, 6, 3)), '')

    @defer.inlineCallbacks
    def test_getLogLines_empty(self):
        yield self.insertTestData(self.backgroundData + [
            fakedb.Log(id=201,
                       stepid=101,
                       name=u'stdio',
                       slug=u'stdio',
                       complete=0,
                       num_lines=200,
                       type=u's'),
        ])
        self.assertEqual((yield self.db.logs.getLogLines(201, 9, 99)), '')
        self.assertEqual((yield self.db.logs.getLogLines(999, 9, 99)), '')

    @defer.inlineCallbacks
    def test_getLogLines_bug3101(self):
        # regression test for #3101
        content = self.bug3101Content
        yield self.insertTestData(self.backgroundData + self.bug3101Rows)
        # overall content is the same, with '\n' padding at the end
        self.assertEqual((yield self.db.logs.getLogLines(1470, 0, 99)),
                         self.bug3101Content + '\n')
        # try to fetch just one line
        self.assertEqual((yield self.db.logs.getLogLines(1470, 0, 0)),
                         content.split('\n')[0] + '\n')

    @defer.inlineCallbacks
    def test_addLog_getLog(self):
        yield self.insertTestData(self.backgroundData)
        logid = yield self.db.logs.addLog(stepid=101,
                                          name=u'config.log',
                                          slug=u'config_log',
                                          type=u't')
        logdict = yield self.db.logs.getLog(logid)
        validation.verifyDbDict(self, 'logdict', logdict)
        self.assertEqual(
            logdict, {
                'id': logid,
                'stepid': 101,
                'name': u'config.log',
                'slug': u'config_log',
                'complete': False,
                'num_lines': 0,
                'type': 't',
            })

    @defer.inlineCallbacks
    def test_appendLog_getLogLines(self):
        yield self.insertTestData(self.backgroundData + self.testLogLines)
        logid = yield self.db.logs.addLog(stepid=102,
                                          name=u'another',
                                          slug=u'another',
                                          type=u's')
        self.assertEqual((yield self.db.logs.appendLog(logid, u'xyz\n')),
                         (0, 0))
        self.assertEqual((yield self.db.logs.appendLog(201, u'abc\ndef\n')),
                         (7, 8))
        self.assertEqual((yield self.db.logs.appendLog(logid, u'XYZ\n')),
                         (1, 1))
        self.assertEqual((yield self.db.logs.getLogLines(201, 6, 7)),
                         u"yet another line\nabc\n")
        self.assertEqual((yield self.db.logs.getLogLines(201, 7, 8)),
                         u"abc\ndef\n")
        self.assertEqual((yield self.db.logs.getLogLines(201, 8, 8)), u"def\n")
        self.assertEqual((yield self.db.logs.getLogLines(logid, 0, 1)),
                         u"xyz\nXYZ\n")
        self.assertEqual(
            (yield self.db.logs.getLog(logid)), {
                'complete': False,
                'id': logid,
                'name': u'another',
                'slug': u'another',
                'num_lines': 2,
                'stepid': 102,
                'type': u's',
            })

    @defer.inlineCallbacks
    def test_compressLog(self):
        yield self.insertTestData(self.backgroundData + self.testLogLines)
        yield self.db.logs.compressLog(201)
        # test log lines should still be readable just the same
        yield self.checkTestLogLines()

    @defer.inlineCallbacks
    def test_addLogLines_big_chunk(self):
        yield self.insertTestData(self.backgroundData + self.testLogLines)
        self.assertEqual(
            (yield self.db.logs.appendLog(201, u'abc\n' * 20000)),  # 80k
            (7, 20006))
        lines = yield self.db.logs.getLogLines(201, 7, 50000)
        self.assertEqual(len(lines), 80000)
        self.assertEqual(lines, (u'abc\n' * 20000))

    @defer.inlineCallbacks
    def test_addLogLines_big_chunk_big_lines(self):
        yield self.insertTestData(self.backgroundData + self.testLogLines)
        line = u'x' * 33000 + '\n'
        self.assertEqual((yield self.db.logs.appendLog(201, line * 3)),
                         (7, 9))  # three long lines, all truncated
        lines = yield self.db.logs.getLogLines(201, 7, 100)
        self.assertEqual(len(lines), 99003)
        self.assertEqual(lines, (line * 3))
    def testRebuildBuildrequest(self):
        self.master.db.insertTestData([
            fakedb.Builder(id=77, name='builder'),
            fakedb.Master(id=88),
            fakedb.Worker(id=13, name='sl'),
            fakedb.Buildset(id=8822),
            fakedb.SourceStamp(id=234),
            fakedb.BuildsetSourceStamp(buildsetid=8822, sourcestampid=234),
            fakedb.BuildRequest(id=82, buildsetid=8822, builderid=77),
            fakedb.BuildsetProperty(buildsetid=8822,
                                    property_name='prop1',
                                    property_value='["one", "fake1"]'),
            fakedb.BuildsetProperty(buildsetid=8822,
                                    property_name='prop2',
                                    property_value='["two", "fake2"]'),
        ])
        buildrequest = yield self.master.data.get(('buildrequests', 82))
        new_bsid, brid_dict = yield self.rtype.rebuildBuildrequest(
            buildrequest)

        self.assertEqual(brid_dict.keys(), [77])
        buildrequest = yield self.master.data.get(
            ('buildrequests', brid_dict[77]))
        # submitted_at is the time of the test, so better not depend on it
        self.assertTrue(buildrequest['submitted_at'] is not None)
        buildrequest['submitted_at'] = None
        self.assertEqual(
            buildrequest, {
                'buildrequestid': 1001,
                'complete': False,
                'waited_for': False,
                'claimed_at': None,
                'results': -1,
                'claimed': False,
                'buildsetid': 200,
                'complete_at': None,
                'submitted_at': None,
                'builderid': 77,
                'claimed_by_masterid': None,
                'priority': 0
            })
        buildset = yield self.master.data.get(('buildsets', new_bsid))
        oldbuildset = yield self.master.data.get(('buildsets', 8822))

        # assert same sourcestamp
        self.assertEqual(buildset['sourcestamps'], oldbuildset['sourcestamps'])
        buildset['sourcestamps'] = None
        self.assertTrue(buildset['submitted_at'] is not None)
        buildset['submitted_at'] = None
        self.assertEqual(
            buildset, {
                'bsid': 200,
                'complete_at': None,
                'submitted_at': None,
                'sourcestamps': None,
                'parent_buildid': None,
                'results': -1,
                'parent_relationship': None,
                'reason': u'rebuild',
                'external_idstring': u'extid',
                'complete': False
            })

        properties = yield self.master.data.get(
            ('buildsets', new_bsid, 'properties'))
        self.assertEqual(properties, {
            u'prop1': (u'one', u'fake1'),
            u'prop2': (u'two', u'fake2')
        })
class Tests(interfaces.InterfaceTests):

    # common sample data

    builder_row = [
        fakedb.Builder(id=7, name="some:builder"),
    ]

    # tests

    def test_signature_findBuilderId(self):
        @self.assertArgSpecMatches(self.db.builders.findBuilderId)
        def findBuilderId(self, name):
            pass

    def test_signature_addBuilderMaster(self):
        @self.assertArgSpecMatches(self.db.builders.addBuilderMaster)
        def addBuilderMaster(self, builderid=None, masterid=None):
            pass

    def test_signature_removeBuilderMaster(self):
        @self.assertArgSpecMatches(self.db.builders.removeBuilderMaster)
        def removeBuilderMaster(self, builderid=None, masterid=None):
            pass

    def test_signature_getBuilder(self):
        @self.assertArgSpecMatches(self.db.builders.getBuilder)
        def getBuilder(self, builderid):
            pass

    def test_signature_getBuilders(self):
        @self.assertArgSpecMatches(self.db.builders.getBuilders)
        def getBuilders(self, masterid=None):
            pass

    def test_signature_updateBuilderInfo(self):
        @self.assertArgSpecMatches(self.db.builders.updateBuilderInfo)
        def updateBuilderInfo(self, builderid, description, tags):
            pass

    @defer.inlineCallbacks
    def test_updateBuilderInfo(self):
        yield self.insertTestData([
            fakedb.Builder(id=7, name='some:builder7'),
            fakedb.Builder(id=8, name='some:builder8'),
        ])

        yield self.db.builders.updateBuilderInfo(
            7, u'a string which describe the builder', [u'cat1', u'cat2'])
        yield self.db.builders.updateBuilderInfo(
            8, u'a string which describe the builder', [])
        builderdict7 = yield self.db.builders.getBuilder(7)
        validation.verifyDbDict(self, 'builderdict', builderdict7)
        self.assertEqual(
            builderdict7,
            dict(id=7,
                 name='some:builder7',
                 tags=['cat1', 'cat2'],
                 masterids=[],
                 description='a string which describe the builder'))
        builderdict8 = yield self.db.builders.getBuilder(8)
        validation.verifyDbDict(self, 'builderdict', builderdict8)
        self.assertEqual(
            builderdict8,
            dict(id=8,
                 name='some:builder8',
                 tags=[],
                 masterids=[],
                 description='a string which describe the builder'))

    @defer.inlineCallbacks
    def test_findBuilderId_new(self):
        id = yield self.db.builders.findBuilderId('some:builder')
        builderdict = yield self.db.builders.getBuilder(id)
        self.assertEqual(
            builderdict,
            dict(id=id,
                 name='some:builder',
                 tags=[],
                 masterids=[],
                 description=None))

    @defer.inlineCallbacks
    def test_findBuilderId_exists(self):
        yield self.insertTestData([
            fakedb.Builder(id=7, name='some:builder'),
        ])
        id = yield self.db.builders.findBuilderId('some:builder')
        self.assertEqual(id, 7)

    @defer.inlineCallbacks
    def test_addBuilderMaster(self):
        yield self.insertTestData([
            fakedb.Builder(id=7),
            fakedb.Master(id=9, name='abc'),
            fakedb.Master(id=10, name='def'),
            fakedb.BuilderMaster(builderid=7, masterid=10),
        ])
        yield self.db.builders.addBuilderMaster(builderid=7, masterid=9)
        builderdict = yield self.db.builders.getBuilder(7)
        validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            builderdict,
            dict(id=7,
                 name='some:builder',
                 tags=[],
                 masterids=[9, 10],
                 description=None))

    @defer.inlineCallbacks
    def test_addBuilderMaster_already_present(self):
        yield self.insertTestData([
            fakedb.Builder(id=7),
            fakedb.Master(id=9, name='abc'),
            fakedb.Master(id=10, name='def'),
            fakedb.BuilderMaster(builderid=7, masterid=9),
        ])
        yield self.db.builders.addBuilderMaster(builderid=7, masterid=9)
        builderdict = yield self.db.builders.getBuilder(7)
        validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            builderdict,
            dict(id=7,
                 name='some:builder',
                 tags=[],
                 masterids=[9],
                 description=None))

    @defer.inlineCallbacks
    def test_removeBuilderMaster(self):
        yield self.insertTestData([
            fakedb.Builder(id=7),
            fakedb.Master(id=9, name='some:master'),
            fakedb.Master(id=10, name='other:master'),
            fakedb.BuilderMaster(builderid=7, masterid=9),
            fakedb.BuilderMaster(builderid=7, masterid=10),
        ])
        yield self.db.builders.removeBuilderMaster(builderid=7, masterid=9)
        builderdict = yield self.db.builders.getBuilder(7)
        validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            builderdict,
            dict(id=7,
                 name='some:builder',
                 tags=[],
                 masterids=[10],
                 description=None))

    @defer.inlineCallbacks
    def test_getBuilder_no_masters(self):
        yield self.insertTestData([
            fakedb.Builder(id=7, name='some:builder'),
        ])
        builderdict = yield self.db.builders.getBuilder(7)
        validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            builderdict,
            dict(id=7,
                 name='some:builder',
                 tags=[],
                 masterids=[],
                 description=None))

    @defer.inlineCallbacks
    def test_getBuilder_with_masters(self):
        yield self.insertTestData([
            fakedb.Builder(id=7, name='some:builder'),
            fakedb.Master(id=3, name='m1'),
            fakedb.Master(id=4, name='m2'),
            fakedb.BuilderMaster(builderid=7, masterid=3),
            fakedb.BuilderMaster(builderid=7, masterid=4),
        ])
        builderdict = yield self.db.builders.getBuilder(7)
        validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            builderdict,
            dict(id=7,
                 name='some:builder',
                 tags=[],
                 masterids=[3, 4],
                 description=None))

    @defer.inlineCallbacks
    def test_getBuilder_missing(self):
        builderdict = yield self.db.builders.getBuilder(7)
        self.assertEqual(builderdict, None)

    @defer.inlineCallbacks
    def test_getBuilders(self):
        yield self.insertTestData([
            fakedb.Builder(id=7, name='some:builder'),
            fakedb.Builder(id=8, name='other:builder'),
            fakedb.Builder(id=9, name='third:builder'),
            fakedb.Master(id=3, name='m1'),
            fakedb.Master(id=4, name='m2'),
            fakedb.BuilderMaster(builderid=7, masterid=3),
            fakedb.BuilderMaster(builderid=8, masterid=3),
            fakedb.BuilderMaster(builderid=8, masterid=4),
        ])
        builderlist = yield self.db.builders.getBuilders()
        for builderdict in builderlist:
            validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            sorted(builderlist),
            sorted([
                dict(id=7,
                     name='some:builder',
                     masterids=[3],
                     tags=[],
                     description=None),
                dict(id=8,
                     name='other:builder',
                     masterids=[3, 4],
                     tags=[],
                     description=None),
                dict(id=9,
                     name='third:builder',
                     masterids=[],
                     tags=[],
                     description=None),
            ]))

    @defer.inlineCallbacks
    def test_getBuilders_masterid(self):
        yield self.insertTestData([
            fakedb.Builder(id=7, name='some:builder'),
            fakedb.Builder(id=8, name='other:builder'),
            fakedb.Builder(id=9, name='third:builder'),
            fakedb.Master(id=3, name='m1'),
            fakedb.Master(id=4, name='m2'),
            fakedb.BuilderMaster(builderid=7, masterid=3),
            fakedb.BuilderMaster(builderid=8, masterid=3),
            fakedb.BuilderMaster(builderid=8, masterid=4),
        ])
        builderlist = yield self.db.builders.getBuilders(masterid=3)
        for builderdict in builderlist:
            validation.verifyDbDict(self, 'builderdict', builderdict)
        self.assertEqual(
            sorted(builderlist),
            sorted([
                dict(id=7,
                     name='some:builder',
                     masterids=[3],
                     tags=[],
                     description=None),
                dict(id=8,
                     name='other:builder',
                     masterids=[3, 4],
                     tags=[],
                     description=None),
            ]))

    @defer.inlineCallbacks
    def test_getBuilders_empty(self):
        builderlist = yield self.db.builders.getBuilders()
        self.assertEqual(sorted(builderlist), [])
Beispiel #5
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=u'a'),
        fakedb.Builder(id=21, name=u'b'),
        fakedb.Builder(id=22, name=u'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=u"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=u"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)
    def do_test_maybeBuildsetComplete(self,
                                      buildRequestCompletions=None,
                                      buildRequestResults=None,
                                      buildsetComplete=False,
                                      expectComplete=False,
                                      expectMessage=False,
                                      expectSuccess=True):
        """Test maybeBuildsetComplete.

        @param buildRequestCompletions: dict mapping brid to True if complete,
            else False (and defaulting to False)
        @param buildRequestResults: dict mapping brid to result (defaulting
            to SUCCESS)
        @param buildsetComplete: true if the buildset is already complete
        @param expectComplete: true if the buildset should be complete at exit
        @param expectMessage: true if a buildset completion message is expected
        @param expectSuccess: if expectComplete, whether to expect the buildset
            to be complete

        This first adds two buildsets to the database - 72 and 73.  Buildset 72
        is already complete if buildsetComplete is true; 73 is not complete.
        It adds four buildrequests - 42, 43, and 44 for buildset 72, and 45 for
        buildset 73.  The completion and results are based on
        buidlRequestCompletions and buildRequestResults.

        Then, maybeBuildsetComplete is called for buildset 72, and the
        expectations are checked.
        """
        if buildRequestCompletions is None:
            buildRequestCompletions = {}
        if buildRequestResults is None:
            buildRequestResults = {}

        clock = task.Clock()
        clock.advance(A_TIMESTAMP)

        def mkbr(brid, bsid=72):
            return fakedb.BuildRequest(
                id=brid,
                buildsetid=bsid,
                builderid=42,
                complete=buildRequestCompletions.get(brid),
                results=buildRequestResults.get(brid, SUCCESS))

        yield self.master.db.insertTestData([
            fakedb.Builder(id=42, name='bldr1'),
            fakedb.Buildset(
                id=72,
                submitted_at=EARLIER,
                complete=buildsetComplete,
                complete_at=A_TIMESTAMP if buildsetComplete else None),
            mkbr(42),
            mkbr(43),
            mkbr(44),
            fakedb.BuildsetSourceStamp(buildsetid=72, sourcestampid=234),
            fakedb.Buildset(id=73, complete=False),
            mkbr(45, bsid=73),
            fakedb.BuildsetSourceStamp(buildsetid=73, sourcestampid=234),
        ])

        yield self.rtype.maybeBuildsetComplete(72, _reactor=clock)

        self.master.db.buildsets.assertBuildsetCompletion(72, expectComplete)
        if expectMessage:
            self.assertEqual(self.master.mq.productions, [
                self._buildsetCompleteMessage(
                    72,
                    results=SUCCESS if expectSuccess else FAILURE,
                    submitted_at=EARLIER_EPOCH),
            ])
        else:
            self.assertEqual(self.master.mq.productions, [])
Beispiel #7
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    backgroundData = [
        fakedb.Worker(id=47, name='linux'),
        fakedb.Buildset(id=20),
        fakedb.Builder(id=88, name='b1'),
        fakedb.BuildRequest(id=41, buildsetid=20, builderid=88),
        fakedb.Master(id=88),
        fakedb.Build(id=30, buildrequestid=41, number=7, masterid=88,
                     builderid=88, workerid=47),
        fakedb.Build(id=31, buildrequestid=41, number=8, masterid=88,
                     builderid=88, workerid=47),
    ]
    stepRows = [
        fakedb.Step(id=70, number=0, name='one', buildid=30,
                    started_at=TIME1, complete_at=TIME2,
                    state_string=u'test', results=0),
        fakedb.Step(id=71, number=1, name='two', buildid=30,
                    started_at=TIME2, complete_at=TIME3,
                    state_string=u'test', results=2,
                    urls_json=u'["http://url"]',
                    hidden=1),
        fakedb.Step(id=72, number=2, name='three', buildid=30,
                    started_at=TIME3),
        fakedb.Step(id=73, number=0, name='wrong-build', buildid=31),
    ]
    stepDicts = [
        {'id': 70, 'buildid': 30, 'number': 0, 'name': u'one',
         'results': 0,
         'started_at': epoch2datetime(TIME1),
         'complete_at': epoch2datetime(TIME2),
         'state_string': u'test',
         'urls': [],
         'hidden': False},
        {'id': 71, 'buildid': 30, 'number': 1, 'name': u'two',
         'results': 2,
         'started_at': epoch2datetime(TIME2),
         'complete_at': epoch2datetime(TIME3),
         'state_string': u'test',
         'urls': [u'http://url'],
         'hidden': True},
        {'id': 72, 'buildid': 30, 'number': 2, 'name': u'three',
         'results': None,
         'started_at': epoch2datetime(TIME3),
         'complete_at': None,
         'state_string': u'',
         'urls': [],
         'hidden': False},
    ]

    # signature tests

    def test_signature_getStep(self):
        @self.assertArgSpecMatches(self.db.steps.getStep)
        def getStep(self, stepid=None, buildid=None, number=None, name=None):
            pass

    def test_signature_getSteps(self):
        @self.assertArgSpecMatches(self.db.steps.getSteps)
        def getSteps(self, buildid):
            pass

    def test_signature_addStep(self):
        @self.assertArgSpecMatches(self.db.steps.addStep)
        def addStep(self, buildid, name, state_string):
            pass

    def test_signature_startStep(self):
        @self.assertArgSpecMatches(self.db.steps.startStep)
        def addStep(self, stepid):
            pass

    def test_signature_setStepStateString(self):
        @self.assertArgSpecMatches(self.db.steps.setStepStateString)
        def setStepStateString(self, stepid, state_string):
            pass

    def test_signature_finishStep(self):
        @self.assertArgSpecMatches(self.db.steps.finishStep)
        def finishStep(self, stepid, results, hidden):
            pass

    # method tests

    @defer.inlineCallbacks
    def test_getStep(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[0]])
        stepdict = yield self.db.steps.getStep(70)
        validation.verifyDbDict(self, 'stepdict', stepdict)
        self.assertEqual(stepdict, self.stepDicts[0])

    @defer.inlineCallbacks
    def test_getStep_missing(self):
        stepdict = yield self.db.steps.getStep(50)
        self.assertEqual(stepdict, None)

    @defer.inlineCallbacks
    def test_getStep_number(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[1]])
        stepdict = yield self.db.steps.getStep(buildid=30, number=1)
        validation.verifyDbDict(self, 'stepdict', stepdict)
        self.assertEqual(stepdict['id'], 71)

    @defer.inlineCallbacks
    def test_getStep_number_missing(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[1]])
        stepdict = yield self.db.steps.getStep(buildid=30, number=9)
        self.assertEqual(stepdict, None)

    @defer.inlineCallbacks
    def test_getStep_name(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        stepdict = yield self.db.steps.getStep(buildid=30,
                                               name='three')
        validation.verifyDbDict(self, 'stepdict', stepdict)
        self.assertEqual(stepdict['id'], 72)

    @defer.inlineCallbacks
    def test_getStep_name_missing(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        stepdict = yield self.db.steps.getStep(buildid=30, name='five')
        self.assertEqual(stepdict, None)

    def test_getStep_invalid(self):
        d = self.db.steps.getStep(buildid=30)
        self.assertFailure(d, RuntimeError)

    @defer.inlineCallbacks
    def test_getSteps(self):
        yield self.insertTestData(self.backgroundData + self.stepRows)
        stepdicts = yield self.db.steps.getSteps(buildid=30)
        [validation.verifyDbDict(self, 'stepdict', stepdict)
         for stepdict in stepdicts]
        self.assertEqual(stepdicts, self.stepDicts[:3])

    @defer.inlineCallbacks
    def test_getSteps_none(self):
        yield self.insertTestData(self.backgroundData + self.stepRows)
        stepdicts = yield self.db.steps.getSteps(buildid=33)
        self.assertEqual(stepdicts, [])

    @defer.inlineCallbacks
    def test_addStep_getStep(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData)
        stepid, number, name = yield self.db.steps.addStep(buildid=30,
                                                           name=u'new', state_string=u'new')
        yield self.db.steps.startStep(stepid=stepid, _reactor=clock)
        self.assertEqual((number, name), (0, 'new'))
        stepdict = yield self.db.steps.getStep(stepid=stepid)
        validation.verifyDbDict(self, 'stepdict', stepdict)
        self.assertEqual(stepdict, {
            'id': stepid,
            'buildid': 30,
            'name': u'new',
            'number': 0,
            'started_at': epoch2datetime(TIME1),
            'complete_at': None,
            'results': None,
            'state_string': u'new',
            'urls': [],
            'hidden': False})

    @defer.inlineCallbacks
    def test_addStep_getStep_existing_step(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData + [self.stepRows[0]])
        stepid, number, name = yield self.db.steps.addStep(
            buildid=30, name=u'new', state_string=u'new')
        yield self.db.steps.startStep(stepid=stepid, _reactor=clock)
        self.assertEqual((number, name), (1, 'new'))
        stepdict = yield self.db.steps.getStep(stepid=stepid)
        validation.verifyDbDict(self, 'stepdict', stepdict)
        self.assertEqual(stepdict['number'], number)
        self.assertEqual(stepdict['name'], name)

    @defer.inlineCallbacks
    def test_addStep_getStep_name_collisions(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData + [
            fakedb.Step(id=73, number=0, name=u'new', buildid=30),
            fakedb.Step(id=74, number=1, name=u'new_1', buildid=30),
            fakedb.Step(id=75, number=2, name=u'new_2', buildid=30),
            fakedb.Step(id=76, number=3, name=u'new_step', buildid=30),
        ])
        stepid, number, name = yield self.db.steps.addStep(
            buildid=30, name=u'new', state_string=u'new')
        yield self.db.steps.startStep(stepid=stepid, _reactor=clock)
        self.assertEqual((number, name), (4, u'new_3'))
        stepdict = yield self.db.steps.getStep(stepid=stepid)
        validation.verifyDbDict(self, 'stepdict', stepdict)
        self.assertEqual(stepdict['number'], number)
        self.assertEqual(stepdict['name'], name)

    @defer.inlineCallbacks
    def test_setStepStateString(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        yield self.db.steps.setStepStateString(stepid=72,
                                               state_string=u'aaa')
        stepdict = yield self.db.steps.getStep(stepid=72)
        self.assertEqual(stepdict['state_string'], u'aaa')

    @defer.inlineCallbacks
    def test_addURL(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        yield self.db.steps.addURL(stepid=72, name=u'foo', url=u'bar')

        stepdict = yield self.db.steps.getStep(stepid=72)
        self.assertEqual(stepdict['urls'], [{'name': u'foo', 'url': u'bar'}])

    @defer.inlineCallbacks
    def test_addURL_race(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        yield defer.gatherResults([
            # only a tiny sleep is required to see the problem.
            self.db.steps.addURL(stepid=72, name=u'foo', url=u'bar',
                                 _racehook=lambda: time.sleep(.01)),
            self.db.steps.addURL(stepid=72, name=u'foo2', url=u'bar2')])

        stepdict = yield self.db.steps.getStep(stepid=72)

        def urlKey(url):
            return url['name']

        # order is not guaranteed though
        self.assertEqual(sorted(stepdict['urls'], key=urlKey),
                         sorted([{'name': u'foo', 'url': u'bar'},
                                 {'name': u'foo2', 'url': u'bar2'}],
                                key=urlKey))

    @defer.inlineCallbacks
    def test_finishStep(self):
        clock = task.Clock()
        clock.advance(TIME2)
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        yield self.db.steps.finishStep(stepid=72, results=11, hidden=False,
                                       _reactor=clock)
        stepdict = yield self.db.steps.getStep(stepid=72)
        self.assertEqual(stepdict['results'], 11)
        self.assertEqual(stepdict['complete_at'], epoch2datetime(TIME2))
        self.assertEqual(stepdict['hidden'], False)

    @defer.inlineCallbacks
    def test_finishStep_hidden(self):
        yield self.insertTestData(self.backgroundData + [self.stepRows[2]])
        yield self.db.steps.finishStep(stepid=72, results=11, hidden=True)
        stepdict = yield self.db.steps.getStep(stepid=72)
        self.assertEqual(stepdict['hidden'], True)
    def run_fake_build(self, notifier, info=None):
        notifier.master = fakemaster.make_master()
        notifier.master_status = notifier.master.status

        builders = []
        builds = []

        for i in [0, 1, 2]:
            builder = Mock()
            build = FakeBuildStatus()

            builder.getBuild.return_value = build
            builder.name = "Builder%d" % i

            build.results = SUCCESS
            build.finished = True
            build.reason = "testReason"
            build.getBuilder.return_value = builder

            builders.append(builder)
            builds.append(build)

        def fakeGetBuilder(buildername):
            return {
                "Builder0": builders[0],
                "Builder1": builders[1],
                "Builder2": builders[2]
            }[buildername]

        notifier.master_status.getBuilder = fakeGetBuilder
        notifier.master.db = fakedb.FakeDBConnector(notifier.master, self)

        notifier.master.db.insertTestData([
            fakedb.Master(id=92),
            fakedb.Buildslave(id=13, name='sl'),
            fakedb.Buildset(id=99, results=SUCCESS, reason="testReason"),
            fakedb.Builder(id=80, name='Builder0'),
            fakedb.Builder(id=81, name='Builder1'),
            fakedb.Builder(id=82, name='Builder2'),
            fakedb.BuildRequest(id=10, buildsetid=99, builderid=80),
            fakedb.Build(number=0,
                         buildrequestid=10,
                         masterid=92,
                         buildslaveid=13),
            fakedb.BuildRequest(id=11, buildsetid=99, builderid=81),
            fakedb.Build(number=0,
                         buildrequestid=11,
                         masterid=92,
                         buildslaveid=13),
            fakedb.BuildRequest(id=12, buildsetid=99, builderid=82),
            fakedb.Build(number=0,
                         buildrequestid=12,
                         masterid=92,
                         buildslaveid=13)
        ])

        if info is not None:
            info['bsid'] = 99
            info['builds'] = builds

        d = notifier._buildsetComplete('buildset.99.complete', {
            'bsid': 99,
            'result': SUCCESS
        })
        return d
Beispiel #9
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    backgroundData = [
        fakedb.Buildset(id=20),
        fakedb.Builder(id=77, name="b1"),
        fakedb.Builder(id=88, name="b2"),
        fakedb.BuildRequest(id=40, buildsetid=20, builderid=77),
        fakedb.BuildRequest(id=41, buildsetid=20, builderid=77),
        fakedb.BuildRequest(id=42, buildsetid=20, builderid=88),
        fakedb.Master(id=88),
        fakedb.Master(id=89, name="bar"),
        fakedb.Buildslave(id=13, name='sl'),
    ]
    threeBuilds = [
        fakedb.Build(id=50,
                     buildrequestid=42,
                     number=5,
                     masterid=88,
                     builderid=77,
                     buildslaveid=13,
                     state_strings_json='["test"]',
                     started_at=TIME1),
        fakedb.Build(id=51,
                     buildrequestid=41,
                     number=6,
                     masterid=88,
                     builderid=88,
                     buildslaveid=13,
                     state_strings_json='["test"]',
                     started_at=TIME2),
        fakedb.Build(id=52,
                     buildrequestid=42,
                     number=7,
                     masterid=88,
                     builderid=77,
                     buildslaveid=13,
                     state_strings_json='["test"]',
                     started_at=TIME3,
                     complete_at=TIME4,
                     results=5),
    ]

    threeBdicts = {
        50: {
            'id': 50,
            'buildrequestid': 42,
            'builderid': 77,
            'masterid': 88,
            'number': 5,
            'buildslaveid': 13,
            'started_at': epoch2datetime(TIME1),
            'complete_at': None,
            'state_strings': [u'test'],
            'results': None
        },
        51: {
            'id': 51,
            'buildrequestid': 41,
            'builderid': 88,
            'masterid': 88,
            'number': 6,
            'buildslaveid': 13,
            'started_at': epoch2datetime(TIME2),
            'complete_at': None,
            'state_strings': [u'test'],
            'results': None
        },
        52: {
            'id': 52,
            'buildrequestid': 42,
            'builderid': 77,
            'masterid': 88,
            'number': 7,
            'buildslaveid': 13,
            'started_at': epoch2datetime(TIME3),
            'complete_at': epoch2datetime(TIME4),
            'state_strings': [u'test'],
            'results': 5
        },
    }

    # signature tests

    def test_signature_getBuild(self):
        @self.assertArgSpecMatches(self.db.builds.getBuild)
        def getBuild(self, buildid):
            pass

    def test_signature_getBuildByNumber(self):
        @self.assertArgSpecMatches(self.db.builds.getBuildByNumber)
        def getBuild(self, builderid, number):
            pass

    def test_signature_getBuilds(self):
        @self.assertArgSpecMatches(self.db.builds.getBuilds)
        def getBuilds(self, builderid=None, buildrequestid=None):
            pass

    def test_signature_addBuild(self):
        @self.assertArgSpecMatches(self.db.builds.addBuild)
        def addBuild(self, builderid, buildrequestid, buildslaveid, masterid,
                     state_strings):
            pass

    def test_signature_setBuildStateStrings(self):
        @self.assertArgSpecMatches(self.db.builds.setBuildStateStrings)
        def setBuildStateStrings(self, buildid, state_strings):
            pass

    def test_signature_finishBuild(self):
        @self.assertArgSpecMatches(self.db.builds.finishBuild)
        def finishBuild(self, buildid, results):
            pass

    def test_signature_finishBuildsFromMaster(self):
        @self.assertArgSpecMatches(self.db.builds.finishBuildsFromMaster)
        def finishBuildsFromMaster(self, masterid, results):
            pass

    # method tests

    @defer.inlineCallbacks
    def test_getBuild(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 buildslaveid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=None,
                 state_strings=[u'test'],
                 results=None))

    @defer.inlineCallbacks
    def test_getBuild_missing(self):
        bdict = yield self.db.builds.getBuild(50)
        self.assertEqual(bdict, None)

    @defer.inlineCallbacks
    def test_getBuildByNumber(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        bdict = yield self.db.builds.getBuildByNumber(builderid=77, number=5)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(bdict['id'], 50)

    @defer.inlineCallbacks
    def test_getBuilds(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds()
        for bdict in bdicts:
            validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(
            sorted(bdicts, key=lambda bd: bd['id']),
            [self.threeBdicts[50], self.threeBdicts[51], self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_getBuilds_builderid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(builderid=88)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[51]])

    @defer.inlineCallbacks
    def test_getBuilds_buildrequestid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(buildrequestid=42)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[50], self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_addBuild_first(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData)
        id, number = yield self.db.builds.addBuild(
            builderid=77,
            buildrequestid=41,
            buildslaveid=13,
            masterid=88,
            state_strings=[u'test', u'test2'],
            _reactor=clock)
        bdict = yield self.db.builds.getBuild(id)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(
            bdict, {
                'buildrequestid': 41,
                'builderid': 77,
                'id': id,
                'masterid': 88,
                'number': number,
                'buildslaveid': 13,
                'started_at': epoch2datetime(TIME1),
                'complete_at': None,
                'state_strings': [u'test', u'test2'],
                'results': None
            })

    @defer.inlineCallbacks
    def test_addBuild_existing(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData + [
            fakedb.Build(number=10,
                         buildrequestid=41,
                         builderid=77,
                         masterid=88,
                         buildslaveid=13),
        ])
        id, number = yield self.db.builds.addBuild(
            builderid=77,
            buildrequestid=41,
            buildslaveid=13,
            masterid=88,
            state_strings=[u'test', u'test2'],
            _reactor=clock)
        bdict = yield self.db.builds.getBuild(id)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(number, 11)
        self.assertEqual(
            bdict, {
                'buildrequestid': 41,
                'builderid': 77,
                'id': id,
                'masterid': 88,
                'number': number,
                'buildslaveid': 13,
                'started_at': epoch2datetime(TIME1),
                'complete_at': None,
                'state_strings': [u'test', u'test2'],
                'results': None
            })

    @defer.inlineCallbacks
    def test_setBuildStateStrings(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        yield self.db.builds.setBuildStateStrings(
            buildid=50, state_strings=[u'test', u'test2', u'test3'])
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 buildslaveid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=None,
                 state_strings=[u'test', u'test2', u'test3'],
                 results=None))

    @defer.inlineCallbacks
    def test_finishBuild(self):
        clock = task.Clock()
        clock.advance(TIME4)
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        yield self.db.builds.finishBuild(buildid=50, results=7, _reactor=clock)
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 buildslaveid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=epoch2datetime(TIME4),
                 state_strings=[u'test'],
                 results=7))

    @defer.inlineCallbacks
    def test_finishBuildsFromMaster(self):
        clock = task.Clock()
        clock.advance(TIME4)
        yield self.insertTestData(self.backgroundData + self.threeBuilds + [
            fakedb.Build(id=54,
                         buildrequestid=40,
                         number=50,
                         masterid=89,
                         builderid=77,
                         buildslaveid=13,
                         state_strings_json='["test"]',
                         started_at=TIME1)
        ])
        yield self.db.builds.finishBuildsFromMaster(masterid=88,
                                                    results=7,
                                                    _reactor=clock)
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'builddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 buildslaveid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=epoch2datetime(TIME4),
                 state_strings=[u'test'],
                 results=7))
        for _id, results in [(50, 7), (51, 7), (52, 5), (54, None)]:
            bdict = yield self.db.builds.getBuild(_id)
            validation.verifyDbDict(self, 'builddict', bdict)
            self.assertEqual(bdict['results'], results)
Beispiel #10
0
    def setupDb(self):
        self.db = self.master.db
        self.db.insertTestData([
            fakedb.Master(id=92),
            fakedb.Worker(id=13, name='sl'),
            fakedb.Buildset(id=98, results=SUCCESS, reason="testReason1"),
            fakedb.Builder(id=80, name='Builder1'),
            fakedb.BuildRequest(id=9, buildsetid=97, builderid=80),
            fakedb.BuildRequest(id=10, buildsetid=97, builderid=80),
            fakedb.BuildRequest(id=11, buildsetid=98, builderid=80),
            fakedb.BuildRequest(id=12, buildsetid=98, builderid=80),
            fakedb.Build(id=18,
                         number=0,
                         builderid=80,
                         buildrequestid=9,
                         workerid=13,
                         masterid=92,
                         results=FAILURE),
            fakedb.Build(id=19,
                         number=1,
                         builderid=80,
                         buildrequestid=10,
                         workerid=13,
                         masterid=92,
                         results=RETRY),
            fakedb.Build(id=20,
                         number=2,
                         builderid=80,
                         buildrequestid=11,
                         workerid=13,
                         masterid=92,
                         results=SUCCESS),
            fakedb.Build(id=21,
                         number=3,
                         builderid=80,
                         buildrequestid=12,
                         workerid=13,
                         masterid=92,
                         results=SUCCESS),
            fakedb.BuildsetSourceStamp(buildsetid=98, sourcestampid=234),
            fakedb.SourceStamp(id=234),
            fakedb.Change(changeid=13,
                          branch=u'trunk',
                          revision=u'9283',
                          author='me@foo',
                          repository=u'svn://...',
                          codebase=u'cbsvn',
                          project=u'world-domination',
                          sourcestampid=234),
            fakedb.Patch(id=99,
                         patch_base64='aGVsbG8sIHdvcmxk',
                         patch_author='him@foo',
                         patch_comment='foo',
                         subdir='/foo',
                         patchlevel=3),
            fakedb.SourceStamp(id=235, patchid=99),
        ])
        for _id in (20, 21):
            self.db.insertTestData([
                fakedb.BuildProperty(buildid=_id,
                                     name="workername",
                                     value="sl"),
                fakedb.BuildProperty(buildid=_id,
                                     name="reason",
                                     value="because"),
                fakedb.BuildProperty(buildid=_id, name="owner", value="him"),
                fakedb.Step(id=100 + _id, buildid=_id, name="step1"),
                fakedb.Step(id=200 + _id, buildid=_id, name="step2"),
                fakedb.Log(id=60 + _id,
                           stepid=100 + _id,
                           name='stdio',
                           slug='stdio',
                           type='s',
                           num_lines=2),
                fakedb.LogChunk(logid=60 + _id,
                                first_line=0,
                                last_line=1,
                                compressed=0,
                                content=self.LOGCONTENT),
            ])

        @defer.inlineCallbacks
        def getChangesForBuild(buildid):
            assert buildid == 20
            ch = yield self.master.db.changes.getChange(13)
            defer.returnValue([ch])

        self.master.db.changes.getChangesForBuild = getChangesForBuild
Beispiel #11
0
    def setupStep(self,
                  step,
                  sourcestampsInBuild=None,
                  gotRevisionsInBuild=None,
                  *args,
                  **kwargs):
        sourcestamps = sourcestampsInBuild or []
        got_revisions = gotRevisionsInBuild or {}

        super().setupStep(step, *args, **kwargs)

        # This step reaches deeply into a number of parts of Buildbot.  That
        # should be fixed!

        # set up a buildmaster that knows about two fake schedulers, a and b
        m = self.master
        m.db.checkForeignKeys = True
        self.build.builder.botmaster = m.botmaster
        self.build.conn = object()
        m.status = master.Status()
        m.status.setServiceParent(m)
        m.config.buildbotURL = "baseurl/"
        m.scheduler_manager = FakeSchedulerManager()

        self.scheduler_a = a = FakeTriggerable(name='a')
        self.scheduler_b = b = FakeTriggerable(name='b')
        self.scheduler_c = c = FakeTriggerable(name='c')
        m.scheduler_manager.namedServices = dict(a=a, b=b, c=c)

        a.brids = {77: 11}
        b.brids = {78: 22}
        c.brids = {79: 33, 80: 44}

        def make_fake_br(brid, builderid):
            return fakedb.BuildRequest(id=brid,
                                       buildsetid=BRID_TO_BSID(brid),
                                       builderid=builderid)

        def make_fake_build(brid, builderid):
            return fakedb.Build(buildrequestid=brid,
                                id=BRID_TO_BID(brid),
                                number=BRID_TO_BUILD_NUMBER(brid),
                                masterid=9,
                                workerid=13,
                                builderid=builderid)

        m.db.insertTestData([
            fakedb.Builder(id=77, name='A'),
            fakedb.Builder(id=78, name='B'),
            fakedb.Builder(id=79, name='C1'),
            fakedb.Builder(id=80, name='C2'),
            fakedb.Master(id=9),
            fakedb.Buildset(id=2022),
            fakedb.Buildset(id=2011),
            fakedb.Buildset(id=2033),
            fakedb.Worker(id=13, name="some:worker"),
            make_fake_br(11, 77),
            make_fake_br(22, 78),
            fakedb.BuildRequest(id=33, buildsetid=2033, builderid=79),
            fakedb.BuildRequest(id=44, buildsetid=2033, builderid=80),
            make_fake_build(11, builderid=77),
            make_fake_build(22, builderid=78),
            make_fake_build(33, builderid=79),
            # builderid is 79 on purpose, changed, from the one of the buildrequest
            # to test the case of the virtual
            make_fake_build(44, builderid=79),
        ])

        def getAllSourceStamps():
            return sourcestamps

        self.build.getAllSourceStamps = getAllSourceStamps

        def getAllGotRevisions():
            return got_revisions

        self.step.getAllGotRevisions = getAllGotRevisions

        self.exp_add_sourcestamp = None
        self.exp_a_trigger = None
        self.exp_b_trigger = None
        self.exp_c_trigger = None
        self.exp_added_urls = []
 def setUp(self):
     self.setUpEndpoint()
     self.db.insertTestData([
         fakedb.Builder(id=77),
         fakedb.Worker(id=13, name='sl'),
         fakedb.Master(id=88),
         fakedb.Buildset(id=8822),
         fakedb.BuildRequest(id=82, buildsetid=8822),
         fakedb.Build(id=13,
                      builderid=77,
                      masterid=88,
                      workerid=13,
                      buildrequestid=82,
                      number=3),
         fakedb.Step(id=50, buildid=13, number=9, name='make'),
         fakedb.Log(id=60,
                    stepid=50,
                    name='stdio',
                    slug='stdio',
                    type='s',
                    num_lines=7),
         fakedb.LogChunk(logid=60,
                         first_line=0,
                         last_line=1,
                         compressed=0,
                         content=textwrap.dedent("""\
                     line zero
                     line 1""")),
         fakedb.LogChunk(logid=60,
                         first_line=2,
                         last_line=4,
                         compressed=0,
                         content=textwrap.dedent("""\
                     line TWO
                     line 3
                     line 2**2""")),
         fakedb.LogChunk(logid=60,
                         first_line=5,
                         last_line=5,
                         compressed=0,
                         content="another line"),
         fakedb.LogChunk(logid=60,
                         first_line=6,
                         last_line=6,
                         compressed=0,
                         content="yet another line"),
         fakedb.Log(id=61,
                    stepid=50,
                    name='errors',
                    slug='errors',
                    type='t',
                    num_lines=100),
     ] + [
         fakedb.LogChunk(logid=61,
                         first_line=i,
                         last_line=i,
                         compressed=0,
                         content="%08d" % i) for i in range(100)
     ] + [
         fakedb.Log(id=62,
                    stepid=50,
                    name='notes',
                    slug='notes',
                    type='t',
                    num_lines=0),
         # logid 62 is empty
     ])
Beispiel #13
0
    def run_fake_summary_build(self, gsp, buildResults, finalResult,
                               resultText, expWarning=False):
        buildpairs = []
        i = 0
        for i in xrange(len(buildResults)):
            buildResult = buildResults[i]

            builder = Mock()
            build = FakeBuildStatus()

            builder.getBuild.return_value = build
            builder.name = "Builder-%d" % i
            builder.getName.return_value = builder.name
            builder._builderid = i
            build.results = buildResult
            build.finished = True
            build.reason = "testReason"
            build.getBuilder.return_value = builder
            build.getResults.return_value = build.results
            build.getText.return_value = ['buildText']
            build.getProperty = self.TEST_PROPS.get

            buildpairs.append((builder, build))

        def fakeGetBuilder(buildername):
            # e.g. Builder-5 will be buildpairs[5][0]
            return buildpairs[int(buildername.split("-")[1])][0]

        gsp.master_status.getBuilder = fakeGetBuilder
        gsp.master_status.getURLForThing = Mock()
        gsp.master_status.getURLForThing.return_value = self.THING_URL

        gsp.master.db = fakedb.FakeDBConnector(gsp.master, self)

        fakedata = [
            fakedb.Master(id=92),
            fakedb.Buildslave(id=13, name='sl'),
            fakedb.Buildset(id=99, results=finalResult, reason="testReason"),
        ]

        breqid = 1000
        for (builder, build) in buildpairs:
            fakedata.append(fakedb.Builder(id=builder._builderid, name=builder.name))
            fakedata.append(fakedb.BuildRequest(id=breqid, buildsetid=99,
                                                builderid=builder._builderid))
            fakedata.append(fakedb.Build(number=0, buildrequestid=breqid,
                                         masterid=92, buildslaveid=13))
            breqid = breqid + 1

        gsp.master.db.insertTestData(fakedata)

        d = gsp._buildsetComplete('buildset.99.complete',
                                  dict(bsid=99, result=SUCCESS))

        @d.addCallback
        def check(_):
            info = []
            for i in xrange(len(buildResults)):
                info.append({'name': "Builder-%d" % i, 'result': buildResults[i],
                             'resultText': resultText[i], 'text': 'buildText',
                             'url': self.THING_URL})
            if expWarning:
                self.assertEqual([w['message'] for w in self.flushWarnings()],
                                 ['The Gerrit status callback uses the old '
                                  'way to communicate results.  The outcome '
                                  'might be not what is expected.'])
            return str(info)
        return d
Beispiel #14
0
class TestBuildRequestCollapser(unittest.TestCase):

    @defer.inlineCallbacks
    def setUp(self):
        self.master = fakemaster.make_master(testcase=self,
                                             wantData=True,
                                             wantDb=True)
        self.master.botmaster = mock.Mock(name='botmaster')
        self.master.botmaster.builders = {}
        self.builders = {}
        self.bldr = yield self.createBuilder('A', builderid=77)

    @defer.inlineCallbacks
    def createBuilder(self, name, builderid=None):
        if builderid is None:
            b = fakedb.Builder(name=name)
            yield self.master.db.insertTestData([b])
            builderid = b.id

        bldr = mock.Mock(name=name)
        bldr.name = name
        bldr.master = self.master
        self.master.botmaster.builders[name] = bldr
        self.builders[name] = bldr
        bldr.getCollapseRequestsFn = lambda: False

        defer.returnValue(bldr)

    def tearDown(self):
        pass

    @defer.inlineCallbacks
    def do_request_collapse(self, rows, brids, exp):
        yield self.master.db.insertTestData(rows)
        brCollapser = buildrequest.BuildRequestCollapser(self.master, brids)
        self.assertEqual(exp, (yield brCollapser.collapse()))

    def test_collapseRequests_no_other_request(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            # Allow all requests
            self.fail("Should never be called")
            return True

        self.bldr.getCollapseRequestsFn = lambda: collapseRequests_fn
        rows = [
            fakedb.Builder(id=77, name='A'),
            fakedb.SourceStamp(id=234, codebase='A'),
            fakedb.Change(changeid=14, codebase='A', sourcestampid=234),
            fakedb.Buildset(id=30, reason='foo',
                            submitted_at=1300305712, results=-1),
            fakedb.BuildsetSourceStamp(sourcestampid=234, buildsetid=30),
            fakedb.BuildRequest(id=19, buildsetid=30, builderid=77,
                                priority=13, submitted_at=1300305712, results=-1),
        ]
        return self.do_request_collapse(rows, [19], [])

    BASE_ROWS = [
        fakedb.Builder(id=77, name='A'),
        fakedb.SourceStamp(id=234, codebase='C'),
        fakedb.Buildset(id=30, reason='foo',
                        submitted_at=1300305712, results=-1),
        fakedb.BuildsetSourceStamp(sourcestampid=234, buildsetid=30),
        fakedb.SourceStamp(id=235, codebase='C'),
        fakedb.Buildset(id=31, reason='foo',
                        submitted_at=1300305712, results=-1),
        fakedb.BuildsetSourceStamp(sourcestampid=235, buildsetid=31),
        fakedb.SourceStamp(id=236, codebase='C'),
        fakedb.Buildset(id=32, reason='foo',
                        submitted_at=1300305712, results=-1),
        fakedb.BuildsetSourceStamp(sourcestampid=236, buildsetid=32),
        fakedb.BuildRequest(id=19, buildsetid=30, builderid=77,
                            priority=13, submitted_at=1300305712, results=-1),
        fakedb.BuildRequest(id=20, buildsetid=31, builderid=77,
                            priority=13, submitted_at=1300305712, results=-1),
        fakedb.BuildRequest(id=21, buildsetid=32, builderid=77,
                            priority=13, submitted_at=1300305712, results=-1),
    ]

    def test_collapseRequests_no_collapse(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            # Fail all collapse attempts
            return False

        self.bldr.getCollapseRequestsFn = lambda: collapseRequests_fn
        return self.do_request_collapse(self.BASE_ROWS, [21], [])

    def test_collapseRequests_collapse_all(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            # collapse all attempts
            return True

        self.bldr.getCollapseRequestsFn = lambda: collapseRequests_fn
        return self.do_request_collapse(self.BASE_ROWS, [21], [19, 20])

    def test_collapseRequests_collapse_all_duplicates(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            # collapse all attempts
            return True

        self.bldr.getCollapseRequestsFn = lambda: collapseRequests_fn
        return self.do_request_collapse(self.BASE_ROWS, [21, 21], [19, 20])

    # As documented:
    # Sourcestamps are compatible if all of the below conditions are met:
    #
    # * Their codebase, branch, project, and repository attributes match exactly
    # * Neither source stamp has a patch (e.g., from a try scheduler)
    # * Either both source stamps are associated with changes, or neither are associated with changes but they have matching revisions.

    def makeBuildRequestRows(self, brid, bsid, changeid, ssid, codebase, branch=None,
                             project=None, repository=None, patchid=None, revision=None):
        rows = [
            fakedb.SourceStamp(id=ssid, codebase=codebase, branch=branch,
                               project=project, repository=repository, patchid=patchid, revision=revision),
            fakedb.Buildset(id=bsid, reason='foo',
                            submitted_at=1300305712, results=-1),
            fakedb.BuildsetSourceStamp(sourcestampid=ssid, buildsetid=bsid),
            fakedb.BuildRequest(id=brid, buildsetid=bsid, builderid=77,
                            priority=13, submitted_at=1300305712, results=-1),
            ]
        if changeid:
            rows.append(
                fakedb.Change(changeid=changeid, branch='trunk', revision='9283',
                              repository='svn://...', project='world-domination',
                              sourcestampid=ssid)
                              )
        if patchid:
            rows.append(
                fakedb.Patch(id=patchid, patch_base64=u'aGVsbG8sIHdvcmxk',
                 patch_author='bar', patch_comment='foo', subdir='/foo',
                 patchlevel=3))

        return rows

    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_codebases(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A')
        rows += self.makeBuildRequestRows(21, 121, None, 221, 'C')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C')
        rows += self.makeBuildRequestRows(20, 120, None, 220, 'C')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [19, 20])

    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_codebases_branches(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A', 'br1')
        rows += self.makeBuildRequestRows(21, 121, None, 221, 'C', 'br2')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C', 'br2')
        rows += self.makeBuildRequestRows(20, 120, None, 220, 'C', 'br3')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [19])

    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_codebases_repository(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A', None, 'p1')
        rows += self.makeBuildRequestRows(21, 121, None, 221, 'C', None, 'p2')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C', None, 'p2')
        rows += self.makeBuildRequestRows(20, 120, None, 220, 'C', None, 'p3')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [19])

    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_codebases_projects(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A', None, None, 'project1')
        rows += self.makeBuildRequestRows(21, 121, None, 221, 'C', None, None, 'project2')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C', None, None, 'project2')
        rows += self.makeBuildRequestRows(20, 120, None, 220, 'C', None, None, 'project3')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [19])

    # * Neither source stamp has a patch (e.g., from a try scheduler)
    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_a_patch(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A')
        rows += self.makeBuildRequestRows(21, 121, None, 221, 'C')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C', patchid=123)
        rows += self.makeBuildRequestRows(20, 120, None, 220, 'C')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [20])

    # * Either both source stamps are associated with changes..
    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_changes(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A')
        rows += self.makeBuildRequestRows(21, 121, 123, 221, 'C')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C')
        rows += self.makeBuildRequestRows(20, 120, 124, 220, 'C')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [20])

    # * ... or neither are associated with changes but they have matching revisions.
    @defer.inlineCallbacks
    def test_collapseRequests_collapse_default_with_non_matching_revision(self):

        def collapseRequests_fn(master, builder, brdict1, brdict2):
            return buildrequest.BuildRequest.canBeCollapsed(builder.master, brdict1, brdict2)

        rows = [
            fakedb.Builder(id=77, name='A'),
        ]
        rows += self.makeBuildRequestRows(22, 122, None, 222, 'A')
        rows += self.makeBuildRequestRows(21, 121, None, 221, 'C')
        rows += self.makeBuildRequestRows(19, 119, None, 210, 'C', revision='abcd1234')
        rows += self.makeBuildRequestRows(20, 120, None, 220, 'C')
        self.bldr.getCollapseRequestsFn = lambda: Builder._defaultCollapseRequestFn
        yield self.do_request_collapse(rows, [22], [])
        yield self.do_request_collapse(rows, [21], [20])
Beispiel #15
0
    def insertTestData(self, buildResults, finalResult, insertSS=True):
        self.db = self.master.db
        self.db.insertTestData([
            fakedb.Master(id=92),
            fakedb.Worker(id=13, name='wrk'),
            fakedb.Builder(id=79, name='Builder0'),
            fakedb.Builder(id=80, name='Builder1'),
            fakedb.Buildset(id=98, results=finalResult, reason="testReason1"),
            fakedb.Change(changeid=13,
                          branch=u'master',
                          revision=u'9283',
                          author='me@foo',
                          repository=self.TEST_REPO,
                          codebase=u'cbgerrit',
                          project=u'world-domination',
                          sourcestampid=234),
        ])

        if insertSS:
            self.db.insertTestData([
                fakedb.BuildsetSourceStamp(buildsetid=98, sourcestampid=234),
                fakedb.SourceStamp(id=234,
                                   project=self.TEST_PROJECT,
                                   revision=self.TEST_REVISION,
                                   repository=self.TEST_REPO)
            ])

        for i, results in enumerate(buildResults):
            self.db.insertTestData([
                fakedb.BuildRequest(id=11 + i, buildsetid=98,
                                    builderid=79 + i),
                fakedb.Build(id=20 + i,
                             number=i,
                             builderid=79 + i,
                             buildrequestid=11 + i,
                             workerid=13,
                             masterid=92,
                             results=results,
                             state_string=u"buildText"),
                fakedb.Step(id=50 + i, buildid=20 + i, number=5, name='make'),
                fakedb.Log(id=60 + i,
                           stepid=50 + i,
                           name='stdio',
                           slug='stdio',
                           type='s',
                           num_lines=7),
                fakedb.LogChunk(
                    logid=60 + i,
                    first_line=0,
                    last_line=1,
                    compressed=0,
                    content=u'Unicode log with non-ascii (\u00E5\u00E4\u00F6).'
                ),
                fakedb.BuildProperty(buildid=20 + i,
                                     name="workername",
                                     value="wrk"),
                fakedb.BuildProperty(buildid=20 + i,
                                     name="reason",
                                     value="because"),
                fakedb.BuildProperty(buildid=20 + i,
                                     name="buildername",
                                     value="Builder0"),
            ])
            for k, v in iteritems(self.TEST_PROPS):
                self.db.insertTestData(
                    [fakedb.BuildProperty(buildid=20 + i, name=k, value=v)])
Beispiel #16
0
    def test_masterDeactivated(self):
        self.master.db.insertTestData([
            fakedb.Master(id=14, name='other', active=0, last_active=0),

            # set up a running build with some steps
            fakedb.Builder(id=77, name='b1'),
            fakedb.Worker(id=13, name='sl'),
            fakedb.Buildset(id=8822),
            fakedb.BuildRequest(id=82, builderid=77, buildsetid=8822),
            fakedb.BuildRequestClaim(brid=82, masterid=14,
                                     claimed_at=SOMETIME),
            fakedb.Build(id=13,
                         builderid=77,
                         masterid=14,
                         workerid=13,
                         buildrequestid=82,
                         number=3,
                         results=None),
            fakedb.Step(id=200, buildid=13),
            fakedb.Log(id=2000, stepid=200, num_lines=2),
            fakedb.LogChunk(logid=2000,
                            first_line=1,
                            last_line=2,
                            content=u'ab\ncd')
        ])

        # mock out the _masterDeactivated methods this will call
        for rtype in 'builder', 'scheduler', 'changesource':
            rtype_obj = getattr(self.master.data.rtypes, rtype)
            m = mock.Mock(name='%s._masterDeactivated' % rtype,
                          spec=rtype_obj._masterDeactivated)
            m.side_effect = lambda masterid: defer.succeed(None)
            rtype_obj._masterDeactivated = m

        # and the update methods..
        for meth in 'finishBuild', 'finishStep', 'finishLog':
            m = mock.create_autospec(getattr(self.master.data.updates, meth))
            m.side_effect = lambda *args, **kwargs: defer.succeed(None)
            setattr(self.master.data.updates, meth, m)

        yield self.rtype._masterDeactivated(14, 'other')

        self.master.data.rtypes.builder._masterDeactivated. \
            assert_called_with(masterid=14)
        self.master.data.rtypes.scheduler._masterDeactivated. \
            assert_called_with(masterid=14)
        self.master.data.rtypes.changesource._masterDeactivated. \
            assert_called_with(masterid=14)

        # see that we finished off that build and its steps and logs
        updates = self.master.data.updates
        updates.finishLog.assert_called_with(logid=2000)
        updates.finishStep.assert_called_with(stepid=200,
                                              results=RETRY,
                                              hidden=False)
        updates.finishBuild.assert_called_with(buildid=13, results=RETRY)

        self.assertEqual(self.master.mq.productions, [
            (('masters', '14', 'stopped'),
             dict(masterid=14, name='other', active=False)),
        ])
Beispiel #17
0
    def setUp(self):
        self.setUpTestReactor()
        authzcfg = authz.Authz(
            # simple matcher with '*' glob character
            stringsMatcher=authz.fnmatchStrMatcher,
            # stringsMatcher = authz.Authz.reStrMatcher,  # if you prefer
            # regular expressions
            allowRules=[
                # admins can do anything,
                # defaultDeny=False: if user does not have the admin role, we
                # continue parsing rules
                AnyEndpointMatcher(role="admins", defaultDeny=False),

                # rules for viewing builds, builders, step logs
                # depending on the sourcestamp or buildername
                ViewBuildsEndpointMatcher(branch="secretbranch",
                                          role="agents"),
                ViewBuildsEndpointMatcher(project="secretproject",
                                          role="agents"),
                ViewBuildsEndpointMatcher(branch="*", role="*"),
                ViewBuildsEndpointMatcher(project="*", role="*"),
                StopBuildEndpointMatcher(role="owner"),
                RebuildBuildEndpointMatcher(role="owner"),

                # nine-* groups can do stuff on the nine branch
                BranchEndpointMatcher(branch="nine", role="nine-*"),
                # eight-* groups can do stuff on the eight branch
                BranchEndpointMatcher(branch="eight", role="eight-*"),

                # *-try groups can start "try" builds
                ForceBuildEndpointMatcher(builder="try", role="*-developers"),
                # *-mergers groups can start "merge" builds
                ForceBuildEndpointMatcher(builder="merge", role="*-mergers"),
                # *-releasers groups can start "release" builds
                ForceBuildEndpointMatcher(builder="release",
                                          role="*-releasers"),
            ],
            roleMatchers=[
                RolesFromGroups(groupPrefix="buildbot-"),
                RolesFromEmails(admins=["*****@*****.**"],
                                agents=["*****@*****.**"]),
                RolesFromOwner(role="owner"),
                RolesFromDomain(admins=["mi7.uk"])
            ])
        self.users = dict(homer=dict(email="*****@*****.**"),
                          bond=dict(email="*****@*****.**"),
                          moneypenny=dict(email="*****@*****.**"),
                          nineuser=dict(email="*****@*****.**",
                                        groups=[
                                            "buildbot-nine-mergers",
                                            "buildbot-nine-developers"
                                        ]),
                          eightuser=dict(email="*****@*****.**",
                                         groups=["buildbot-eight-deverlopers"
                                                 ]))
        self.master = self.make_master(url='h:/a/b/', authz=authzcfg)
        self.authz = self.master.authz
        self.master.db.insertTestData([
            fakedb.Builder(id=77, name="mybuilder"),
            fakedb.Master(id=88),
            fakedb.Worker(id=13, name='wrk'),
            fakedb.Buildset(id=8822),
            fakedb.BuildsetProperty(
                buildsetid=8822,
                property_name='owner',
                property_value='["*****@*****.**", "force"]'),
            fakedb.BuildRequest(id=82, buildsetid=8822, builderid=77),
            fakedb.Build(id=13,
                         builderid=77,
                         masterid=88,
                         workerid=13,
                         buildrequestid=82,
                         number=3),
            fakedb.Build(id=14,
                         builderid=77,
                         masterid=88,
                         workerid=13,
                         buildrequestid=82,
                         number=4),
            fakedb.Build(id=15,
                         builderid=77,
                         masterid=88,
                         workerid=13,
                         buildrequestid=82,
                         number=5),
        ])
Beispiel #18
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    backgroundData = [
        fakedb.Buildset(id=20),
        fakedb.Builder(id=77, name="b1"),
        fakedb.Builder(id=88, name="b2"),
        fakedb.BuildRequest(id=40, buildsetid=20, builderid=77),
        fakedb.BuildRequest(id=41, buildsetid=20, builderid=77),
        fakedb.BuildRequest(id=42, buildsetid=20, builderid=88),
        fakedb.Master(id=88),
        fakedb.Master(id=89, name="bar"),
        fakedb.Worker(id=13, name='sl'),
        fakedb.Worker(id=12, name='sl2'),
    ]

    threeBuilds = [
        fakedb.Build(id=50,
                     buildrequestid=42,
                     number=5,
                     masterid=88,
                     builderid=77,
                     workerid=13,
                     state_string="test",
                     started_at=TIME1),
        fakedb.Build(id=51,
                     buildrequestid=41,
                     number=6,
                     masterid=88,
                     builderid=88,
                     workerid=13,
                     state_string="test",
                     started_at=TIME2),
        fakedb.Build(id=52,
                     buildrequestid=42,
                     number=7,
                     masterid=88,
                     builderid=77,
                     workerid=12,
                     state_string="test",
                     started_at=TIME3,
                     complete_at=TIME4,
                     results=5),
    ]

    threeBdicts = {
        50: {
            'id': 50,
            'buildrequestid': 42,
            'builderid': 77,
            'masterid': 88,
            'number': 5,
            'workerid': 13,
            'started_at': epoch2datetime(TIME1),
            'complete_at': None,
            'state_string': 'test',
            'results': None
        },
        51: {
            'id': 51,
            'buildrequestid': 41,
            'builderid': 88,
            'masterid': 88,
            'number': 6,
            'workerid': 13,
            'started_at': epoch2datetime(TIME2),
            'complete_at': None,
            'state_string': 'test',
            'results': None
        },
        52: {
            'id': 52,
            'buildrequestid': 42,
            'builderid': 77,
            'masterid': 88,
            'number': 7,
            'workerid': 12,
            'started_at': epoch2datetime(TIME3),
            'complete_at': epoch2datetime(TIME4),
            'state_string': 'test',
            'results': 5
        },
    }

    # signature tests

    def test_signature_getBuild(self):
        @self.assertArgSpecMatches(self.db.builds.getBuild)
        def getBuild(self, buildid):
            pass

    def test_signature_getBuildByNumber(self):
        @self.assertArgSpecMatches(self.db.builds.getBuildByNumber)
        def getBuild(self, builderid, number):
            pass

    def test_signature_getBuilds(self):
        @self.assertArgSpecMatches(self.db.builds.getBuilds)
        def getBuilds(self,
                      builderid=None,
                      buildrequestid=None,
                      workerid=None,
                      complete=None):
            pass

    def test_signature_addBuild(self):
        @self.assertArgSpecMatches(self.db.builds.addBuild)
        def addBuild(self, builderid, buildrequestid, workerid, masterid,
                     state_string):
            pass

    def test_signature_setBuildStateString(self):
        @self.assertArgSpecMatches(self.db.builds.setBuildStateString)
        def setBuildStateString(self, buildid, state_string):
            pass

    def test_signature_finishBuild(self):
        @self.assertArgSpecMatches(self.db.builds.finishBuild)
        def finishBuild(self, buildid, results):
            pass

    def test_signature_getBuildProperties(self):
        @self.assertArgSpecMatches(self.db.builds.getBuildProperties)
        def getBuildProperties(self, bid):
            pass

    def test_signature_setBuildProperty(self):
        @self.assertArgSpecMatches(self.db.builds.setBuildProperty)
        def setBuildProperty(self, bid, name, value, source):
            pass

    # method tests

    @defer.inlineCallbacks
    def test_getBuild(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 workerid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=None,
                 state_string=u'test',
                 results=None))

    @defer.inlineCallbacks
    def test_getBuild_missing(self):
        bdict = yield self.db.builds.getBuild(50)
        self.assertEqual(bdict, None)

    @defer.inlineCallbacks
    def test_getBuildByNumber(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        bdict = yield self.db.builds.getBuildByNumber(builderid=77, number=5)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(bdict['id'], 50)

    @defer.inlineCallbacks
    def test_getBuilds(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds()
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            sorted(bdicts, key=lambda bd: bd['id']),
            [self.threeBdicts[50], self.threeBdicts[51], self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_getBuilds_builderid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(builderid=88)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[51]])

    @defer.inlineCallbacks
    def test_getBuilds_buildrequestid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(buildrequestid=42)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[50], self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_getBuilds_workerid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(workerid=13)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[50], self.threeBdicts[51]])

    @defer.inlineCallbacks
    def test_getBuilds_complete(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(complete=True)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_addBuild_first(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData)
        id, number = yield self.db.builds.addBuild(builderid=77,
                                                   buildrequestid=41,
                                                   workerid=13,
                                                   masterid=88,
                                                   state_string=u'test test2',
                                                   _reactor=clock)
        bdict = yield self.db.builds.getBuild(id)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict, {
                'buildrequestid': 41,
                'builderid': 77,
                'id': id,
                'masterid': 88,
                'number': number,
                'workerid': 13,
                'started_at': epoch2datetime(TIME1),
                'complete_at': None,
                'state_string': u'test test2',
                'results': None
            })

    @defer.inlineCallbacks
    def test_addBuild_existing(self):
        clock = task.Clock()
        clock.advance(TIME1)
        yield self.insertTestData(self.backgroundData + [
            fakedb.Build(number=10,
                         buildrequestid=41,
                         builderid=77,
                         masterid=88,
                         workerid=13),
        ])
        id, number = yield self.db.builds.addBuild(builderid=77,
                                                   buildrequestid=41,
                                                   workerid=13,
                                                   masterid=88,
                                                   state_string=u'test test2',
                                                   _reactor=clock)
        bdict = yield self.db.builds.getBuild(id)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(number, 11)
        self.assertEqual(
            bdict, {
                'buildrequestid': 41,
                'builderid': 77,
                'id': id,
                'masterid': 88,
                'number': number,
                'workerid': 13,
                'started_at': epoch2datetime(TIME1),
                'complete_at': None,
                'state_string': u'test test2',
                'results': None
            })

    @defer.inlineCallbacks
    def test_setBuildStateString(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        yield self.db.builds.setBuildStateString(buildid=50,
                                                 state_string=u'test test2')
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 workerid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=None,
                 state_string=u'test test2',
                 results=None))

    @defer.inlineCallbacks
    def test_finishBuild(self):
        clock = task.Clock()
        clock.advance(TIME4)
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        yield self.db.builds.finishBuild(buildid=50, results=7, _reactor=clock)
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 workerid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=epoch2datetime(TIME4),
                 state_string=u'test',
                 results=7))

    @defer.inlineCallbacks
    def testgetBuildPropertiesEmpty(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        for buildid in (50, 51, 52):
            props = yield self.db.builds.getBuildProperties(buildid)
            self.assertEquals(0, len(props))

    @defer.inlineCallbacks
    def testsetandgetProperties(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        yield self.db.builds.setBuildProperty(50, 'prop', 42, 'test')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (42, 'test')})

    @defer.inlineCallbacks
    def testsetgetsetProperties(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {})
        yield self.db.builds.setBuildProperty(50, 'prop', 42, 'test')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (42, 'test')})
        # set a new value
        yield self.db.builds.setBuildProperty(50, 'prop', 45, 'test')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (45, 'test')})
        # set a new source
        yield self.db.builds.setBuildProperty(50, 'prop', 45, 'test_source')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (45, 'test_source')})
        # set the same
        yield self.db.builds.setBuildProperty(50, 'prop', 45, 'test_source')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (45, 'test_source')})
Beispiel #19
0
    def test_getChangesForBuild(self):
        rows = [fakedb.Master(id=88, name="bar"),
                fakedb.Worker(id=13, name='one'),
                fakedb.Builder(id=77, name='A')]
        lastID = {"changeid": 0,
                  "sourcestampid": 0,
                  "buildsetid": 0,
                  "buildsetSourceStampid": 0,
                  "buildrequestid": 0,
                  "buildid": 0}

        codebase_ss = {}  # shared state between addChange and addBuild

        def addChange(codebase, revision, author, comments, branch='master', category='cat', project='proj', repository='repo'):
            lastID["sourcestampid"] += 1
            lastID["changeid"] += 1
            parent_changeids = codebase_ss.get(codebase, None)

            codebase_ss[codebase] = lastID["sourcestampid"]

            changeRows = [fakedb.SourceStamp(id=lastID["sourcestampid"],
                                             codebase=codebase,
                                             revision=revision),
                          fakedb.Change(changeid=lastID["changeid"],
                                        author=author,
                                        comments=comments,
                                        revision=revision,
                                        sourcestampid=lastID["sourcestampid"],
                                        parent_changeids=parent_changeids,
                                        when_timestamp=SOMETIME +
                                        lastID["changeid"],
                                        branch=branch,
                                        category=category,
                                        project=project,
                                        repository=repository)]
            return changeRows

        def addBuild(codebase_ss, results=0):

            lastID["buildid"] += 1
            lastID["buildsetid"] += 1
            lastID["buildrequestid"] += 1

            buildRows = [fakedb.Buildset(id=lastID["buildsetid"],
                                         reason='foo',
                                         submitted_at=1300305012, results=-1)]
            for cb, ss in iteritems(codebase_ss):
                lastID["buildsetSourceStampid"] += 1
                buildRows.append(
                    fakedb.BuildsetSourceStamp(id=lastID["buildsetSourceStampid"],
                                               sourcestampid=ss,
                                               buildsetid=lastID["buildsetid"]))
            codebase_ss.clear()
            buildRows.extend([
                fakedb.BuildRequest(id=lastID["buildrequestid"],
                                    buildsetid=lastID["buildsetid"],
                                    builderid=77,
                                    priority=13, submitted_at=1300305712, results=-1),
                fakedb.Build(id=lastID["buildid"],
                             buildrequestid=lastID["buildrequestid"],
                             number=lastID["buildid"],
                             masterid=88,
                             builderid=77,
                             state_string="test",
                             workerid=13,
                             started_at=SOMETIME + lastID["buildid"],
                             complete_at=SOMETIME + 2 * lastID["buildid"],
                             results=results)])
            return buildRows

        # Build1 has 1 change per code base
        rows.extend(addChange('A', 1, 'franck', '1st commit'))
        rows.extend(addChange('B', 1, 'alice', '2nd commit'))
        rows.extend(addChange('C', 1, 'bob', '3rd commit'))
        rows.extend(addBuild(codebase_ss))
        # Build 2 has only one change for codebase A
        rows.extend(addChange('A', 2, 'delanne', '4th commit'))
        rows.extend(addBuild(codebase_ss))
        # Build 3 has only one change for codebase B
        rows.extend(addChange('B', 2, 'bob', '6th commit'))
        rows.extend(addBuild(codebase_ss))
        # Build 4 has no change
        rows.extend(addBuild(codebase_ss))
        # Build 5 has 2 changes for codebase A and 1 change for codebase C
        rows.extend(addChange('A', 3, 'franck', '7th commit'))
        rows.extend(addChange('A', 4, 'alice', '8th commit'))
        rows.extend(addChange('B', 3, 'bob', '9th commit'))
        rows.extend(addBuild(codebase_ss))
        # Build 6 has only one change for codebase C
        rows.extend(addChange('C', 2, 'bob', '10th commit'))
        rows.extend(addBuild(codebase_ss, 2))
        # Build 7 has only one change for codebase C
        rows.extend(addChange('C', 3, 'bob', '11th commit'))
        rows.extend(addBuild(codebase_ss, 2))
        yield self.insertTestData(rows)

        @defer.inlineCallbacks
        def expect(buildid, commits):
            got = yield self.db.changes.getChangesForBuild(buildid)
            got_commits = [c['comments'] for c in got]
            self.assertEqual(sorted(got_commits), sorted(commits))

        yield expect(1, [u'2nd commit', u'3rd commit', u'1st commit'])
        yield expect(2, [u'4th commit'])
        yield expect(3, [u'6th commit'])
        yield expect(4, [])
        yield expect(5, [u'8th commit', u'9th commit', u'7th commit'])
        yield expect(6, [u'10th commit'])
        yield expect(7, [u'11th commit'])
Beispiel #20
0
    def attachScheduler(self,
                        scheduler,
                        objectid,
                        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 overriden to simply append the method
        name and arguments to self.addBuildsetCalls.  These overriden 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')
        ]
        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(xrange(500, 999))
            self._bridGenerator = iter(xrange(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)

            def newMethod():
                self._parentMethodCalled = False
                d = defer.maybeDeferred(oldMethod)

                @d.addCallback
                def check(rv):
                    self.assertTrue(self._parentMethodCalled,
                                    "'%s' did not call its parent" % meth)
                    return rv

                return d

            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
 def test_findBuilderId_exists(self):
     yield self.insertTestData([
         fakedb.Builder(id=7, name='some:builder'),
     ])
     id = yield self.db.builders.findBuilderId('some:builder')
     self.assertEqual(id, 7)
Beispiel #22
0
    def test_getSourceStampsForBuild_3CodeBases(self):
        rows = [
            fakedb.Master(id=88, name="bar"),
            fakedb.Worker(id=13, name='one'),
            fakedb.Builder(id=77, name='A'),
            fakedb.SourceStamp(id=234,
                               codebase='A',
                               created_at=CREATED_AT,
                               revision="aaa"),
            fakedb.SourceStamp(id=235,
                               codebase='B',
                               created_at=CREATED_AT + 10,
                               revision="bbb"),
            fakedb.SourceStamp(id=236,
                               codebase='C',
                               created_at=CREATED_AT + 20,
                               revision="ccc"),
            # fakedb.Change(changeid=14, codebase='A', sourcestampid=234),
            fakedb.Buildset(id=30,
                            reason='foo',
                            submitted_at=1300305712,
                            results=-1),
            fakedb.BuildsetSourceStamp(sourcestampid=234, buildsetid=30),
            fakedb.BuildsetSourceStamp(sourcestampid=235, buildsetid=30),
            fakedb.BuildsetSourceStamp(sourcestampid=236, buildsetid=30),
            fakedb.BuildRequest(id=19,
                                buildsetid=30,
                                builderid=77,
                                priority=13,
                                submitted_at=1300305712,
                                results=-1),
            fakedb.Build(id=50,
                         buildrequestid=19,
                         number=5,
                         masterid=88,
                         builderid=77,
                         state_string="test",
                         workerid=13,
                         started_at=1304262222),
        ]

        expected = [{
            'branch': u'master',
            'codebase': u'A',
            'created_at': epoch2datetime(CREATED_AT),
            'patch_author': None,
            'patch_body': None,
            'patch_comment': None,
            'patch_level': None,
            'patch_subdir': None,
            'patchid': None,
            'project': u'proj',
            'repository': u'repo',
            'revision': u'aaa',
            'ssid': 234
        }, {
            'branch': u'master',
            'codebase': u'B',
            'created_at': epoch2datetime(CREATED_AT + 10),
            'patch_author': None,
            'patch_body': None,
            'patch_comment': None,
            'patch_level': None,
            'patch_subdir': None,
            'patchid': None,
            'project': u'proj',
            'repository': u'repo',
            'revision': u'bbb',
            'ssid': 235
        }, {
            'branch': u'master',
            'codebase': u'C',
            'created_at': epoch2datetime(CREATED_AT + 20),
            'patch_author': None,
            'patch_body': None,
            'patch_comment': None,
            'patch_level': None,
            'patch_subdir': None,
            'patchid': None,
            'project': u'proj',
            'repository': u'repo',
            'revision': u'ccc',
            'ssid': 236
        }]
        return self.do_test_getSourceStampsForBuild(rows, 50, expected)
from __future__ import print_function

import mock

from twisted.internet import defer
from twisted.trial import unittest

from buildbot.data import exceptions
from buildbot.data import workers
from buildbot.test.fake import fakedb
from buildbot.test.fake import fakemaster
from buildbot.test.util import endpoint
from buildbot.test.util import interfaces

testData = [
    fakedb.Builder(id=40, name=u'b1'),
    fakedb.Builder(id=41, name=u'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=u'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=u'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 test_fromBrdict_multiple_sourcestamps(self):
        master = fakemaster.make_master(testcase=self,
                                        wantData=True,
                                        wantDb=True)
        master.db.insertTestData([
            fakedb.Builder(id=77, name='bldr'),
            fakedb.SourceStamp(id=234,
                               branch='trunk',
                               revision='9283',
                               repository='svn://a..',
                               codebase='A',
                               project='world-domination'),
            fakedb.Change(changeid=13,
                          branch='trunk',
                          revision='9283',
                          repository='svn://a..',
                          codebase='A',
                          project='world-domination',
                          sourcestampid=234),
            fakedb.SourceStamp(id=235,
                               branch='trunk',
                               revision='9284',
                               repository='svn://b..',
                               codebase='B',
                               project='world-domination'),
            fakedb.Change(changeid=14,
                          branch='trunk',
                          revision='9284',
                          repository='svn://b..',
                          codebase='B',
                          project='world-domination',
                          sourcestampid=235),
            fakedb.Buildset(id=539, reason='triggered'),
            fakedb.BuildsetSourceStamp(buildsetid=539, sourcestampid=234),
            fakedb.BuildsetProperty(buildsetid=539,
                                    property_name='x',
                                    property_value='[1, "X"]'),
            fakedb.BuildsetProperty(buildsetid=539,
                                    property_name='y',
                                    property_value='[2, "Y"]'),
            fakedb.BuildRequest(id=288,
                                buildsetid=539,
                                builderid=77,
                                priority=13,
                                submitted_at=1200000000),
        ])
        # use getBuildRequest to minimize the risk from changes to the format
        # of the brdict
        d = master.db.buildrequests.getBuildRequest(288)
        d.addCallback(lambda brdict: buildrequest.BuildRequest.fromBrdict(
            master, brdict))

        def check(br):
            self.assertEqual(br.reason, 'triggered')

            self.assertEqual(br.properties.getProperty('x'), 1)
            self.assertEqual(br.properties.getProperty('y'), 2)
            self.assertEqual(br.submittedAt, 1200000000)
            self.assertEqual(br.buildername, 'bldr')
            self.assertEqual(br.priority, 13)
            self.assertEqual(br.id, 288)
            self.assertEqual(br.bsid, 539)

        d.addCallback(check)
        return d
Beispiel #25
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    backgroundData = [
        fakedb.Buildset(id=20),
        fakedb.Builder(id=77, name="b1"),
        fakedb.Builder(id=88, name="b2"),
        fakedb.BuildRequest(id=40, buildsetid=20, builderid=77),
        fakedb.BuildRequest(id=41, buildsetid=20, builderid=77),
        fakedb.BuildRequest(id=42, buildsetid=20, builderid=88),
        fakedb.Master(id=88),
        fakedb.Master(id=89, name="bar"),
        fakedb.Worker(id=13, name='wrk'),
        fakedb.Worker(id=12, name='sl2'),
    ]

    threeBuilds = [
        fakedb.Build(id=50,
                     buildrequestid=42,
                     number=5,
                     masterid=88,
                     builderid=77,
                     workerid=13,
                     state_string="build 5",
                     started_at=TIME1),
        fakedb.Build(id=51,
                     buildrequestid=41,
                     number=6,
                     masterid=88,
                     builderid=88,
                     workerid=13,
                     state_string="build 6",
                     started_at=TIME2),
        fakedb.Build(id=52,
                     buildrequestid=42,
                     number=7,
                     masterid=88,
                     builderid=77,
                     workerid=12,
                     state_string="build 7",
                     started_at=TIME3,
                     complete_at=TIME4,
                     results=5),
    ]

    threeBdicts = {
        50: {
            'id': 50,
            'buildrequestid': 42,
            'builderid': 77,
            'masterid': 88,
            'number': 5,
            'workerid': 13,
            'started_at': epoch2datetime(TIME1),
            'complete_at': None,
            'state_string': 'build 5',
            'results': None
        },
        51: {
            'id': 51,
            'buildrequestid': 41,
            'builderid': 88,
            'masterid': 88,
            'number': 6,
            'workerid': 13,
            'started_at': epoch2datetime(TIME2),
            'complete_at': None,
            'state_string': 'build 6',
            'results': None
        },
        52: {
            'id': 52,
            'buildrequestid': 42,
            'builderid': 77,
            'masterid': 88,
            'number': 7,
            'workerid': 12,
            'started_at': epoch2datetime(TIME3),
            'complete_at': epoch2datetime(TIME4),
            'state_string': 'build 7',
            'results': 5
        },
    }

    # signature tests

    def test_signature_getBuild(self):
        @self.assertArgSpecMatches(self.db.builds.getBuild)
        def getBuild(self, buildid):
            pass

    def test_signature_getBuildByNumber(self):
        @self.assertArgSpecMatches(self.db.builds.getBuildByNumber)
        def getBuild(self, builderid, number):
            pass

    def test_signature_getBuilds(self):
        @self.assertArgSpecMatches(self.db.builds.getBuilds)
        def getBuilds(self,
                      builderid=None,
                      buildrequestid=None,
                      workerid=None,
                      complete=None,
                      resultSpec=None):
            pass

    def test_signature_addBuild(self):
        @self.assertArgSpecMatches(self.db.builds.addBuild)
        def addBuild(self, builderid, buildrequestid, workerid, masterid,
                     state_string):
            pass

    def test_signature_setBuildStateString(self):
        @self.assertArgSpecMatches(self.db.builds.setBuildStateString)
        def setBuildStateString(self, buildid, state_string):
            pass

    def test_signature_finishBuild(self):
        @self.assertArgSpecMatches(self.db.builds.finishBuild)
        def finishBuild(self, buildid, results):
            pass

    def test_signature_getBuildProperties(self):
        @self.assertArgSpecMatches(self.db.builds.getBuildProperties)
        def getBuildProperties(self, bid):
            pass

    def test_signature_setBuildProperty(self):
        @self.assertArgSpecMatches(self.db.builds.setBuildProperty)
        def setBuildProperty(self, bid, name, value, source):
            pass

    # method tests

    @defer.inlineCallbacks
    def test_getBuild(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 workerid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=None,
                 state_string='build 5',
                 results=None))

    @defer.inlineCallbacks
    def test_getBuild_missing(self):
        bdict = yield self.db.builds.getBuild(50)
        self.assertEqual(bdict, None)

    @defer.inlineCallbacks
    def test_getBuildByNumber(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        bdict = yield self.db.builds.getBuildByNumber(builderid=77, number=5)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(bdict['id'], 50)

    @defer.inlineCallbacks
    def test_getBuilds(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds()
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            sorted(bdicts, key=lambda bd: bd['id']),
            [self.threeBdicts[50], self.threeBdicts[51], self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_getBuilds_builderid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(builderid=88)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[51]])

    @defer.inlineCallbacks
    def test_getBuilds_buildrequestid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(buildrequestid=42)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[50], self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_getBuilds_workerid(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(workerid=13)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[50], self.threeBdicts[51]])

    def test_signature_getBuildsForChange(self):
        @self.assertArgSpecMatches(self.db.builds.getBuildsForChange)
        def getBuildsForChange(self, changeid):
            pass

    @defer.inlineCallbacks
    def do_test_getBuildsForChange(self, rows, changeid, expected):
        yield self.insertTestData(rows)

        builds = yield self.db.builds.getBuildsForChange(changeid)

        self.assertEqual(sorted(builds), sorted(expected))

    def test_getBuildsForChange_OneCodebase(self):
        rows = [
            fakedb.Master(id=88, name="bar"),
            fakedb.Worker(id=13, name='one'),
            fakedb.Builder(id=77, name='A'),
            fakedb.SourceStamp(id=234, created_at=CREATED_AT, revision="aaa"),
            fakedb.Change(changeid=14, codebase='A', sourcestampid=234),
            fakedb.Buildset(id=30,
                            reason='foo',
                            submitted_at=1300305712,
                            results=1),
            fakedb.BuildsetSourceStamp(sourcestampid=234, buildsetid=30),
            fakedb.BuildRequest(id=19,
                                buildsetid=30,
                                builderid=77,
                                priority=13,
                                submitted_at=1300305712,
                                results=1,
                                complete=0,
                                complete_at=None),
            fakedb.Build(id=50,
                         buildrequestid=19,
                         number=5,
                         masterid=88,
                         builderid=77,
                         state_string="test",
                         workerid=13,
                         started_at=1304262222,
                         results=1),
        ]

        expected = [{
            'id': 50,
            'number': 5,
            'builderid': 77,
            'buildrequestid': 19,
            'workerid': 13,
            'masterid': 88,
            'started_at': epoch2datetime(1304262222),
            'complete_at': None,
            'state_string': 'test',
            'results': 1
        }]

        return self.do_test_getBuildsForChange(rows, 14, expected)

    @defer.inlineCallbacks
    def test_getBuilds_complete(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        bdicts = yield self.db.builds.getBuilds(complete=True)
        for bdict in bdicts:
            validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(sorted(bdicts, key=lambda bd: bd['id']),
                         [self.threeBdicts[52]])

    @defer.inlineCallbacks
    def test_addBuild_first(self):
        self.reactor.advance(TIME1)
        yield self.insertTestData(self.backgroundData)
        id, number = yield self.db.builds.addBuild(builderid=77,
                                                   buildrequestid=41,
                                                   workerid=13,
                                                   masterid=88,
                                                   state_string='test test2')
        bdict = yield self.db.builds.getBuild(id)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict, {
                'buildrequestid': 41,
                'builderid': 77,
                'id': id,
                'masterid': 88,
                'number': number,
                'workerid': 13,
                'started_at': epoch2datetime(TIME1),
                'complete_at': None,
                'state_string': 'test test2',
                'results': None
            })

    @defer.inlineCallbacks
    def test_addBuild_existing(self):
        self.reactor.advance(TIME1)
        yield self.insertTestData(self.backgroundData + [
            fakedb.Build(number=10,
                         buildrequestid=41,
                         builderid=77,
                         masterid=88,
                         workerid=13),
        ])
        id, number = yield self.db.builds.addBuild(builderid=77,
                                                   buildrequestid=41,
                                                   workerid=13,
                                                   masterid=88,
                                                   state_string='test test2')
        bdict = yield self.db.builds.getBuild(id)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(number, 11)
        self.assertEqual(
            bdict, {
                'buildrequestid': 41,
                'builderid': 77,
                'id': id,
                'masterid': 88,
                'number': number,
                'workerid': 13,
                'started_at': epoch2datetime(TIME1),
                'complete_at': None,
                'state_string': 'test test2',
                'results': None
            })

    @defer.inlineCallbacks
    def test_setBuildStateString(self):
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        yield self.db.builds.setBuildStateString(buildid=50,
                                                 state_string='test test2')
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 workerid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=None,
                 state_string='test test2',
                 results=None))

    @defer.inlineCallbacks
    def test_finishBuild(self):
        self.reactor.advance(TIME4)
        yield self.insertTestData(self.backgroundData + [self.threeBuilds[0]])
        yield self.db.builds.finishBuild(buildid=50, results=7)
        bdict = yield self.db.builds.getBuild(50)
        validation.verifyDbDict(self, 'dbbuilddict', bdict)
        self.assertEqual(
            bdict,
            dict(id=50,
                 number=5,
                 buildrequestid=42,
                 masterid=88,
                 builderid=77,
                 workerid=13,
                 started_at=epoch2datetime(TIME1),
                 complete_at=epoch2datetime(TIME4),
                 state_string='build 5',
                 results=7))

    @defer.inlineCallbacks
    def testgetBuildPropertiesEmpty(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        for buildid in (50, 51, 52):
            props = yield self.db.builds.getBuildProperties(buildid)
            self.assertEqual(0, len(props))

    @defer.inlineCallbacks
    def testsetandgetProperties(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        yield self.db.builds.setBuildProperty(50, 'prop', 42, 'test')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (42, 'test')})

    @defer.inlineCallbacks
    def testsetgetsetProperties(self):
        yield self.insertTestData(self.backgroundData + self.threeBuilds)
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {})
        yield self.db.builds.setBuildProperty(50, 'prop', 42, 'test')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (42, 'test')})
        # set a new value
        yield self.db.builds.setBuildProperty(50, 'prop', 45, 'test')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (45, 'test')})
        # set a new source
        yield self.db.builds.setBuildProperty(50, 'prop', 45, 'test_source')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (45, 'test_source')})
        # set the same
        yield self.db.builds.setBuildProperty(50, 'prop', 45, 'test_source')
        props = yield self.db.builds.getBuildProperties(50)
        self.assertEqual(props, {'prop': (45, 'test_source')})
    def test_mergeSourceStampsWith_common_codebases(self):
        """ This testcase has two buildrequests
            Request Change Codebase Revision Comment
            ----------------------------------------------------------------------
            288     13     A        9283
            289     15     A        9284
            288     14     B        9200
            289     16     B        9201
            --------------------------------
            After merged in Build:
            Source1 has rev 9284 and contains changes 13 and 15 from repository svn://a
            Source2 has rev 9201 and contains changes 14 and 16 from repository svn://b
        """
        brs = []  # list of buildrequests
        master = fakemaster.make_master(testcase=self,
                                        wantData=True,
                                        wantDb=True)
        master.db.insertTestData([
            fakedb.Builder(id=77, name='bldr'),
            fakedb.SourceStamp(id=234,
                               branch='trunk',
                               revision='9283',
                               repository='svn://a..',
                               codebase='A',
                               project='world-domination'),
            fakedb.Change(changeid=13,
                          branch='trunk',
                          revision='9283',
                          repository='svn://a..',
                          codebase='A',
                          project='world-domination',
                          sourcestampid=234),
            fakedb.SourceStamp(id=235,
                               branch='trunk',
                               revision='9200',
                               repository='svn://b..',
                               codebase='B',
                               project='world-domination'),
            fakedb.Change(changeid=14,
                          branch='trunk',
                          revision='9200',
                          repository='svn://b..',
                          codebase='A',
                          project='world-domination',
                          sourcestampid=235),
            fakedb.SourceStamp(id=236,
                               branch='trunk',
                               revision='9284',
                               repository='svn://a..',
                               codebase='A',
                               project='world-domination'),
            fakedb.Change(changeid=15,
                          branch='trunk',
                          revision='9284',
                          repository='svn://a..',
                          codebase='A',
                          project='world-domination',
                          sourcestampid=236),
            fakedb.SourceStamp(id=237,
                               branch='trunk',
                               revision='9201',
                               repository='svn://b..',
                               codebase='B',
                               project='world-domination'),
            fakedb.Change(changeid=16,
                          branch='trunk',
                          revision='9201',
                          repository='svn://b..',
                          codebase='B',
                          project='world-domination',
                          sourcestampid=237),
            fakedb.Buildset(id=539, reason='triggered'),
            fakedb.BuildsetSourceStamp(buildsetid=539, sourcestampid=234),
            fakedb.BuildsetSourceStamp(buildsetid=539, sourcestampid=235),
            fakedb.BuildRequest(id=288, buildsetid=539, builderid=77),
            fakedb.Buildset(id=540, reason='triggered'),
            fakedb.BuildsetSourceStamp(buildsetid=540, sourcestampid=236),
            fakedb.BuildsetSourceStamp(buildsetid=540, sourcestampid=237),
            fakedb.BuildRequest(id=289, buildsetid=540, builderid=77),
        ])
        # use getBuildRequest to minimize the risk from changes to the format
        # of the brdict
        d = master.db.buildrequests.getBuildRequest(288)
        d.addCallback(lambda brdict: buildrequest.BuildRequest.fromBrdict(
            master, brdict))
        d.addCallback(lambda br: brs.append(br))
        d.addCallback(lambda _: master.db.buildrequests.getBuildRequest(289))
        d.addCallback(lambda brdict: buildrequest.BuildRequest.fromBrdict(
            master, brdict))
        d.addCallback(lambda br: brs.append(br))

        def check(_):
            sources = brs[0].mergeSourceStampsWith(brs[1:])

            source1 = source2 = None
            for source in sources:
                if source.codebase == 'A':
                    source1 = source
                if source.codebase == 'B':
                    source2 = source

            self.assertFalse(source1 is None)
            self.assertEqual(source1.revision, '9284')

            self.assertFalse(source2 is None)
            self.assertEqual(source2.revision, '9201')

        d.addCallback(check)
        return d
Beispiel #27
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=u'a'),
        fakedb.Builder(id=21, name=u'b'),
        fakedb.Builder(id=22, name=u'c'),
        fakedb.Buildslave(id=30, name='zero'),
        fakedb.Buildslave(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.ConfiguredBuildslave(
            id=3012, buildslaveid=30, buildermasterid=12),
        fakedb.ConfiguredBuildslave(
            id=3013, buildslaveid=30, buildermasterid=13),
        fakedb.ConfiguredBuildslave(
            id=3014, buildslaveid=30, buildermasterid=14),
        fakedb.ConfiguredBuildslave(
            id=3114, buildslaveid=31, buildermasterid=14),
        fakedb.ConfiguredBuildslave(
            id=3115, buildslaveid=31, buildermasterid=15),
        fakedb.ConnectedBuildslave(id=3010, buildslaveid=30, masterid=10),
        fakedb.ConnectedBuildslave(id=3111, buildslaveid=31, masterid=11),
    ]

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

    BOGUS_NAME = 'bogus'

    BS1_NAME, BS1_ID, BS1_INFO = 'bs1', 100, {'a': 1}
    buildslave1_rows = [
        fakedb.Buildslave(id=BS1_ID, name=BS1_NAME, info=BS1_INFO),
    ]

    BS2_NAME, BS2_ID, BS2_INFO = 'bs2', 200, {'a': 1, 'b': 2}
    buildslave2_rows = [
        fakedb.Buildslave(id=BS2_ID, name=BS2_NAME, info=BS2_INFO),
    ]

    # tests

    def test_signature_findBuildslaveId(self):
        @self.assertArgSpecMatches(self.db.buildslaves.findBuildslaveId)
        def findBuildslaveId(self, name):
            pass

    def test_signature_getBuildslave(self):
        @self.assertArgSpecMatches(self.db.buildslaves.getBuildslave)
        def getBuildslave(self, buildslaveid=None, name=None,
                          masterid=None, builderid=None):
            pass

    def test_signature_getBuildslaves(self):
        @self.assertArgSpecMatches(self.db.buildslaves.getBuildslaves)
        def getBuildslaves(self, masterid=None, builderid=None):
            pass

    def test_signature_buildslaveConnected(self):
        @self.assertArgSpecMatches(self.db.buildslaves.buildslaveConnected)
        def buildslaveConnected(self, buildslaveid, masterid, slaveinfo):
            pass

    def test_signature_buildslaveDisconnected(self):
        @self.assertArgSpecMatches(self.db.buildslaves.buildslaveDisconnected)
        def buildslaveDisconnected(self, buildslaveid, masterid):
            pass

    def test_signature_buildslaveConfigured(self):
        @self.assertArgSpecMatches(self.db.buildslaves.buildslaveConfigured)
        def buildslaveConfigured(self, buildslaveid, masterid, builderids):
            pass

    def test_signature_deconfigureAllBuidslavesForMaster(self):
        @self.assertArgSpecMatches(self.db.buildslaves.deconfigureAllBuidslavesForMaster)
        def deconfigureAllBuidslavesForMaster(self, masterid):
            pass

    @defer.inlineCallbacks
    def test_findBuildslaveId_insert(self):
        id = yield self.db.buildslaves.findBuildslaveId(name=u"xyz")
        bslave = yield self.db.buildslaves.getBuildslave(buildslaveid=id)
        self.assertEqual(bslave['name'], 'xyz')
        self.assertEqual(bslave['slaveinfo'], {})

    @defer.inlineCallbacks
    def test_findBuildslaveId_existing(self):
        yield self.insertTestData(self.baseRows)
        id = yield self.db.buildslaves.findBuildslaveId(name=u"one")
        self.assertEqual(id, 31)

    @defer.inlineCallbacks
    def test_getBuildslave_no_such(self):
        yield self.insertTestData(self.baseRows)
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=99)
        self.assertEqual(slavedict, None)

    @defer.inlineCallbacks
    def test_getBuildslave_by_name_no_such(self):
        yield self.insertTestData(self.baseRows)
        slavedict = yield self.db.buildslaves.getBuildslave(name='NOSUCH')
        self.assertEqual(slavedict, None)

    @defer.inlineCallbacks
    def test_getBuildslave_not_configured(self):
        yield self.insertTestData(self.baseRows)
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              connected_to=[], configured_on=[]))

    @defer.inlineCallbacks
    def test_getBuildslave_connected_not_configured(self):
        yield self.insertTestData(self.baseRows + [
            # the slave is connected to this master, but not configured.
            # weird, but the DB should represent it.
            fakedb.Buildslave(id=32, name='two'),
            fakedb.ConnectedBuildslave(buildslaveid=32, masterid=11),
        ])
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=32)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=32, name='two', slaveinfo={'a': 'b'},
                              connected_to=[11], configured_on=[]))

    @defer.inlineCallbacks
    def test_getBuildslave_multiple_connections(self):
        yield self.insertTestData(self.baseRows + [
            # the slave is connected to two masters at once.
            # weird, but the DB should represent it.
            fakedb.Buildslave(id=32, name='two'),
            fakedb.ConnectedBuildslave(buildslaveid=32, masterid=10),
            fakedb.ConnectedBuildslave(buildslaveid=32, masterid=11),
            fakedb.BuilderMaster(id=24, builderid=20, masterid=10),
            fakedb.BuilderMaster(id=25, builderid=20, masterid=11),
            fakedb.ConfiguredBuildslave(buildslaveid=32, buildermasterid=24),
            fakedb.ConfiguredBuildslave(buildslaveid=32, buildermasterid=25),
        ])
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=32)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=32, name='two', slaveinfo={'a': 'b'},
                              connected_to=[10, 11], configured_on=[
                                  {'builderid': 20, 'masterid': 10},
                                  {'builderid': 20, 'masterid': 11},
                                  ]))

    @defer.inlineCallbacks
    def test_getBuildslave_by_name_not_configured(self):
        yield self.insertTestData(self.baseRows)
        slavedict = yield self.db.buildslaves.getBuildslave(name='zero')
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              connected_to=[], configured_on=[]))

    @defer.inlineCallbacks
    def test_getBuildslave_not_connected(self):
        yield self.insertTestData(self.baseRows + [
            fakedb.BuilderMaster(id=12, builderid=20, masterid=10),
            fakedb.ConfiguredBuildslave(buildslaveid=30, buildermasterid=12),
        ])
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=[
                                  {'masterid': 10, 'builderid': 20}],
                              connected_to=[]))

    @defer.inlineCallbacks
    def test_getBuildslave_connected(self):
        yield self.insertTestData(self.baseRows + [
            fakedb.BuilderMaster(id=12, builderid=20, masterid=10),
            fakedb.ConfiguredBuildslave(buildslaveid=30, buildermasterid=12),
            fakedb.ConnectedBuildslave(buildslaveid=30, masterid=10),
        ])
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=[
                                  {'masterid': 10, 'builderid': 20}],
                              connected_to=[10]))

    @defer.inlineCallbacks
    def test_getBuildslave_with_multiple_masters(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        slavedict['configured_on'].sort()
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=sorted([
                                  {'masterid': 10, 'builderid': 20},
                                  {'masterid': 10, 'builderid': 21},
                                  {'masterid': 11, 'builderid': 20},
                              ]), connected_to=[10]))

    @defer.inlineCallbacks
    def test_getBuildslave_with_multiple_masters_builderid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30, builderid=20)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        slavedict['configured_on'].sort()
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=sorted([
                                  {'masterid': 10, 'builderid': 20},
                                  {'masterid': 11, 'builderid': 20},
                              ]), connected_to=[10]))

    @defer.inlineCallbacks
    def test_getBuildslave_with_multiple_masters_masterid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30, masterid=11)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=[
                                  {'masterid': 11, 'builderid': 20},
                                  ], connected_to=[]))

    @defer.inlineCallbacks
    def test_getBuildslave_with_multiple_masters_builderid_masterid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30,
                                                            builderid=20, masterid=11)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=[
                                  {'masterid': 11, 'builderid': 20},
                                  ], connected_to=[]))

    @defer.inlineCallbacks
    def test_getBuildslave_by_name_with_multiple_masters_builderid_masterid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedict = yield self.db.buildslaves.getBuildslave(name='zero',
                                                            builderid=20, masterid=11)
        validation.verifyDbDict(self, 'buildslavedict', slavedict)
        self.assertEqual(slavedict,
                         dict(id=30, name='zero', slaveinfo={'a': 'b'},
                              configured_on=[
                                  {'masterid': 11, 'builderid': 20},
                                  ], connected_to=[]))

    @defer.inlineCallbacks
    def test_getBuildslaves_no_config(self):
        yield self.insertTestData(self.baseRows)
        slavedicts = yield self.db.buildslaves.getBuildslaves()
        [validation.verifyDbDict(self, 'buildslavedict', slavedict)
         for slavedict in slavedicts]
        self.assertEqual(sorted(slavedicts), sorted([
            dict(id=30, name='zero', slaveinfo={'a': 'b'},
                 configured_on=[], connected_to=[]),
            dict(id=31, name='one', slaveinfo={'a': 'b'},
                 configured_on=[], connected_to=[]),
        ]))

    @defer.inlineCallbacks
    def test_getBuildslaves_with_config(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedicts = yield self.db.buildslaves.getBuildslaves()
        for slavedict in slavedicts:
            validation.verifyDbDict(self, 'buildslavedict', slavedict)
            slavedict['configured_on'].sort()
        self.assertEqual(sorted(slavedicts), sorted([
            dict(id=30, name='zero', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 10, 'builderid': 20},
                     {'masterid': 10, 'builderid': 21},
                     {'masterid': 11, 'builderid': 20},
                 ]), connected_to=[10]),
            dict(id=31, name='one', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 11, 'builderid': 20},
                     {'masterid': 11, 'builderid': 22},
                 ]), connected_to=[11]),
        ]))

    @defer.inlineCallbacks
    def test_getBuildslaves_empty(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedicts = yield self.db.buildslaves.getBuildslaves(masterid=11, builderid=21)
        for slavedict in slavedicts:
            validation.verifyDbDict(self, 'buildslavedict', slavedict)
            slavedict['configured_on'].sort()
        self.assertEqual(sorted(slavedicts), [])

    @defer.inlineCallbacks
    def test_getBuildslaves_with_config_builderid(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedicts = yield self.db.buildslaves.getBuildslaves(builderid=20)
        for slavedict in slavedicts:
            validation.verifyDbDict(self, 'buildslavedict', slavedict)
            slavedict['configured_on'].sort()
        self.assertEqual(sorted(slavedicts), sorted([
            dict(id=30, name='zero', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 10, 'builderid': 20},
                     {'masterid': 11, 'builderid': 20},
                 ]), connected_to=[10]),
            dict(id=31, name='one', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 11, 'builderid': 20},
                 ]), connected_to=[11]),
        ]))

    @defer.inlineCallbacks
    def test_getBuildslaves_with_config_masterid_10(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedicts = yield self.db.buildslaves.getBuildslaves(masterid=10)
        for slavedict in slavedicts:
            validation.verifyDbDict(self, 'buildslavedict', slavedict)
            slavedict['configured_on'].sort()
        self.assertEqual(sorted(slavedicts), sorted([
            dict(id=30, name='zero', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 10, 'builderid': 20},
                     {'masterid': 10, 'builderid': 21},
                 ]), connected_to=[10]),
        ]))

    @defer.inlineCallbacks
    def test_getBuildslaves_with_config_masterid_11(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedicts = yield self.db.buildslaves.getBuildslaves(masterid=11)
        for slavedict in slavedicts:
            validation.verifyDbDict(self, 'buildslavedict', slavedict)
            slavedict['configured_on'].sort()
        self.assertEqual(sorted(slavedicts), sorted([
            dict(id=30, name='zero', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 11, 'builderid': 20},
                 ]), connected_to=[]),
            dict(id=31, name='one', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 11, 'builderid': 20},
                     {'masterid': 11, 'builderid': 22},
                 ]), connected_to=[11]),
        ]))

    @defer.inlineCallbacks
    def test_getBuildslaves_with_config_masterid_11_builderid_22(self):
        yield self.insertTestData(self.baseRows + self.multipleMasters)
        slavedicts = yield self.db.buildslaves.getBuildslaves(
            masterid=11, builderid=22)
        for slavedict in slavedicts:
            validation.verifyDbDict(self, 'buildslavedict', slavedict)
            slavedict['configured_on'].sort()
        self.assertEqual(sorted(slavedicts), sorted([
            dict(id=31, name='one', slaveinfo={'a': 'b'},
                 configured_on=sorted([
                     {'masterid': 11, 'builderid': 22},
                 ]), connected_to=[11]),
        ]))

    @defer.inlineCallbacks
    def test_buildslaveConnected_existing(self):
        yield self.insertTestData(self.baseRows + self.buildslave1_rows)

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

        yield self.db.buildslaves.buildslaveConnected(
            buildslaveid=self.BS1_ID, masterid=11, slaveinfo=NEW_INFO)

        bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID)
        self.assertEqual(bs, {
            'id': self.BS1_ID,
            'name': self.BS1_NAME,
            'slaveinfo': NEW_INFO,
            'configured_on': [],
            'connected_to': [11]})

    @defer.inlineCallbacks
    def test_buildslaveConnected_already_connected(self):
        yield self.insertTestData(self.baseRows + self.buildslave1_rows + [
            fakedb.ConnectedBuildslave(id=888,
                                       buildslaveid=self.BS1_ID, masterid=11),
        ])
        yield self.db.buildslaves.buildslaveConnected(
            buildslaveid=self.BS1_ID, masterid=11, slaveinfo={})

        bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID)
        self.assertEqual(bs['connected_to'], [11])

    @defer.inlineCallbacks
    def test_buildslaveDisconnected(self):
        yield self.insertTestData(self.baseRows + self.buildslave1_rows + [
            fakedb.ConnectedBuildslave(id=888,
                                       buildslaveid=self.BS1_ID, masterid=10),
            fakedb.ConnectedBuildslave(id=889,
                                       buildslaveid=self.BS1_ID, masterid=11),
        ])
        yield self.db.buildslaves.buildslaveDisconnected(
            buildslaveid=self.BS1_ID, masterid=11)

        bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID)
        self.assertEqual(bs['connected_to'], [10])

    @defer.inlineCallbacks
    def test_buildslaveDisconnected_already_disconnected(self):
        yield self.insertTestData(self.baseRows + self.buildslave1_rows)
        yield self.db.buildslaves.buildslaveDisconnected(
            buildslaveid=self.BS1_ID, masterid=11)

        bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID)
        self.assertEqual(bs['connected_to'], [])

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

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

        yield self.db.buildslaves.buildslaveConfigured(
            buildslaveid=30, masterid=10, builderids=[20, 22])

        bs = yield self.db.buildslaves.getBuildslave(30)
        self.assertEqual(sorted(bs['configured_on']), sorted([
            {'builderid': 20, 'masterid': 11},
            {'builderid': 20, 'masterid': 10},
            {'builderid': 22, 'masterid': 10}]))

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

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

        yield self.db.buildslaves.buildslaveConfigured(
            buildslaveid=30, masterid=10, builderids=[20, 22])

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

        bs = yield self.db.buildslaves.getBuildslave(30)
        self.assertEqual(sorted(bs['configured_on']), sorted([
            {'builderid': 20, 'masterid': 11},
            {'builderid': 20, 'masterid': 10},
            {'builderid': 21, 'masterid': 10},
            {'builderid': 22, 'masterid': 10}]))

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

        # should remove builder 21, and add 22
        yield self.db.buildslaves.deconfigureAllBuidslavesForMaster(masterid=10)
        yield self.db.buildslaves.buildslaveConfigured(
            buildslaveid=30, masterid=10, builderids=[])

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

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

        res = yield self.db.buildslaves.getBuildslaves(masterid=11)
        self.assertEqual(len(res), 2)

        # should remove all slave configured for masterid 11
        yield self.db.buildslaves.deconfigureAllBuidslavesForMaster(masterid=11)

        res = yield self.db.buildslaves.getBuildslaves(masterid=11)
        self.assertEqual(len(res), 0)
    def test_canBeCollapsed_different_codebases_raises_error(self):
        """ This testcase has two buildrequests
            Request Change Codebase   Revision Comment
            ----------------------------------------------------------------------
            288     17     C          1800     request 1 has repo not in request 2
            289     18     D          2100     request 2 has repo not in request 1
            --------------------------------
            Merge cannot be performd and raises error:
              Merging requests requires both requests to have the same codebases
        """
        brDicts = []  # list of buildrequests dictionnary
        master = fakemaster.make_master(testcase=self,
                                        wantData=True,
                                        wantDb=True)
        master.db.insertTestData([
            fakedb.Builder(id=77, name='bldr'),
            fakedb.SourceStamp(id=238,
                               branch='trunk',
                               revision='1800',
                               repository='svn://c..',
                               codebase='C',
                               project='world-domination'),
            fakedb.Change(changeid=17,
                          branch='trunk',
                          revision='1800',
                          repository='svn://c..',
                          codebase='C',
                          project='world-domination',
                          sourcestampid=238),
            fakedb.SourceStamp(id=239,
                               branch='trunk',
                               revision='2100',
                               repository='svn://d..',
                               codebase='D',
                               project='world-domination'),
            fakedb.Change(changeid=18,
                          branch='trunk',
                          revision='2100',
                          repository='svn://d..',
                          codebase='D',
                          project='world-domination',
                          sourcestampid=239),
            fakedb.Buildset(id=539, reason='triggered'),
            fakedb.BuildsetSourceStamp(buildsetid=539, sourcestampid=238),
            fakedb.BuildRequest(id=288, buildsetid=539, builderid=77),
            fakedb.Buildset(id=540, reason='triggered'),
            fakedb.BuildsetSourceStamp(buildsetid=540, sourcestampid=239),
            fakedb.BuildRequest(id=289, buildsetid=540, builderid=77),
        ])
        # use getBuildRequest to minimize the risk from changes to the format
        # of the brdict
        d = master.db.buildrequests.getBuildRequest(288)
        d.addCallback(lambda brdict: brDicts.append(brdict))
        d.addCallback(lambda _: master.db.buildrequests.getBuildRequest(289))
        d.addCallback(lambda brdict: brDicts.append(brdict))
        d.addCallback(lambda _: buildrequest.BuildRequest.canBeCollapsed(
            master, brDicts[0], brDicts[1]))

        def check(canBeCollapsed):
            self.assertEqual(canBeCollapsed, False)

        d.addCallback(check)
        return d
Beispiel #29
0
    def setupBuildResults(self, results, wantPreviousBuild=False):
        # this testsuite always goes through setupBuildResults so that
        # the data is sure to be the real data schema known coming from data
        # api

        self.db = self.master.db
        self.db.insertTestData([
            fakedb.Master(id=92),
            fakedb.Worker(id=13, name='sl'),
            fakedb.Buildset(id=98, results=results, reason="testReason1"),
            fakedb.Builder(id=80, name='Builder1'),
            fakedb.BuildRequest(id=11, buildsetid=98, builderid=80),
            fakedb.Build(id=20,
                         number=0,
                         builderid=80,
                         buildrequestid=11,
                         workerid=13,
                         masterid=92,
                         results=results),
            fakedb.Step(id=50, buildid=20, number=5, name='make'),
            fakedb.BuildsetSourceStamp(buildsetid=98, sourcestampid=234),
            fakedb.SourceStamp(id=234, patchid=99),
            fakedb.Change(changeid=13,
                          branch=u'trunk',
                          revision=u'9283',
                          author='me@foo',
                          repository=u'svn://...',
                          codebase=u'cbsvn',
                          project=u'world-domination',
                          sourcestampid=234),
            fakedb.Log(id=60,
                       stepid=50,
                       name='stdio',
                       slug='stdio',
                       type='s',
                       num_lines=7),
            fakedb.LogChunk(
                logid=60,
                first_line=0,
                last_line=1,
                compressed=0,
                content=u'Unicode log with non-ascii (\u00E5\u00E4\u00F6).'),
            fakedb.Patch(id=99,
                         patch_base64='aGVsbG8sIHdvcmxk',
                         patch_author='him@foo',
                         patch_comment='foo',
                         subdir='/foo',
                         patchlevel=3),
        ])
        for _id in (20, ):
            self.db.insertTestData([
                fakedb.BuildProperty(buildid=_id,
                                     name="workername",
                                     value="sl"),
                fakedb.BuildProperty(buildid=_id,
                                     name="reason",
                                     value="because"),
                fakedb.BuildProperty(buildid=_id,
                                     name="scheduler",
                                     value="checkin"),
                fakedb.BuildProperty(buildid=_id,
                                     name="branch",
                                     value="master"),
            ])
        res = yield utils.getDetailsForBuildset(
            self.master,
            98,
            wantProperties=True,
            wantPreviousBuild=wantPreviousBuild)
        builds = res['builds']
        buildset = res['buildset']

        @defer.inlineCallbacks
        def getChangesForBuild(buildid):
            assert buildid == 20
            ch = yield self.master.db.changes.getChange(13)
            defer.returnValue([ch])

        self.master.db.changes.getChangesForBuild = getChangesForBuild
        defer.returnValue((buildset, builds))
    def makeScheduler(self, firstBuildDuration=0, **kwargs):

        sched = self.attachScheduler(timed.Nightly(**kwargs),
                                     self.OBJECTID,
                                     overrideBuildsetMethods=True)

        self.master.db.insertTestData([
            fakedb.Builder(name=bname)
            for bname in kwargs.get("builderNames", [])
        ])

        # add a Clock to help checking timing issues
        self.clock = sched._reactor = task.Clock()
        self.clock.advance(self.localtime_offset)  # get to 0 min past the hour

        # keep track of builds in self.events
        self.events = []

        def addBuildsetForLatest(reason='',
                                 external_idstring='',
                                 branch=None,
                                 repository='',
                                 project=''):
            self.assertIn('scheduler named', reason)
            isFirst = (self.events == [])
            self.events.append('B(%s)@%d' % (
                branch,
                # show the offset as seconds past the GMT hour
                self.clock.seconds() - self.localtime_offset))
            if isFirst and firstBuildDuration:
                d = defer.Deferred()
                self.clock.callLater(firstBuildDuration, d.callback, None)
                return d
            else:
                return defer.succeed(None)

        sched.addBuildsetForLatest = addBuildsetForLatest

        origAddBuildsetForChanges = sched.addBuildsetForChanges

        def addBuildsetForChanges(reason='',
                                  external_idstring=None,
                                  changeids=[]):
            self.events.append('B%s@%d' % (
                repr(changeids).replace(' ', ''),
                # show the offset as seconds past the GMT hour
                self.clock.seconds() - self.localtime_offset))
            return origAddBuildsetForChanges(
                reason=reason,
                external_idstring=external_idstring,
                changeids=changeids)

        sched.addBuildsetForChanges = addBuildsetForChanges

        # see self.assertConsumingChanges
        self.consumingChanges = None

        def startConsumingChanges(**kwargs):
            self.consumingChanges = kwargs
            return defer.succeed(None)

        sched.startConsumingChanges = startConsumingChanges

        return sched