[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