[CalendarServer-changes] [3892] CalendarServer/branches/exarkun/update-twisted-3816

source_changes at macosforge.org source_changes at macosforge.org
Thu Mar 19 09:30:45 PDT 2009


Revision: 3892
          http://trac.macosforge.org/projects/calendarserver/changeset/3892
Author:   exarkun at twistedmatrix.com
Date:     2009-03-19 09:30:45 -0700 (Thu, 19 Mar 2009)
Log Message:
-----------
Migrated into Twisted

Modified Paths:
--------------
    CalendarServer/branches/exarkun/update-twisted-3816/run

Removed Paths:
-------------
    CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.test.test_xattrprops.patch
    CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.xattrprops.patch

Deleted: CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.test.test_xattrprops.patch
===================================================================
--- CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.test.test_xattrprops.patch	2009-03-19 16:14:09 UTC (rev 3891)
+++ CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.test.test_xattrprops.patch	2009-03-19 16:30:45 UTC (rev 3892)
@@ -1,238 +0,0 @@
-Index: twisted/web2/dav/test/test_xattrprops.py
-===================================================================
---- twisted/web2/dav/test/test_xattrprops.py	(revision 0)
-+++ twisted/web2/dav/test/test_xattrprops.py	(revision 0)
-@@ -0,0 +1,233 @@
-+# Copyright (c) 2009 Twisted Matrix Laboratories.
-+# See LICENSE for details.
-+
-+"""
-+Tests for L{twisted.web2.dav.xattrprops}.
-+"""
-+
-+from zlib import compress, decompress
-+from pickle import dumps
-+from cPickle import UnpicklingError
-+
-+from twisted.python.filepath import FilePath
-+from twisted.trial.unittest import TestCase
-+from twisted.web2.responsecode import NOT_FOUND, INTERNAL_SERVER_ERROR
-+from twisted.web2.responsecode import FORBIDDEN
-+from twisted.web2.http import HTTPError
-+from twisted.web2.dav.static import DAVFile
-+from twisted.web2.dav.davxml import Depth, WebDAVDocument
-+
-+try:
-+    from twisted.web2.dav.xattrprops import xattrPropertyStore
-+except ImportError:
-+    xattrPropertyStore = None
-+else:
-+    from xattr import xattr
-+
-+class ExtendedAttributesPropertyStoreTests(TestCase):
-+    """
-+    Tests for L{xattrPropertyStore}.
-+    """
-+    if xattrPropertyStore is None:
-+        skip = "xattr package missing, cannot test xattr property store"
-+
-+    def setUp(self):
-+        """
-+        Create a resource and a xattr property store for it.
-+        """
-+        self.resourcePath = FilePath(self.mktemp())
-+        self.resourcePath.setContent("")
-+        self.attrs = xattr(self.resourcePath.path)
-+        self.resource = DAVFile(self.resourcePath.path)
-+        self.propertyStore = xattrPropertyStore(self.resource)
-+
-+
-+    def test_getAbsent(self):
-+        """
-+        L{xattrPropertyStore.get} raises L{HTTPError} with a I{NOT FOUND}
-+        response code if passed the name of an attribute for which there is no
-+        corresponding value.
-+        """
-+        error = self.assertRaises(HTTPError, self.propertyStore.get, ("foo", "bar"))
-+        self.assertEquals(error.response.code, NOT_FOUND)
-+
-+
-+    def _makeValue(self):
-+        """
-+        Create and return any old WebDAVDocument for use by the get tests.
-+        """
-+        element = Depth("0")
-+        document = WebDAVDocument(element)
-+        return document
-+
-+
-+    def _setValue(self, originalDocument, value):
-+        element = originalDocument.root_element
-+        attribute = (
-+            self.propertyStore.deadPropertyXattrPrefix +
-+            "{%s}%s" % element.qname())
-+        self.attrs[attribute] = value
-+
-+
-+    def _getValue(self, originalDocument):
-+        element = originalDocument.root_element
-+        attribute = (
-+            self.propertyStore.deadPropertyXattrPrefix +
-+            "{%s}%s" % element.qname())
-+        return self.attrs[attribute]
-+
-+
-+    def _checkValue(self, originalDocument):
-+        property = originalDocument.root_element.qname()
-+
-+        # Try to load it via xattrPropertyStore.get
-+        loadedDocument = self.propertyStore.get(property)
-+
-+        # XXX Why isn't this a WebDAVDocument?
-+        self.assertIsInstance(loadedDocument, Depth)
-+        self.assertEquals(str(loadedDocument), "0")
-+
-+
-+    def test_getXML(self):
-+        """
-+        If there is an XML document associated with the property name passed to
-+        L{xattrPropertyStore.get}, that value is parsed into a
-+        L{WebDAVDocument}, the root element of which C{get} then returns.
-+        """
-+        document = self._makeValue()
-+        self._setValue(document, document.toxml())
-+        self._checkValue(document)
-+
-+
-+    def test_getCompressed(self):
-+        """
-+        If there is a compressed value associated with the property name passed
-+        to L{xattrPropertyStore.get}, that value is decompressed and parsed
-+        into a L{WebDAVDocument}, the root element of which C{get} then
-+        returns.
-+        """
-+        document = self._makeValue()
-+        self._setValue(document, compress(document.toxml()))
-+        self._checkValue(document)
-+
-+
-+    def test_getPickled(self):
-+        """
-+        If there is a pickled document associated with the property name passed
-+        to L{xattrPropertyStore.get}, that value is unpickled into a
-+        L{WebDAVDocument}, the root element of which is returned.
-+        """
-+        document = self._makeValue()
-+        self._setValue(document, dumps(document))
-+        self._checkValue(document)
-+
-+
-+    def test_getUpgradeXML(self):
-+        """
-+        If the value associated with the property name passed to
-+        L{xattrPropertyStore.get} is an uncompressed XML document, it is
-+        upgraded on access by compressing it.
-+        """
-+        document = self._makeValue()
-+        originalValue = document.toxml()
-+        self._setValue(document, originalValue)
-+        self._checkValue(document)
-+        self.assertEquals(
-+            decompress(self._getValue(document)), originalValue)
-+
-+
-+    def test_getUpgradeCompressedPickle(self):
-+        """
-+        If the value associated with the property name passed to
-+        L{xattrPropertyStore.get} is a compressed pickled document, it is
-+        upgraded on access to the compressed XML format.
-+        """
-+        document = self._makeValue()
-+        self._setValue(document, compress(dumps(document)))
-+        self._checkValue(document)
-+        self.assertEquals(
-+            decompress(self._getValue(document)), document.toxml())
-+
-+
-+    def test_getInvalid(self):
-+        """
-+        If the value associated with the property name passed to
-+        L{xattrPropertyStore.get} cannot be interpreted, an error is logged and
-+        L{HTTPError} is raised with the I{INTERNAL SERVER ERROR} response code.
-+        """
-+        document = self._makeValue()
-+        self._setValue(
-+            document,
-+            "random garbage goes here! \0 that nul is definitely garbage")
-+
-+        property = document.root_element.qname()
-+        error = self.assertRaises(HTTPError, self.propertyStore.get, property)
-+        self.assertEquals(error.response.code, INTERNAL_SERVER_ERROR)
-+        self.assertEquals(
-+            len(self.flushLoggedErrors(UnpicklingError)), 1)
-+
-+
-+    def test_set(self):
-+        """
-+        L{xattrPropertyStore.set} accepts a L{WebDAVElement} and stores a
-+        compressed XML document representing it in an extended attribute.
-+        """
-+        document = self._makeValue()
-+        self.propertyStore.set(document.root_element)
-+        self.assertEquals(
-+            decompress(self._getValue(document)), document.toxml())
-+
-+
-+    def test_delete(self):
-+        """
-+        L{xattrPropertyStore.delete} deletes the named property.
-+        """
-+        document = self._makeValue()
-+        self.propertyStore.set(document.root_element)
-+        self.propertyStore.delete(document.root_element.qname())
-+        self.assertRaises(KeyError, self._getValue, document)
-+
-+
-+    def test_deleteNonExistent(self):
-+        """
-+        L{xattrPropertyStore.delete} does nothing if passed a property which
-+        has no value.
-+        """
-+        document = self._makeValue()
-+        self.propertyStore.delete(document.root_element.qname())
-+        self.assertRaises(KeyError, self._getValue, document)
-+
-+
-+    def test_deleteErrors(self):
-+        """
-+        If there is a problem deleting the specified property (aside from the
-+        property not existing), L{xattrPropertyStore.delete} raises
-+        L{HTTPError} with a status code which is determined by the nature of
-+        the problem.
-+        """
-+        # Remove access from the directory containing the file so that deleting
-+        # extended attributes of it fails with EPERM.
-+        self.resourcePath.remove()
-+
-+        # Try to delete a property from it - and fail.
-+        document = self._makeValue()
-+        error = self.assertRaises(
-+            HTTPError,
-+            self.propertyStore.delete, document.root_element.qname())
-+
-+        # Make sure that the status is FORBIDDEN, a roughly reasonable mapping
-+        # of the EPERM failure.
-+        self.assertEquals(error.response.code, FORBIDDEN)
-+
-+
-+    def test_contains(self):
-+        """
-+        L{xattrPropertyStore.contains} returns C{True} if the given property
-+        has a value, C{False} otherwise.
-+        """
-+        document = self._makeValue()
-+        self.assertFalse(
-+            self.propertyStore.contains(document.root_element.qname()))
-+        self._setValue(document, document.toxml())
-+        self.assertTrue(
-+            self.propertyStore.contains(document.root_element.qname()))

Deleted: CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.xattrprops.patch
===================================================================
--- CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.xattrprops.patch	2009-03-19 16:14:09 UTC (rev 3891)
+++ CalendarServer/branches/exarkun/update-twisted-3816/lib-patches/Twisted/twisted.web2.dav.xattrprops.patch	2009-03-19 16:30:45 UTC (rev 3892)
@@ -1,167 +0,0 @@
-Index: twisted/web2/dav/xattrprops.py
-===================================================================
---- twisted/web2/dav/xattrprops.py	(revision 26389)
-+++ twisted/web2/dav/xattrprops.py	(working copy)
-@@ -34,21 +34,27 @@
- import urllib
- import sys
- import zlib
-+
-+from operator import setitem
- from time import sleep
- from random import random
- from errno import EAGAIN
- from zlib import compress, decompress
-+from cPickle import UnpicklingError, loads as unpickle
- 
- import xattr
- 
- if getattr(xattr, 'xattr', None) is None:
-     raise ImportError("wrong xattr package imported")
- 
-+from twisted.python.util import untilConcludes
- from twisted.python import log
- from twisted.web2 import responsecode
- from twisted.web2.http import HTTPError, StatusResponse
- from twisted.web2.dav import davxml
-+from twisted.web2.dav.http import statusForFailure
- 
-+
- class xattrPropertyStore (object):
-     """
- 
-@@ -94,59 +100,109 @@
-         self.attrs = xattr.xattr(self.resource.fp.path)
- 
-     def get(self, qname):
-+        """
-+        Retrieve the value of a property stored as an extended attribute on the
-+        wrapped path.
-+
-+        @param qname: The property to retrieve as a two-tuple of namespace URI
-+            and local name.
-+
-+        @raise HTTPError: If there is no value associated with the given
-+            property.
-+
-+        @return: A L{WebDAVDocument} representing the value associated with the
-+            given property.
-+        """
-         try:
-             data = self.attrs[self._encode(qname)]
--            try:
--                value = decompress(data)
--            except zlib.error:
--                # Value is not compressed; data was stored by old
--                # code.  This is easy to handle, so let's keep
--                # compatibility here.
--                value = data
--            del data
-         except KeyError:
-             raise HTTPError(StatusResponse(
-                 responsecode.NOT_FOUND,
-                 "No such property: {%s}%s" % qname
-             ))
-+        except:
-+            # XXX Untested, I can't get the getitem to actually fail in a test
-+            # environment. -exarkun
-+            raise HTTPError(
-+                StatusResponse(
-+                    statusForFailure(Failure()),
-+                    "Unable to read property: " + key))
- 
-+        #
-+        # Unserialize XML data from an xattr.  The storage format has changed
-+        # over time:
-+        #
-+        #  1- Started with XML
-+        #  2- Started compressing the XML due to limits on xattr size
-+        #  3- Switched to pickle which is faster, still compressing
-+        #  4- Back to compressed XML for interoperability, size
-+        #
-+        # We only write the current format, but we also read the old
-+        # ones for compatibility.
-+        #
-+        legacy = False
-+
-         try:
--            doc = davxml.WebDAVDocument.fromString(value)
-+            data = decompress(data)
-+        except zlib.error:
-+            legacy = True
- 
--            return doc.root_element
-+        try:
-+            doc = davxml.WebDAVDocument.fromString(data)
-         except ValueError:
--            msg = "Invalid property value stored on server: {%s}%s %s" % (qname[0], qname[1], value)
--            log.err(msg)
--            raise HTTPError(StatusResponse(responsecode.INTERNAL_SERVER_ERROR, msg))
--
--    def set(self, property):
--        for n in range(20):
-             try:
--                self.attrs[self._encode(property.qname())] = compress(property.toxml())
--            except IOError, error:
--                if error.errno != EAGAIN:
--                    raise
--                sleep(random() / 10) # OMG Brutal Hax
-+                doc = unpickle(data)
-+            except UnpicklingError:
-+                format = "Invalid property value stored on server: {%s}%s %s"
-+                msg = format % (qname[0], qname[1], data)
-+                log.err(None, msg)
-+                raise HTTPError(
-+                    StatusResponse(responsecode.INTERNAL_SERVER_ERROR, msg))
-             else:
--                break
--    
-+                legacy = True
- 
-+        if legacy:
-+            self.set(doc.root_element)
-+
-+        return doc.root_element
-+
-+
-+    def set(self, property):
-+        key = self._encode(property.qname())
-+        value = compress(property.toxml())
-+        untilConcludes(setitem, self.attrs, key, value)
-+
-         # Update the resource because we've modified it
-         self.resource.fp.restat()
- 
-     def delete(self, qname):
-+        key = self._encode(qname)
-         try:
--            del(self.attrs[self._encode(qname)])
--        except KeyError:
-+            del self.attrs[key]
-+        except KeyError, e:
-             # RFC 2518 Section 12.13.1 says that removal of
-             # non-existing property is not an error.
-             pass
-+        except:
-+            # XXX Untested, I can't get the delitem to actually fail in a test
-+            # environment. -exarkun
-+            raise HTTPError(
-+                StatusResponse(
-+                    statusForFailure(Failure()),
-+                    "Unable to delete property: " + key))
- 
-     def contains(self, qname):
-         try:
-             return self._encode(qname) in self.attrs
-         except TypeError:
-             return False
-+        except:
-+            # XXX Untested, I can't get the __contains__ to actually fail in a
-+            # test environment. -exarkun
-+            raise HTTPError(
-+                StatusResponse(
-+                    statusForFailure(Failure()),
-+                    "Unable to read property: " + key))
- 
-     def list(self):
-         prefix     = self.deadPropertyXattrPrefix

Modified: CalendarServer/branches/exarkun/update-twisted-3816/run
===================================================================
--- CalendarServer/branches/exarkun/update-twisted-3816/run	2009-03-19 16:14:09 UTC (rev 3891)
+++ CalendarServer/branches/exarkun/update-twisted-3816/run	2009-03-19 16:30:45 UTC (rev 3892)
@@ -636,7 +636,7 @@
     ;;
 esac;
 svn_uri="${proto}://svn.twistedmatrix.com/svn/Twisted/branches/dav-take-two-3081-3";
-svn_get "Twisted" "${twisted}" "${svn_uri}" 26422;
+svn_get "Twisted" "${twisted}" "${svn_uri}" 26427;
 
 # No py_build step, since we tend to do edit Twisted, we want the sources in
 # PYTHONPATH, not a build directory.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090319/1abcd85a/attachment-0001.html>


More information about the calendarserver-changes mailing list