4 from twisted
.python
import log
, failure
5 from twisted
.internet
import defer
6 from twisted
.trial
import unittest
8 from buildbot
.twcompat
import maybeWait
9 from buildbot
.changes
.changes
import Change
10 from buildbot
.changes
.p4poller
import P4Source
, get_simple_split
12 #log.startLogging(sys.stderr)
15 """Change 1 on 2006/04/13 by slamb@testclient 'first rev'
19 """Change 3 on 2006/04/13 by bob@testclient 'short desc truncated'
20 Change 2 on 2006/04/13 by slamb@testclient 'bar'
24 """Change 5 on 2006/04/13 by mpatel@testclient 'first rev'
28 """Change 4 by mpatel@testclient on 2006/04/13 21:55:39
30 short desc truncated because this is a long description.
33 """Change 3 by bob@testclient on 2006/04/13 21:51:39
35 short desc truncated because this is a long description.
39 """Change 2 by slamb@testclient on 2006/04/13 21:46:23
48 ... //depot/myproject/branch_b/branch_b_file#1 add
49 ... //depot/myproject/branch_b/whatbranch#1 branch
50 ... //depot/myproject/branch_c/whatbranch#1 branch
55 ... //depot/myproject/trunk/whatbranch#1 add
56 ... //depot/otherproject/trunk/something#1 add
61 ... //depot/myproject/branch_b/branch_b_file#1 add
62 ... //depot/myproject/branch_b#75 edit
63 ... //depot/myproject/branch_c/branch_c_file#1 add
68 class MockP4Source(P4Source
):
69 """Test P4Source which doesn't actually invoke p4."""
72 def __init__(self
, p4changes
, p4change
, *args
, **kwargs
):
73 P4Source
.__init
__(self
, *args
, **kwargs
)
74 self
.p4changes
= p4changes
75 self
.p4change
= p4change
77 def _get_changes(self
):
79 result
= self
.p4changes
[self
.invocation
]
81 return defer
.succeed(result
)
83 def _get_describe(self
, dummy
, num
):
85 return defer
.succeed(self
.p4change
[num
])
87 class TestP4Poller(unittest
.TestCase
):
90 self
.addChange
= self
.changes
.append
93 """successful checks"""
94 self
.t
= MockP4Source(p4changes
=[first_p4changes
, second_p4changes
],
96 p4port
=None, p4user
=None,
97 p4base
='//depot/myproject/',
98 split_file
=lambda x
: x
.split('/', 1))
101 # The first time, it just learns the change to start at.
102 self
.assert_(self
.t
.last_change
is None)
103 self
.assert_(not self
.t
.working
)
104 return maybeWait(self
.t
.checkp4().addCallback(self
._testCheck
2))
106 def _testCheck2(self
, res
):
107 self
.assertEquals(self
.changes
, [])
108 self
.assertEquals(self
.t
.last_change
, '1')
110 # Subsequent times, it returns Change objects for new changes.
111 return self
.t
.checkp4().addCallback(self
._testCheck
3)
113 def _testCheck3(self
, res
):
114 self
.assertEquals(len(self
.changes
), 3)
115 self
.assertEquals(self
.t
.last_change
, '3')
116 self
.assert_(not self
.t
.working
)
118 # They're supposed to go oldest to newest, so this one must be first.
119 self
.assertEquals(self
.changes
[0].asText(),
121 files
=['whatbranch'],
122 comments
=change_2_log
,
124 when
=time
.mktime((2006, 4, 13, 21, 46, 23, 3, 103, -1)),
125 branch
='trunk').asText())
127 # These two can happen in either order, since they're from the same
131 files
=['branch_b_file',
133 comments
=change_3_log
,
135 when
=time
.mktime((2006, 4, 13, 21, 51, 39, 3, 103, -1)),
136 branch
='branch_b').asText(),
137 [c
.asText() for c
in self
.changes
])
140 files
=['whatbranch'],
141 comments
=change_3_log
,
143 when
=time
.mktime((2006, 4, 13, 21, 51, 39, 3, 103, -1)),
144 branch
='branch_c').asText(),
145 [c
.asText() for c
in self
.changes
])
147 def testFailedChanges(self
):
148 """'p4 changes' failure is properly reported"""
149 self
.t
= MockP4Source(p4changes
=['Perforce client error:\n...'],
151 p4port
=None, p4user
=None)
154 d
.addBoth(self
._testFailedChanges
2)
157 def _testFailedChanges2(self
, f
):
158 self
.assert_(isinstance(f
, failure
.Failure
))
159 self
.assertIn('Perforce client error', str(f
))
160 self
.assert_(not self
.t
.working
)
162 def testFailedDescribe(self
):
163 """'p4 describe' failure is properly reported"""
165 c
['3'] = 'Perforce client error:\n...'
166 self
.t
= MockP4Source(p4changes
=[first_p4changes
, second_p4changes
],
167 p4change
=c
, p4port
=None, p4user
=None)
170 d
.addCallback(self
._testFailedDescribe
2)
173 def _testFailedDescribe2(self
, res
):
174 # first time finds nothing; check again.
175 return self
.t
.checkp4().addBoth(self
._testFailedDescribe
3)
177 def _testFailedDescribe3(self
, f
):
178 self
.assert_(isinstance(f
, failure
.Failure
))
179 self
.assertIn('Perforce client error', str(f
))
180 self
.assert_(not self
.t
.working
)
181 self
.assertEquals(self
.t
.last_change
, '2')
183 def testAlreadyWorking(self
):
184 """don't launch a new poll while old is still going"""
186 self
.t
.working
= True
187 self
.assert_(self
.t
.last_change
is None)
189 d
.addCallback(self
._testAlreadyWorking
2)
191 def _testAlreadyWorking2(self
, res
):
192 self
.assert_(self
.t
.last_change
is None)
194 def testSplitFile(self
):
195 """Make sure split file works on branch only changes"""
196 self
.t
= MockP4Source(p4changes
=[third_p4changes
],
198 p4port
=None, p4user
=None,
199 p4base
='//depot/myproject/',
200 split_file
=get_simple_split
)
202 self
.t
.last_change
= 50
204 d
.addCallback(self
._testSplitFile
)
206 def _testSplitFile(self
, res
):
207 self
.assertEquals(len(self
.changes
), 2)
208 self
.assertEquals(self
.t
.last_change
, '5')