From c1cb11a5d0377e42766c8d79b32edb2545ec62e9 Mon Sep 17 00:00:00 2001 From: warner Date: Sun, 30 Sep 2007 01:46:34 +0100 Subject: [PATCH] bonsaipoller: apply bugfixes from the mozilla folks. Closes #61. --- ChangeLog | 7 +++++++ buildbot/changes/bonsaipoller.py | 22 +++++++++++----------- buildbot/test/test_bonsaipoller.py | 19 +++++++++---------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index efcde2c..8a02985 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-09-29 Brian Warner + + * buildbot/changes/bonsaipoller.py: apply changes from the Mozilla + team, to fix some bugs and avoid the use of blocking urlopen(). + closes #61. + * buildbot/test/test_bonsaipoller.py: same + 2007-09-28 Brian Warner * buildbot/buildslave.py (BuildSlave): add notify_on_missing= diff --git a/buildbot/changes/bonsaipoller.py b/buildbot/changes/bonsaipoller.py index 7a3f5c7..8c3bc5b 100644 --- a/buildbot/changes/bonsaipoller.py +++ b/buildbot/changes/bonsaipoller.py @@ -1,10 +1,10 @@ import time -from urllib import urlopen from xml.dom import minidom from twisted.python import log, failure -from twisted.internet import defer, reactor +from twisted.internet import reactor from twisted.internet.task import LoopingCall +from twisted.web.client import getPage from buildbot.changes import base, changes @@ -64,14 +64,12 @@ class FileNode: class BonsaiParser: """I parse the XML result from a bonsai cvsquery.""" - def __init__(self, bonsaiQuery): + def __init__(self, data): try: # this is a fix for non-ascii characters - # readlines() + join is being used because read() is not guaranteed - # to work. because bonsai does not give us an encoding to work with + # because bonsai does not give us an encoding to work with # it impossible to be 100% sure what to decode it as but latin1 covers # the broadest base - data = "".join(bonsaiQuery.readlines()) data = data.decode("latin1") data = data.encode("ascii", "replace") self.dom = minidom.parseString(data) @@ -148,7 +146,10 @@ class BonsaiParser: elif len(logs) > 1: raise InvalidResultError("Multiple logs present") - return logs[0].firstChild.data + # catch empty check-in comments + if logs[0].firstChild: + return logs[0].firstChild.data + return '' def _getWho(self): """Returns the e-mail address of the commiter""" @@ -284,10 +285,9 @@ class BonsaiPoller(base.ChangeSource): self.lastPoll = time.time() # get the page, in XML format - return defer.maybeDeferred(urlopen, url) + return getPage(url, timeout=self.pollInterval) def _process_changes(self, query): - files = [] try: bp = BonsaiParser(query) result = bp.getData() @@ -298,8 +298,8 @@ class BonsaiPoller(base.ChangeSource): return for cinode in result.nodes: - for file in cinode.files: - files.append(file.filename+' (revision '+file.revision+')') + files = [file.filename + ' (revision '+file.revision+')' + for file in cinode.files] c = changes.Change(who = cinode.who, files = files, comments = cinode.log, diff --git a/buildbot/test/test_bonsaipoller.py b/buildbot/test/test_bonsaipoller.py index b8ca811..666b840 100644 --- a/buildbot/test/test_bonsaipoller.py +++ b/buildbot/test/test_bonsaipoller.py @@ -4,7 +4,6 @@ from twisted.trial import unittest from buildbot.changes.bonsaipoller import FileNode, CiNode, BonsaiResult, \ BonsaiParser, BonsaiPoller, InvalidResultError, EmptyResult -from StringIO import StringIO from copy import deepcopy import re @@ -116,7 +115,7 @@ class FakeBonsaiPoller(BonsaiPoller): class TestBonsaiPoller(unittest.TestCase): def testFullyFormedResult(self): - br = BonsaiParser(StringIO(goodUnparsedResult)) + br = BonsaiParser(goodUnparsedResult) result = br.getData() # make sure the result is a BonsaiResult self.failUnless(isinstance(result, BonsaiResult)) @@ -126,49 +125,49 @@ class TestBonsaiPoller(unittest.TestCase): def testBadUnparsedResult(self): try: - BonsaiParser(StringIO(badUnparsedResult)) + BonsaiParser(badUnparsedResult) self.fail(badResultMsgs["badUnparsedResult"]) except InvalidResultError: pass def testInvalidDateResult(self): try: - BonsaiParser(StringIO(invalidDateResult)) + BonsaiParser(invalidDateResult) self.fail(badResultMsgs["invalidDateResult"]) except InvalidResultError: pass def testMissingRevisionResult(self): try: - BonsaiParser(StringIO(missingRevisionResult)) + BonsaiParser(missingRevisionResult) self.fail(badResultMsgs["missingRevisionResult"]) except InvalidResultError: pass def testMissingFilenameResult(self): try: - BonsaiParser(StringIO(missingFilenameResult)) + BonsaiParser(missingFilenameResult) self.fail(badResultMsgs["missingFilenameResult"]) except InvalidResultError: pass def testDuplicateLogResult(self): try: - BonsaiParser(StringIO(duplicateLogResult)) + BonsaiParser(duplicateLogResult) self.fail(badResultMsgs["duplicateLogResult"]) except InvalidResultError: pass def testDuplicateFilesResult(self): try: - BonsaiParser(StringIO(duplicateFilesResult)) + BonsaiParser(duplicateFilesResult) self.fail(badResultMsgs["duplicateFilesResult"]) except InvalidResultError: pass def testMissingCiResult(self): try: - BonsaiParser(StringIO(missingCiResult)) + BonsaiParser(missingCiResult) self.fail(badResultMsgs["missingCiResult"]) except EmptyResult: pass @@ -177,6 +176,6 @@ class TestBonsaiPoller(unittest.TestCase): "Make sure a change is not submitted if the BonsaiParser fails" poller = FakeBonsaiPoller() lastChangeBefore = poller.lastChange - poller._process_changes(StringIO(badUnparsedResult)) + poller._process_changes(badUnparsedResult) # self.lastChange will not be updated if the change was not submitted self.failUnlessEqual(lastChangeBefore, poller.lastChange) -- 2.11.4.GIT