Rev 4258: Far too many modifications for a single commit, need to restart. in file:///home/vila/src/bzr/bugs/355454-unicode-warning/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Apr 16 15:13:57 BST 2009


At file:///home/vila/src/bzr/bugs/355454-unicode-warning/

------------------------------------------------------------
revno: 4258
revision-id: v.ladeuil+lp at free.fr-20090416141357-dowo6huqi1232fgm
parent: v.ladeuil+lp at free.fr-20090415150037-vrzwuwzv0uh0w3nx
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 355454-unicode-warning
timestamp: Thu 2009-04-16 16:13:57 +0200
message:
  Far too many modifications for a single commit, need to restart.
  
  * bzrlib/tests/workingtree_implementations/test_parents.py:
  (TestSetParents.test_unicode_symlink): Add more checks for
  involved trees.
  
  * bzrlib/tests/tree_implementations/test_get_symlink_target.py:
  (TestGetSymlinkTarget.test_get_unicode_symlink_target): Bah, no
  need to test unicode file-ids here.
  
  * bzrlib/tests/test_transform.py:
  (TestBuildTree.test_case_insensitive_build_tree_inventory): Fix
  the test condition for good.
  
  * bzrlib/tests/test_shelf.py:
  Fix imports.
  (TestPrepareShelf._test_shelve_symlink_target_change): Factored
  out.
  (TestPrepareShelf.test_shelve_symlink_target_change)
  (TestPrepareShelf.test_shelve_unicode_symlink_target_change): Also
  test unicode symlinks.
  
  * bzrlib/tests/test_bundle.py:
  (BundleTester._test_symlink_bundle): Factored out.
  (BundleTester.test_symlink_bundle,
  BundleTester.test_unicode_symlink_bundle): Also test unicode
  symlinks.
  
  * bzrlib/tests/test__dirstate_helpers.py:
  Fix some imports.
  (load_tests): Start parametrizing against DirReaders.
  
  * bzrlib/merge_directive.py:
  (MergeDirectiveFormatRegistry): Add Aaron explanation for the
  double registration.
  
  * bzrlib/hashcache.py:
  (HashCache.get_sha1): Instrumented for pronto.
  
  * bzrlib/revisiontree.py:
  (RevisionTree.get_symlink_target): Add comment.
  
  * bzrlib/osutils.py:
  (_walkdirs_utf8, UnicodeDirReader.read_dir): Intrumented for pronto.
  
  * bzrlib/dirstate.py:
  (DirState._read_link): Intrumented for pronto.
  
  * bzrlib/tests/per_repository/test_commit_builder.py:
  (TestCommitBuilder._add_commit_change_check_changed): Add a
  file_id optional parameter.
  (TestCommitBuilder._test_last_mod_rev_after_content_link_changes_ric):
  Factored out.
  (TestCommitBuilder.test_last_modified_rev_after_content_link_changes_ric,
  TestCommitBuilder.test_last_modified_rev_after_content_unicode_link_changes_ric):
  Also test unicode symlinks.
  
  * bzrlib/tests/branch_implementations/test_sprout.py:
  (TestSprout.test_sprout_with_unicode_symlink): Use an unicode name
  for the link too. Add more checks for involved trees.
-------------- next part --------------
=== modified file 'BRANCH.TODO'
--- a/BRANCH.TODO	2009-04-08 16:33:19 +0000
+++ b/BRANCH.TODO	2009-04-16 14:13:57 +0000
@@ -3,3 +3,32 @@
 # 
 #
 
+- test and code osutils.readlink around:
+
+        def read_link(link):
+            # The only reliable way to get the link target for python2.[456]
+            # other aternative implementations either fails to reliably return
+            # a unicode string or fails to encode the received unicode string
+            link = link.encode(osutils._fs_enc)
+            target = os.readlink(link)
+            target = target.decode(osutils._fs_enc)
+            return target
+
+- use osutils.readlink in: 
+
+  - HashCache.get_sha1 (one test failing)
+  - bzrlib/tests/test_transform.py
+  - bzrlib/transform.py _PreviewTree.get_symlink_target
+  - bzrlib/workingtree.py WorkingTree.path_content_summary and
+    get_symlink_target
+ 
+- finish parametrizing bzrlib/tests/test__dirstate_helpers.py
+
+- add unicode symlink tests in :
+
+  - bzrlib/tests/test_transform.py
+
+- clean up spurious changes
+
+- check all pdb and pronto calls
+

=== modified file 'bzrlib/bundle/bundle_data.py'
--- a/bzrlib/bundle/bundle_data.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/bundle/bundle_data.py	2009-04-16 14:13:57 +0000
@@ -458,6 +458,7 @@
 
 
 class BundleTree(Tree):
+
     def __init__(self, base_tree, revision_id):
         self.base_tree = base_tree
         self._renamed = {} # Mapping from old_path => new_path

=== modified file 'bzrlib/bundle/serializer/v08.py'
--- a/bzrlib/bundle/serializer/v08.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/bundle/serializer/v08.py	2009-04-16 14:13:57 +0000
@@ -91,6 +91,7 @@
 
 
 class BundleSerializerV08(BundleSerializer):
+
     def read(self, f):
         """Read the rest of the bundles from the supplied file.
 

=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py	2009-04-08 03:34:31 +0000
+++ b/bzrlib/dirstate.py	2009-04-16 14:13:57 +0000
@@ -1637,6 +1637,7 @@
         #       higher level, because there either won't be anything on disk,
         #       or the thing on disk will be a file.
         fs_encoding = osutils._fs_enc
+        import pronto; pronto.bzr_test('dirstate._read_link(%r)' % abspath)
         if isinstance(abspath, unicode):
             # abspath is defined as the path to pass to lstat. readlink is
             # buggy in python < 2.6 (it doesn't encode unicode path into FS
@@ -1647,6 +1648,7 @@
         if fs_encoding not in ('UTF-8', 'US-ASCII', 'ANSI_X3.4-1968'):
             # Change encoding if needed
             target = target.decode(fs_encoding).encode('UTF-8')
+        pronto.bzr_test('dirstate._read_link() -> %r' % target)
         return target
 
     def get_ghosts(self):

=== modified file 'bzrlib/hashcache.py'
--- a/bzrlib/hashcache.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/hashcache.py	2009-04-16 14:13:57 +0000
@@ -176,9 +176,13 @@
                 filters = self._filter_provider(path=path, file_id=None)
             digest = self._really_sha1_file(abspath, filters)
         elif stat.S_ISLNK(mode):
-            digest = sha_string(os.readlink(abspath))
+            target = os.readlink(abspath)
+            import pronto
+            pronto.bzr_test('HashCache.get_sha1(%r) -> %r' % (abspath, target))
+            digest = sha_string(target)
         else:
-            raise BzrError("file %r: unknown file stat mode: %o"%(abspath,mode))
+            raise BzrError("file %r: unknown file stat mode: %o"
+                           % (abspath, mode))
 
         # window of 3 seconds to allow for 2s resolution on windows,
         # unsynchronized file servers, etc.

=== modified file 'bzrlib/merge_directive.py'
--- a/bzrlib/merge_directive.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/merge_directive.py	2009-04-16 14:13:57 +0000
@@ -566,5 +566,8 @@
 _format_registry = MergeDirectiveFormatRegistry()
 _format_registry.register(MergeDirective)
 _format_registry.register(MergeDirective2)
+# 0.19 never existed.  It got renamed to 0.90.  But by that point, there were
+# already merge directives in the wild that used 0.19. Registering with the old
+# format string to retain compatibility with those merge directives.
 _format_registry.register(MergeDirective2,
                           'Bazaar merge directive format 2 (Bazaar 0.19)')

=== modified file 'bzrlib/osutils.py'
--- a/bzrlib/osutils.py	2009-04-10 12:01:07 +0000
+++ b/bzrlib/osutils.py	2009-04-16 14:13:57 +0000
@@ -1381,6 +1381,7 @@
         path-from-top might be unicode or utf8, but it is the correct path to
         pass to os functions to affect the file in question. (such as os.lstat)
     """
+    import pronto; pronto.bzr_test('osutils._walkdirs_utf8')
     global _selected_dir_reader
     if _selected_dir_reader is None:
         fs_encoding = _fs_enc.upper()
@@ -1449,6 +1450,7 @@
 
         See DirReader.read_dir for details.
         """
+        import pronto; pronto.bzr_test('UnicodeDirReader._read_dir')
         _utf8_encode = self._utf8_encode
         _lstat = os.lstat
         _listdir = os.listdir

=== modified file 'bzrlib/revisiontree.py'
--- a/bzrlib/revisiontree.py	2009-04-09 20:23:07 +0000
+++ b/bzrlib/revisiontree.py	2009-04-16 14:13:57 +0000
@@ -125,7 +125,8 @@
 
     def get_symlink_target(self, file_id):
         ie = self._inventory[file_id]
-        return ie.symlink_target;
+        # Inventories store symlink targets in unicode
+        return ie.symlink_target
 
     def get_reference_revision(self, file_id, path=None):
         return self.inventory[file_id].reference_revision

=== modified file 'bzrlib/tests/branch_implementations/test_sprout.py'
--- a/bzrlib/tests/branch_implementations/test_sprout.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/branch_implementations/test_sprout.py	2009-04-16 14:13:57 +0000
@@ -20,6 +20,7 @@
 from bzrlib import (
     branch as _mod_branch,
     errors,
+    osutils,
     remote,
     revision as _mod_revision,
     tests,
@@ -139,11 +140,30 @@
         # The link points to a file whose name is an omega
         # U+03A9 GREEK CAPITAL LETTER OMEGA
         # UTF-8: ce a9  UTF-16BE: 03a9  Decimal: &#937;
-        os.symlink(u'\u03a9','tree1/link_name')
-        tree.add(['link_name'],['link-id'])
+        target = u'\u03a9'
+        link_name = u'\N{Euro Sign}link'
+        os.symlink(target, 'tree1/' + link_name)
+        tree.add([link_name],['link-id'])
 
         revision = tree.commit('added a link to a Unicode target')
-        tree.bzrdir.sprout('target')
+        tree.bzrdir.sprout('dest')
+
+        def read_link(link):
+            # The only reliable way to get the link target for python2.[456]
+            # other aternative implementations either fails to reliably return
+            # a unicode string or fails to encode the received unicode string
+            link = link.encode(osutils._fs_enc)
+            target = os.readlink(link)
+            target = target.decode(osutils._fs_enc)
+            return target
+
+        self.assertEqual(target, read_link('dest/' + link_name))
+        tree.lock_read()
+        self.addCleanup(tree.unlock)
+        # Check that the symlink target is safely round-tripped in the trees.
+        self.assertEqual(target, tree.get_symlink_target('link-id'))
+        self.assertEqual(target,
+                         tree.basis_tree().get_symlink_target('link-id'))
 
     def assertBranchHookBranchIsStacked(self, pre_change_params):
         # Just calling will either succeed or fail.

=== modified file 'bzrlib/tests/per_repository/test_commit_builder.py'
--- a/bzrlib/tests/per_repository/test_commit_builder.py	2009-04-09 20:23:07 +0000
+++ b/bzrlib/tests/per_repository/test_commit_builder.py	2009-04-16 14:13:57 +0000
@@ -735,9 +735,12 @@
             mini_commit=self.mini_commit_record_iter_changes)
 
     def _add_commit_change_check_changed(self, tree, name, changer,
-        expect_fs_hash=False, mini_commit=None):
-        tree.add([name], [name + 'id'])
-        self._commit_change_check_changed(tree, name, name + 'id',
+        expect_fs_hash=False, mini_commit=None, file_id=None):
+        if file_id is None:
+            file_id = name + 'id'
+        tree.add([name], [file_id])
+        self._commit_change_check_changed(
+            tree, name, file_id,
             changer, expect_fs_hash=expect_fs_hash, mini_commit=mini_commit)
 
     def _commit_change_check_changed(self, tree, name, file_id, changer,
@@ -947,16 +950,32 @@
             os.symlink('newtarget', 'link')
         self._add_commit_change_check_changed(tree, 'link', change_link)
 
-    def test_last_modified_revision_after_content_link_changes_ric(self):
+    def _test_last_mod_rev_after_content_link_changes_ric(
+        self, link, target, newtarget, file_id=None):
+        if file_id is None:
+            file_id = link
         # changing a link changes the last modified.
         self.requireFeature(tests.SymlinkFeature)
         tree = self.make_branch_and_tree('.')
-        os.symlink('target', 'link')
+        os.symlink(target, link)
         def change_link():
-            os.unlink('link')
-            os.symlink('newtarget', 'link')
-        self._add_commit_change_check_changed(tree, 'link', change_link,
-            mini_commit=self.mini_commit_record_iter_changes)
+            os.unlink(link)
+            os.symlink(newtarget, link)
+        self._add_commit_change_check_changed(
+            tree, link, change_link,
+            mini_commit=self.mini_commit_record_iter_changes,
+            file_id=file_id)
+
+    def test_last_modified_rev_after_content_link_changes_ric(self):
+        self._test_last_mod_rev_after_content_link_changes_ric(
+            'link', 'target', 'newtarget')
+
+    def test_last_modified_rev_after_content_unicode_link_changes_ric(self):
+        self.requireFeature(tests.UnicodeFilenameFeature)
+        self._test_last_mod_rev_after_content_link_changes_ric(
+            u'li\u1234nk', u'targ\N{Euro Sign}t', u'n\N{Euro Sign}wtarget',
+
+            file_id=u'li\u1234nk'.encode('UTF-8'))
 
     def _commit_sprout(self, tree, name):
         tree.add([name], [name + 'id'])

=== modified file 'bzrlib/tests/test__dirstate_helpers.py'
--- a/bzrlib/tests/test__dirstate_helpers.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/test__dirstate_helpers.py	2009-04-16 14:13:57 +0000
@@ -27,9 +27,21 @@
     tests,
     )
 from bzrlib.tests import (
-        SymlinkFeature,
-        )
-from bzrlib.tests import test_dirstate
+    test_dirstate,
+    test_osutils,
+    )
+
+
+def load_tests(basic_tests, module, loader):
+    # FIXME: we should also parametrize agsinst C/Python
+    suite = loader.suiteClass()
+    dir_reader_tests, remaining_tests = tests.split_suite_by_condition(
+        basic_tests, tests.condition_isinstance(
+            test_dirstate.TestCaseWithDirState))
+    tests.multiply_tests(dir_reader_tests,
+                         test_osutils.dir_reader_scenarios(), suite)
+    suite.addTest(remaining_tests)
+    return suite
 
 
 class _CompiledDirstateHelpersFeature(tests.Feature):
@@ -921,7 +933,7 @@
 
     def test_update_entry_symlink(self):
         """Update entry should read symlinks."""
-        self.requireFeature(SymlinkFeature)
+        self.requireFeature(tests.SymlinkFeature)
         state, entry = self.get_state_with_a()
         state.save()
         self.assertEqual(dirstate.DirState.IN_MEMORY_UNMODIFIED,
@@ -1098,7 +1110,7 @@
 
     def test_update_file_to_symlink(self):
         """File becomes a symlink"""
-        self.requireFeature(SymlinkFeature)
+        self.requireFeature(tests.SymlinkFeature)
         state, entry = self.get_state_with_a()
         # The file sha1 won't be cached unless the file is old
         state.adjust_time(+10)
@@ -1117,7 +1129,7 @@
 
     def test_update_dir_to_symlink(self):
         """Directory becomes a symlink"""
-        self.requireFeature(SymlinkFeature)
+        self.requireFeature(tests.SymlinkFeature)
         state, entry = self.get_state_with_a()
         # The symlink target won't be cached if it isn't old
         state.adjust_time(+10)
@@ -1127,7 +1139,7 @@
 
     def test_update_symlink_to_file(self):
         """Symlink becomes a file"""
-        self.requireFeature(SymlinkFeature)
+        self.requireFeature(tests.SymlinkFeature)
         state, entry = self.get_state_with_a()
         # The symlink and file info won't be cached unless old
         state.adjust_time(+10)
@@ -1137,7 +1149,7 @@
 
     def test_update_symlink_to_dir(self):
         """Symlink becomes a directory"""
-        self.requireFeature(SymlinkFeature)
+        self.requireFeature(tests.SymlinkFeature)
         state, entry = self.get_state_with_a()
         # The symlink target won't be cached if it isn't old
         state.adjust_time(+10)

=== modified file 'bzrlib/tests/test_bundle.py'
--- a/bzrlib/tests/test_bundle.py	2009-03-25 16:27:34 +0000
+++ b/bzrlib/tests/test_bundle.py	2009-04-16 14:13:57 +0000
@@ -661,36 +661,60 @@
                           verbose=False)
         bundle = self.get_valid_bundle('a at cset-0-6', 'a at cset-0-7')
 
-    def test_symlink_bundle(self):
+    def _test_symlink_bundle(self, link_name, link_target, new_link_target):
+        link_id = 'link-1'
+
         self.requireFeature(SymlinkFeature)
         self.tree1 = self.make_branch_and_tree('b1')
         self.b1 = self.tree1.branch
+
         tt = TreeTransform(self.tree1)
-        tt.new_symlink('link', tt.root, 'bar/foo', 'link-1')
+        tt.new_symlink(link_name, tt.root, link_target, link_id)
         tt.apply()
         self.tree1.commit('add symlink', rev_id='l at cset-0-1')
-        self.get_valid_bundle('null:', 'l at cset-0-1')
+        bundle = self.get_valid_bundle('null:', 'l at cset-0-1')
+        if getattr(bundle ,'revision_tree', None) is not None:
+            # Not all bundle formats supports revision_tree
+            bund_tree = bundle.revision_tree(self.b1.repository, 'l at cset-0-1')
+            self.assertEqual(link_target, bund_tree.get_symlink_target(link_id))
+
         tt = TreeTransform(self.tree1)
-        trans_id = tt.trans_id_tree_file_id('link-1')
+        trans_id = tt.trans_id_tree_file_id(link_id)
         tt.adjust_path('link2', tt.root, trans_id)
         tt.delete_contents(trans_id)
-        tt.create_symlink('mars', trans_id)
+        tt.create_symlink(new_link_target, trans_id)
         tt.apply()
         self.tree1.commit('rename and change symlink', rev_id='l at cset-0-2')
-        self.get_valid_bundle('l at cset-0-1', 'l at cset-0-2')
+        bundle = self.get_valid_bundle('l at cset-0-1', 'l at cset-0-2')
+        if getattr(bundle ,'revision_tree', None) is not None:
+            # Not all bundle formats supports revision_tree
+            bund_tree = bundle.revision_tree(self.b1.repository, 'l at cset-0-2')
+            self.assertEqual(new_link_target,
+                             bund_tree.get_symlink_target(link_id))
+
         tt = TreeTransform(self.tree1)
-        trans_id = tt.trans_id_tree_file_id('link-1')
+        trans_id = tt.trans_id_tree_file_id(link_id)
         tt.delete_contents(trans_id)
         tt.create_symlink('jupiter', trans_id)
         tt.apply()
         self.tree1.commit('just change symlink target', rev_id='l at cset-0-3')
-        self.get_valid_bundle('l at cset-0-2', 'l at cset-0-3')
+        bundle = self.get_valid_bundle('l at cset-0-2', 'l at cset-0-3')
+
         tt = TreeTransform(self.tree1)
-        trans_id = tt.trans_id_tree_file_id('link-1')
+        trans_id = tt.trans_id_tree_file_id(link_id)
         tt.delete_contents(trans_id)
         tt.apply()
         self.tree1.commit('Delete symlink', rev_id='l at cset-0-4')
-        self.get_valid_bundle('l at cset-0-3', 'l at cset-0-4')
+        bundle = self.get_valid_bundle('l at cset-0-3', 'l at cset-0-4')
+
+    def test_symlink_bundle(self):
+        self._test_symlink_bundle('link', 'bar/foo', 'mars')
+
+    def test_unicode_symlink_bundle(self):
+        self.requireFeature(tests.UnicodeFilenameFeature)
+        self._test_symlink_bundle(u'\N{Euro Sign}link',
+                                  u'bar/\N{Euro Sign}foo',
+                                  u'mars\N{Euro Sign}')
 
     def test_binary_bundle(self):
         self.tree1 = self.make_branch_and_tree('b1')

=== modified file 'bzrlib/tests/test_shelf.py'
--- a/bzrlib/tests/test_shelf.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/test_shelf.py	2009-04-16 14:13:57 +0000
@@ -16,7 +16,15 @@
 
 import os
 
-from bzrlib import errors, pack, shelf, tests, transform, workingtree
+from bzrlib import (
+    errors,
+    osutils,
+    pack,
+    shelf,
+    tests,
+    transform,
+    workingtree,
+    )
 
 
 EMPTY_SHELF = ("Bazaar pack format 1 (introduced in 0.18)\n"
@@ -140,26 +148,46 @@
         limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
         self.assertEqual('bar', os.readlink(limbo_name))
 
-    def test_shelve_symlink_target_change(self):
+    def _test_shelve_symlink_target_change(self, link_name,
+                                           old_target, new_target):
         self.requireFeature(tests.SymlinkFeature)
         tree = self.make_branch_and_tree('.')
         tree.lock_write()
         self.addCleanup(tree.unlock)
-        os.symlink('bar', 'foo')
-        tree.add('foo', 'foo-id')
+        os.symlink(old_target, link_name)
+        tree.add(link_name, 'foo-id')
         tree.commit("commit symlink")
-        os.unlink("foo")
-        os.symlink('baz', 'foo')
+        os.unlink(link_name)
+        os.symlink(new_target, link_name)
         creator = shelf.ShelfCreator(tree, tree.basis_tree())
         self.addCleanup(creator.finalize)
-        self.assertEqual([('modify target', 'foo-id', 'foo', 'bar', 'baz')],
+        self.assertEqual([('modify target', 'foo-id', link_name,
+                           old_target, new_target)],
                          list(creator.iter_shelvable()))
         creator.shelve_modify_target('foo-id')
         creator.transform()
-        self.assertEqual('bar', os.readlink('foo'))
+
+        def read_link(link):
+            # Only reliable way to get the link target for python2.[456] other
+            # laternative implementations either fails to reliably reutrn a
+            # unicode string or fails to encode the received unicode string
+            link = link.encode(osutils._fs_enc)
+            target = os.readlink(link)
+            target = target.decode(osutils._fs_enc)
+            return target
+
+        self.assertEqual(old_target, read_link(link_name))
         s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
         limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
-        self.assertEqual('baz', os.readlink(limbo_name))
+        self.assertEqual(new_target, read_link(limbo_name))
+
+    def test_shelve_symlink_target_change(self):
+        self._test_shelve_symlink_target_change('foo', 'bar', 'baz')
+
+    def test_shelve_unicode_symlink_target_change(self):
+        self.requireFeature(tests.UnicodeFilenameFeature)
+        self._test_shelve_symlink_target_change(
+            u'fo\N{Euro Sign}o', u'b\N{Euro Sign}ar', u'b\N{Euro Sign}az')
 
     def test_shelve_creation_no_contents(self):
         tree = self.make_branch_and_tree('.')

=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py	2009-04-06 11:41:40 +0000
+++ b/bzrlib/tests/test_transform.py	2009-04-16 14:13:57 +0000
@@ -525,9 +525,10 @@
         resolve_conflicts(replace)
         replace.apply()
 
+    # unicode symlinks ?
     def test_symlinks(self):
         self.requireFeature(SymlinkFeature)
-        transform,root = self.get_transform()
+        transform, root = self.get_transform()
         oz_id = transform.new_directory('oz', root, 'oz-id')
         wizard = transform.new_symlink('wizard', oz_id, 'wizard-target',
                                        'wizard-id')
@@ -1841,8 +1842,8 @@
         self.assertTrue(source.is_executable('file1-id'))
 
     def test_case_insensitive_build_tree_inventory(self):
-        if (not tests.CaseInsensitiveFilesystemFeature.available()
-            or not tests.CaseInsCasePresFilenameFeature.available()):
+        if (tests.CaseInsensitiveFilesystemFeature.available()
+            or tests.CaseInsCasePresFilenameFeature.available()):
             raise tests.UnavailableFeature('Fully case sensitive filesystem')
         source = self.make_branch_and_tree('source')
         self.build_tree(['source/file', 'source/FILE'])
@@ -2688,10 +2689,12 @@
         self.assertSerializesTo(self.symlink_creation_records(), tt)
 
     def test_deserialize_symlink_creation(self):
+        self.requireFeature(tests.SymlinkFeature)
         tt = self.get_preview()
         tt.deserialize(iter(self.symlink_creation_records()))
-        # XXX readlink should be returning unicode, not utf-8
-        foo_content = os.readlink(tt._limbo_name('new-1')).decode('utf-8')
+        abspath = tt._limbo_name('new-1')
+        # FIXME: should use a safe readlink impl.
+        foo_content = os.readlink(abspath).decode(osutils._fs_enc)
         self.assertEqual(u'bar\u1234', foo_content)
 
     def make_destruction_preview(self):

=== modified file 'bzrlib/tests/tree_implementations/test_get_symlink_target.py'
--- a/bzrlib/tests/tree_implementations/test_get_symlink_target.py	2009-04-11 16:06:53 +0000
+++ b/bzrlib/tests/tree_implementations/test_get_symlink_target.py	2009-04-16 14:13:57 +0000
@@ -53,9 +53,9 @@
         tree = self.make_branch_and_tree('tree')
         target = u'targ\N{Euro Sign}t'
         os.symlink(target,  u'tree/\u03b2_link'.encode(osutils._fs_enc))
-        tree.add([u'\u03b2_link'], ['unicode-link-id'])
+        tree.add([u'\u03b2_link'], ['link-id'])
         tree.lock_read()
         self.addCleanup(tree.unlock)
-        actual = tree.get_symlink_target(u'unicode-link-id')
+        actual = tree.get_symlink_target('link-id')
         self.assertEqual(target, actual)
 

=== modified file 'bzrlib/tests/workingtree_implementations/test_parents.py'
--- a/bzrlib/tests/workingtree_implementations/test_parents.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_parents.py	2009-04-16 14:13:57 +0000
@@ -237,12 +237,20 @@
         # The link points to a file whose name is an omega
         # U+03A9 GREEK CAPITAL LETTER OMEGA
         # UTF-8: ce a9  UTF-16BE: 03a9  Decimal: &#937;
-        os.symlink(u'\u03a9','tree1/link_name')
-        tree.add(['link_name'],['link-id'])
+        target = u'\u03a9'
+        link_name = u'\N{Euro Sign}link'
+        os.symlink(target, 'tree1/' + link_name)
+        tree.add([link_name],['link-id'])
 
         revision1 = tree.commit('added a link to a Unicode target')
         revision2 = tree.commit('this revision will be discarded')
         tree.set_parent_ids([revision1])
+        tree.lock_read()
+        self.addCleanup(tree.unlock)
+        # Check that the symlink target is safely round-tripped in the trees.
+        self.assertEqual(target, tree.get_symlink_target('link-id'))
+        basis = tree.basis_tree()
+        self.assertEqual(target, basis.get_symlink_target('link-id'))
 
 
 class TestAddParent(TestParents):

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2009-04-02 04:12:11 +0000
+++ b/bzrlib/transform.py	2009-04-16 14:13:57 +0000
@@ -1910,6 +1910,7 @@
             return self._transform._tree.get_symlink_target(file_id)
         trans_id = self._transform.trans_id_file_id(file_id)
         name = self._transform._limbo_name(trans_id)
+        # XXX: Looks like we can return arbitrary encoded path below
         return os.readlink(name)
 
     def walkdirs(self, prefix=''):

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2009-04-04 02:50:01 +0000
+++ b/bzrlib/workingtree.py	2009-04-16 14:13:57 +0000
@@ -749,9 +749,10 @@
                 kind = 'tree-reference'
             return kind, None, None, None
         elif kind == 'symlink':
-            return ('symlink', None, None,
-                    os.readlink(abspath.encode(osutils._fs_enc)
-                                ).decode(osutils._fs_enc))
+#            import pronto; pronto.bzr_test('WorkingTree.path_content_summary')
+            target = os.readlink(abspath.encode(osutils._fs_enc))
+            target = target.decode(osutils._fs_enc)
+            return ('symlink', None, None, target)
         else:
             return (kind, None, None, None)
 
@@ -973,8 +974,10 @@
         return file_id
 
     def get_symlink_target(self, file_id):
-        return os.readlink(self.id2abspath(file_id).encode(osutils._fs_enc)
-            ).decode(osutils._fs_enc)
+        abspath = self.id2abspath(file_id)
+        target = os.readlink(abspath.encode(osutils._fs_enc))
+        target = target.decode(osutils._fs_enc)
+        return target
 
     @needs_write_lock
     def subsume(self, other_tree):



More information about the bazaar-commits mailing list