]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
Use "long" paths prefixed with \\?\ on Windows. refs #2235
authorDaira Hopwood <daira@jacaranda.org>
Fri, 30 Jan 2015 00:05:14 +0000 (00:05 +0000)
committerDaira Hopwood <daira@jacaranda.org>
Fri, 30 Jan 2015 00:05:14 +0000 (00:05 +0000)
Signed-off-by: Daira Hopwood <daira@jacaranda.org>
src/allmydata/scripts/debug.py
src/allmydata/test/test_cli.py
src/allmydata/test/test_client.py
src/allmydata/test/test_util.py
src/allmydata/util/fileutil.py

index 8ef82eca9a0de26a2cd0c8dcdad9707d4830f934..1bba9d5fdb1082cadf7482216aa6591fc3933c91 100644 (file)
@@ -650,7 +650,7 @@ def find_shares(options):
     out = options.stdout
     sharedir = storage_index_to_dir(si_a2b(options.si_s))
     for d in options.nodedirs:
-        d = os.path.join(d, "storage/shares", sharedir)
+        d = os.path.join(d, "storage", "shares", sharedir)
         if os.path.exists(d):
             for shnum in listdir_unicode(d):
                 print >>out, os.path.join(d, shnum)
@@ -832,7 +832,7 @@ def catalog_shares(options):
     err = options.stderr
     now = time.time()
     for d in options.nodedirs:
-        d = os.path.join(d, "storage/shares")
+        d = os.path.join(d, "storage", "shares")
         try:
             abbrevs = listdir_unicode(d)
         except EnvironmentError:
index 6bc5fc1c614b367a90b87e91bdc3a147fe9c0526..a277f0b6b9228fc9fba978f1cb9fad720f7a9cda 100644 (file)
@@ -3779,7 +3779,7 @@ class Webopen(GridTestMixin, CLITestMixin, unittest.TestCase):
             raise
         return d
 
-class Options(unittest.TestCase):
+class Options(ReallyEqualMixin, unittest.TestCase):
     # this test case only looks at argument-processing and simple stuff.
 
     def parse(self, args, stdout=None):
@@ -3861,17 +3861,17 @@ class Options(unittest.TestCase):
         # option after, or a basedir argument after, but none in the wrong
         # place, and not more than one of the three.
         o = self.parse(["start"])
-        self.failUnlessEqual(o["basedir"], os.path.join(os.path.expanduser("~"),
-                                                        ".tahoe"))
+        self.failUnlessReallyEqual(o["basedir"], os.path.join(fileutil.abspath_expanduser_unicode(u"~"),
+                                                              u".tahoe"))
         o = self.parse(["start", "here"])
-        self.failUnlessEqual(o["basedir"], os.path.abspath("here"))
+        self.failUnlessReallyEqual(o["basedir"], fileutil.abspath_expanduser_unicode(u"here"))
         o = self.parse(["start", "--basedir", "there"])
-        self.failUnlessEqual(o["basedir"], os.path.abspath("there"))
+        self.failUnlessReallyEqual(o["basedir"], fileutil.abspath_expanduser_unicode(u"there"))
         o = self.parse(["--node-directory", "there", "start"])
-        self.failUnlessEqual(o["basedir"], os.path.abspath("there"))
+        self.failUnlessReallyEqual(o["basedir"], fileutil.abspath_expanduser_unicode(u"there"))
 
         o = self.parse(["start", "here", "--nodaemon"])
-        self.failUnlessEqual(o["basedir"], os.path.abspath("here"))
+        self.failUnlessReallyEqual(o["basedir"], fileutil.abspath_expanduser_unicode(u"here"))
 
         self.failUnlessRaises(usage.UsageError, self.parse,
                               ["--basedir", "there", "start"])
index 531215f6129cfbf53f1c1bbe96e3be15a410b0e1..f5b0526ba624b0f2588d86b2b2cf6ee44a75ea79 100644 (file)
@@ -1,4 +1,4 @@
-import os
+import os, sys
 from twisted.trial import unittest
 from twisted.application import service
 
@@ -68,10 +68,11 @@ class Basic(testutil.ReallyEqualMixin, unittest.TestCase):
         fileutil.write(os.path.join(basedir, "debug_discard_storage"), "")
 
         e = self.failUnlessRaises(OldConfigError, client.Client, basedir)
-        self.failUnlessIn(os.path.abspath(os.path.join(basedir, "introducer.furl")), e.args[0])
-        self.failUnlessIn(os.path.abspath(os.path.join(basedir, "no_storage")), e.args[0])
-        self.failUnlessIn(os.path.abspath(os.path.join(basedir, "readonly_storage")), e.args[0])
-        self.failUnlessIn(os.path.abspath(os.path.join(basedir, "debug_discard_storage")), e.args[0])
+        abs_basedir = fileutil.abspath_expanduser_unicode(unicode(basedir)).encode(sys.getfilesystemencoding())
+        self.failUnlessIn(os.path.join(abs_basedir, "introducer.furl"), e.args[0])
+        self.failUnlessIn(os.path.join(abs_basedir, "no_storage"), e.args[0])
+        self.failUnlessIn(os.path.join(abs_basedir, "readonly_storage"), e.args[0])
+        self.failUnlessIn(os.path.join(abs_basedir, "debug_discard_storage"), e.args[0])
 
         for oldfile in ['introducer.furl', 'no_storage', 'readonly_storage',
                         'debug_discard_storage']:
index 20f157b946b27f6bbee43fd34d2eb707cb30eaf4..16e8383fc01788fb8bc7696325f90a872b080dd4 100644 (file)
@@ -15,6 +15,8 @@ from allmydata.util import limiter, time_format, pollmixin, cachedir
 from allmydata.util import statistics, dictutil, pipeline
 from allmydata.util import log as tahoe_log
 from allmydata.util.spans import Spans, overlap, DataSpans
+from allmydata.test.common_util import ReallyEqualMixin
+
 
 class Base32(unittest.TestCase):
     def test_b2a_matches_Pythons(self):
@@ -370,7 +372,7 @@ class Asserts(unittest.TestCase):
         m = self.should_assert(f, False, othermsg="message2")
         self.failUnlessEqual("postcondition: othermsg: 'message2' <type 'str'>", m)
 
-class FileUtil(unittest.TestCase):
+class FileUtil(ReallyEqualMixin, unittest.TestCase):
     def mkdir(self, basedir, path, mode=0777):
         fn = os.path.join(basedir, path)
         fileutil.make_dirs(fn, mode)
@@ -472,7 +474,16 @@ class FileUtil(unittest.TestCase):
         abspath_cwd = fileutil.abspath_expanduser_unicode(u".")
         self.failUnless(isinstance(saved_cwd, unicode), saved_cwd)
         self.failUnless(isinstance(abspath_cwd, unicode), abspath_cwd)
-        self.failUnlessEqual(abspath_cwd, saved_cwd)
+        if sys.platform == "win32":
+            self.failUnlessReallyEqual(abspath_cwd, fileutil.to_windows_long_path(saved_cwd))
+        else:
+            self.failUnlessReallyEqual(abspath_cwd, saved_cwd)
+
+        self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"\\\\?\\foo"), u"\\\\?\\foo")
+        self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"\\\\.\\foo"), u"\\\\.\\foo")
+        self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"\\\\server\\foo"), u"\\\\?\\UNC\\server\\foo")
+        self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"C:\\foo"), u"\\\\?\\C:\\foo")
+        self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"C:\\foo/bar"), u"\\\\?\\C:\\foo\\bar")
 
         # adapted from <http://svn.python.org/view/python/branches/release26-maint/Lib/test/test_posixpath.py?view=markup&pathrev=78279#test_abspath>
 
@@ -496,6 +507,20 @@ class FileUtil(unittest.TestCase):
             finally:
                 os.chdir(saved_cwd)
 
+    def test_create_long_path(self):
+        workdir = u"test_create_long_path"
+        fileutil.make_dirs(workdir)
+        long_path = fileutil.abspath_expanduser_unicode(os.path.join(workdir, u'x'*255))
+        def _cleanup():
+            fileutil.remove(long_path)
+        self.addCleanup(_cleanup)
+
+        fileutil.write(long_path, "test")
+        self.failUnless(os.path.exists(long_path))
+        self.failUnlessEqual(fileutil.read(long_path), "test")
+        _cleanup()
+        self.failIf(os.path.exists(long_path))
+
     def test_disk_stats(self):
         avail = fileutil.get_available_space('.', 2**14)
         if avail == 0:
index 9446a3f6a99888d5ea84507fb74d5da6564ebb84..9bacf130cb4586a0bb73fb623b994f66a1025643 100644 (file)
@@ -305,7 +305,28 @@ def abspath_expanduser_unicode(path):
 
     # We won't hit <http://bugs.python.org/issue5827> because
     # there is always at least one Unicode path component.
-    return os.path.normpath(path)
+    path = os.path.normpath(path)
+
+    if sys.platform == "win32":
+        path = to_windows_long_path(path)
+
+    return path
+
+def to_windows_long_path(path):
+    # '/' is normally a perfectly valid path component separator in Windows.
+    # However, when using the "\\?\" syntax it is not recognized, so we
+    # replace it with '\' here.
+    path = path.replace(u"/", u"\\")
+
+    # Note that other normalizations such as removing '.' and '..' should
+    # be done outside this function.
+
+    if path.startswith(u"\\\\?\\") or path.startswith(u"\\\\.\\"):
+        return path
+    elif path.startswith(u"\\\\"):
+        return u"\\\\?\\UNC\\" + path[2 :]
+    else:
+        return u"\\\\?\\" + path
 
 
 have_GetDiskFreeSpaceExW = False