def test_sendToInterestedUsers_two_builds(self):
        from email.message import Message
        m = Message()

        mn = MailNotifier(fromaddr="*****@*****.**", lookup=None)
        mn.sendMessage = Mock()

        def fakeGetBuilder(buildername):
            if buildername == builder.name:
                return builder
            return None

        def fakeGetBuildRequests(self, bsid):
            return defer.succeed([{"buildername": "Builder", "brid": 1}])

        builder = Mock()
        builder.name = "Builder"

        build1 = FakeBuildStatus(name="build")
        build1.result = FAILURE
        build1.finished = True
        build1.reason = "testReason"
        build1.builder = builder

        build2 = FakeBuildStatus(name="build")
        build2.result = FAILURE
        build2.finished = True
        build2.reason = "testReason"
        build2.builder = builder

        def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
                            patches=None, logs=None):
            # only concerned with m['To'] and m['CC'], which are added in
            # _got_recipients later
            return defer.succeed(m)
        mn.createEmail = fakeCreateEmail

        self.db = self.master.db
        self.db.insertTestData([
            fakedb.Master(id=92),
            fakedb.Buildslave(id=13, name='sl'),
            fakedb.Buildset(id=99, results=SUCCESS, reason="testReason"),
            fakedb.BuildRequest(id=11, buildsetid=99, buildername='Builder'),
            fakedb.Build(number=0, buildrequestid=11, buildslaveid=13,
                         masterid=92),
            fakedb.Build(number=1, buildrequestid=11, buildslaveid=13,
                         masterid=92),
            fakedb.Change(changeid=9123),
            fakedb.Change(changeid=9124),
            fakedb.ChangeUser(changeid=9123, uid=1),
            fakedb.ChangeUser(changeid=9124, uid=2),
            fakedb.User(uid=1, identifier="tdurden"),
            fakedb.User(uid=2, identifier="user2"),
            fakedb.UserInfo(uid=1, attr_type='email',
                            attr_data="*****@*****.**"),
            fakedb.UserInfo(uid=2, attr_type='email',
                            attr_data="*****@*****.**")
        ])

        def _getInterestedUsers():
            # 'narrator' in this case is the owner, which tests the lookup
            return ["narrator"]
        build1.getInterestedUsers = _getInterestedUsers
        build2.getInterestedUsers = _getInterestedUsers

        def _getResponsibleUsers():
            return ["Big Bob <*****@*****.**>"]
        build1.getResponsibleUsers = _getResponsibleUsers
        build2.getResponsibleUsers = _getResponsibleUsers

        # fake sourcestamp with relevant user bits
        ss1 = Mock(name="sourcestamp")
        fake_change1 = Mock(name="change")
        fake_change1.number = 9123
        ss1.changes = [fake_change1]
        ss1.patch, ss1.addPatch = None, None

        ss2 = Mock(name="sourcestamp")
        fake_change2 = Mock(name="change")
        fake_change2.number = 9124
        ss2.changes = [fake_change2]
        ss2.patch, ss1.addPatch = None, None

        def fakeGetSSlist(ss):
            return lambda: [ss]
        build1.getSourceStamps = fakeGetSSlist(ss1)
        build2.getSourceStamps = fakeGetSSlist(ss2)

        self.setupMailNotifier(mn)
        mn.buildMessageDict = Mock()
        mn.master_status.getBuilder = fakeGetBuilder
        mn.buildMessageDict.return_value = {"body": "body", "type": "text"}

        mn.buildMessage(builder.name, [build1, build2], build1.result)
        self.assertEqual(m['To'], "[email protected], [email protected]")
class TestBuildslavesConnectorComponent(
        connector_component.ConnectorComponentMixin, unittest.TestCase):
    def setUp(self):
        d = self.setUpConnectorComponent(table_names=['buildslaves'])

        def finish_setup(_):
            self.db.buildslaves = buildslaves.BuildslavesConnectorComponent(
                self.db)

        d.addCallback(finish_setup)
        return d

    def tearDown(self):
        return self.tearDownConnectorComponent()

    # 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_getBuildslaveByName_empty(self):
        d = self.insertTestData(self.buildslave1_rows)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaveByName(self.BOGUS_NAME)

        @d.addCallback
        def check(res):
            self.assertEqual(res, None)

        return d

    def test_getBuildslaveByName_existing(self):
        d = self.insertTestData(self.buildslave1_rows)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaveByName(self.BS1_NAME)

        @d.addCallback
        def check(res):
            self.assertEqual(res['slaveid'], self.BS1_ID)
            self.assertEqual(res['name'], self.BS1_NAME)
            self.assertEqual(res['slaveinfo'], self.BS1_INFO)

        return d

    def test_getBuildslaves_empty(self):
        d = self.db.buildslaves.getBuildslaves()

        @d.addCallback
        def check(res):
            self.assertEqual(res, [])

        return d

    def test_getBuildslaves_some(self):
        d = self.insertTestData(self.buildslave1_rows + self.buildslave2_rows)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaves()

        @d.addCallback
        def check(res):
            self.assertEqual(len(res), 2)

            self.assertEqual(res[0]['slaveid'], self.BS1_ID)
            self.assertEqual(res[0]['name'], self.BS1_NAME)

            self.assertEqual(res[1]['slaveid'], self.BS2_ID)
            self.assertEqual(res[1]['name'], self.BS2_NAME)

        return d

    def test_updateBuildslaves_existing(self):
        d = self.insertTestData(self.buildslave1_rows)

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

        @d.addCallback
        def update(_):
            return self.db.buildslaves.updateBuildslave(name=self.BS1_NAME,
                                                        slaveinfo=NEW_INFO)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaveByName(self.BS1_NAME)

        @d.addCallback
        def check(res):
            self.assertEqual(res['slaveid'], self.BS1_ID)
            self.assertEqual(res['name'], self.BS1_NAME)
            self.assertEqual(res['slaveinfo'], NEW_INFO)

        return d

    def test_updateBuildslaves_new(self):
        # insert only #1, but not #2
        d = self.insertTestData(self.buildslave1_rows)

        @d.addCallback
        def update(_):
            return self.db.buildslaves.updateBuildslave(
                name=self.BS2_NAME, slaveinfo=self.BS2_INFO)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaveByName(self.BS2_NAME)

        @d.addCallback
        def check(res):
            self.failIfIdentical(res['slaveid'], None)
            self.assertEqual(res['name'], self.BS2_NAME)
            self.assertEqual(res['slaveinfo'], self.BS2_INFO)

        return d

    def test_updateBuildslave_race(self):
        RACE_INFO = {'race': 'yep'}

        def race_thd(conn):
            # generate a new connection, since the passed connection will be
            # rolled back as a result of the conflicting insert
            newConn = conn.engine.connect()
            newConn.execute(self.db.model.buildslaves.insert(),
                            name=self.BS1_NAME,
                            info=RACE_INFO)

        d = self.db.buildslaves.updateBuildslave(name=self.BS1_NAME,
                                                 slaveinfo=self.BS1_INFO,
                                                 _race_hook=race_thd)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaveByName(self.BS1_NAME)

        @d.addCallback
        def check(res):
            self.failIfIdentical(res['slaveid'], None)
            self.assertEqual(res['name'], self.BS1_NAME)
            self.assertEqual(res['slaveinfo'], RACE_INFO)  # race wins

        return d

    def test_updateBuildslave_badJson(self):
        d = self.insertTestData(self.buildslave1_rows)

        @d.addCallback
        def corrupt(_):
            BAD_JSON = {
                'key': object(),  # something json wont serialize
            }
            return self.db.buildslaves.updateBuildslave(name=self.BS1_NAME,
                                                        slaveinfo=BAD_JSON)

        @d.addBoth
        def shouldThrow(res):
            self.assertIsInstance(res, failure.Failure)

        @d.addCallback
        def get(_):
            return self.db.buildslaves.getBuildslaveByName(self.BS1_NAME)

        @d.addCallback
        def checkUnchanged(res):
            # should be unchanged from the original value
            self.assertEqual(res['slaveinfo'], self.BS1_INFO)

        return d
Exemple #3
0
    def test_getChangesForBuild(self):
        rows = [
            fakedb.Master(id=88, name="bar"),
            fakedb.Buildslave(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 = {}

        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])[-1]

            if codebase not in codebase_ss:
                codebase_ss[codebase] = list()
            codebase_ss[codebase].append(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_list in codebase_ss.iteritems():
                for ss in ss_list:
                    lastID["buildsetSourceStampid"] += 1
                    buildRows.append(
                        fakedb.BuildsetSourceStamp(
                            id=lastID["buildsetSourceStampid"],
                            sourcestampid=ss,
                            buildsetid=lastID["buildsetid"]))
            codebase_ss = {}
            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",
                             buildslaveid=13,
                             started_at=SOMETIME + lastID["buildid"],
                             complete_at=SOMETIME + 2 * lastID["buildid"],
                             results=results)
            ])
            return buildRows

        # Build1 has 1 change per code base. build result = success
        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. build result = success
        rows.extend(addChange('A', 2, 'delanne', '4th commit'))
        rows.extend(addBuild(codebase_ss))
        # Build 3 has only one change for codebase B. build result = success
        rows.extend(addChange('B', 2, 'bob', '6th commit'))
        rows.extend(addBuild(codebase_ss))
        # Build 4 has no change. build result = success
        rows.extend(addBuild(codebase_ss))
        # Build 5 has 2 changes for codebase A and 1 change for codebase C. build result = success
        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. build result = failure
        rows.extend(addChange('C', 2, 'bob', '10th commit'))
        rows.extend(addBuild(codebase_ss, 2))
        # Build 7 has only one change for codebase C. build result = success
        rows.extend(addChange('C', 3, 'bob', '11th commit'))
        rows.extend(addBuild(codebase_ss, 2))
        yield self.insertTestData(rows)

        expected_1stBuild = [{
            'author': u'alice',
            'branch': u'master',
            'category': u'cat',
            'changeid': 2,
            'codebase': u'',
            'comments': u'2nd commit',
            'files': [],
            'parent_changeids': [],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'1',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 2,
            'when_timestamp': epoch2datetime(SOMETIME + 2)
        }, {
            'author': u'bob',
            'branch': u'master',
            'category': u'cat',
            'changeid': 3,
            'codebase': u'',
            'comments': u'3rd commit',
            'files': [],
            'parent_changeids': [],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'1',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 3,
            'when_timestamp': epoch2datetime(SOMETIME + 3)
        }, {
            'author': u'franck',
            'branch': u'master',
            'category': u'cat',
            'changeid': 1,
            'codebase': u'',
            'comments': u'1st commit',
            'files': [],
            'parent_changeids': [],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'1',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 1,
            'when_timestamp': epoch2datetime(SOMETIME + 1)
        }]
        expected_2ndBuild = [{
            'author': u'delanne',
            'branch': u'master',
            'category': u'cat',
            'changeid': 4,
            'codebase': u'',
            'comments': u'4th commit',
            'files': [],
            'parent_changeids': [1],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'2',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 4,
            'when_timestamp': epoch2datetime(SOMETIME + 4)
        }]
        expected_3rdBuild = [{
            'author': u'bob',
            'branch': u'master',
            'category': u'cat',
            'changeid': 5,
            'codebase': u'',
            'comments': u'6th commit',
            'files': [],
            'parent_changeids': [2],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'2',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 5,
            'when_timestamp': epoch2datetime(SOMETIME + 5)
        }]
        expected_4thBuild = []
        expected_5thBuild = [{
            'author': u'alice',
            'branch': u'master',
            'category': u'cat',
            'changeid': 7,
            'codebase': u'',
            'comments': u'8th commit',
            'files': [],
            'parent_changeids': [6],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'4',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 7,
            'when_timestamp': epoch2datetime(SOMETIME + 7)
        }, {
            'author': u'bob',
            'branch': u'master',
            'category': u'cat',
            'changeid': 8,
            'codebase': u'',
            'comments': u'9th commit',
            'files': [],
            'parent_changeids': [5],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'3',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 8,
            'when_timestamp': epoch2datetime(SOMETIME + 8)
        }, {
            'author': u'franck',
            'branch': u'master',
            'category': u'cat',
            'changeid': 6,
            'codebase': u'',
            'comments': u'7th commit',
            'files': [],
            'parent_changeids': [4],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'3',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 6,
            'when_timestamp': epoch2datetime(SOMETIME + 6)
        }]
        expected_6thBuild = [{
            'author': u'bob',
            'branch': u'master',
            'category': u'cat',
            'changeid': 9,
            'codebase': u'',
            'comments': u'10th commit',
            'files': [],
            'parent_changeids': [3],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'2',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 9,
            'when_timestamp': epoch2datetime(SOMETIME + 9)
        }]
        expected_7thBuild = [{
            'author': u'bob',
            'branch': u'master',
            'category': u'cat',
            'changeid': 9,
            'codebase': u'',
            'comments': u'10th commit',
            'files': [],
            'parent_changeids': [3],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'2',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 9,
            'when_timestamp': epoch2datetime(SOMETIME + 9)
        }, {
            'author': u'bob',
            'branch': u'master',
            'category': u'cat',
            'changeid': 10,
            'codebase': u'',
            'comments': u'11th commit',
            'files': [],
            'parent_changeids': [9],
            'project': u'proj',
            'properties': {},
            'repository': u'repo',
            'revision': u'3',
            'revlink': u'http://vc/abcd',
            'sourcestampid': 10,
            'when_timestamp': epoch2datetime(SOMETIME + 10)
        }]

        # 1st build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(1))),
                         sorted(expected_1stBuild))
        # 2nd build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(2))),
                         sorted(expected_2ndBuild))
        # 3rd build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(3))),
                         sorted(expected_3rdBuild))
        # 4th build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(4))),
                         sorted(expected_4thBuild))
        # 5th build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(5))),
                         sorted(expected_5thBuild))
        # 6th build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(6))),
                         sorted(expected_6thBuild))
        # 7th build
        self.assertEqual(sorted((yield self.db.changes.getChangesForBuild(7))),
                         sorted(expected_7thBuild))
from buildbot.test.fake import fakedb
from buildbot.test.fake import fakemaster
from buildbot.test.util import endpoint
from buildbot.test.util import interfaces
from twisted.internet import defer
from twisted.trial import unittest

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.Buildslave(id=1, name=u'linux', info={}),
    fakedb.ConfiguredBuildslave(id=14013, buildslaveid=1,
                                buildermasterid=4013),
    fakedb.ConfiguredBuildslave(id=14014, buildslaveid=1,
                                buildermasterid=4014),
    fakedb.ConnectedBuildslave(id=113, masterid=13, buildslaveid=1),
    fakedb.Buildslave(id=2, name=u'windows', info={"a": "b"}),
    fakedb.ConfiguredBuildslave(id=24013, buildslaveid=2,
                                buildermasterid=4013),
    fakedb.ConfiguredBuildslave(id=24014, buildslaveid=2,
                                buildermasterid=4014),
    fakedb.ConfiguredBuildslave(id=24113, buildslaveid=2,
                                buildermasterid=4113),
    fakedb.ConnectedBuildslave(id=214, masterid=14, buildslaveid=2),
]
    def test_getSourceStampsForBuild_3CodeBases(self):
        rows = [
            fakedb.Master(id=88, name="bar"),
            fakedb.Buildslave(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",
                         buildslaveid=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)
 def setUp(self):
     self.setUpEndpoint()
     self.db.insertTestData([
         fakedb.Builder(id=77),
         fakedb.Buildslave(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,
                      buildslaveid=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
     ])
Exemple #7
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    backgroundData = [
        fakedb.Buildset(id=20),
        fakedb.BuildRequest(id=40, buildsetid=20, buildername='b1'),
        fakedb.BuildRequest(id=41, buildsetid=20, buildername='b1'),
        fakedb.BuildRequest(id=42, buildsetid=20, buildername='b2'),
        fakedb.Builder(id=77, name="b1"),
        fakedb.Builder(id=88, name="b2"),
        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)
    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)
        m.config.buildbotURL = "baseurl/"

        self.scheduler_a = a = FakeTriggerable(name='a')
        self.scheduler_b = b = FakeTriggerable(name='b')

        def allSchedulers():
            return [a, b]

        m.allSchedulers = allSchedulers

        a.brids = {'A': 11}
        b.brids = {'B': 22}

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

        m.db.insertTestData([
            fakedb.Master(id=9),
            fakedb.Buildset(id=2022),
            fakedb.Buildset(id=2011),
            fakedb.Buildslave(id=13, name="some:slave"),
            make_fake_br(11, "A"),
            make_fake_br(22, "B"),
            make_fake_build(11),
            make_fake_build(22),
        ])

        def getAllSourceStamps():
            return sourcestamps

        self.build.getAllSourceStamps = getAllSourceStamps

        def getAllGotRevisions():
            return got_revisions

        self.build.build_status.getAllGotRevisions = getAllGotRevisions

        self.exp_add_sourcestamp = None
        self.exp_a_trigger = None
        self.exp_b_trigger = None
        self.exp_added_urls = []
    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.Buildslave(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,
                         buildslaveid=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="slavename",
                                     value="sl"),
                fakedb.BuildProperty(buildid=_id,
                                     name="reason",
                                     value="because"),
            ])
        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))
Exemple #10
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)
Exemple #11
0
    def run_fake_summary_build(self, buildResults, finalResult, resultText,
                               verifiedScore):
        gsp = GerritStatusPush('host.example.com',
                               'username',
                               summaryCB=testSummaryCB)

        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

            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 = lambda prop: self.TEST_PROPS.get(prop)

            buildpairs.append((builder, build))

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

        self.run_prepare_gsp(gsp)
        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.BuildRequest(id=breqid,
                                    buildsetid=99,
                                    buildername=builder.name))
            fakedata.append(
                fakedb.Build(number=0,
                             buildrequestid=breqid,
                             masterid=92,
                             buildslaveid=13))
            breqid = breqid + 1

        gsp.master.db.insertTestData(fakedata)

        fakeSCR = Mock()
        gsp.sendCodeReview = fakeSCR

        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
                })
            fakeSCR.assert_called_once_with(self.TEST_PROJECT,
                                            self.TEST_REVISION, str(info),
                                            verifiedScore, 0)

        return d
    def setUp(self):
        authzcfg = authz.Authz(
            stringsMatcher=authz.
            fnmatchStrMatcher,  # simple matcher with '*' glob character
            # 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")
            ])
        self.users = dict(homer=dict(email="*****@*****.**"),
                          bond=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.Buildslave(id=13, name='sl'),
            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,
                         buildslaveid=13,
                         buildrequestid=82,
                         number=3),
            fakedb.Build(id=14,
                         builderid=77,
                         masterid=88,
                         buildslaveid=13,
                         buildrequestid=82,
                         number=4),
            fakedb.Build(id=15,
                         builderid=77,
                         masterid=88,
                         buildslaveid=13,
                         buildrequestid=82,
                         number=5),
        ])
    def testRebuildBuildrequest(self):
        self.master.db.insertTestData([
            fakedb.Builder(id=77, name='builder'),
            fakedb.Master(id=88),
            fakedb.Buildslave(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')
        })
Exemple #14
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_string="test",
                     started_at=TIME1),
        fakedb.Build(id=51,
                     buildrequestid=41,
                     number=6,
                     masterid=88,
                     builderid=88,
                     buildslaveid=13,
                     state_string="test",
                     started_at=TIME2),
        fakedb.Build(id=52,
                     buildrequestid=42,
                     number=7,
                     masterid=88,
                     builderid=77,
                     buildslaveid=13,
                     state_string="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_string': 'test',
            'results': None
        },
        51: {
            'id': 51,
            'buildrequestid': 41,
            'builderid': 88,
            'masterid': 88,
            'number': 6,
            'buildslaveid': 13,
            'started_at': epoch2datetime(TIME2),
            'complete_at': None,
            'state_string': '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_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,
                      complete=None):
            pass

    def test_signature_addBuild(self):
        @self.assertArgSpecMatches(self.db.builds.addBuild)
        def addBuild(self, builderid, buildrequestid, buildslaveid, 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, '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_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, '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_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, 'builddict', 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,
                                                   buildslaveid=13,
                                                   masterid=88,
                                                   state_string=u'test 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_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,
                         buildslaveid=13),
        ])
        id, number = yield self.db.builds.addBuild(builderid=77,
                                                   buildrequestid=41,
                                                   buildslaveid=13,
                                                   masterid=88,
                                                   state_string=u'test 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_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, '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_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, '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_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')})
Exemple #15
0
    def test_buildsetComplete_doesnt_send_email(self):
        fakeBuildMessage = Mock()
        mn = MailNotifier('*****@*****.**',
                          buildSetSummary=True,
                          mode=("failing", "warnings"),
                          builders=["Builder"])
        mn.buildMessage = fakeBuildMessage

        def fakeGetBuild(number):
            return build

        def fakeGetBuilder(buildername):
            if buildername == builder.name:
                return builder
            return None

        def fakeGetBuildRequests(self, bsid):
            return defer.succeed([{"buildername": "Builder", "brid": 1}])

        builder = Mock()
        builder.getBuild = fakeGetBuild
        builder.name = "Builder"

        build = FakeBuildStatus()
        build.results = SUCCESS
        build.finished = True
        build.reason = "testReason"
        build.getBuilder.return_value = builder
        build.getResults.return_value = build.results

        self.db = self.master.db
        self.db.insertTestData([
            fakedb.Master(id=92),
            fakedb.Buildslave(id=13, name='sl'),
            fakedb.Buildset(id=99, results=SUCCESS, reason="testReason"),
            fakedb.BuildRequest(id=11, buildsetid=99, buildername='Builder'),
            fakedb.Build(number=0,
                         buildrequestid=11,
                         buildslaveid=13,
                         masterid=92),
        ])
        mn.master = self.master

        self.status = Mock()
        mn.master_status = Mock()
        mn.master_status.getBuilder = fakeGetBuilder
        mn.buildMessageDict = Mock()
        mn.buildMessageDict.return_value = {
            "body": "body",
            "type": "text",
            "subject": "subject"
        }

        d = mn._buildsetComplete('buildset.99.complete',
                                 dict(bsid=99, result=FAILURE))

        @d.addCallback
        def check(_):
            self.assertFalse(fakeBuildMessage.called)

        return d
Exemple #16
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
Exemple #17
0
class Tests(interfaces.InterfaceTests):

    backgroundData = [
        fakedb.Buildslave(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,
                     buildslaveid=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""")),
        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', '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):
            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))
Exemple #18
0
class Tests(interfaces.InterfaceTests):

    backgroundData = [
        fakedb.Buildslave(id=47, name='linux'),
        fakedb.Buildset(id=20),
        fakedb.Builder(id=88, name='b1'),
        fakedb.BuildRequest(id=41, buildsetid=20, buildername='b1'),
        fakedb.Master(id=88),
        fakedb.Build(id=30,
                     buildrequestid=41,
                     number=7,
                     masterid=88,
                     builderid=88,
                     buildslaveid=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""")),
        fakedb.LogChunk(logid=201,
                        first_line=2,
                        last_line=4,
                        compressed=0,
                        content=textwrap.dedent("""\
                    line TWO
                    line 3
                    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"),
    ]

    def checkTestLogLines(self):
        expLines = [
            'line zero', 'line 1', 'line TWO', 'line 3', '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] + "\n"))
        # check overflow
        self.assertEqual((yield self.db.logs.getLogLines(201, 5, 20)),
                         "\n".join(expLines[5:7] + "\n"))

    # 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):
            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)
        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_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
        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 test_buildsetComplete_sends_email(self):
        fakeBuildMessage = Mock()
        mn = MailNotifier('*****@*****.**',
                          buildSetSummary=True,
                          mode=("failing", "passing", "warnings"),
                          builders=["Builder1", "Builder2"])

        mn.buildMessage = fakeBuildMessage

        builder1 = Mock()
        builder1.getBuild = lambda number: build1
        builder1.name = "Builder1"

        build1 = FakeBuildStatus()
        build1.results = FAILURE
        build1.finished = True
        build1.reason = "testReason"
        build1.getBuilder.return_value = builder1
        build1.getResults.return_value = build1.results

        builder2 = Mock()
        builder2.getBuild = lambda number: build2
        builder2.name = "Builder2"

        build2 = FakeBuildStatus()
        build2.results = FAILURE
        build2.finished = True
        build2.reason = "testReason"
        build2.getBuilder.return_value = builder1
        build2.getResults.return_value = build2.results

        def fakeGetBuilder(buildername):
            return {"Builder1": builder1, "Builder2": builder2}[buildername]

        self.db = self.master.db
        self.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='Builder1'),
            fakedb.Builder(id=81, name='Builder2'),
            fakedb.BuildRequest(id=11, buildsetid=99, builderid=80),
            fakedb.Build(number=0, buildrequestid=11, buildslaveid=13,
                         masterid=92),
            fakedb.BuildRequest(id=12, buildsetid=99, builderid=81),
            fakedb.Build(number=0, buildrequestid=12, buildslaveid=13,
                         masterid=92),
        ])
        self.setupMailNotifier(mn)
        mn.master_status.getBuilder = fakeGetBuilder
        mn.buildMessageDict = Mock()
        mn.buildMessageDict.return_value = {"body": "body", "type": "text",
                                            "subject": "subject"}

        d = mn._buildsetComplete('buildset.99.complete',
                                 dict(bsid=99, result=FAILURE))

        @d.addCallback
        def check(_):
            fakeBuildMessage.assert_called_with(
                "(whole buildset)",
                [build1, build2], SUCCESS)
        return d
Exemple #20
0
    def setupBuildResults(self, buildResults, finalResult):
        # 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.Buildslave(id=13, name='sl'),
            fakedb.Builder(id=79, name='Builder0'),
            fakedb.Builder(id=80, name='Builder1'),
            fakedb.Buildset(id=98, results=finalResult, reason="testReason1"),
            fakedb.BuildsetSourceStamp(buildsetid=98, sourcestampid=234),
            fakedb.SourceStamp(id=234),
            fakedb.Change(changeid=13,
                          branch=u'master',
                          revision=u'9283',
                          author='me@foo',
                          repository=u'https://...',
                          codebase=u'cbgerrit',
                          project=u'world-domination',
                          sourcestampid=234),
        ])
        i = 0
        for results in 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,
                             buildslaveid=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="slavename",
                                     value="sl"),
                fakedb.BuildProperty(buildid=20 + i,
                                     name="reason",
                                     value="because"),
            ])
            for k, v in iteritems(self.TEST_PROPS):
                self.db.insertTestData(
                    [fakedb.BuildProperty(buildid=20 + i, name=k, value=v)])
            i += 1
        res = yield utils.getDetailsForBuildset(self.master,
                                                98,
                                                wantProperties=True)
        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 test_getCustomMesgData_single_sourcestamp(self):
        self.passedAttrs = {}

        def fakeCustomMessage(attrs):
            self.passedAttrs = attrs
            return ("", "")

        mn = MailNotifier('*****@*****.**',
                          buildSetSummary=True,
                          mode=("failing", "passing", "warnings"),
                          builders=["Builder"])

        def fakeBuildMessage(name, builds, results):
            for build in builds:
                mn.buildMessageDict(name=build.getBuilder().name,
                                    build=build, results=build.results)

        mn.buildMessage = fakeBuildMessage
        mn.customMesg = fakeCustomMessage

        def fakeGetBuild(number):
            return build

        def fakeGetBuilder(buildername):
            if buildername == builder.name:
                return builder
            return None

        def fakeGetBuildRequests(self, bsid):
            return defer.succeed([{"buildername": "Builder", "brid": 1}])

        self.db = self.master.db
        self.db.insertTestData([
            fakedb.Master(id=22),
            fakedb.Buildslave(id=13, name='sl'),
            fakedb.Builder(id=80, name='Builder'),
            fakedb.Buildset(id=99, results=SUCCESS, reason="testReason"),
            fakedb.BuildRequest(id=11, buildsetid=99, builderid=80),
            fakedb.Build(number=0, buildrequestid=11, buildslaveid=13,
                         masterid=22),
        ])
        self.setupMailNotifier(mn)

        builder = Mock()
        builder.getBuild = fakeGetBuild
        builder.name = "Builder"

        build = FakeBuildStatus()
        build.results = FAILURE
        build.finished = True
        build.reason = "testReason"
        build.getLogs.return_value = []
        build.getBuilder.return_value = builder
        build.getResults.return_value = build.results

        mn.master_status.getBuilder = fakeGetBuilder

        ss1 = FakeSource(revision='111222', codebase='testlib1')
        build.getSourceStamps.return_value = [ss1]

        d = mn._buildsetComplete('buildset.99.complete',
                                 dict(bsid=99, result=FAILURE))

        @d.addCallback
        def check(_):
            self.assertTrue('builderName' in self.passedAttrs,
                            "No builderName entry found in attrs")
            self.assertEqual(self.passedAttrs['builderName'], 'Builder')
            self.assertTrue('revision' in self.passedAttrs,
                            "No revision entry found in attrs")
            self.assertTrue(isinstance(self.passedAttrs['revision'], str))
            self.assertEqual(self.passedAttrs['revision'], '111222')
        return d
Exemple #22
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    backgroundData = [
        fakedb.Buildslave(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,
                     buildslaveid=47),
        fakedb.Build(id=31,
                     buildrequestid=41,
                     number=8,
                     masterid=88,
                     builderid=88,
                     buildslaveid=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)
        # order is not garanteed though
        self.assertEqual(sorted(stepdict['urls']), [{
            'name': u'foo',
            'url': u'bar'
        }, {
            'name': u'foo2',
            'url': u'bar2'
        }])

    @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 do_test_sendToInterestedUsers(self, lookup=None, extraRecipients=[],
                                      sendToInterestedUsers=True,
                                      exp_called_with=None, exp_TO=None,
                                      exp_CC=None):
        from email.message import Message
        m = Message()

        mn = MailNotifier(fromaddr='*****@*****.**',
                          lookup=lookup,
                          sendToInterestedUsers=sendToInterestedUsers,
                          extraRecipients=extraRecipients)
        mn.sendMessage = Mock()

        def fakeGetBuild(number):
            return build

        def fakeGetBuilder(buildername):
            if buildername == builder.name:
                return builder
            return None

        def fakeGetBuildRequests(self, bsid):
            return defer.succeed([{"buildername": "Builder", "brid": 1}])

        builder = Mock()
        builder.getBuild = fakeGetBuild
        builder.name = "Builder"

        build = FakeBuildStatus(name="build")
        build.result = FAILURE
        build.finished = True
        build.reason = "testReason"
        build.builder = builder

        def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
                            patches=None, logs=None):
            # only concerned with m['To'] and m['CC'], which are added in
            # _got_recipients later
            return defer.succeed(m)
        mn.createEmail = fakeCreateEmail

        self.db = self.master.db
        self.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='Builder'),
            fakedb.BuildRequest(id=11, buildsetid=99, builderid=80),
            fakedb.Build(number=0, buildrequestid=11, masterid=92,
                         buildslaveid=13),
            fakedb.Change(changeid=9123),
            fakedb.ChangeUser(changeid=9123, uid=1),
            fakedb.User(uid=1, identifier="tdurden"),
            fakedb.UserInfo(uid=1, attr_type='svn', attr_data="tdurden"),
            fakedb.UserInfo(uid=1, attr_type='email',
                            attr_data="*****@*****.**")
        ])

        # fake sourcestamp with relevant user bits
        ss = Mock(name="sourcestamp")
        fake_change = Mock(name="change")
        fake_change.number = 9123
        ss.changes = [fake_change]
        ss.patch, ss.addPatch = None, None

        def fakeGetSSlist():
            return [ss]
        build.getSourceStamps = fakeGetSSlist

        def _getInterestedUsers():
            # 'narrator' in this case is the owner, which tests the lookup
            return ["narrator"]
        build.getInterestedUsers = _getInterestedUsers

        def _getResponsibleUsers():
            return ["Big Bob <*****@*****.**>"]
        build.getResponsibleUsers = _getResponsibleUsers

        self.setupMailNotifier(mn)
        mn.buildMessageDict = Mock()
        mn.master_status.getBuilder = fakeGetBuilder
        mn.buildMessageDict.return_value = {"body": "body", "type": "text"}

        mn.buildMessage(builder.name, [build], build.result)
        mn.sendMessage.assert_called_with(m, exp_called_with)
        self.assertEqual(m['To'], exp_TO)
        self.assertEqual(m['CC'], exp_CC)
Exemple #24
0
    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.BuildRequest(id=10, buildsetid=99, buildername="Builder0"),
            fakedb.Build(number=0,
                         buildrequestid=10,
                         masterid=92,
                         buildslaveid=13),
            fakedb.BuildRequest(id=11, buildsetid=99, buildername="Builder1"),
            fakedb.Build(number=0,
                         buildrequestid=11,
                         masterid=92,
                         buildslaveid=13),
            fakedb.BuildRequest(id=12, buildsetid=99, buildername="Builder2"),
            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
    def test_getChangesForBuild(self):
        rows = [
            fakedb.Master(id=88, name="bar"),
            fakedb.Buildslave(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 codebase_ss.iteritems():
                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",
                             buildslaveid=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'])