[CalendarServer-changes] [13931] CalendarServer/trunk/txdav/caldav/datastore

source_changes at macosforge.org source_changes at macosforge.org
Tue Sep 2 11:56:19 PDT 2014


Revision: 13931
          http://trac.calendarserver.org//changeset/13931
Author:   cdaboo at apple.com
Date:     2014-09-02 11:56:19 -0700 (Tue, 02 Sep 2014)
Log Message:
-----------
Make sure free busy updates properly when overridden instances are added/removed from an auto-accept attendee.

Modified Paths:
--------------
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py
    CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py
    CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py	2014-09-02 18:53:50 UTC (rev 13930)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/icaldiff.py	2014-09-02 18:56:19 UTC (rev 13931)
@@ -770,16 +770,28 @@
 
         # Now verify that each additional component in oldset matches a derived component in newset
         for key in oldset - newset:
+            rid = key[2]
             oldcomponent = oldmap[key]
-            newcomponent = self.newcalendar.deriveInstance(key[2])
+            newcomponent = self.newcalendar.deriveInstance(rid)
             if newcomponent is None:
+                # For the non iTIP case we must report missing components on either side. Marking
+                # the DTSTART as changed is enough to trigger logic in the caller to treat this
+                # as a significant change.
+                if not isiTip:
+                    rids[rid.getText() if rid is not None else ""] = {"DTSTART": set()}
                 continue
             self._diffComponents(oldcomponent, newcomponent, rids, isiTip)
 
         # Now verify that each additional component in oldset matches a derived component in newset
         for key in newset - oldset:
-            oldcomponent = self.oldcalendar.deriveInstance(key[2])
+            rid = key[2]
+            oldcomponent = self.oldcalendar.deriveInstance(rid)
             if oldcomponent is None:
+                # For the non iTIP case we must report missing components on either side. Marking
+                # the DTSTART as changed is enough to trigger logic in the caller to treat this
+                # as a significant change.
+                if not isiTip:
+                    rids[rid.getText() if rid is not None else ""] = {"DTSTART": set()}
                 continue
             newcomponent = newmap[key]
             self._diffComponents(oldcomponent, newcomponent, rids, isiTip)

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py	2014-09-02 18:53:50 UTC (rev 13930)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/processing.py	2014-09-02 18:56:19 UTC (rev 13931)
@@ -43,7 +43,6 @@
 import hashlib
 import json
 import uuid
-import time
 
 """
 CalDAV implicit processing.
@@ -755,9 +754,7 @@
                             end=str(makeTimedUTC(instance.end)),
                         )
 
-                        t = time.time()
                         yield generateFreeBusyInfo(testcal, fbinfo, tr, 0, uid, servertoserver=True, accountingItems=accounting if len(instances) == 1 else None)
-                        print time.time() - t
 
                         # If any fbinfo entries exist we have an overlap
                         if len(fbinfo[0]) or len(fbinfo[1]) or len(fbinfo[2]):

Modified: CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py	2014-09-02 18:53:50 UTC (rev 13930)
+++ CalendarServer/trunk/txdav/caldav/datastore/scheduling/test/test_icaldiff.py	2014-09-02 18:56:19 UTC (rev 13931)
@@ -4520,13 +4520,164 @@
             ),
         )
 
-        for description, calendar1, calendar2, rids in itertools.chain(data1, data2, data3,):
+        data4 = (
+            (
+                "#4.1 Override component removed",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                {},
+            ),
+            (
+                "#4.2 Override component added",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+SUMMARY:Test
+END:VCALENDAR
+""",
+                {},
+            ),
+        )
+
+        data5 = (
+            (
+                "#5.1 Override component removed",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                {"20080602T120000Z": {"DTSTART": set()}},
+            ),
+            (
+                "#5.2 Override component added",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+SUMMARY:Test
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
+RECURRENCE-ID:20080602T120000Z
+DTSTART:20080602T130000Z
+DTEND:20080602T140000Z
+SUMMARY:Test
+END:VEVENT
+END:VCALENDAR
+""",
+                {"20080602T120000Z": {"DTSTART": set()}},
+            ),
+        )
+
+        for description, calendar1, calendar2, rids in itertools.chain(data1, data2, data3, data4,):
             differ = iCalDiff(Component.fromString(calendar1), Component.fromString(calendar2), False)
             got_rids = differ.whatIsDifferent()
             rids = dict([(DateTime.parseText(k) if k else None, v) for k, v in rids.items()])
             self.assertEqual(got_rids, rids, msg="%s expected R-IDs: '%s', got: '%s'" % (description, rids, got_rids,))
 
+        for description, calendar1, calendar2, rids in itertools.chain(data5,):
+            differ = iCalDiff(Component.fromString(calendar1), Component.fromString(calendar2), False)
+            got_rids = differ.whatIsDifferent(isiTip=False)
+            self.assertEqual(got_rids, rids, msg="%s expected R-IDs: '%s', got: '%s'" % (description, rids, got_rids,))
 
+
     def test_attendee_needs_action(self):
 
         data = (

Modified: CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py	2014-09-02 18:53:50 UTC (rev 13930)
+++ CalendarServer/trunk/txdav/caldav/datastore/test/test_sql.py	2014-09-02 18:56:19 UTC (rev 13931)
@@ -7003,7 +7003,7 @@
 
 class TimeRangeUpdateOptimization(CommonCommonTests, unittest.TestCase):
     """
-    CalendarObject splitting tests
+    CalendarObject time range optimization tests.
     """
 
     EVENT1 = """BEGIN:VCALENDAR
@@ -7174,13 +7174,17 @@
 
         self.now = DateTime.getNowUTC()
         self.now.setDateOnly(True)
+        self.now1 = self.now.duplicate()
+        self.now1.offsetDay(1)
+        self.now2 = self.now.duplicate()
+        self.now2.offsetDay(2)
 
         self.trcount = 0
         base_addInstances = CalendarObject._addInstances
-        def __addInstances(*args):
+        def _addInstances(*args):
             self.trcount += 1
             return base_addInstances(*args)
-        self.patch(CalendarObject, "_addInstances", __addInstances)
+        self.patch(CalendarObject, "_addInstances", _addInstances)
 
         self.patch(config, "FreeBusyIndexDelayedExpand", False)
         self.patch(config, "FreeBusyIndexSmartUpdate", True)
@@ -7489,7 +7493,7 @@
     @inlineCallbacks
     def test_schedulingPUT(self):
         """
-        Test that second PUT withe time change causes a TIME_RANGE update
+        Test that second PUT with time change causes a TIME_RANGE update
         """
 
         # Need schedule-q off for this test
@@ -7529,7 +7533,7 @@
     @inlineCallbacks
     def test_schedulingPUT_withoutOptimization(self):
         """
-        Test that second PUT withe time change causes a TIME_RANGE update
+        Test that second PUT with time change causes a TIME_RANGE update
         """
 
         self.patch(config, "FreeBusyIndexSmartUpdate", False)
@@ -7566,3 +7570,189 @@
         yield self.commit()
 
         self.assertEqual(self.trcount, 11)
+
+
+    INVITE_OVERRIDE1 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+DTSTART:{now}T120000Z
+DURATION:PT1H
+SUMMARY:New Event
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+RECURRENCE-ID:{now1}T120000Z
+DTSTART:{now1}T120000Z
+DURATION:PT1H
+SUMMARY:New Event now1
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:urn:x-uid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+"""
+
+    INVITE_OVERRIDE2 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+RECURRENCE-ID:{now1}T120000Z
+DTSTART:{now1}T120000Z
+DURATION:PT1H
+SUMMARY:New Event now1
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:urn:x-uid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+"""
+
+    INVITE_OVERRIDE3 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+DTSTART:{now}T120000Z
+DURATION:PT1H
+SUMMARY:New Event
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+RECURRENCE-ID:{now1}T120000Z
+DTSTART:{now1}T120000Z
+DURATION:PT1H
+SUMMARY:New Event now1
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:urn:x-uid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+RECURRENCE-ID:{now2}T120000Z
+DTSTART:{now2}T120000Z
+DURATION:PT1H
+SUMMARY:New Event now2
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:urn:x-uid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+"""
+
+    INVITE_OVERRIDE4 = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+DTSTART:{now}T120000Z
+DURATION:PT1H
+SUMMARY:New Event
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+RECURRENCE-ID:{now1}T120000Z
+DTSTART:{now1}T120000Z
+DURATION:PT1H
+SUMMARY:New Event now1
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20100203T013849Z
+UID:uid1
+RECURRENCE-ID:{now2}T120000Z
+DTSTART:{now2}T120000Z
+DURATION:PT1H
+SUMMARY:New Event now2
+DTSTAMP:20100203T013909Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:urn:x-uid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+"""
+
+
+    @inlineCallbacks
+    def test_schedulingPUT_AddRemoveOverride_AutoAccept(self):
+        """
+        Test that second PUT with override change causes a TIME_RANGE update
+        """
+
+        # Need schedule-q off for this test
+        self.patch(config.Scheduling.Options.WorkQueues, "Enabled", False)
+        self.patch(config.Scheduling.Options.WorkQueues, "AutoReplyDelaySeconds", 1)
+
+        # First PUT causes T-R change
+        cal = yield self.calendarUnderTest(home="user01", name="calendar")
+        yield cal.createObjectResourceWithName("1.ics", Component.fromString(self.INVITE_OVERRIDE1.format(
+            now=self.now.getText(),
+            now1=self.now1.getText(),
+            now2=self.now2.getText(),
+        )))
+        yield self.commit()
+
+        # Wait for it to complete
+        yield JobItem.waitEmpty(self._sqlCalendarStore.newTransaction, reactor, 60)
+
+        self.assertEqual(self.trcount, 3)
+
+        # Organizer adds attendee to override causes T-R change (except for their item)
+        cobj = yield self.calendarObjectUnderTest(home="user01", calendar_name="calendar")
+        yield cobj.setComponent(Component.fromString(self.INVITE_OVERRIDE3.format(
+            now=self.now.getText(),
+            now1=self.now1.getText(),
+            now2=self.now2.getText(),
+        )))
+        yield self.commit()
+
+        # Wait for it to complete
+        yield JobItem.waitEmpty(self._sqlCalendarStore.newTransaction, reactor, 60)
+
+        self.assertEqual(self.trcount, 5)
+
+        # Organizer removes attendee from override causes T-R change (except for their item)
+        cobj = yield self.calendarObjectUnderTest(home="user01", calendar_name="calendar")
+        yield cobj.setComponent(Component.fromString(self.INVITE_OVERRIDE4.format(
+            now=self.now.getText(),
+            now1=self.now1.getText(),
+            now2=self.now2.getText(),
+        )))
+        yield self.commit()
+
+        # Wait for it to complete
+        yield JobItem.waitEmpty(self._sqlCalendarStore.newTransaction, reactor, 60)
+
+        self.assertEqual(self.trcount, 6)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140902/b33d02aa/attachment-0001.html>


More information about the calendarserver-changes mailing list