[CalendarServer-changes] [7476] CalendarServer/branches/users/glyph/new-export/calendarserver/tools
source_changes at macosforge.org
source_changes at macosforge.org
Mon May 16 07:46:25 PDT 2011
Revision: 7476
http://trac.macosforge.org/projects/calendarserver/changeset/7476
Author: glyph at apple.com
Date: 2011-05-16 07:46:25 -0700 (Mon, 16 May 2011)
Log Message:
-----------
Almost end-to-end test.
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:46:13 UTC (rev 7475)
+++ CalendarServer/branches/users/glyph/new-export/calendarserver/tools/export.py 2011-05-16 14:46:25 UTC (rev 7476)
@@ -43,8 +43,8 @@
from os.path import dirname, abspath
from twisted.python.usage import Options
-from twisted.internet.defer import inlineCallbacks
-#from twisted.internet.defer import returnValue
+from twisted.python import log
+from twisted.internet.defer import inlineCallbacks, returnValue
from twistedcaldav.config import ConfigurationError
from twistedcaldav.ical import Component
@@ -55,6 +55,7 @@
from twistedcaldav.stdconfig import DEFAULT_CARDDAV_CONFIG_FILE
from calendarserver.tools.cmdline import utilityMain
from twisted.application.service import Service
+from calendarserver.tap.util import directoryFromConfig
from calendarserver.tools.util import (loadConfig, getDirectory)
@@ -93,7 +94,7 @@
def opt_record(self, recordName):
"""
- add a directory record's calendar home (format: 'recordType:shortName')
+ Add a directory record's calendar home (format: 'recordType:shortName').
"""
recordType, shortName = recordName.split(":", 1)
self.exporters.append(HomeExporter(recordType, shortName))
@@ -122,6 +123,15 @@
opt_o = opt_output
+ def opt_user(self, user):
+ """
+ Add a user's calendar home (shorthand for '-r users:shortName').
+ """
+ self.opt_record("users:" + user)
+
+ opt_u = opt_user
+
+
def openOutput(self):
"""
Open the appropriate output file based on the '--output' option.
@@ -158,7 +168,21 @@
self.shortName = shortName
+ @inlineCallbacks
+ def listCalendars(self, txn, exportService):
+ directory = exportService.directoryService()
+ record = directory.recordWithShortName(self.recordType, self.shortName)
+ home = yield txn.calendarHomeWithUID(record.guid)
+ if self.collections:
+ result = []
+ for collection in self.collections:
+ result.append((yield home.calendarWithName(collection)))
+ else:
+ result = yield home.calendars()
+ returnValue(result)
+
+
@inlineCallbacks
def exportToFile(calendars, fileobj):
"""
@@ -305,12 +329,14 @@
Service which runs, exports the appropriate records, then stops the reactor.
"""
- def __init__(self, store, options, output, reactor):
+ def __init__(self, store, options, output, reactor, config):
super(ExporterService, self).__init__()
self.store = store
self.options = options
self.output = output
self.reactor = reactor
+ self.config = config
+ self._directory = None
def startService(self):
@@ -326,14 +352,34 @@
"""
Do the export, stopping the reactor when done.
"""
- allCalendars = itertools.chain(
- [exporter.listCalendars(self) for exporter in
- self.options.exporters]
- )
- yield exportToFile(allCalendars, self.output)
+ txn = self.store.newTransaction()
+ try:
+ allCalendars = itertools.chain(
+ *[(yield exporter.listCalendars(txn, self)) for exporter in
+ self.options.exporters]
+ )
+ yield exportToFile(allCalendars, self.output)
+ except:
+ log.err()
+
+ yield txn.commit()
+ # TODO: should be read-only, so commit/abort shouldn't make a
+ # difference. commit() for now, in case any transparent cache / update
+ # stuff needed to happen, don't want to undo it.
+ self.output.close()
self.reactor.stop()
+ def directoryService(self):
+ """
+ Get an appropriate directory service for this L{ExporterService}'s
+ configuration, creating one first if necessary.
+ """
+ if self._directory is None:
+ self._directory = directoryFromConfig(self.config)
+ return self._directory
+
+
def stopService(self):
"""
Stop the service. Nothing to do; everything should be finished by this
@@ -360,9 +406,9 @@
stderr.write("Unable to open output file for writing: %s\n" %
(e))
sys.exit(1)
- utilityMain(options['config'],
- lambda store: ExporterService(store, options, output, reactor),
- reactor)
- output #pyflakes
+ def makeService(store):
+ from twistedcaldav.config import config
+ return ExporterService(store, options, output, reactor, config)
+ utilityMain(options['config'], makeService, reactor)
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:46:13 UTC (rev 7475)
+++ CalendarServer/branches/users/glyph/new-export/calendarserver/tools/test/test_export.py 2011-05-16 14:46:25 UTC (rev 7476)
@@ -24,14 +24,13 @@
from twisted.trial.unittest import TestCase
-#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 twistedcaldav.directory import augment
+from twistedcaldav.directory import augment
from twistedcaldav.datafilters.test.test_peruserdata import dataForTwoUsers
from twistedcaldav.datafilters.test.test_peruserdata import resultForUser2
@@ -39,8 +38,10 @@
from calendarserver.tools.export import ExportOptions, main
from calendarserver.tools.export import HomeExporter
+from twisted.python.filepath import FilePath
+from twistedcaldav.test.util import patchConfig
from twisted.internet.defer import Deferred
-#from twistedcaldav.directory.xmlfile import XMLDirectoryService
+
from txdav.common.datastore.test.util import buildStore
from txdav.common.datastore.test.util import populateCalendarsFrom
@@ -168,6 +169,9 @@
Tests for exporting data from a live store.
"""
+ accountsFile = 'no-accounts.xml'
+ augmentsFile = 'no-augments.xml'
+
@inlineCallbacks
def setUp(self):
"""
@@ -180,17 +184,7 @@
self.mainCalled = False
self.patch(export, "utilityMain", self.fakeUtilityMain)
- # In lieu of a configuration file, patch up the augment service and make
- # it so directoryFromConfig will return something useful.
-# self.patch(augment, "AugmentService",
-# augment.AugmentXMLDB(xmlFiles=(self.augmentsFile().path,)))
-#
-# self.patch(export, "directoryFromConfig",
-# XMLDirectoryService({'xmlFile' : self.xmlFile()},
-# alwaysStat=True))
-
-
self.store = yield buildStore(self, None)
self.waitToStop = Deferred()
@@ -210,6 +204,32 @@
if self.mainCalled:
raise RuntimeError(
"Main called twice during this test; duplicate reactor run.")
+
+ # In lieu of a configuration file, patch up the augment service and make
+ # it so directoryFromConfig will return something useful. Don't
+ # actually need to patch the augment service to a real fake; just patch
+ # it so that trial will restore the previous one when this test has
+ # completed.
+
+ self.patch(augment, "AugmentService", None)
+
+ patchConfig(
+ self,
+ DirectoryService=dict(
+ type="twistedcaldav.directory.xmlfile.XMLDirectoryService",
+ params=dict(
+ xmlFile=self.accountsFile
+ )
+ ),
+ ResourceService=dict(Enabled=False),
+ AugmentService=dict(
+ type="twistedcaldav.directory.augment.AugmentXMLDB",
+ params=dict(
+ xmlFiles=[self.augmentsFile]
+ )
+ )
+ )
+
self.mainCalled = True
self.usedConfigFile = configFileName
self.usedReactor = reactor
@@ -400,4 +420,61 @@
)
+ @inlineCallbacks
+ def test_full(self):
+ """
+ Running C{calendarserver_export} on the command line exports an ics
+ file. (Almost-full integration test, starting from the main point, using
+ as few test fakes as possible.)
+ Note: currently the only test for directory interaction.
+ """
+ yield populateCalendarsFrom(
+ {
+ "user02": {
+ "calendar1": {
+ "peruser.ics": (dataForTwoUsers, {}), # EST
+ }
+ }
+ }, self.store
+ )
+
+ augmentsData = """
+ <augments>
+ <record>
+ <uid>Default</uid>
+ <enable>true</enable>
+ <enable-calendar>true</enable-calendar>
+ <enable-addressbook>true</enable-addressbook>
+ </record>
+ </augments>
+ """
+ augments = FilePath(self.mktemp())
+ augments.setContent(augmentsData)
+
+ accountsData = """
+ <accounts realm="Test Realm">
+ <user>
+ <uid>user-under-test</uid>
+ <guid>user02</guid>
+ <name>Not Interesting</name>
+ <password>very-secret</password>
+ </user>
+ </accounts>
+ """
+ accounts = FilePath(self.mktemp())
+ accounts.setContent(accountsData)
+ output = FilePath(self.mktemp())
+ self.accountsFile = accounts.path
+ self.augmentsFile = augments.path
+ main(['calendarserver_export', '--output',
+ output.path, '--user', 'user-under-test'], reactor=self)
+
+ yield self.waitToStop
+
+ self.assertEquals(
+ Component.fromString(resultForUser2),
+ Component.fromString(output.getContent())
+ )
+
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110516/75cc98d2/attachment-0001.html>
More information about the calendarserver-changes
mailing list