OLD | NEW |
| (Empty) |
1 import time | |
2 | |
3 from twisted.internet import defer | |
4 from twisted.trial import unittest | |
5 | |
6 from buildbot.changes.changes import Change | |
7 from buildbot.changes.p4poller import P4Source, get_simple_split | |
8 | |
9 first_p4changes = \ | |
10 """Change 1 on 2006/04/13 by slamb@testclient 'first rev' | |
11 """ | |
12 | |
13 second_p4changes = \ | |
14 """Change 3 on 2006/04/13 by bob@testclient 'short desc truncated' | |
15 Change 2 on 2006/04/13 by slamb@testclient 'bar' | |
16 """ | |
17 | |
18 third_p4changes = \ | |
19 """Change 5 on 2006/04/13 by mpatel@testclient 'first rev' | |
20 """ | |
21 | |
22 change_4_log = \ | |
23 """Change 4 by mpatel@testclient on 2006/04/13 21:55:39 | |
24 | |
25 short desc truncated because this is a long description. | |
26 """ | |
27 change_3_log = \ | |
28 """Change 3 by bob@testclient on 2006/04/13 21:51:39 | |
29 | |
30 short desc truncated because this is a long description. | |
31 """ | |
32 | |
33 change_2_log = \ | |
34 """Change 2 by slamb@testclient on 2006/04/13 21:46:23 | |
35 | |
36 creation | |
37 """ | |
38 | |
39 p4change = { | |
40 3: change_3_log + | |
41 """Affected files ... | |
42 | |
43 ... //depot/myproject/branch_b/branch_b_file#1 add | |
44 ... //depot/myproject/branch_b/whatbranch#1 branch | |
45 ... //depot/myproject/branch_c/whatbranch#1 branch | |
46 """, | |
47 2: change_2_log + | |
48 """Affected files ... | |
49 | |
50 ... //depot/myproject/trunk/whatbranch#1 add | |
51 ... //depot/otherproject/trunk/something#1 add | |
52 """, | |
53 5: change_4_log + | |
54 """Affected files ... | |
55 | |
56 ... //depot/myproject/branch_b/branch_b_file#1 add | |
57 ... //depot/myproject/branch_b#75 edit | |
58 ... //depot/myproject/branch_c/branch_c_file#1 add | |
59 """, | |
60 } | |
61 | |
62 | |
63 class MockP4Source(P4Source): | |
64 """Test P4Source which doesn't actually invoke p4.""" | |
65 invocation = 0 | |
66 | |
67 def __init__(self, p4changes, p4change, *args, **kwargs): | |
68 P4Source.__init__(self, *args, **kwargs) | |
69 self.p4changes = p4changes | |
70 self.p4change = p4change | |
71 | |
72 def _get_changes(self): | |
73 assert self.working | |
74 result = self.p4changes[self.invocation] | |
75 self.invocation += 1 | |
76 return defer.succeed(result) | |
77 | |
78 def _get_describe(self, dummy, num): | |
79 assert self.working | |
80 return defer.succeed(self.p4change[num]) | |
81 | |
82 class TestP4Poller(unittest.TestCase): | |
83 def setUp(self): | |
84 self.changes = [] | |
85 self.addChange = self.changes.append | |
86 | |
87 def failUnlessIn(self, substr, string): | |
88 # this is for compatibility with python2.2 | |
89 if isinstance(string, str): | |
90 self.failUnless(string.find(substr) != -1) | |
91 else: | |
92 self.assertIn(substr, string) | |
93 | |
94 def testCheck(self): | |
95 """successful checks""" | |
96 self.t = MockP4Source(p4changes=[first_p4changes, second_p4changes], | |
97 p4change=p4change, | |
98 p4port=None, p4user=None, | |
99 p4base='//depot/myproject/', | |
100 split_file=lambda x: x.split('/', 1)) | |
101 self.t.parent = self | |
102 | |
103 # The first time, it just learns the change to start at. | |
104 self.assert_(self.t.last_change is None) | |
105 self.assert_(not self.t.working) | |
106 return self.t.checkp4().addCallback(self._testCheck2) | |
107 | |
108 def _testCheck2(self, res): | |
109 self.assertEquals(self.changes, []) | |
110 self.assertEquals(self.t.last_change, 1) | |
111 | |
112 # Subsequent times, it returns Change objects for new changes. | |
113 return self.t.checkp4().addCallback(self._testCheck3) | |
114 | |
115 def _testCheck3(self, res): | |
116 self.assertEquals(len(self.changes), 3) | |
117 self.assertEquals(self.t.last_change, 3) | |
118 self.assert_(not self.t.working) | |
119 | |
120 # They're supposed to go oldest to newest, so this one must be first. | |
121 self.assertEquals(self.changes[0].asText(), | |
122 Change(who='slamb', | |
123 files=['whatbranch'], | |
124 comments=change_2_log, | |
125 revision='2', | |
126 when=self.makeTime("2006/04/13 21:46:23"), | |
127 branch='trunk').asText()) | |
128 | |
129 # These two can happen in either order, since they're from the same | |
130 # Perforce change. | |
131 self.failUnlessIn( | |
132 Change(who='bob', | |
133 files=['branch_b_file', | |
134 'whatbranch'], | |
135 comments=change_3_log, | |
136 revision='3', | |
137 when=self.makeTime("2006/04/13 21:51:39"), | |
138 branch='branch_b').asText(), | |
139 [c.asText() for c in self.changes]) | |
140 self.failUnlessIn( | |
141 Change(who='bob', | |
142 files=['whatbranch'], | |
143 comments=change_3_log, | |
144 revision='3', | |
145 when=self.makeTime("2006/04/13 21:51:39"), | |
146 branch='branch_c').asText(), | |
147 [c.asText() for c in self.changes]) | |
148 | |
149 def makeTime(self, timestring): | |
150 datefmt = '%Y/%m/%d %H:%M:%S' | |
151 when = time.mktime(time.strptime(timestring, datefmt)) | |
152 return when | |
153 | |
154 def testFailedChanges(self): | |
155 """'p4 changes' failure is properly ignored""" | |
156 self.t = MockP4Source(p4changes=['Perforce client error:\n...'], | |
157 p4change={}, | |
158 p4port=None, p4user=None) | |
159 self.t.parent = self | |
160 d = self.t.checkp4() | |
161 d.addCallback(self._testFailedChanges2) | |
162 return d | |
163 | |
164 def _testFailedChanges2(self, f): | |
165 self.failUnlessEqual(f, None) | |
166 self.assert_(not self.t.working) | |
167 | |
168 def testFailedDescribe(self): | |
169 """'p4 describe' failure is properly ignored""" | |
170 c = dict(p4change) | |
171 c[3] = 'Perforce client error:\n...' | |
172 self.t = MockP4Source(p4changes=[first_p4changes, second_p4changes], | |
173 p4change=c, p4port=None, p4user=None) | |
174 self.t.parent = self | |
175 d = self.t.checkp4() | |
176 d.addCallback(self._testFailedDescribe2) | |
177 return d | |
178 | |
179 def _testFailedDescribe2(self, res): | |
180 # first time finds nothing; check again. | |
181 return self.t.checkp4().addCallback(self._testFailedDescribe3) | |
182 | |
183 def _testFailedDescribe3(self, f): | |
184 self.failUnlessEqual(f, None) | |
185 self.assert_(not self.t.working) | |
186 self.assertEquals(self.t.last_change, 2) | |
187 | |
188 def testAlreadyWorking(self): | |
189 """don't launch a new poll while old is still going""" | |
190 self.t = P4Source() | |
191 self.t.working = True | |
192 self.assert_(self.t.last_change is None) | |
193 d = self.t.checkp4() | |
194 d.addCallback(self._testAlreadyWorking2) | |
195 | |
196 def _testAlreadyWorking2(self, res): | |
197 self.assert_(self.t.last_change is None) | |
198 | |
199 def testSplitFile(self): | |
200 """Make sure split file works on branch only changes""" | |
201 self.t = MockP4Source(p4changes=[third_p4changes], | |
202 p4change=p4change, | |
203 p4port=None, p4user=None, | |
204 p4base='//depot/myproject/', | |
205 split_file=get_simple_split) | |
206 self.t.parent = self | |
207 self.t.last_change = 50 | |
208 d = self.t.checkp4() | |
209 d.addCallback(self._testSplitFile) | |
210 | |
211 def _testSplitFile(self, res): | |
212 self.assertEquals(len(self.changes), 2) | |
213 self.assertEquals(self.t.last_change, 5) | |
OLD | NEW |