3 commits - pykolab/imap tests/functional wallace/module_resources.py

Thomas Brüderli bruederli at kolabsys.com
Tue Mar 25 18:50:44 CET 2014


 pykolab/imap/__init__.py                                       |    3 
 tests/functional/test_wallace/test_005_resource_invitation.py  |    3 
 tests/functional/test_wallace/test_006_resource_performance.py |  145 ++++++++++
 wallace/module_resources.py                                    |   16 -
 4 files changed, 157 insertions(+), 10 deletions(-)

New commits:
commit bda214e7d6e1bda174bd683a98d2c580de307f7d
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Mar 25 13:50:34 2014 -0400

    Add functional test to measure performance of resource calendar processing

diff --git a/tests/functional/test_wallace/test_005_resource_invitation.py b/tests/functional/test_wallace/test_005_resource_invitation.py
index 6d7748c..946cb5f 100644
--- a/tests/functional/test_wallace/test_005_resource_invitation.py
+++ b/tests/functional/test_wallace/test_005_resource_invitation.py
@@ -5,12 +5,9 @@ import email
 import datetime
 import uuid
 
-from pykolab import wap_client
-from pykolab.auth import Auth
 from pykolab.imap import IMAP
 from wallace import module_resources
 
-from icalendar import Calendar
 from email import message_from_string
 from twisted.trial import unittest
 
diff --git a/tests/functional/test_wallace/test_006_resource_performance.py b/tests/functional/test_wallace/test_006_resource_performance.py
new file mode 100644
index 0000000..ed83611
--- /dev/null
+++ b/tests/functional/test_wallace/test_006_resource_performance.py
@@ -0,0 +1,145 @@
+import time
+import datetime
+import pykolab
+import pytz
+import uuid
+import string
+import random
+
+from pykolab.xml import Event
+from pykolab.xml import Attendee
+from pykolab.imap import IMAP
+
+from wallace import module_resources
+from twisted.trial import unittest
+
+from tests.functional import resource_func as funcs
+from tests.functional.synchronize import synchronize_once
+
+conf = pykolab.getConf()
+
+
+class TestWallacePerformance(unittest.TestCase):
+
+    rooms = None
+
+    @classmethod
+    def setUp(self):
+        """ Compatibility for twisted.trial.unittest
+        """
+        if not self.rooms:
+            self.setup_class()
+
+    @classmethod
+    def setup_class(self, *args, **kw):
+        funcs.purge_resources()
+        self.room1 = funcs.resource_add("confroom", "Room 101")
+        self.room2 = funcs.resource_add("confroom", "Conference Room B-222")
+        self.rooms = funcs.resource_add("collection", "Rooms", [ self.room1['dn'], self.room2['dn'] ])
+
+        time.sleep(1)
+        synchronize_once()
+
+        module_resources.imap = IMAP()
+        module_resources.imap.connect()
+
+    def purge_mailbox(self, mailbox):
+        imap = IMAP()
+        imap.connect()
+        imap.set_acl(mailbox, "cyrus-admin", "lrwcdest")
+        imap.imap.m.select(imap.folder_quote(mailbox))
+
+        typ, data = imap.imap.m.search(None, 'ALL')
+        for num in data[0].split():
+            imap.imap.m.store(num, '+FLAGS', '\\Deleted')
+
+        imap.imap.m.expunge()
+        imap.disconnect()
+
+    def populate_calendar(self, resource, num=10, date=None):
+        if date is None:
+            date = datetime.datetime.now(pytz.timezone("Europe/London"))
+
+        i = 0
+        while i < num:
+            offset = random.randint(-3200, 3200) * 10
+            duration = random.randint(3, 72) * 10
+            summary = ''.join(random.sample((string.ascii_uppercase + string.digits) * 12, random.randint(6, 18)))
+            start = date + datetime.timedelta(minutes=offset)
+
+            event = Event()
+            event.set_summary(summary)
+            event.set_start(start)
+            event.set_end(start + datetime.timedelta(minutes=duration))
+            saved = module_resources.save_resource_event(dict(xml=event), resource)
+            i += 1
+
+
+    def test_001_save_resource_event(self):
+        event = Event()
+        event.set_summary("test")
+
+        date = datetime.datetime.now(pytz.timezone("Europe/London"))
+        event.set_start(date)
+        event.set_end(date + datetime.timedelta(hours=2))
+
+        saved = module_resources.save_resource_event(dict(xml=event), self.room1)
+        self.assertTrue(saved)
+
+
+    def test_002_read_resource_calendar(self):
+        self.purge_mailbox(self.room1['kolabtargetfolder'])
+
+        event = Event()
+        event.set_summary("test")
+        event.set_start(datetime.datetime(2014,4,1, 12,0,0, tzinfo=pytz.timezone("Europe/London")))
+        event.set_end(datetime.datetime(2014,4,1, 14,0,0, tzinfo=pytz.timezone("Europe/London")))
+        saved = module_resources.save_resource_event(dict(xml=event), self.room1)
+        self.assertTrue(saved)
+        uid = event.get_uid()
+
+        itip = dict(
+            uid = str(uuid.uuid4()),
+            sequence = 0,
+            start = datetime.datetime(2014,4,1, 13,0,0, tzinfo=pytz.timezone("Europe/London")),
+            end = datetime.datetime(2014,4,1, 14,30,0, tzinfo=pytz.timezone("Europe/London"))
+        )
+
+        event.set_uid(itip['uid'])
+        event.set_start(itip['start'])
+        event.set_end(itip['end'])
+        itip['xml'] = event
+
+        res = module_resources.read_resource_calendar(self.room1, [ itip ])
+        self.assertEqual(res, 1)
+        self.assertTrue(self.room1['conflict'])
+        self.assertIn(uid, self.room1['conflicting_events'])
+
+
+    def test_003_read_time(self):
+        self.purge_mailbox(self.room1['kolabtargetfolder'])
+
+        # populate 5K random events
+        num = 5000
+        date = datetime.datetime.now(pytz.timezone("Europe/London")).replace(hour=10, minute=0, second=0, microsecond=0)
+        self.populate_calendar(self.room1, num, date)
+
+        itip = dict(
+            uid = str(uuid.uuid4()),
+            sequence = 0,
+            start = date,
+            end = date + datetime.timedelta(minutes=90)
+        )
+
+        event = Event()
+        event.set_uid(itip['uid'])
+        event.set_start(itip['start'])
+        event.set_end(itip['end'])
+        itip['xml'] = event
+
+        start = time.time()
+        res = module_resources.read_resource_calendar(self.room1, [ itip ])
+        self.assertEqual(res, num)
+
+        print "\nREAD TIME:", time.time() - start
+        print "CONFLICTS:", self.room1['conflicting_events']


commit baf122c45870ff1b182273e2ae3855d34d3a6e8e
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Mar 25 13:45:42 2014 -0400

    Quote resource folder names for IMAP operations

diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index fbe515d..c9df6d3 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -253,6 +253,9 @@ class IMAP(object):
         from pykolab import imap_utf7
         return imap_utf7.decode(folder)
 
+    def folder_quote(self, folder):
+        return u'"' + str(folder).strip('"') + '"'
+
     def get_metadata(self, folder):
         """
             Obtain all metadata entries on a folder
diff --git a/wallace/module_resources.py b/wallace/module_resources.py
index ebc7d38..6a9e4ba 100644
--- a/wallace/module_resources.py
+++ b/wallace/module_resources.py
@@ -447,7 +447,7 @@ def read_resource_calendar(resource_rec, itip_events):
     )
 
     # might raise an exception, let that bubble
-    imap.imap.m.select(mailbox)
+    imap.imap.m.select(imap.folder_quote(mailbox))
     typ, data = imap.imap.m.search(None, 'ALL')
 
     num_messages = len(data[0].split())
@@ -579,9 +579,10 @@ def save_resource_event(itip_event, resource):
     """
     try:
         # Administrator login name comes from configuration.
-        imap.imap.m.setacl(resource['kolabtargetfolder'], conf.get(conf.get('kolab', 'imap_backend'), 'admin_login'), "lrswipkxtecda")
+        targetfolder = imap.folder_quote(resource['kolabtargetfolder'])
+        imap.imap.m.setacl(targetfolder, conf.get(conf.get('kolab', 'imap_backend'), 'admin_login'), "lrswipkxtecda")
         result = imap.imap.m.append(
-            resource['kolabtargetfolder'],
+            targetfolder,
             None,
             None,
             itip_event['xml'].to_message().as_string()
@@ -600,8 +601,9 @@ def delete_resource_event(uid, resource):
     """
         Removes the IMAP object with the given UID from a resource's calendar folder
     """
-    imap.imap.m.setacl(resource['kolabtargetfolder'], conf.get(conf.get('kolab', 'imap_backend'), 'admin_login'), "lrswipkxtecda")
-    imap.imap.m.select(resource['kolabtargetfolder'])
+    targetfolder = imap.folder_quote(resource['kolabtargetfolder'])
+    imap.imap.m.setacl(targetfolder, conf.get(conf.get('kolab', 'imap_backend'), 'admin_login'), "lrswipkxtecda")
+    imap.imap.m.select(targetfolder)
 
     typ, data = imap.imap.m.search(None, '(HEADER SUBJECT "%s")' % uid)
 


commit cdc894bf66bc5c66337548d6baf24483647d1c2e
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Tue Mar 25 12:14:07 2014 -0400

    Adjust debug logging levels for better tracking

diff --git a/wallace/module_resources.py b/wallace/module_resources.py
index ed78024..ebc7d38 100644
--- a/wallace/module_resources.py
+++ b/wallace/module_resources.py
@@ -443,7 +443,7 @@ def read_resource_calendar(resource_rec, itip_events):
 
     log.debug(
         _("Checking events in resource folder %r") % (mailbox),
-        level=8
+        level=9
     )
 
     # might raise an exception, let that bubble
@@ -553,7 +553,7 @@ def accept_reservation_request(itip_event, resource, delegator=None):
 
     log.debug(
         _("Adding event to %r: %r") % (resource['kolabtargetfolder'], saved),
-        level=9
+        level=8
     )
 
     send_response(delegator['mail'] if delegator else resource['mail'], itip_event, get_resource_owner(resource))




More information about the commits mailing list