[CalendarServer-changes] [7460] CalendarServer/branches/users/glyph/new-export/calendarserver/tools
source_changes at macosforge.org
source_changes at macosforge.org
Mon May 16 07:43:08 PDT 2011
Revision: 7460
http://trac.macosforge.org/projects/calendarserver/changeset/7460
Author: glyph at apple.com
Date: 2011-05-16 07:43:07 -0700 (Mon, 16 May 2011)
Log Message:
-----------
Start testing some actual export logic.
Modified Paths:
--------------
CalendarServer/branches/users/glyph/new-export/calendarserver/tools/export.py
CalendarServer/branches/users/glyph/new-export/calendarserver/tools/test/test_export.py
Modified: CalendarServer/branches/users/glyph/new-export/calendarserver/tools/export.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/calendarserver/tools/export.py 2011-05-16 14:42:55 UTC (rev 7459)
+++ CalendarServer/branches/users/glyph/new-export/calendarserver/tools/export.py 2011-05-16 14:43:07 UTC (rev 7460)
@@ -41,15 +41,19 @@
from getopt import getopt, GetoptError
from os.path import dirname, abspath
+from twisted.internet.defer import inlineCallbacks
+#from twisted.internet.defer import returnValue
+
from twistedcaldav.config import ConfigurationError
-from twistedcaldav.ical import Component as iComponent, Property as iProperty
+from twistedcaldav.ical import Component, Property
from twistedcaldav.ical import iCalendarProductID
from twistedcaldav.resource import isCalendarCollectionResource,\
CalendarHomeResource
from twistedcaldav.directory.directory import DirectoryService
from calendarserver.tools.util import UsageError
-from calendarserver.tools.util import loadConfig, getDirectory, dummyDirectoryRecord, autoDisableMemcached
+from calendarserver.tools.util import (
+ loadConfig, getDirectory, dummyDirectoryRecord, autoDisableMemcached)
def usage(e=None):
if e:
@@ -78,7 +82,48 @@
else:
sys.exit(0)
+
+
+def emptyComponent():
+ """
+ Create and return an empty C{VCALENDAR} component.
+ """
+ c = Component("VCALENDAR")
+ c.addProperty(Property("VERSION", "2.0"))
+ c.addProperty(Property("PRODID", iCalendarProductID))
+ return c
+
+
+
+ at inlineCallbacks
+def exportToFile(calendars, exporterUID, fileobj):
+ """
+ Export some calendars to a file as a particular UID.
+
+ @param calendars: an iterable of L{ICalendar} providers (or L{Deferred}s of
+ same).
+
+ @param exporterUID:
+
+ @return: a L{Deferred} which fires when the export is complete. (Note that
+ the file will not be closed.)
+ @rtype: L{Deferred} that fires with C{None}
+ """
+ comp = emptyComponent()
+ for calendar in calendars:
+ calendar = yield calendar
+ for obj in (yield calendar.calendarObjects()):
+ evt = yield obj.component()
+ for sub in evt.subcomponents():
+ comp.addComponent(sub)
+
+ fileobj.write(str(comp))
+
+
+
def main():
+ # quiet pyflakes while I'm working on this.
+ from stopbotheringme import CalDAVFile
try:
(optargs, args) = getopt(
sys.argv[1:], "hf:o:c:H:r:u:", [
@@ -173,9 +218,7 @@
collections.add(child)
try:
- calendar = iComponent("VCALENDAR")
- calendar.addProperty(iProperty("VERSION", "2.0"))
- calendar.addProperty(iProperty("PRODID", iCalendarProductID))
+ calendar = emptyComponent()
uids = set()
tzids = set()
@@ -186,7 +229,7 @@
childData = child.iCalendarText()
try:
- childCalendar = iComponent.fromString(childData)
+ childCalendar = Component.fromString(childData)
except ValueError:
continue
assert childCalendar.name() == "VCALENDAR"
Modified: CalendarServer/branches/users/glyph/new-export/calendarserver/tools/test/test_export.py
===================================================================
--- CalendarServer/branches/users/glyph/new-export/calendarserver/tools/test/test_export.py 2011-05-16 14:42:55 UTC (rev 7459)
+++ CalendarServer/branches/users/glyph/new-export/calendarserver/tools/test/test_export.py 2011-05-16 14:43:07 UTC (rev 7460)
@@ -24,8 +24,32 @@
from twisted.trial.unittest import TestCase
-from calendarserver.tools.export import usage
+#from calendarserver.tools import export
+from twisted.internet.defer import inlineCallbacks
+from twisted.python.modules import getModule
+from twext.enterprise.ienterprise import AlreadyFinishedError
+
+from twistedcaldav.ical import Component
+from txdav.common.datastore.test.util import buildStore
+from txdav.common.datastore.test.util import populateCalendarsFrom
+
+from calendarserver.tools.export import usage, exportToFile, emptyComponent
+
+def holiday(uid):
+ return (
+ getModule("twistedcaldav.test").filePath
+ .sibling("data").child("Holidays").child(uid + ".ics")
+ .getContent()
+ )
+
+valentines = holiday("C31854DA-1ED0-11D9-A5E0-000A958A3252")
+newYears = holiday("C3184A66-1ED0-11D9-A5E0-000A958A3252")
+payday = (
+ getModule("twistedcaldav.test").filePath
+ .sibling("data").child("PayDay.ics").getContent()
+)
+
class CommandLine(TestCase):
"""
Simple tests for command-line parsing.
@@ -50,3 +74,125 @@
+class IntegrationTests(TestCase):
+ """
+ Tests for exporting data from a live store.
+ """
+
+ FAKE_CONFIG_FILE = 'not-a-real-config-file.plist'
+
+ @inlineCallbacks
+ def setUp(self):
+ """
+ Set up a store and fix the imported C{utilityMain} function (normally
+ from L{calendarserver.tools.cmdline.utilityMain}) to point to a
+ temporary method of this class. Also, patch the imported C{reactor},
+ since the SUT needs to call C{reactor.stop()} in order to work with
+ L{utilityMain}.
+ """
+ self.mainCalled = False
+ #self.patch(export, "utilityMain", self.fakeUtilityMain)
+ self.store = yield buildStore(self, None)
+
+
+ def fakeUtilityMain(self, configFileName, serviceClass, reactor=None):
+ """
+ Verify a few basic things.
+ """
+ if self.mainCalled:
+ raise RuntimeError(
+ "Main called twice this test; duplicate reactor run.")
+ self.mainCalled = True
+ self.assertEquals(configFileName, self.FAKE_CONFIG_FILE)
+ theService = serviceClass(self.store)
+ theService.startService()
+
+
+ @inlineCallbacks
+ def test_emptyCalendar(self):
+ """
+ Exporting an empty calendar results in an empty calendar.
+ """
+ io = StringIO()
+ value = yield exportToFile([], "nobody", io)
+ # it doesn't return anything, it writes to the file.
+ self.assertEquals(value, None)
+ # but it should write a valid component to the file.
+ self.assertEquals(Component.fromString(io.getvalue()),
+ emptyComponent())
+
+
+ def txn(self):
+ aTransaction = self.store.newTransaction()
+ def maybeAbort():
+ try:
+ aTransaction.abort()
+ except AlreadyFinishedError:
+ pass
+ self.addCleanup(maybeAbort)
+ return aTransaction
+
+
+ @inlineCallbacks
+ def test_oneEventCalendar(self):
+ """
+ Exporting an calendar with one event in it will result in just that
+ event.
+ """
+ yield populateCalendarsFrom(
+ {
+ "home1": {
+ "calendar1": {
+ "valentines-day.ics": (valentines, {})
+ }
+ }
+ }, self.store
+ )
+
+ expected = emptyComponent()
+ [theComponent] = Component.fromString(valentines).subcomponents()
+ expected.addComponent(theComponent)
+
+ io = StringIO()
+ yield exportToFile(
+ [(yield self.txn().calendarHomeWithUID("home1"))
+ .calendarWithName("calendar1")],
+ "nobody", io
+ )
+ self.assertEquals(Component.fromString(io.getvalue()),
+ expected)
+
+
+ @inlineCallbacks
+ def test_twoSimpleEvents(self):
+ """
+ Exporting a calendar with two events in it will result in a VCALENDAR
+ component with both VEVENTs in it.
+ """
+ yield populateCalendarsFrom(
+ {
+ "home1": {
+ "calendar1": {
+ "valentines-day.ics": (valentines, {}),
+ "new-years-day.ics": (newYears, {})
+ }
+ }
+ }, self.store
+ )
+
+ expected = emptyComponent()
+ a = Component.fromString(valentines)
+ b = Component.fromString(newYears)
+ for comp in a, b:
+ for sub in comp.subcomponents():
+ expected.addComponent(sub)
+
+ io = StringIO()
+ yield exportToFile(
+ [(yield self.txn().calendarHomeWithUID("home1"))
+ .calendarWithName("calendar1")],
+ "nobody", io
+ )
+ self.assertEquals(Component.fromString(io.getvalue()),
+ expected)
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110516/5b6ac36c/attachment-0001.html>
More information about the calendarserver-changes
mailing list