Rev 4723: Start testing and implementing --strict for dpush. in file:///home/vila/src/bzr/bugs/438158-dpush-strict/

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Oct 2 09:57:13 BST 2009


At file:///home/vila/src/bzr/bugs/438158-dpush-strict/

------------------------------------------------------------
revno: 4723
revision-id: v.ladeuil+lp at free.fr-20091002085713-fk4vvapu1dox6hn1
parent: v.ladeuil+lp at free.fr-20091002072429-9662j2l401jz5vch
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 438158-dpush-strict
timestamp: Fri 2009-10-02 10:57:13 +0200
message:
  Start testing and implementing --strict for dpush.
  
  * bzrlib/tests/blackbox/test_dpush.py:
  (load_tests, TestDpushStrictMixin, TestDpushStrictWithoutChanges,
  TestDpushStrictWithChanges): Copied from test_push with minimal
  changes to have running tests with some even passing.
  
  * bzrlib/foreign.py:
  (cmd_dpush): Add the --strict option.
-------------- next part --------------
=== modified file 'bzrlib/foreign.py'
--- a/bzrlib/foreign.py	2009-09-18 01:25:08 +0000
+++ b/bzrlib/foreign.py	2009-10-02 08:57:13 +0000
@@ -271,16 +271,22 @@
     """
     hidden = True
     takes_args = ['location?']
-    takes_options = ['remember', Option('directory',
-            help='Branch to push from, '
-                 'rather than the one containing the working directory.',
-            short_name='d',
-            type=unicode,
-            ),
-            Option('no-rebase', help="Do not rebase after push.")]
+    takes_options = [
+        'remember',
+        Option('directory',
+               help='Branch to push from, '
+               'rather than the one containing the working directory.',
+               short_name='d',
+               type=unicode,
+               ),
+        Option('no-rebase', help="Do not rebase after push."),
+        Option('strict',
+               help='Refuse to push if there are uncommitted changes in'
+               ' the working tree, --no-strict disables the check.'),
+        ]
 
-    def run(self, location=None, remember=False, directory=None, 
-            no_rebase=False):
+    def run(self, location=None, remember=False, directory=None,
+            no_rebase=False, strict=None):
         from bzrlib import urlutils
         from bzrlib.bzrdir import BzrDir
         from bzrlib.errors import BzrCommandError, NoWorkingTree

=== modified file 'bzrlib/tests/blackbox/test_dpush.py'
--- a/bzrlib/tests/blackbox/test_dpush.py	2009-10-02 07:24:29 +0000
+++ b/bzrlib/tests/blackbox/test_dpush.py	2009-10-02 08:57:13 +0000
@@ -25,16 +25,38 @@
     bzrdir,
     foreign,
     tests,
-    )
-from bzrlib.tests.test_foreign import (
-    DummyForeignVcsDirFormat,
-    InterToDummyVcsBranch,
+    workingtree,
     )
 from bzrlib.tests import (
     blackbox,
     test_foreign,
     )
 
+
+def load_tests(standard_tests, module, loader):
+    """Multiply tests for the dpush command."""
+    result = loader.suiteClass()
+
+    # one for each king of change
+    changes_tests, remaining_tests = tests.split_suite_by_condition(
+        standard_tests, tests.condition_isinstance((
+                TestDpushStrictWithChanges,
+                )))
+    changes_scenarios = [
+        ('uncommitted',
+         dict(_changes_type= '_uncommitted_changes')),
+        ('pending-merges',
+         dict(_changes_type= '_pending_merges')),
+        ('out-of-sync-trees',
+         dict(_changes_type= '_out_of_sync_trees')),
+        ]
+    tests.multiply_tests(changes_tests, changes_scenarios, result)
+    # No parametrization for the remaining tests
+    result.addTests(remaining_tests)
+
+    return result
+
+
 class TestDpush(blackbox.ExternalBase):
 
     def setUp(self):
@@ -124,3 +146,163 @@
         output, error = self.run_bzr("dpush -d dc d", retcode=3)
         self.assertEquals(output, "")
         self.assertContainsRe(error, "have diverged")
+
+
+class TestDpushStrictMixin(object):
+
+    # FIXME: setUp and unregister_format needs to be dedupe from TestDpush
+    # (made into functions in test_foreign ?).
+    def setUp(self):
+        bzrdir.BzrDirFormat.register_control_format(
+            test_foreign.DummyForeignVcsDirFormat)
+        branch.InterBranch.register_optimiser(
+            test_foreign.InterToDummyVcsBranch)
+        self.addCleanup(self.unregister_format)
+
+    def unregister_format(self):
+        try:
+            bzrdir.BzrDirFormat.unregister_control_format(
+                test_foreign.DummyForeignVcsDirFormat)
+        except ValueError:
+            pass
+        branch.InterBranch.unregister_optimiser(
+            test_foreign.InterToDummyVcsBranch)
+
+    def make_local_branch_and_tree(self):
+        self.tree = self.make_branch_and_tree('local')
+        self.build_tree_contents([('local/file', 'initial')])
+        self.tree.add('file')
+        self.tree.commit('adding file', rev_id='added')
+        self.build_tree_contents([('local/file', 'modified')])
+        self.tree.commit('modify file', rev_id='modified')
+
+    def make_foreign_branch(self, relpath='to'):
+        # Create an empty branch where we will be able to push
+        self.foreign = self.make_branch(
+            relpath, format=test_foreign.DummyForeignVcsDirFormat())
+
+    def set_config_dpush_strict(self, value):
+        # set config var (any of bazaar.conf, locations.conf, branch.conf
+        # should do)
+        conf = self.tree.branch.get_config()
+        conf.set_user_option('dpush_strict', value)
+
+    _default_command = ['dpush', '../to']
+    _default_wd = 'local'
+    _default_errors = ['Working tree ".*/local/" has uncommitted '
+                       'changes \(See bzr status\)\.',]
+    _default_dpushed_revid = 'modified'
+
+    def assertDpushFails(self, args):
+        self.run_bzr_error(self._default_errors, self._default_command + args,
+                           working_dir=self._default_wd, retcode=3)
+
+    def assertDpushSucceeds(self, args, pushed_revid=None):
+        self.run_bzr(self._default_command + args,
+                     working_dir=self._default_wd)
+        if pushed_revid is None:
+            # dpush change the revids, so we need to get back to it
+            branch_from = branch.Branch.open(self._default_wd)
+            pushed_revid = branch_from.last_revision()
+        branch_to = branch.Branch.open('to')
+        repo_to = branch_to.repository
+        self.assertTrue(repo_to.has_revision(pushed_revid))
+        self.assertEqual(branch_to.last_revision(), pushed_revid)
+
+
+
+class TestDpushStrictWithoutChanges(tests.TestCaseWithTransport,
+                                    TestDpushStrictMixin):
+
+    def setUp(self):
+        super(TestDpushStrictWithoutChanges, self).setUp()
+        TestDpushStrictMixin.setUp(self)
+        self.make_local_branch_and_tree()
+        self.make_foreign_branch()
+
+    def test_dpush_default(self):
+        self.assertDpushSucceeds([])
+
+    def test_dpush_strict(self):
+        self.assertDpushSucceeds(['--strict'])
+
+    def test_dpush_no_strict(self):
+        self.assertDpushSucceeds(['--no-strict'])
+
+    def test_dpush_config_var_strict(self):
+        self.set_config_dpush_strict('true')
+        self.assertDpushSucceeds([])
+
+    def test_dpush_config_var_no_strict(self):
+        self.set_config_dpush_strict('false')
+        self.assertDpushSucceeds([])
+
+
+class TestDpushStrictWithChanges(tests.TestCaseWithTransport,
+                                 TestDpushStrictMixin):
+
+    _changes_type = None # Set by load_tests
+
+    def setUp(self):
+        super(TestDpushStrictWithChanges, self).setUp()
+        TestDpushStrictMixin.setUp(self)
+        # Apply the changes defined in load_tests: one of _uncommitted_changes,
+        # _pending_merges or _out_of_sync_trees
+        getattr(self, self._changes_type)()
+        self.make_foreign_branch()
+
+    def _uncommitted_changes(self):
+        self.make_local_branch_and_tree()
+        # Make a change without committing it
+        self.build_tree_contents([('local/file', 'in progress')])
+
+    def _pending_merges(self):
+        self.make_local_branch_and_tree()
+        # Create 'other' branch containing a new file
+        other_bzrdir = self.tree.bzrdir.sprout('other')
+        other_tree = other_bzrdir.open_workingtree()
+        self.build_tree_contents([('other/other-file', 'other')])
+        other_tree.add('other-file')
+        other_tree.commit('other commit', rev_id='other')
+        # Merge and revert, leaving a pending merge
+        self.tree.merge_from_branch(other_tree.branch)
+        self.tree.revert(filenames=['other-file'], backups=False)
+
+    def _out_of_sync_trees(self):
+        self.make_local_branch_and_tree()
+        self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
+        # Make a change and commit it
+        self.build_tree_contents([('local/file', 'modified in local')])
+        self.tree.commit('modify file', rev_id='modified-in-local')
+        # Exercise commands from the checkout directory
+        self._default_wd = 'checkout'
+        self._default_errors = ["Working tree is out of date, please run"
+                                " 'bzr update'\.",]
+        self._default_dpushed_revid = 'modified-in-local'
+
+    def test_dpush_default(self):
+        self.assertDpushFails([])
+
+    def test_dpush_no_strict(self):
+        self.assertDpushSucceeds(['--no-strict'])
+
+    def test_dpush_strict_with_changes(self):
+        self.assertDpushFails(['--strict'])
+
+    def test_dpush_respect_config_var_strict(self):
+        self.set_config_dpush_strict('true')
+        self.assertDpushFails([])
+
+    def test_dpush_bogus_config_var_ignored(self):
+        self.set_config_dpush_strict("I don't want you to be strict")
+        self.assertDpushFails([])
+
+    def test_dpush_no_strict_command_line_override_config(self):
+        self.set_config_dpush_strict('yES')
+        self.assertDpushFails([])
+        self.assertDpushSucceeds(['--no-strict'])
+
+    def test_dpush_strict_command_line_override_config(self):
+        self.set_config_dpush_strict('oFF')
+        self.assertDpushFails(['--strict'])
+        self.assertDpushSucceeds([])



More information about the bazaar-commits mailing list