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
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 ])
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))
class Tests(interfaces.InterfaceTests): # common sample data baseRows = [ fakedb.Master(id=10, name='m10'), fakedb.Master(id=11, name='m11'), fakedb.Builder(id=20, name=u'a'), fakedb.Builder(id=21, name=u'b'), fakedb.Builder(id=22, name=u'c'), fakedb.Buildslave(id=30, name='zero'), fakedb.Buildslave(id=31, name='one'), ] multipleMasters = [ fakedb.BuilderMaster(id=12, builderid=20, masterid=10), fakedb.BuilderMaster(id=13, builderid=21, masterid=10), fakedb.BuilderMaster(id=14, builderid=20, masterid=11), fakedb.BuilderMaster(id=15, builderid=22, masterid=11), fakedb.BuilderMaster(id=16, builderid=22, masterid=10), fakedb.ConfiguredBuildslave( id=3012, buildslaveid=30, buildermasterid=12), fakedb.ConfiguredBuildslave( id=3013, buildslaveid=30, buildermasterid=13), fakedb.ConfiguredBuildslave( id=3014, buildslaveid=30, buildermasterid=14), fakedb.ConfiguredBuildslave( id=3114, buildslaveid=31, buildermasterid=14), fakedb.ConfiguredBuildslave( id=3115, buildslaveid=31, buildermasterid=15), fakedb.ConnectedBuildslave(id=3010, buildslaveid=30, masterid=10), fakedb.ConnectedBuildslave(id=3111, buildslaveid=31, masterid=11), ] # sample buildslave data, with id's avoiding the postgres id sequence BOGUS_NAME = 'bogus' BS1_NAME, BS1_ID, BS1_INFO = 'bs1', 100, {'a': 1} buildslave1_rows = [ fakedb.Buildslave(id=BS1_ID, name=BS1_NAME, info=BS1_INFO), ] BS2_NAME, BS2_ID, BS2_INFO = 'bs2', 200, {'a': 1, 'b': 2} buildslave2_rows = [ fakedb.Buildslave(id=BS2_ID, name=BS2_NAME, info=BS2_INFO), ] # tests def test_signature_findBuildslaveId(self): @self.assertArgSpecMatches(self.db.buildslaves.findBuildslaveId) def findBuildslaveId(self, name): pass def test_signature_getBuildslave(self): @self.assertArgSpecMatches(self.db.buildslaves.getBuildslave) def getBuildslave(self, buildslaveid=None, name=None, masterid=None, builderid=None): pass def test_signature_getBuildslaves(self): @self.assertArgSpecMatches(self.db.buildslaves.getBuildslaves) def getBuildslaves(self, masterid=None, builderid=None): pass def test_signature_buildslaveConnected(self): @self.assertArgSpecMatches(self.db.buildslaves.buildslaveConnected) def buildslaveConnected(self, buildslaveid, masterid, slaveinfo): pass def test_signature_buildslaveDisconnected(self): @self.assertArgSpecMatches(self.db.buildslaves.buildslaveDisconnected) def buildslaveDisconnected(self, buildslaveid, masterid): pass def test_signature_buildslaveConfigured(self): @self.assertArgSpecMatches(self.db.buildslaves.buildslaveConfigured) def buildslaveConfigured(self, buildslaveid, masterid, builderids): pass def test_signature_deconfigureAllBuidslavesForMaster(self): @self.assertArgSpecMatches(self.db.buildslaves.deconfigureAllBuidslavesForMaster) def deconfigureAllBuidslavesForMaster(self, masterid): pass @defer.inlineCallbacks def test_findBuildslaveId_insert(self): id = yield self.db.buildslaves.findBuildslaveId(name=u"xyz") bslave = yield self.db.buildslaves.getBuildslave(buildslaveid=id) self.assertEqual(bslave['name'], 'xyz') self.assertEqual(bslave['slaveinfo'], {}) @defer.inlineCallbacks def test_findBuildslaveId_existing(self): yield self.insertTestData(self.baseRows) id = yield self.db.buildslaves.findBuildslaveId(name=u"one") self.assertEqual(id, 31) @defer.inlineCallbacks def test_getBuildslave_no_such(self): yield self.insertTestData(self.baseRows) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=99) self.assertEqual(slavedict, None) @defer.inlineCallbacks def test_getBuildslave_by_name_no_such(self): yield self.insertTestData(self.baseRows) slavedict = yield self.db.buildslaves.getBuildslave(name='NOSUCH') self.assertEqual(slavedict, None) @defer.inlineCallbacks def test_getBuildslave_not_configured(self): yield self.insertTestData(self.baseRows) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, connected_to=[], configured_on=[])) @defer.inlineCallbacks def test_getBuildslave_connected_not_configured(self): yield self.insertTestData(self.baseRows + [ # the slave is connected to this master, but not configured. # weird, but the DB should represent it. fakedb.Buildslave(id=32, name='two'), fakedb.ConnectedBuildslave(buildslaveid=32, masterid=11), ]) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=32) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=32, name='two', slaveinfo={'a': 'b'}, connected_to=[11], configured_on=[])) @defer.inlineCallbacks def test_getBuildslave_multiple_connections(self): yield self.insertTestData(self.baseRows + [ # the slave is connected to two masters at once. # weird, but the DB should represent it. fakedb.Buildslave(id=32, name='two'), fakedb.ConnectedBuildslave(buildslaveid=32, masterid=10), fakedb.ConnectedBuildslave(buildslaveid=32, masterid=11), fakedb.BuilderMaster(id=24, builderid=20, masterid=10), fakedb.BuilderMaster(id=25, builderid=20, masterid=11), fakedb.ConfiguredBuildslave(buildslaveid=32, buildermasterid=24), fakedb.ConfiguredBuildslave(buildslaveid=32, buildermasterid=25), ]) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=32) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=32, name='two', slaveinfo={'a': 'b'}, connected_to=[10, 11], configured_on=[ {'builderid': 20, 'masterid': 10}, {'builderid': 20, 'masterid': 11}, ])) @defer.inlineCallbacks def test_getBuildslave_by_name_not_configured(self): yield self.insertTestData(self.baseRows) slavedict = yield self.db.buildslaves.getBuildslave(name='zero') validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, connected_to=[], configured_on=[])) @defer.inlineCallbacks def test_getBuildslave_not_connected(self): yield self.insertTestData(self.baseRows + [ fakedb.BuilderMaster(id=12, builderid=20, masterid=10), fakedb.ConfiguredBuildslave(buildslaveid=30, buildermasterid=12), ]) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=[ {'masterid': 10, 'builderid': 20}], connected_to=[])) @defer.inlineCallbacks def test_getBuildslave_connected(self): yield self.insertTestData(self.baseRows + [ fakedb.BuilderMaster(id=12, builderid=20, masterid=10), fakedb.ConfiguredBuildslave(buildslaveid=30, buildermasterid=12), fakedb.ConnectedBuildslave(buildslaveid=30, masterid=10), ]) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=[ {'masterid': 10, 'builderid': 20}], connected_to=[10])) @defer.inlineCallbacks def test_getBuildslave_with_multiple_masters(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30) validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 10, 'builderid': 20}, {'masterid': 10, 'builderid': 21}, {'masterid': 11, 'builderid': 20}, ]), connected_to=[10])) @defer.inlineCallbacks def test_getBuildslave_with_multiple_masters_builderid(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30, builderid=20) validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 10, 'builderid': 20}, {'masterid': 11, 'builderid': 20}, ]), connected_to=[10])) @defer.inlineCallbacks def test_getBuildslave_with_multiple_masters_masterid(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30, masterid=11) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=[ {'masterid': 11, 'builderid': 20}, ], connected_to=[])) @defer.inlineCallbacks def test_getBuildslave_with_multiple_masters_builderid_masterid(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedict = yield self.db.buildslaves.getBuildslave(buildslaveid=30, builderid=20, masterid=11) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=[ {'masterid': 11, 'builderid': 20}, ], connected_to=[])) @defer.inlineCallbacks def test_getBuildslave_by_name_with_multiple_masters_builderid_masterid(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedict = yield self.db.buildslaves.getBuildslave(name='zero', builderid=20, masterid=11) validation.verifyDbDict(self, 'buildslavedict', slavedict) self.assertEqual(slavedict, dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=[ {'masterid': 11, 'builderid': 20}, ], connected_to=[])) @defer.inlineCallbacks def test_getBuildslaves_no_config(self): yield self.insertTestData(self.baseRows) slavedicts = yield self.db.buildslaves.getBuildslaves() [validation.verifyDbDict(self, 'buildslavedict', slavedict) for slavedict in slavedicts] self.assertEqual(sorted(slavedicts), sorted([ dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=[], connected_to=[]), dict(id=31, name='one', slaveinfo={'a': 'b'}, configured_on=[], connected_to=[]), ])) @defer.inlineCallbacks def test_getBuildslaves_with_config(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedicts = yield self.db.buildslaves.getBuildslaves() for slavedict in slavedicts: validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(sorted(slavedicts), sorted([ dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 10, 'builderid': 20}, {'masterid': 10, 'builderid': 21}, {'masterid': 11, 'builderid': 20}, ]), connected_to=[10]), dict(id=31, name='one', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 11, 'builderid': 20}, {'masterid': 11, 'builderid': 22}, ]), connected_to=[11]), ])) @defer.inlineCallbacks def test_getBuildslaves_empty(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedicts = yield self.db.buildslaves.getBuildslaves(masterid=11, builderid=21) for slavedict in slavedicts: validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(sorted(slavedicts), []) @defer.inlineCallbacks def test_getBuildslaves_with_config_builderid(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedicts = yield self.db.buildslaves.getBuildslaves(builderid=20) for slavedict in slavedicts: validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(sorted(slavedicts), sorted([ dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 10, 'builderid': 20}, {'masterid': 11, 'builderid': 20}, ]), connected_to=[10]), dict(id=31, name='one', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 11, 'builderid': 20}, ]), connected_to=[11]), ])) @defer.inlineCallbacks def test_getBuildslaves_with_config_masterid_10(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedicts = yield self.db.buildslaves.getBuildslaves(masterid=10) for slavedict in slavedicts: validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(sorted(slavedicts), sorted([ dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 10, 'builderid': 20}, {'masterid': 10, 'builderid': 21}, ]), connected_to=[10]), ])) @defer.inlineCallbacks def test_getBuildslaves_with_config_masterid_11(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedicts = yield self.db.buildslaves.getBuildslaves(masterid=11) for slavedict in slavedicts: validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(sorted(slavedicts), sorted([ dict(id=30, name='zero', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 11, 'builderid': 20}, ]), connected_to=[]), dict(id=31, name='one', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 11, 'builderid': 20}, {'masterid': 11, 'builderid': 22}, ]), connected_to=[11]), ])) @defer.inlineCallbacks def test_getBuildslaves_with_config_masterid_11_builderid_22(self): yield self.insertTestData(self.baseRows + self.multipleMasters) slavedicts = yield self.db.buildslaves.getBuildslaves( masterid=11, builderid=22) for slavedict in slavedicts: validation.verifyDbDict(self, 'buildslavedict', slavedict) slavedict['configured_on'].sort() self.assertEqual(sorted(slavedicts), sorted([ dict(id=31, name='one', slaveinfo={'a': 'b'}, configured_on=sorted([ {'masterid': 11, 'builderid': 22}, ]), connected_to=[11]), ])) @defer.inlineCallbacks def test_buildslaveConnected_existing(self): yield self.insertTestData(self.baseRows + self.buildslave1_rows) NEW_INFO = {'other': [1, 2, 3]} yield self.db.buildslaves.buildslaveConnected( buildslaveid=self.BS1_ID, masterid=11, slaveinfo=NEW_INFO) bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID) self.assertEqual(bs, { 'id': self.BS1_ID, 'name': self.BS1_NAME, 'slaveinfo': NEW_INFO, 'configured_on': [], 'connected_to': [11]}) @defer.inlineCallbacks def test_buildslaveConnected_already_connected(self): yield self.insertTestData(self.baseRows + self.buildslave1_rows + [ fakedb.ConnectedBuildslave(id=888, buildslaveid=self.BS1_ID, masterid=11), ]) yield self.db.buildslaves.buildslaveConnected( buildslaveid=self.BS1_ID, masterid=11, slaveinfo={}) bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID) self.assertEqual(bs['connected_to'], [11]) @defer.inlineCallbacks def test_buildslaveDisconnected(self): yield self.insertTestData(self.baseRows + self.buildslave1_rows + [ fakedb.ConnectedBuildslave(id=888, buildslaveid=self.BS1_ID, masterid=10), fakedb.ConnectedBuildslave(id=889, buildslaveid=self.BS1_ID, masterid=11), ]) yield self.db.buildslaves.buildslaveDisconnected( buildslaveid=self.BS1_ID, masterid=11) bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID) self.assertEqual(bs['connected_to'], [10]) @defer.inlineCallbacks def test_buildslaveDisconnected_already_disconnected(self): yield self.insertTestData(self.baseRows + self.buildslave1_rows) yield self.db.buildslaves.buildslaveDisconnected( buildslaveid=self.BS1_ID, masterid=11) bs = yield self.db.buildslaves.getBuildslave(self.BS1_ID) self.assertEqual(bs['connected_to'], []) @defer.inlineCallbacks def test_buildslaveConfigured(self): yield self.insertTestData(self.baseRows + self.multipleMasters) # should remove builder 21, and add 22 yield self.db.buildslaves.deconfigureAllBuidslavesForMaster(masterid=10) yield self.db.buildslaves.buildslaveConfigured( buildslaveid=30, masterid=10, builderids=[20, 22]) bs = yield self.db.buildslaves.getBuildslave(30) self.assertEqual(sorted(bs['configured_on']), sorted([ {'builderid': 20, 'masterid': 11}, {'builderid': 20, 'masterid': 10}, {'builderid': 22, 'masterid': 10}])) @defer.inlineCallbacks def test_buildslaveConfiguredTwice(self): yield self.insertTestData(self.baseRows + self.multipleMasters) # should remove builder 21, and add 22 yield self.db.buildslaves.deconfigureAllBuidslavesForMaster(masterid=10) yield self.db.buildslaves.buildslaveConfigured( buildslaveid=30, masterid=10, builderids=[20, 22]) # configure again (should eat the duplicate insertion errors) yield self.db.buildslaves.buildslaveConfigured( buildslaveid=30, masterid=10, builderids=[20, 21, 22]) bs = yield self.db.buildslaves.getBuildslave(30) self.assertEqual(sorted(bs['configured_on']), sorted([ {'builderid': 20, 'masterid': 11}, {'builderid': 20, 'masterid': 10}, {'builderid': 21, 'masterid': 10}, {'builderid': 22, 'masterid': 10}])) @defer.inlineCallbacks def test_nothingConfigured(self): yield self.insertTestData(self.baseRows + self.multipleMasters) # should remove builder 21, and add 22 yield self.db.buildslaves.deconfigureAllBuidslavesForMaster(masterid=10) yield self.db.buildslaves.buildslaveConfigured( buildslaveid=30, masterid=10, builderids=[]) # should only keep builder for master 11 bs = yield self.db.buildslaves.getBuildslave(30) self.assertEqual(sorted(bs['configured_on']), sorted([ {'builderid': 20, 'masterid': 11}])) @defer.inlineCallbacks def test_deconfiguredAllSlaves(self): yield self.insertTestData(self.baseRows + self.multipleMasters) res = yield self.db.buildslaves.getBuildslaves(masterid=11) self.assertEqual(len(res), 2) # should remove all slave configured for masterid 11 yield self.db.buildslaves.deconfigureAllBuidslavesForMaster(masterid=11) res = yield self.db.buildslaves.getBuildslaves(masterid=11) self.assertEqual(len(res), 0)
def 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') })
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')})
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
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
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))
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
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
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)
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'])