| 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 |