def setUp(self): super(TestCaseWithCorruptRepository, self).setUp() # a inventory with no parents and the revision has parents.. # i.e. a ghost. repo = self.make_repository('inventory_with_unnecessary_ghost') repo.lock_write() repo.start_write_group() inv = inventory.Inventory(revision_id=b'ghost') inv.root.revision = b'ghost' if repo.supports_rich_root(): root_id = inv.root.file_id repo.texts.add_lines((root_id, b'ghost'), [], []) sha1 = repo.add_inventory(b'ghost', inv, []) rev = _mod_revision.Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id=b'ghost') rev.parent_ids = [b'the_ghost'] try: repo.add_revision(b'ghost', rev) except (errors.NoSuchRevision, errors.RevisionNotPresent): raise tests.TestNotApplicable( "Cannot test with ghosts for this format.") inv = inventory.Inventory(revision_id=b'the_ghost') inv.root.revision = b'the_ghost' if repo.supports_rich_root(): root_id = inv.root.file_id repo.texts.add_lines((root_id, b'the_ghost'), [], []) sha1 = repo.add_inventory(b'the_ghost', inv, []) rev = _mod_revision.Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id=b'the_ghost') rev.parent_ids = [] repo.add_revision(b'the_ghost', rev) # check its setup usefully inv_weave = repo.inventories possible_parents = (None, ((b'ghost', ), )) self.assertSubset( inv_weave.get_parent_map([(b'ghost', )])[(b'ghost', )], possible_parents) repo.commit_write_group() repo.unlock()
def test_create_anonymous_heavyweight_checkout(self): """A regular checkout from a readonly branch should succeed.""" tree_a = self.make_branch_and_tree('a') rev_id = tree_a.commit('put some content in the branch') # open the branch via a readonly transport url = self.get_readonly_url( osutils.basename(tree_a.branch.base.rstrip('/'))) t = transport.get_transport_from_url(url) if not tree_a.branch.controldir._format.supports_transport(t): raise tests.TestNotApplicable("format does not support transport") source_branch = _mod_branch.Branch.open(url) # sanity check that the test will be valid self.assertRaises((errors.LockError, errors.TransportNotPossible), source_branch.lock_write) checkout = source_branch.create_checkout('c') self.assertEqual(rev_id, checkout.last_revision())
def test_bind_clears_cached_master_branch(self): """b.bind clears any cached value of b.get_master_branch.""" master1 = self.make_branch('master1') master2 = self.make_branch('master2') branch = self.make_branch('branch') try: branch.bind(master1) except errors.UpgradeRequired: raise tests.TestNotApplicable('Format does not support binding') self.addCleanup(branch.lock_write().unlock) self.assertNotEqual(None, branch.get_master_branch()) branch.bind(master2) self.assertEqual( '.', urlutils.relative_url(self.get_url('master2'), branch.get_master_branch().base))
def test_revision_tree_different_root_id(self): """A revision tree might have a very different root.""" tree = self.make_branch_and_tree('tree1') if not tree.supports_setting_file_ids(): raise tests.TestNotApplicable( 'tree does not support setting file ids') tree.set_root_id(b'one') rev1 = tree.commit('first post') tree.set_root_id(b'two') try: cached_revision_tree = tree.revision_tree(rev1) except errors.NoSuchRevision: # its ok for a working tree to not cache trees, so just return. return repository_revision_tree = tree.branch.repository.revision_tree(rev1) self.assertTreesEqual(repository_revision_tree, cached_revision_tree)
def test_create_clone_on_transport_stacked(self): tree = self.make_branch_and_tree('source') tree.commit('a commit') trunk = tree.branch.create_clone_on_transport( self.get_transport('trunk')) revid = tree.commit('a second commit') source = tree.branch target_transport = self.get_transport('target') try: result = tree.branch.create_clone_on_transport( target_transport, stacked_on=trunk.base) except branch.UnstackableBranchFormat: if not trunk.repository._format.supports_full_versioned_files: raise tests.TestNotApplicable("can not stack on format") raise self.assertEqual(revid, result.last_revision()) self.assertEqual(trunk.base, result.get_stacked_on_url())
def test_open_containing(self): self.assertRaises(errors.NotBranchError, _mod_branch.Branch.open_containing, self.get_readonly_url('')) self.assertRaises(errors.NotBranchError, _mod_branch.Branch.open_containing, self.get_readonly_url('g/p/q')) branch = self.make_branch('.') if not branch.controldir._format.supports_transport( transport.get_transport_from_url(self.get_readonly_url('.'))): raise tests.TestNotApplicable("format does not support transport") branch, relpath = _mod_branch.Branch.open_containing( self.get_readonly_url('')) self.assertEqual('', relpath) branch, relpath = _mod_branch.Branch.open_containing( self.get_readonly_url('g/p/q')) self.assertEqual('g/p/q', relpath)
def test_record_two_ghosts(self): """The working tree should preserve all the parents during commit.""" wt = self.make_branch_and_tree('.') if not wt.branch.repository._format.supports_ghosts: raise tests.TestNotApplicable('format does not support ghosts') wt.set_parent_ids([ b'foo@azkhazan-123123-abcabc', b'wibble@fofof--20050401--1928390812', ], allow_leftmost_as_ghost=True) rev_id = wt.commit("commit from ghost base with one merge") # the revision should have been committed with two parents rev = wt.branch.repository.get_revision(rev_id) self.assertEqual([ b'foo@azkhazan-123123-abcabc', b'wibble@fofof--20050401--1928390812' ], rev.parent_ids)
def test_move_directory_into_parent(self): if not self.workingtree_format.supports_versioned_directories: raise tests.TestNotApplicable( "test requires versioned directories") tree = self.make_branch_and_tree('.') self.build_tree(['c/', 'c/b/', 'c/b/d/']) tree.add(['c', 'c/b', 'c/b/d']) tree.commit('initial') self.assertEqual([('c/b', 'b')], tree.move(['c/b'], '')) self.assertPathRelations( tree.basis_tree(), tree, [('', ''), ('b/', 'c/b/'), ('c/', 'c/'), ('b/d/', 'c/b/d/')]) tree._validate()
def test_sprout_preserves_tags(self): """Sprout preserves tags, even tags of absent revisions.""" try: builder = self.make_branch_builder('source') except errors.UninitializableFormat: raise tests.TestSkipped('Uninitializable branch format') builder.build_commit(message="Rev 1") source = builder.get_branch() try: source.tags.set_tag('tag-a', b'missing-rev') except (errors.TagsNotSupported, errors.GhostTagsNotSupported): raise tests.TestNotApplicable( 'Branch format does not support tags or tags to ghosts.') # Now source has a tag pointing to an absent revision. Sprout it. target_bzrdir = self.make_repository('target').controldir new_branch = source.sprout(target_bzrdir) # The tag is present in the target self.assertEqual(b'missing-rev', new_branch.tags.lookup_tag('tag-a'))
def test_stacked_repositories_reject_commit_builder(self): # As per bug 375013, committing to stacked repositories is currently # broken if we aren't in a chk repository. So old repositories with # fallbacks refuse to hand out a commit builder. repo_basis = self.make_repository('basis') branch = self.make_branch('local') repo_local = branch.repository try: repo_local.add_fallback_repository(repo_basis) except errors.UnstackableRepositoryFormat: raise tests.TestNotApplicable("not a stackable format.") self.addCleanup(repo_local.lock_write().unlock) if not repo_local._format.supports_chks: self.assertRaises(errors.BzrError, repo_local.get_commit_builder, branch, [], branch.get_config_stack()) else: builder = repo_local.get_commit_builder(branch, [], branch.get_config_stack()) builder.abort()
def test_walkdir_versioned_kind(self): work_tree = self.make_branch_and_tree('tree') self.build_tree(['tree/file', 'tree/dir/']) work_tree.add(['file', 'dir']) os.unlink('tree/file') os.rmdir('tree/dir') tree = self._convert_tree(work_tree) tree.lock_read() self.addCleanup(tree.unlock) if tree.path2id('file') is None: raise tests.TestNotApplicable( 'Tree type cannot represent dangling ids.') expected = [('', ([ ('dir', 'dir', 'unknown', None, 'directory')] if tree.has_versioned_directories() else []) + [('file', 'file', 'unknown', None, 'file')])] if tree.has_versioned_directories(): expected.append(('dir', [])) self.assertEqual(expected, list(tree.walkdirs()))
def make_builder_with_merges(self, relpath): try: builder = self.make_branch_builder(relpath) except (errors.TransportNotPossible, errors.UninitializableFormat): raise tests.TestNotApplicable('format not directly constructable') builder.start_series() # 1 # |\ # 2 | # | | # | 1.1.1 # |/ # 3 self.make_snapshot(builder, None, '1') self.make_snapshot(builder, ['1'], '1.1.1') self.make_snapshot(builder, ['1'], '2') self.make_snapshot(builder, ['2', '1.1.1'], '3') builder.finish_series() return builder
def setUp(self): super(TestBreakLock, self).setUp() self.build_tree([ 'master-repo/', 'master-repo/master-branch/', 'repo/', 'repo/branch/', 'checkout/' ]) controldir.ControlDir.create('master-repo').create_repository() self.master_branch = controldir.ControlDir.create_branch_convenience( 'master-repo/master-branch') controldir.ControlDir.create('repo').create_repository() local_branch = controldir.ControlDir.create_branch_convenience( 'repo/branch') try: local_branch.bind(self.master_branch) except branch.BindingUnsupported: raise tests.TestNotApplicable( 'default format does not support bound branches') checkoutdir = controldir.ControlDir.create('checkout') checkoutdir.set_branch_reference(local_branch) self.wt = checkoutdir.create_workingtree()
def test_get_commit_builder_with_surrogateescape(self): tree = self.make_branch_and_tree(".") with tree.lock_write(): builder = tree.branch.get_commit_builder( [], revprops={ 'invalid': u'property' + b'\xc0'.decode('utf-8', 'surrogateescape') }) list( builder.record_iter_changes( tree, tree.last_revision(), tree.iter_changes(tree.basis_tree()))) builder.finish_inventory() try: rev_id = builder.commit('foo bar blah') except NotImplementedError: raise tests.TestNotApplicable( 'Format does not support revision properties') rev = tree.branch.repository.get_revision(rev_id) self.assertEqual('foo bar blah', rev.message)
def break_dirstate(self, tree, completely=False): """Write garbage into the dirstate file.""" if getattr(tree, 'current_dirstate', None) is None: raise tests.TestNotApplicable( 'Only applies to dirstate-based trees') tree.lock_read() try: dirstate = tree.current_dirstate() dirstate_path = dirstate._filename self.assertPathExists(dirstate_path) finally: tree.unlock() # We have to have the tree unlocked at this point, so we can safely # mutate the state file on all platforms. if completely: f = open(dirstate_path, 'wb') else: f = open(dirstate_path, 'ab') try: f.write(b'garbage-at-end-of-file\n') finally: f.close()
def test_sprout_uses_bzrdir_branch_format(self): # branch.sprout(bzrdir) is defined as using the branch format selected # by bzrdir; format preservation is achieved by parameterising the # bzrdir during bzrdir.sprout, which is where stacking compatibility # checks are done. So this test tests that each implementation of # Branch.sprout delegates appropriately to the bzrdir which the # branch is being created in, rather than testing that the result is # in the format that we are testing (which is what would happen if # the branch did not delegate appropriately). if isinstance(self.branch_format, _mod_bzrbranch.BranchReferenceFormat): raise tests.TestNotApplicable('cannot sprout to a reference') # Start with a format that is unlikely to be the target format # We call the super class to allow overriding the format of creation) source = tests.TestCaseWithTransport.make_branch(self, 'old-branch', format='knit') target_bzrdir = self.make_controldir('target') target_bzrdir.create_repository() result_format = self.branch_format if isinstance(target_bzrdir, remote.RemoteBzrDir): # for a remote bzrdir, we need to parameterise it with a branch # format, as, after creation, the newly opened remote objects # do not have one unless a branch was created at the time. # We use branch format 6 because its not the default, and its not # metaweave either. target_bzrdir._format.set_branch_format( _mod_bzrbranch.BzrBranchFormat6()) result_format = target_bzrdir._format.get_branch_format() target = source.sprout(target_bzrdir) if isinstance(target, remote.RemoteBranch): # we have to look at the real branch to see whether RemoteBranch # did the right thing. target._ensure_real() target = target._real_branch if isinstance(result_format, remote.RemoteBranchFormat): # Unwrap a parameterised RemoteBranchFormat for comparison. result_format = result_format._custom_format self.assertIs(result_format.__class__, target._format.__class__)
def test_get_reference(self): """get_reference on all regular branches should return None.""" if not self.branch_format.is_supported(): # unsupported formats are not loopback testable # because the default open will not open them and # they may not be initializable. return made_controldir = self.make_controldir('.') made_controldir.create_repository() if made_controldir._format.colocated_branches: # Formats that support colocated branches sometimes have a default # branch that is a reference branch (such as Git). Cope with # those by creating a different colocated branch. name = 'foo' else: name = None try: made_branch = made_controldir.create_branch(name) except errors.UninitializableFormat: raise tests.TestNotApplicable('Uninitializable branch format') self.assertEqual(None, made_branch._format.get_reference(made_branch.controldir, name))
def test_kind_parent_tree(self): tree, [base_revid, this_revid, other_revid] = self.make_branch_with_merged_deletions() tree.lock_read() self.addCleanup(tree.unlock) parents = tree.get_parent_ids() self.assertEqual([this_revid, other_revid], parents) basis = tree.revision_tree(parents[0]) basis.lock_read() self.addCleanup(basis.unlock) self.assertRaises(errors.NoSuchFile, basis.kind, 'a') self.assertEqual(['directory', 'file'], [basis.kind('b'), basis.kind('b/c')]) try: other = tree.revision_tree(parents[1]) except errors.NoSuchRevisionInTree: raise tests.TestNotApplicable( 'Tree type %s caches only the basis revision tree.' % type(tree)) other.lock_read() self.addCleanup(other.unlock) self.assertRaises(errors.NoSuchFile, other.kind, 'b') self.assertRaises(errors.NoSuchFile, other.kind, 'c') self.assertEqual('file', other.kind('a'))
def test_readonly_unclean(self): """Even if the tree is unclean, we should still handle readonly dirs.""" # First create a tree tree = self.create_basic_tree() if not isinstance(tree, InventoryWorkingTree): raise tests.TestNotApplicable("requires inventory working tree") # XXX: *Ugly* *ugly* hack, we need the hashcache to think it is out of # date, but we don't want to actually wait 3 seconds doing nothing. # WorkingTree formats that don't have a _hashcache should update this # test so that they pass. For now, we just assert that we have the # right type of objects available. the_hashcache = getattr(tree, '_hashcache', None) if the_hashcache is not None: self.assertIsInstance(the_hashcache, hashcache.HashCache) the_hashcache._cutoff_time = self._custom_cutoff_time hack_dirstate = False else: # DirState trees don't have a HashCache, but they do have the same # function as part of the DirState. However, until the tree is # locked, we don't have a DirState to modify hack_dirstate = True # Make it a little dirty self.build_tree_contents([('tree/a', b'new contents of a\n')]) # Make it readonly, and do some operations and then unlock self.set_dirs_readonly('tree') with tree.lock_read(): if hack_dirstate: tree._dirstate._cutoff_time = self._custom_cutoff_time() # Make sure we check all the files for path in tree.all_versioned_paths(): size = tree.get_file_size(path) sha1 = tree.get_file_sha1(path)
def test_create_checkout(self): tree_a = self.make_branch_and_tree('a') branch_a = tree_a.branch checkout_b = branch_a.create_checkout('b') self.assertEqual(b'null:', checkout_b.last_revision()) try: rev1 = checkout_b.commit('rev1') except errors.NoRoundtrippingSupport: raise tests.TestNotApplicable( 'roundtripping between %r and %r not supported' % (checkout_b.branch, checkout_b.branch.get_master_branch())) self.assertEqual(rev1, branch_a.last_revision()) self.assertNotEqual(checkout_b.branch.base, branch_a.base) checkout_c = branch_a.create_checkout('c', lightweight=True) self.assertEqual(rev1, checkout_c.last_revision()) rev2 = checkout_c.commit('rev2') self.assertEqual(rev2, branch_a.last_revision()) self.assertEqual(checkout_c.branch.base, branch_a.base) checkout_d = branch_a.create_checkout('d', lightweight=True) self.assertEqual(rev2, checkout_d.last_revision()) checkout_e = branch_a.create_checkout('e') self.assertEqual(rev2, checkout_e.last_revision())
def setUp(self): super(TestCaseWithComplexRepository, self).setUp() tree_a = self.make_branch_and_tree('a') self.controldir = tree_a.branch.controldir # add a corrupt inventory 'orphan' # this may need some generalising for knits. with tree_a.lock_write(), _mod_repository.WriteGroup(tree_a.branch.repository): inv_file = tree_a.branch.repository.inventories inv_file.add_lines((b'orphan',), [], []) # add a real revision 'rev1' tree_a.commit('rev1', rev_id=b'rev1', allow_pointless=True) # add a real revision 'rev2' based on rev1 tree_a.commit('rev2', rev_id=b'rev2', allow_pointless=True) # add a reference to a ghost tree_a.add_parent_tree_id(b'ghost1') try: tree_a.commit('rev3', rev_id=b'rev3', allow_pointless=True) except errors.RevisionNotPresent: raise tests.TestNotApplicable( "Cannot test with ghosts for this format.") # add another reference to a ghost, and a second ghost. tree_a.add_parent_tree_id(b'ghost1') tree_a.add_parent_tree_id(b'ghost2') tree_a.commit('rev4', rev_id=b'rev4', allow_pointless=True)
def skip_if_no_reference(self, tree): if not tree.supports_tree_reference(): raise tests.TestNotApplicable('Tree references not supported')
def make_reference(self, name): tree = self.make_branch_and_tree(name) if not tree.branch.repository._format.rich_root_data: raise tests.TestNotApplicable('format does not support rich roots') tree.commit('foo') return tree
def skip_if_no_reference(self, tree): if not getattr(tree, 'supports_tree_reference', lambda: False)(): raise tests.TestNotApplicable('Tree references not supported')
def setUp(self): super(TestApplyInventoryDelta, self).setUp() if not self.bzrdir_format.repository_format.supports_full_versioned_files: raise tests.TestNotApplicable( "format does not support inventory deltas")
def bind(self, branch, master): try: branch.bind(master) except errors.UpgradeRequired: raise tests.TestNotApplicable('Branch cannot be bound.')
def setUp(self): super(TestUncommittedChanges, self).setUp() if not self.branch_format.supports_store_uncommitted(): raise tests.TestNotApplicable( 'Branch format does not support store_uncommitted')
def skip_if_storing_uncommitted_unsupported(): try: yield except errors.StoringUncommittedNotSupported: raise tests.TestNotApplicable('Cannot store uncommitted changes.')
def setUp(self): super(TestIsIgnored, self).setUp() if self.workingtree_format.ignore_filename != '.bzrignore': raise tests.TestNotApplicable( 'format does not use .bzrignore for ignore patterns')
def setUp(self): super(TestFileIds, self).setUp() if not self.workingtree_format.supports_setting_file_ids: raise tests.TestNotApplicable("working tree does not support setting file ids")