[CalendarServer-changes] [6836] CalendarServer/trunk/contrib/performance/loadtest

source_changes at macosforge.org source_changes at macosforge.org
Mon Jan 31 18:02:11 PST 2011


Revision: 6836
          http://trac.macosforge.org/projects/calendarserver/changeset/6836
Author:   exarkun at twistedmatrix.com
Date:     2011-01-31 18:02:11 -0800 (Mon, 31 Jan 2011)
Log Message:
-----------
Handle a couple more states the clients can be in to avoid tripping over our own feet

If we have learned of an event but not of its details yet, don't try to do anything with its details.
If we have already accepted an invitation to an event, don't try to accept it again.

Modified Paths:
--------------
    CalendarServer/trunk/contrib/performance/loadtest/profiles.py
    CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py

Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2011-01-31 20:23:00 UTC (rev 6835)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2011-02-01 02:02:11 UTC (rev 6836)
@@ -26,6 +26,7 @@
 
 from protocol.caldav.definitions import caldavxml
 
+from twisted.python.log import msg
 from twisted.internet.defer import succeed
 from twisted.internet.task import LoopingCall
 
@@ -108,22 +109,28 @@
             if not calendar.events:
                 continue
 
-            uuid = self.random.choice(calendar.events.keys())
-            event = calendar.events[uuid].vevent
-            href = calendar.url + uuid
+            events = calendar.events.keys()
+            while events:
+                uuid = self.random.choice(events)
+                events.remove(uuid)
+                event = calendar.events[uuid].vevent
+                if event is None:
+                    continue
 
-            # Find out who might attend
-            attendees = event.contents['vevent'][0].contents.get('attendee', [])
+                href = calendar.url + uuid
 
-            d = self._addAttendee(event, attendees)
-            d.addCallback(
-                lambda attendee:
-                    self._client.addEventAttendee(
-                        href, attendee))
-            return d
+                # Find out who might attend
+                attendees = event.contents['vevent'][0].contents.get('attendee', [])
 
+                d = self._addAttendee(event, attendees)
+                d.addCallback(
+                    lambda attendee:
+                        self._client.addEventAttendee(
+                            href, attendee))
+                return d
 
 
+
 class Accepter(object):
     """
     A Calendar user who accepts invitations to events.
@@ -134,6 +141,7 @@
         self._reactor = reactor
         self._client = client
         self._number = userNumber
+        self._accepting = set()
 
 
     def run(self):
@@ -149,6 +157,8 @@
             return
         if calendar.resourceType != caldavxml.calendar:
             return
+        if href in self._accepting:
+            return
 
         vevent = self._client._events[href].vevent
         # Check to see if this user is in the attendee list in the
@@ -158,13 +168,15 @@
             if attendee.params[u'EMAIL'][0] == self._client.email[len('mailto:'):]:
                 if attendee.params[u'PARTSTAT'][0] == 'NEEDS-ACTION':
                     # XXX Base this on something real
-                    delay = 3 # self.random.gauss(10, 10)
+                    delay = self.random.gauss(10, 2)
+                    self._accepting.add(href)
                     self._reactor.callLater(
                         delay, self._acceptInvitation, href, attendee)
                     return
 
 
     def _acceptInvitation(self, href, attendee):
+        self._accepting.remove(href)
         accepted = self._makeAcceptedAttendee(attendee)
         self._client.changeEventAttendee(href, attendee, accepted)
 
@@ -172,5 +184,8 @@
     def _makeAcceptedAttendee(self, attendee):
         accepted = ContentLine.duplicate(attendee)
         accepted.params[u'PARTSTAT'] = [u'ACCEPTED']
-        del accepted.params[u'RSVP']
+        try:
+            del accepted.params[u'RSVP']
+        except KeyError:
+            msg("Duplicated an attendee with no RSVP: %r" % (attendee,))
         return accepted

Modified: CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py	2011-01-31 20:23:00 UTC (rev 6835)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py	2011-02-01 02:02:11 UTC (rev 6836)
@@ -202,7 +202,6 @@
         return vevent, event, calendar, client
 
 
-
     def test_doNotAddAttendeeToInbox(self):
         """
         When the only calendar with any events is a schedule inbox, no
@@ -230,6 +229,22 @@
         self.assertEquals(client._calendars, {})
 
 
+    def test_doNotAddAttendeeToUninitializedEvent(self):
+        """
+        When there is an L{Event} on a calendar but the details of the
+        event have not yet been retrieved, no attempt is made to add
+        invitees to that event.
+        """
+        userNumber = 19
+        vevent, event, calendar, client = self._simpleAccount(
+            userNumber, SIMPLE_EVENT)
+        event.vevent = event.etag = event.scheduleTag = None
+        inviter = Inviter(None, client, userNumber)
+        inviter._invite()
+        self.assertEquals(client._events, {event.url: event})
+        self.assertEquals(client._calendars, {calendar.url: calendar})
+
+
     def test_addAttendeeToEvent(self):
         """
         When there is a normal calendar with an event, inviter adds an
@@ -360,6 +375,33 @@
         accepter.eventChanged(event.url)
 
 
+    def test_ignoreAlreadyAccepting(self):
+        """
+        If the client sees an event change a second time before
+        responding to an invitation found on it during the first
+        change notification, the second change notification does not
+        generate another accept attempt.
+        """
+        clock = Clock()
+        randomDelay = 7
+        vevent = list(readComponents(INVITED_EVENT))[0]
+        attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
+        userNumber = int(attendees[1].params[u'CN'][0].split(None, 1)[1])
+        calendarURL = '/some/calendar/'
+        calendar = Calendar(
+            caldavxml.calendar, u'calendar', calendarURL, None)
+        client = StubClient(userNumber)
+        client._calendars[calendarURL] = calendar
+        event = Event(calendarURL + u'1234.ics', None, vevent)
+        client._events[event.url] = event
+        accepter = Accepter(clock, client, userNumber)
+        accepter.random = Deterministic()
+        accepter.random.gauss = lambda mu, sigma: randomDelay
+        accepter.eventChanged(event.url)
+        accepter.eventChanged(event.url)
+        clock.advance(randomDelay)
+
+
     def test_acceptInvitation(self):
         """
         If the client is an attendee on an event and the PARTSTAT is
@@ -394,4 +436,43 @@
         self.assertNotIn(u'RSVP', attendees[1].params)
 
 
-        
+    def test_reacceptInvitation(self):
+        """
+        If a client accepts an invitation on an event and then is
+        later re-invited to the same event, the invitation is again
+        accepted.
+        """
+        clock = Clock()
+        randomDelay = 7
+        vevent = list(readComponents(INVITED_EVENT))[0]
+        attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
+        userNumber = int(attendees[1].params[u'CN'][0].split(None, 1)[1])
+        calendarURL = '/some/calendar/'
+        calendar = Calendar(
+            caldavxml.calendar, u'calendar', calendarURL, None)
+        client = StubClient(userNumber)
+        client._calendars[calendarURL] = calendar
+        event = Event(calendarURL + u'1234.ics', None, vevent)
+        client._events[event.url] = event
+        accepter = Accepter(clock, client, userNumber)
+        accepter.random = Deterministic()
+        accepter.random.gauss = lambda mu, sigma: randomDelay
+        accepter.eventChanged(event.url)
+        clock.advance(randomDelay)
+
+        # Now re-set the event so it has to be accepted again
+        event.vevent = list(readComponents(INVITED_EVENT))[0]
+
+        # And now re-deliver it
+        accepter.eventChanged(event.url)
+        clock.advance(randomDelay)
+
+        # And ensure that it was accepted again
+        vevent = client._events[event.url].vevent
+        attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
+        self.assertEquals(len(attendees), 2)
+        self.assertEquals(
+            attendees[1].params[u'CN'], [u'User %02d' % (userNumber,)])
+        self.assertEquals(
+            attendees[1].params[u'PARTSTAT'], [u'ACCEPTED'])
+        self.assertNotIn(u'RSVP', attendees[1].params)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110131/ca019edb/attachment-0001.html>


More information about the calendarserver-changes mailing list