1 # -*- test-case-name: buildbot.test.test_bonsaipoller -*-
3 from twisted
.trial
import unittest
4 from buildbot
.changes
.bonsaipoller
import FileNode
, CiNode
, BonsaiResult
, \
5 BonsaiParser
, BonsaiPoller
, InvalidResultError
, EmptyResult
7 from copy
import deepcopy
10 log1
= "Add Bug 338541a"
11 who1
= "sar@gmail.com"
13 log2
= "bug 357427 add static ctor/dtor methods"
14 who2
= "aarrg@ooacm.org"
16 log3
= "Testing log #3 lbah blah"
17 who3
= "huoents@hueont.net"
20 file1
= "mozilla/testing/mochitest/tests/index.html"
22 file2
= "mozilla/testing/mochitest/tests/test_bug338541.xhtml"
24 file3
= "mozilla/xpcom/threads/nsAutoLock.cpp"
26 file4
= "mozilla/xpcom/threads/nsAutoLock.h"
28 file5
= "mozilla/xpcom/threads/test.cpp"
32 files
.append(FileNode(rev1
,file1
))
33 nodes
.append(CiNode(log1
, who1
, date1
, files
))
36 files
.append(FileNode(rev2
, file2
))
37 files
.append(FileNode(rev3
, file3
))
38 nodes
.append(CiNode(log2
, who2
, date2
, files
))
40 nodes
.append(CiNode(log3
, who3
, date3
, []))
42 goodParsedResult
= BonsaiResult(nodes
)
44 goodUnparsedResult
= """\
47 <ci who="%s" date="%d">
53 <ci who="%s" date="%d">
60 <ci who="%s" date="%d">
66 """ % (who1
, date1
, log1
, rev1
, file1
,
67 who2
, date2
, log2
, rev2
, file2
, rev3
, file3
,
70 badUnparsedResult
= deepcopy(goodUnparsedResult
)
71 badUnparsedResult
= badUnparsedResult
.replace("</queryResults>", "")
73 invalidDateResult
= deepcopy(goodUnparsedResult
)
74 invalidDateResult
= invalidDateResult
.replace(str(date1
), "foobar")
76 missingRevisionResult
= deepcopy(goodUnparsedResult
)
77 missingRevisionResult
= missingRevisionResult
.replace("rev=\""+rev3
+"\"", "")
79 missingFilenameResult
= deepcopy(goodUnparsedResult
)
80 missingFilenameResult
= missingFilenameResult
.replace(file2
, "")
82 duplicateLogResult
= deepcopy(goodUnparsedResult
)
83 duplicateLogResult
= re
.sub("<log>"+log1
+"</log>",
84 "<log>blah</log><log>blah</log>",
87 duplicateFilesResult
= deepcopy(goodUnparsedResult
)
88 duplicateFilesResult
= re
.sub("<files>\s*</files>",
89 "<files></files><files></files>",
92 missingCiResult
= deepcopy(goodUnparsedResult
)
93 r
= re
.compile("<ci.*</ci>", re
.DOTALL | re
.MULTILINE
)
94 missingCiResult
= re
.sub(r
, "", missingCiResult
)
96 badResultMsgs
= { 'badUnparsedResult':
97 "BonsaiParser did not raise an exception when given a bad query",
99 "BonsaiParser did not raise an exception when given an invalid date",
100 'missingRevisionResult':
101 "BonsaiParser did not raise an exception when a revision was missing",
102 'missingFilenameResult':
103 "BonsaiParser did not raise an exception when a filename was missing",
104 'duplicateLogResult':
105 "BonsaiParser did not raise an exception when there was two <log> tags",
106 'duplicateFilesResult':
107 "BonsaiParser did not raise an exception when there was two <files> tags",
109 "BonsaiParser did not raise an exception when there was no <ci> tags"
112 noCheckinMsgResult
= """\
113 <?xml version="1.0"?>
115 <ci who="johndoe@domain.tld" date="12345678">
118 <f rev="1.1">first/file.ext</f>
121 <ci who="johndoe@domain.tld" date="12345678">
124 <f rev="1.2">second/file.ext</f>
127 <ci who="johndoe@domain.tld" date="12345678">
130 <f rev="1.3">third/file.ext</f>
136 noCheckinMsgRef
= [dict(filename
="first/file.ext",
138 dict(filename
="second/file.ext",
140 dict(filename
="third/file.ext",
143 class FakeBonsaiPoller(BonsaiPoller
):
145 BonsaiPoller
.__init
__(self
, "fake url", "fake module", "fake branch")
147 class TestBonsaiPoller(unittest
.TestCase
):
148 def testFullyFormedResult(self
):
149 br
= BonsaiParser(goodUnparsedResult
)
150 result
= br
.getData()
151 # make sure the result is a BonsaiResult
152 self
.failUnless(isinstance(result
, BonsaiResult
))
153 # test for successful parsing
154 self
.failUnlessEqual(goodParsedResult
, result
,
155 "BonsaiParser did not return the expected BonsaiResult")
157 def testBadUnparsedResult(self
):
159 BonsaiParser(badUnparsedResult
)
160 self
.fail(badResultMsgs
["badUnparsedResult"])
161 except InvalidResultError
:
164 def testInvalidDateResult(self
):
166 BonsaiParser(invalidDateResult
)
167 self
.fail(badResultMsgs
["invalidDateResult"])
168 except InvalidResultError
:
171 def testMissingRevisionResult(self
):
173 BonsaiParser(missingRevisionResult
)
174 self
.fail(badResultMsgs
["missingRevisionResult"])
175 except InvalidResultError
:
178 def testMissingFilenameResult(self
):
180 BonsaiParser(missingFilenameResult
)
181 self
.fail(badResultMsgs
["missingFilenameResult"])
182 except InvalidResultError
:
185 def testDuplicateLogResult(self
):
187 BonsaiParser(duplicateLogResult
)
188 self
.fail(badResultMsgs
["duplicateLogResult"])
189 except InvalidResultError
:
192 def testDuplicateFilesResult(self
):
194 BonsaiParser(duplicateFilesResult
)
195 self
.fail(badResultMsgs
["duplicateFilesResult"])
196 except InvalidResultError
:
199 def testMissingCiResult(self
):
201 BonsaiParser(missingCiResult
)
202 self
.fail(badResultMsgs
["missingCiResult"])
206 def testChangeNotSubmitted(self
):
207 "Make sure a change is not submitted if the BonsaiParser fails"
208 poller
= FakeBonsaiPoller()
209 lastChangeBefore
= poller
.lastChange
210 poller
._process
_changes
(badUnparsedResult
)
211 # self.lastChange will not be updated if the change was not submitted
212 self
.failUnlessEqual(lastChangeBefore
, poller
.lastChange
)
214 def testMergeEmptyLogMsg(self
):
215 """Ensure that BonsaiPoller works around the bonsai xml output
216 issue when the check-in comment is empty"""
217 bp
= BonsaiParser(noCheckinMsgResult
)
218 result
= bp
.getData()
219 self
.failUnlessEqual(len(result
.nodes
), 1)
220 self
.failUnlessEqual(result
.nodes
[0].who
, "johndoe@domain.tld")
221 self
.failUnlessEqual(result
.nodes
[0].date
, 12345678)
222 self
.failUnlessEqual(result
.nodes
[0].log
, "")
223 for file, ref
in zip(result
.nodes
[0].files
, noCheckinMsgRef
):
224 self
.failUnlessEqual(file.filename
, ref
['filename'])
225 self
.failUnlessEqual(file.revision
, ref
['revision'])