r47238 - Merge supportsSymlinks-8292: Add symlink support checks to t.p.runtime.platform

hawkowl-TA+aISz0psMTMxyoc4vAAJOcrHinNvQL0E9HWUfgJXw@public.gmane.org Thu, 14 Apr 2016 19:33:48 -0600 (MDT)
Newsgroups gmane.comp.python.twisted.commits
Message-ID <[email protected]>
Author: hawkowl
Date: Thu Apr 14 19:33:43 2016
New Revision: 47238

Added:
   trunk/twisted/topfiles/8292.misc
Modified:
   trunk/twisted/internet/test/test_address.py
   trunk/twisted/python/runtime.py
   trunk/twisted/test/test_paths.py
   trunk/twisted/web/test/test_static.py

Log:
Merge supportsSymlinks-8292: Add symlink support checks to t.p.runtime.platform

Author: hawkowl
Reviewer: adiroiban
Fixes: #8292

Modified: trunk/twisted/internet/test/test_address.py
==============================================================================
--- trunk/twisted/internet/test/test_address.py	(original)
+++ trunk/twisted/internet/test/test_address.py	Thu Apr 14 19:33:43 2016
@@ -11,10 +11,9 @@
 from twisted.internet.address import IPv4Address, UNIXAddress, IPv6Address
 from twisted.internet.address import HostnameAddress
 from twisted.python.compat import nativeString
+from twisted.python.runtime import platform
 
-try:
-    os.symlink
-except AttributeError:
+if not platform._supportsSymlinks():
     symlinkSkip = "Platform does not support symlinks"
 else:
     symlinkSkip = None
@@ -280,7 +279,8 @@
                              UNIXAddress(linkName))
             self.assertEqual(UNIXAddress(linkName),
                              UNIXAddress(self._socketAddress))
-    test_comparisonOfLinkedFiles.skip = symlinkSkip
+    if not unixSkip:
+        test_comparisonOfLinkedFiles.skip = symlinkSkip
 
 
     def test_hashOfLinkedFiles(self):
@@ -292,7 +292,8 @@
         os.symlink(os.path.abspath(self._socketAddress), linkName)
         self.assertEqual(hash(UNIXAddress(self._socketAddress)),
                          hash(UNIXAddress(linkName)))
-    test_hashOfLinkedFiles.skip = symlinkSkip
+    if not unixSkip:
+        test_hashOfLinkedFiles.skip = symlinkSkip
 
 
 
@@ -336,7 +337,8 @@
                                 UNIXAddress(None))
             self.assertNotEqual(UNIXAddress(None),
                                 UNIXAddress(self._socketAddress))
-    test_comparisonOfLinkedFiles.skip = symlinkSkip
+    if not unixSkip:
+        test_comparisonOfLinkedFiles.skip = symlinkSkip
 
 
     def test_emptyHash(self):

Modified: trunk/twisted/python/runtime.py
==============================================================================
--- trunk/twisted/python/runtime.py	(original)
+++ trunk/twisted/python/runtime.py	Thu Apr 14 19:33:43 2016
@@ -172,6 +172,33 @@
         return False
 
 
+    def _supportsSymlinks(self):
+        """
+        Check for symlink support usable for Twisted's purposes.
+
+        @return: C{True} if symlinks are supported on the current platform,
+                 otherwise C{False}.
+        @rtype: L{bool}
+        """
+        if self.isWindows():
+            # We do the isWindows() check as newer Pythons support the symlink
+            # support in Vista+, but only if you have some obscure permission
+            # (SeCreateSymbolicLinkPrivilege), which can only be given on
+            # platforms with msc.exe (so, Business/Enterprise editions).
+            # This uncommon requirement makes the Twisted test suite test fail
+            # in 99.99% of cases as general users don't have permission to do
+            # it, even if there is "symlink support".
+            return False
+        else:
+            # If we're not on Windows, check for existence of os.symlink.
+            try:
+                os.symlink
+            except AttributeError:
+                return False
+            else:
+                return True
+
+
     def supportsThreads(self):
         """
         Can threads be created?

Modified: trunk/twisted/test/test_paths.py
==============================================================================
--- trunk/twisted/test/test_paths.py	(original)
+++ trunk/twisted/test/test_paths.py	Thu Apr 14 19:33:43 2016
@@ -20,6 +20,12 @@
 
 from zope.interface.verify import verifyObject
 
+if not platform._supportsSymlinks():
+    symlinkSkip = "Platform does not support symlinks"
+else:
+    symlinkSkip = None
+
+
 
 class BytesTestCase(TestCase):
     """
@@ -608,9 +614,8 @@
         @raise SkipTest: raised if symbolic links are not supported on the
             host platform.
         """
-        if getattr(os, 'symlink', None) is None:
-            raise SkipTest(
-                "Platform does not support symbolic links.")
+        if symlinkSkip:
+            raise SkipTest(symlinkSkip)
         os.symlink(target, name)
 
 
@@ -764,11 +769,10 @@
                           self.path.child(b'sub1').child(b'file2'))
 
 
-    if not getattr(os, "symlink", None):
-        skipMsg = "Your platform does not support symbolic links."
-        test_symbolicLink.skip = skipMsg
-        test_linkTo.skip = skipMsg
-        test_linkToErrors.skip = skipMsg
+    if symlinkSkip:
+        test_symbolicLink.skip = symlinkSkip
+        test_linkTo.skip = symlinkSkip
+        test_linkToErrors.skip = symlinkSkip
 
 
     def testMultiExt(self):

Modified: trunk/twisted/web/test/test_static.py
==============================================================================
--- trunk/twisted/web/test/test_static.py	(original)
+++ trunk/twisted/web/test/test_static.py	Thu Apr 14 19:33:43 2016
@@ -1614,7 +1614,7 @@
         self.assertEqual(dirs, [])
         self.assertEqual(files, [])
 
-    if getattr(os, "symlink", None) is None:
+    if not platform._supportsSymlinks():
         test_brokenSymlink.skip = "No symlink support"