Merge lp:~gthorslund/bzr-bisect/539937-subtree into lp:bzr-bisect

Proposed by Gustaf Thorslund
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: 81
Merged at revision: 78
Proposed branch: lp:~gthorslund/bzr-bisect/539937-subtree
Merge into: lp:bzr-bisect
Diff against target: 578 lines (+129/-60)
3 files modified
__init__.py (+35/-35)
meta.py (+1/-1)
tests.py (+93/-24)
To merge this branch: bzr merge lp:~gthorslund/bzr-bisect/539937-subtree
Reviewer Review Type Date Requested Status
Jelmer Vernooij (community) code Approve
Review via email: mp+39785@code.launchpad.net

Description of the change

Added three test cases. Two of them will still fail due to:
  https://bugs.launchpad.net/bzr-bisect/+bug/539937
marked them as KnownFailure.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Thanks! It's nice to have some tests for these bugs, that should make them a lot easier to fix.

For consistency, can you change the syntax of the docstrings to use """ rather than " ?

The script tests probably won't work on Windows at the moment. I wonder if this is an issue for bzr-bisect (did it work on Windows before?). Ideally we should make these tests work on Windows as well, though for the moment it is probably sufficient to check sys.platform and raise TestSkipped if sys.platform is "win32".

review: Needs Fixing (code)
81. By Gustaf Thorslund

Fixed " -> """ for docstrings. Added some docstrings. Also converted some #-comment into a docstring.

Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '__init__.py'
2--- __init__.py 2010-10-16 17:54:57 +0000
3+++ __init__.py 2010-11-05 12:09:47 +0000
4@@ -14,7 +14,7 @@
5 # along with this program; if not, write to the Free Software
6 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
7
8-"Support for git-style bisection."
9+"""Support for git-style bisection."""
10
11 import sys
12 import os
13@@ -22,7 +22,7 @@
14 from bzrlib.commands import Command, register_command
15 from bzrlib.errors import BzrCommandError
16 from bzrlib.option import Option
17-from bzrlib.trace import info
18+from bzrlib.trace import note
19
20 from meta import *
21
22@@ -31,7 +31,7 @@
23
24
25 class BisectCurrent(object):
26- "Bisect class for managing the current revision."
27+ """Bisect class for managing the current revision."""
28
29 def __init__(self, filename = bisect_rev_path):
30 self._filename = filename
31@@ -45,23 +45,23 @@
32 self._revid = self._bzrbranch.last_revision()
33
34 def _save(self):
35- "Save the current revision."
36+ """Save the current revision."""
37
38 revid_file = open(self._filename, "w")
39 revid_file.write(self._revid + "\n")
40 revid_file.close()
41
42 def get_current_revid(self):
43- "Return the current revision id."
44+ """Return the current revision id."""
45 return self._revid
46
47 def get_current_revno(self):
48- "Return the current revision number as a tuple."
49+ """Return the current revision number as a tuple."""
50 revdict = self._bzrbranch.get_revision_id_to_revno_map()
51 return revdict[self.get_current_revid()]
52
53 def get_parent_revids(self):
54- "Return the IDs of the current revision's predecessors."
55+ """Return the IDs of the current revision's predecessors."""
56 repo = self._bzrbranch.repository
57 repo.lock_read()
58 retval = repo.get_parent_map([self._revid]).get(self._revid, None)
59@@ -69,18 +69,18 @@
60 return retval
61
62 def is_merge_point(self):
63- "Is the current revision a merge point?"
64+ """Is the current revision a merge point?"""
65 return len(self.get_parent_revids()) > 1
66
67 def show_rev_log(self, out = sys.stdout):
68- "Write the current revision's log entry to a file."
69+ """Write the current revision's log entry to a file."""
70 rev = self._bzrbranch.repository.get_revision(self._revid)
71 revno = ".".join([str(x) for x in self.get_current_revno()])
72 out.write("On revision %s (%s):\n%s\n" % (revno, rev.revision_id,
73 rev.message))
74
75 def switch(self, revid):
76- "Switch the current revision to the given revid."
77+ """Switch the current revision to the given revid."""
78 working = self._bzrdir.open_workingtree()
79 if isinstance(revid, int):
80 revid = self._bzrbranch.get_rev_id(revid)
81@@ -92,7 +92,7 @@
82 self._save()
83
84 def reset(self):
85- "Revert bisection, setting the working tree to normal."
86+ """Revert bisection, setting the working tree to normal."""
87 working = self._bzrdir.open_workingtree()
88 last_rev = working.branch.last_revision()
89 rev_tree = working.branch.repository.revision_tree(last_rev)
90@@ -102,7 +102,7 @@
91
92
93 class BisectLog(object):
94- "Bisect log file handler."
95+ """Bisect log file handler."""
96
97 def __init__(self, filename = bisect_info_path):
98 self._items = []
99@@ -115,27 +115,27 @@
100 self.load()
101
102 def _open_for_read(self):
103- "Open log file for reading."
104+ """Open log file for reading."""
105 if self._filename:
106 return open(self._filename)
107 else:
108 return sys.stdin
109
110 def _open_for_write(self):
111- "Open log file for writing."
112+ """Open log file for writing."""
113 if self._filename:
114 return open(self._filename, "w")
115 else:
116 return sys.stdout
117
118 def _load_bzr_tree(self):
119- "Load bzr information."
120+ """Load bzr information."""
121 if not self._bzrdir:
122 self._bzrdir = bzrlib.bzrdir.BzrDir.open_containing('.')[0]
123 self._bzrbranch = self._bzrdir.open_branch()
124
125 def _find_range_and_middle(self, branch_last_rev = None):
126- "Find the current revision range, and the midpoint."
127+ """Find the current revision range, and the midpoint."""
128 self._load_bzr_tree()
129 self._middle_revid = None
130
131@@ -193,12 +193,12 @@
132 self._low_revid = low_revid
133
134 def _switch_wc_to_revno(self, revno, outf):
135- "Move the working tree to the given revno."
136+ """Move the working tree to the given revno."""
137 self._current.switch(revno)
138 self._current.show_rev_log(out=outf)
139
140 def _set_status(self, revid, status):
141- "Set the bisect status for the given revid."
142+ """Set the bisect status for the given revid."""
143 if not self.is_done():
144 if status != "done" and revid in [x[0] for x in self._items
145 if x[1] in ['yes', 'no']]:
146@@ -206,11 +206,11 @@
147 self._items.append((revid, status))
148
149 def change_file_name(self, filename):
150- "Switch log files."
151+ """Switch log files."""
152 self._filename = filename
153
154 def load(self):
155- "Load the bisection log."
156+ """Load the bisection log."""
157 self._items = []
158 if os.path.exists(self._filename):
159 revlog = self._open_for_read()
160@@ -219,23 +219,23 @@
161 self._items.append((revid, status))
162
163 def save(self):
164- "Save the bisection log."
165+ """Save the bisection log."""
166 revlog = self._open_for_write()
167 for (revid, status) in self._items:
168 revlog.write("%s %s\n" % (revid, status))
169
170 def is_done(self):
171- "Report whether we've found the right revision."
172+ """Report whether we've found the right revision."""
173 return len(self._items) > 0 and self._items[-1][1] == "done"
174
175 def set_status_from_revspec(self, revspec, status):
176- "Set the bisection status for the revision in revspec."
177+ """Set the bisection status for the revision in revspec."""
178 self._load_bzr_tree()
179 revid = revspec[0].in_history(self._bzrbranch).rev_id
180 self._set_status(revid, status)
181
182 def set_current(self, status):
183- "Set the current revision to the given bisection status."
184+ """Set the current revision to the given bisection status."""
185 self._set_status(self._current.get_current_revid(), status)
186
187 def is_merge_point(self, revid):
188@@ -251,7 +251,7 @@
189 return retval
190
191 def bisect(self, outf):
192- "Using the current revision's status, do a bisection."
193+ """Using the current revision's status, do a bisection."""
194 self._find_range_and_middle()
195 # If we've found the "final" revision, check for a
196 # merge point.
197@@ -322,7 +322,7 @@
198 'revision']
199
200 def _check(self):
201- "Check preconditions for most operations to work."
202+ """Check preconditions for most operations to work."""
203 if not os.path.exists(bisect_info_path):
204 raise BzrCommandError("No bisection in progress.")
205
206@@ -332,7 +332,7 @@
207 Returns boolean indicating if bisection is done."""
208 bisect_log = BisectLog()
209 if bisect_log.is_done():
210- info("No further bisection is possible.\n")
211+ note("No further bisection is possible.\n")
212 bisect_log._current.show_rev_log(self.outf)
213 return True
214
215@@ -345,7 +345,7 @@
216 return False
217
218 def run(self, subcommand, args_list, revision=None, output=None):
219- "Handle the bisect command."
220+ """Handle the bisect command."""
221
222 log_fn = None
223 if subcommand in ('yes', 'no', 'move') and revision:
224@@ -384,13 +384,13 @@
225 "Unknown bisect command: " + subcommand)
226
227 def reset(self):
228- "Reset the bisect state to no state."
229+ """Reset the bisect state to no state."""
230 self._check()
231 BisectCurrent().reset()
232 os.unlink(bisect_info_path)
233
234 def start(self):
235- "Reset the bisect state, then prepare for a new bisection."
236+ """Reset the bisect state, then prepare for a new bisection."""
237 if os.path.exists(bisect_info_path):
238 BisectCurrent().reset()
239 os.unlink(bisect_info_path)
240@@ -400,21 +400,21 @@
241 bisect_log.save()
242
243 def yes(self, revspec):
244- "Mark that a given revision has the state we're looking for."
245+ """Mark that a given revision has the state we're looking for."""
246 self._set_state(revspec, "yes")
247
248 def no(self, revspec):
249- "Mark that a given revision does not have the state we're looking for."
250+ """Mark that a given revision does not have the state we're looking for."""
251 self._set_state(revspec, "no")
252
253 def move(self, revspec):
254- "Move to a different revision manually."
255+ """Move to a different revision manually."""
256 current = BisectCurrent()
257 current.switch(revspec)
258 current.show_rev_log(out=self.outf)
259
260 def log(self, filename):
261- "Write the current bisect log to a file."
262+ """Write the current bisect log to a file."""
263 self._check()
264 bisect_log = BisectLog()
265 bisect_log.change_file_name(filename)
266@@ -434,7 +434,7 @@
267
268 def run_bisect(self, script):
269 import subprocess
270- info("Starting bisect.")
271+ note("Starting bisect.")
272 self.start()
273 while True:
274 try:
275
276=== modified file 'meta.py'
277--- meta.py 2009-04-02 15:11:50 +0000
278+++ meta.py 2010-11-05 12:09:47 +0000
279@@ -14,7 +14,7 @@
280 # along with this program; if not, write to the Free Software
281 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
282
283-# Queryable plugin variables, from a proposal by Robert Collins.
284+"""Queryable plugin variables, from a proposal by Robert Collins."""
285
286 bzr_plugin_name = 'bisect'
287
288
289=== modified file 'tests.py'
290--- tests.py 2010-10-16 17:54:57 +0000
291+++ tests.py 2010-11-05 12:09:47 +0000
292@@ -17,6 +17,7 @@
293 "Test suite for the bzr bisect plugin."
294
295 import os
296+import stat
297 from cStringIO import StringIO
298 import shutil
299 import bzrlib
300@@ -24,13 +25,13 @@
301 import bzrlib.tests
302 import bzrlib.revisionspec
303 import bzrlib.plugins.bisect as bisect
304-
305+from bzrlib.tests import KnownFailure
306
307 class BisectTestCase(bzrlib.tests.TestCaseWithTransport):
308- "Test harness specific to the bisect plugin."
309+ """Test harness specific to the bisect plugin."""
310
311 def assertRevno(self, rev):
312- "Make sure we're at the right revision."
313+ """Make sure we're at the right revision."""
314
315 rev_contents = {1: "one", 1.1: "one dot one", 1.2: "one dot two",
316 1.3: "one dot three", 2: "two", 3: "three",
317@@ -45,12 +46,15 @@
318 % (rev, found_rev))
319
320 def setUp(self):
321- bzrlib.tests.TestCaseWithTransport.setUp(self)
322+ """Set up tests."""
323
324 # These tests assume a branch with five revisions, and
325 # a branch from version 1 containing three revisions
326 # merged at version 2.
327
328+ bzrlib.tests.TestCaseWithTransport.setUp(self)
329+
330+
331 self.tree = self.make_branch_and_tree(".")
332
333 test_file = open("test_file", "w")
334@@ -58,7 +62,12 @@
335 test_file.close()
336 self.tree.add(self.tree.relpath(os.path.join(os.getcwd(),
337 'test_file')))
338- self.tree.commit(message = "add test file")
339+ test_file_append = open("test_file_append", "a")
340+ test_file_append.write("one\n")
341+ test_file_append.close()
342+ self.tree.add(self.tree.relpath(os.path.join(os.getcwd(),
343+ 'test_file_append')))
344+ self.tree.commit(message = "add test files")
345
346 bzrlib.bzrdir.BzrDir.open(".").sprout("../temp-clone")
347 clone_bzrdir = bzrlib.bzrdir.BzrDir.open("../temp-clone")
348@@ -67,6 +76,9 @@
349 test_file = open("../temp-clone/test_file", "w")
350 test_file.write(content)
351 test_file.close()
352+ test_file_append = open("../temp-clone/test_file_append", "a")
353+ test_file_append.write(content + "\n")
354+ test_file_append.close()
355 clone_tree.commit(message = "make branch test change")
356 saved_subtree_revid = clone_tree.branch.last_revision()
357
358@@ -74,6 +86,9 @@
359 test_file = open("test_file", "w")
360 test_file.write("two")
361 test_file.close()
362+ test_file_append = open("test_file_append", "a")
363+ test_file_append.write("two\n")
364+ test_file_append.close()
365 self.tree.commit(message = "merge external branch")
366 shutil.rmtree("../temp-clone")
367
368@@ -84,14 +99,17 @@
369 test_file = open("test_file", "w")
370 test_file.write(content)
371 test_file.close()
372+ test_file_append = open("test_file_append", "a")
373+ test_file_append.write(content + "\n")
374+ test_file_append.close()
375 self.tree.commit(message = "make test change")
376
377
378 class BisectHarnessTests(BisectTestCase):
379- "Tests for the harness itself."
380+ """Tests for the harness itself."""
381
382 def testLastRev(self):
383- "Test that the last revision is correct."
384+ """Test that the last revision is correct."""
385 repo = self.tree.branch.repository
386 top_revtree = repo.revision_tree(self.tree.last_revision())
387 top_revtree.lock_read()
388@@ -102,7 +120,7 @@
389 assert test_content == "five"
390
391 def testSubtreeRev(self):
392- "Test that the last revision in a subtree is correct."
393+ """Test that the last revision in a subtree is correct."""
394 repo = self.tree.branch.repository
395 sub_revtree = repo.revision_tree(self.subtree_rev)
396 sub_revtree.lock_read()
397@@ -114,42 +132,44 @@
398
399
400 class BisectMetaTests(BisectTestCase):
401- "Test the metadata provided by the package."
402+ """Test the metadata provided by the package."""
403
404 def testVersionPresent(self):
405+ """Check if version_info is available for the plugin."""
406 assert bisect.version_info
407
408 def testBzrVersioning(self):
409+ """Check if API is of right version."""
410 assert bisect.bzr_minimum_api <= bzrlib.api_minimum_version
411 assert bisect.bzr_minimum_api <= bzrlib.version_info[:3]
412
413
414 class BisectCurrentUnitTests(BisectTestCase):
415- "Test the BisectCurrent class."
416+ """Test the BisectCurrent class."""
417
418 def testShowLog(self):
419- "Test that the log can be shown."
420+ """Test that the log can be shown."""
421 # Not a very good test; just makes sure the code doesn't fail,
422 # not that the output makes any sense.
423 sio = StringIO()
424 bisect.BisectCurrent().show_rev_log(out=sio)
425
426 def testShowLogSubtree(self):
427- "Test that a subtree's log can be shown."
428+ """Test that a subtree's log can be shown."""
429 current = bisect.BisectCurrent()
430 current.switch(self.subtree_rev)
431 sio = StringIO()
432 current.show_rev_log(out=sio)
433
434 def testSwitchVersions(self):
435- "Test switching versions."
436+ """Test switching versions."""
437 current = bisect.BisectCurrent()
438 self.assertRevno(5)
439 current.switch(4)
440 self.assertRevno(4)
441
442 def testReset(self):
443- "Test resetting the working tree to a non-bisected state."
444+ """Test resetting the working tree to a non-bisected state."""
445 current = bisect.BisectCurrent()
446 current.switch(4)
447 current.reset()
448@@ -157,7 +177,7 @@
449 assert not os.path.exists(bisect.bisect_rev_path)
450
451 def testIsMergePoint(self):
452- "Test merge point detection."
453+ """Test merge point detection."""
454 current = bisect.BisectCurrent()
455 self.assertRevno(5)
456 assert not current.is_merge_point()
457@@ -166,16 +186,16 @@
458
459
460 class BisectLogUnitTests(BisectTestCase):
461- "Test the BisectLog class."
462+ """Test the BisectLog class."""
463
464 def testCreateBlank(self):
465- "Test creation of new log."
466+ """Test creation of new log."""
467 bisect_log = bisect.BisectLog()
468 bisect_log.save()
469 assert os.path.exists(bisect.bisect_info_path)
470
471 def testLoad(self):
472- "Test loading a log."
473+ """Test loading a log."""
474 preloaded_log = open(bisect.bisect_info_path, "w")
475 preloaded_log.write("rev1 yes\nrev2 no\nrev3 yes\n")
476 preloaded_log.close()
477@@ -187,7 +207,7 @@
478 assert bisect_log._items[2] == ("rev3", "yes")
479
480 def testSave(self):
481- "Test saving the log."
482+ """Test saving the log."""
483 bisect_log = bisect.BisectLog()
484 bisect_log._items = [("rev1", "yes"), ("rev2", "no"), ("rev3", "yes")]
485 bisect_log.save()
486@@ -197,10 +217,10 @@
487
488
489 class BisectFuncTests(BisectTestCase):
490- "Functional tests for the bisect plugin."
491+ """Functional tests for the bisect plugin."""
492
493 def testWorkflow(self):
494- "Run through a basic usage scenario."
495+ """Run through a basic usage scenario."""
496
497 # Start up the bisection. When the two ends are set, we should
498 # end up in the middle.
499@@ -266,7 +286,7 @@
500 self.assertRevno(1.1)
501
502 def testMove(self):
503- "Test manually moving to a different revision during the bisection."
504+ """Test manually moving to a different revision during the bisection."""
505
506 # Set up a bisection in progress.
507
508@@ -280,7 +300,7 @@
509 self.assertRevno(2)
510
511 def testReset(self):
512- "Test resetting the tree."
513+ """Test resetting the tree."""
514
515 # Set up a bisection in progress.
516
517@@ -310,7 +330,7 @@
518 self.failUnless(content == "keep me")
519
520 def testLog(self):
521- "Test saving the current bisection state, and re-loading it."
522+ """Test saving the current bisection state, and re-loading it."""
523
524 # Set up a bisection in progress.
525
526@@ -337,3 +357,52 @@
527
528 self.run_bzr(['bisect', 'no'])
529 self.assertRevno(3)
530+
531+ def testRunScript(self):
532+ """Make a test script and run it."""
533+ test_script = open("test_script", "w")
534+ test_script.write("#!/bin/sh\n"
535+ "grep -q '^four' test_file_append\n")
536+ test_script.close()
537+ os.chmod("test_script", stat.S_IRWXU)
538+ self.run_bzr(['bisect', 'start'])
539+ self.run_bzr(['bisect', 'yes'])
540+ self.run_bzr(['bisect', 'no', '-r', '1'])
541+ self.run_bzr(['bisect', 'run', './test_script'])
542+ self.assertRevno(4)
543+
544+ def testRunScriptMergePoint(self):
545+ """Make a test script and run it."""
546+ test_script = open("test_script", "w")
547+ test_script.write("#!/bin/sh\n"
548+ "grep -q '^two' test_file_append\n")
549+ test_script.close()
550+ os.chmod("test_script", stat.S_IRWXU)
551+ self.run_bzr(['bisect', 'start'])
552+ self.run_bzr(['bisect', 'yes'])
553+ self.run_bzr(['bisect', 'no', '-r', '1'])
554+ self.run_bzr(['bisect', 'run', './test_script'])
555+ try:
556+ self.assertRevno(2)
557+ except AssertionError:
558+ raise KnownFailure\
559+ ("bisect does not drill down into merge commits: "
560+ "https://bugs.launchpad.net/bzr-bisect/+bug/539937")
561+
562+ def testRunScriptSubtree(self):
563+ """Make a test script and run it."""
564+ test_script = open("test_script", "w")
565+ test_script.write("#!/bin/sh\n"
566+ "grep -q '^one dot two' test_file_append\n")
567+ test_script.close()
568+ os.chmod("test_script", stat.S_IRWXU)
569+ self.run_bzr(['bisect', 'start'])
570+ self.run_bzr(['bisect', 'yes'])
571+ self.run_bzr(['bisect', 'no', '-r', '1'])
572+ self.run_bzr(['bisect', 'run', './test_script'])
573+ try:
574+ self.assertRevno(1.2)
575+ except AssertionError:
576+ raise KnownFailure\
577+ ("bisect does not drill down into merge commits: "
578+ "https://bugs.launchpad.net/bzr-bisect/+bug/539937")

Subscribers

People subscribed via source and target branches

to all changes: