<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[15297] CalendarServer/trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.calendarserver.org//changeset/15297">15297</a></dd>
<dt>Author</dt> <dd>sagen@apple.com</dd>
<dt>Date</dt> <dd>2015-11-06 14:41:28 -0800 (Fri, 06 Nov 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add attachments, sharing, and calendarserver_principal_search report to sim</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#CalendarServertrunkcalendarserverpushamppushpy">CalendarServer/trunk/calendarserver/push/amppush.py</a></li>
<li><a href="#CalendarServertrunkcalendarserverpushtesttest_amppushpy">CalendarServer/trunk/calendarserver/push/test/test_amppush.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestclientsplist">CalendarServer/trunk/contrib/performance/loadtest/clients.plist</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestconfigplist">CalendarServer/trunk/contrib/performance/loadtest/config.plist</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtesticalpy">CalendarServer/trunk/contrib/performance/loadtest/ical.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestpopulationpy">CalendarServer/trunk/contrib/performance/loadtest/population.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestprofilespy">CalendarServer/trunk/contrib/performance/loadtest/profiles.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestsimpy">CalendarServer/trunk/contrib/performance/loadtest/sim.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtesttest_icalpy">CalendarServer/trunk/contrib/performance/loadtest/test_ical.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtesttest_profilespy">CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtesttest_simpy">CalendarServer/trunk/contrib/performance/loadtest/test_sim.py</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/</li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11Profile">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/Profile</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11StartupProfile">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/StartupProfile</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11notification_multiget_report_hrefsrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_multiget_report_hrefs.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11notification_syncrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_sync.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendar_depth1_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_depth1_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendar_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendarhome_depth1_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_depth1_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendarhome_syncrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_sync.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_notification_depth1_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_notification_depth1_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11post_freebusyrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/post_freebusy.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11principal_search_reportrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/principal_search_report.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11report_principal_searchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/report_principal_search.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_color_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_color_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_description_proppatchrequestxml">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_description_proppatch.request.xml</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_displayname_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_displayname_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_order_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_order_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_timezone_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_timezone_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_transparent_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_transparent_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendarhome_default_alarm_date_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_date_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendarhome_default_alarm_datetime_proppatchrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_datetime_proppatch.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_create_calendarrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_create_calendar.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_delegate_principal_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_delegate_principal_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principal_expandrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_expand.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principal_initial_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_initial_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principal_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_propfind.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principals_reportrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principals_report.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_query_events_depth1_reportrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_query_events_depth1_report.request</a></li>
<li><a href="#CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_well_known_propfindrequest">CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_well_known_propfind.request</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="CalendarServertrunkcalendarserverpushamppushpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/amppush.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/amppush.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/calendarserver/push/amppush.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class UnsubscribeFromID(amp.Command):
</span><del>-    arguments = [('token', amp.String()), ('id', amp.String())]
</del><ins>+    arguments = [('id', amp.String())]
</ins><span class="cx">     response = [('status', amp.String())]
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -257,7 +257,7 @@
</span><span class="cx">         return {&quot;status&quot; : &quot;OK&quot;}
</span><span class="cx">     SubscribeToID.responder(subscribe)
</span><span class="cx"> 
</span><del>-    def unsubscribe(self, token, id):
</del><ins>+    def unsubscribe(self, id):
</ins><span class="cx">         try:
</span><span class="cx">             del self.subscriptions[id]
</span><span class="cx">         except KeyError:
</span></span></pre></div>
<a id="CalendarServertrunkcalendarserverpushtesttest_amppushpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/calendarserver/push/test/test_amppush.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/calendarserver/push/test/test_amppush.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/calendarserver/push/test/test_amppush.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx"> 
</span><span class="cx">         client1.reset()
</span><span class="cx">         client2.reset()
</span><del>-        client2.unsubscribe(&quot;token2&quot;, &quot;/CalDAV/localhost/user01/&quot;)
</del><ins>+        client2.unsubscribe(&quot;/CalDAV/localhost/user01/&quot;)
</ins><span class="cx">         service.enqueue(
</span><span class="cx">             None, &quot;/CalDAV/localhost/user01/&quot;,
</span><span class="cx">             dataChangedTimestamp=dataChangedTimestamp,
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestclientsplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/clients.plist (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/clients.plist        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/clients.plist        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -31,16 +31,16 @@
</span><span class="cx"> 
</span><span class="cx">                                 &lt;!-- Here is a OS X client simulator. --&gt;
</span><span class="cx">                                 &lt;key&gt;software&lt;/key&gt;
</span><del>-                                &lt;string&gt;contrib.performance.loadtest.ical.OS_X_10_7&lt;/string&gt;
</del><ins>+                                &lt;string&gt;contrib.performance.loadtest.ical.OS_X_10_11&lt;/string&gt;
</ins><span class="cx"> 
</span><del>-                                &lt;!-- Arguments to use to initialize the OS_X_10_7 instance. --&gt;
</del><ins>+                                &lt;!-- Arguments to use to initialize the OS_X_10_11 instance. --&gt;
</ins><span class="cx">                                 &lt;key&gt;params&lt;/key&gt;
</span><span class="cx">                                 &lt;dict&gt;
</span><span class="cx">                                         &lt;!-- Name that appears in logs. --&gt;
</span><span class="cx">                                         &lt;key&gt;title&lt;/key&gt;
</span><del>-                                        &lt;string&gt;10.7&lt;/string&gt;
-        
-                                        &lt;!-- OS_X_10_7 can poll the calendar home at some interval. This is
</del><ins>+                                        &lt;string&gt;10.11&lt;/string&gt;
+
+                                        &lt;!-- OS_X_10_11 can poll the calendar home at some interval. This is
</ins><span class="cx">                                                 in seconds. --&gt;
</span><span class="cx">                                         &lt;key&gt;calendarHomePollInterval&lt;/key&gt;
</span><span class="cx">                                         &lt;integer&gt;30&lt;/integer&gt;
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx">                                                 and use it if possible. Still fall back to polling if there is no xmpp push
</span><span class="cx">                                                 advertised. --&gt;
</span><span class="cx">                                         &lt;key&gt;supportPush&lt;/key&gt;
</span><del>-                                        &lt;false /&gt;
</del><ins>+                                        &lt;true/&gt;
</ins><span class="cx"> 
</span><span class="cx">                                         &lt;key&gt;supportAmpPush&lt;/key&gt;
</span><span class="cx">                                         &lt;true/&gt;
</span><span class="lines">@@ -144,13 +144,13 @@
</span><span class="cx">                                                                                 &lt;!-- Half of all events will be non-recurring --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;none&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;50&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Daily and weekly are pretty common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;daily&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;10&lt;/integer&gt;
</span><span class="cx">                                                                                 &lt;key&gt;weekly&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;20&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Monthly, yearly, daily &amp; weekly limit not so common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;monthly&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;2&lt;/integer&gt;
</span><span class="lines">@@ -160,7 +160,7 @@
</span><span class="cx">                                                                                 &lt;integer&gt;2&lt;/integer&gt;
</span><span class="cx">                                                                                 &lt;key&gt;weeklylimit&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;5&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Work days pretty common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;workdays&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;10&lt;/integer&gt;
</span><span class="lines">@@ -171,6 +171,10 @@
</span><span class="cx">                                         &lt;/dict&gt;
</span><span class="cx"> 
</span><span class="cx">                                         &lt;!-- This profile will create a new event, and then periodically update the ACKNOWLEDGED property. --&gt;
</span><ins>+
+                                        &lt;!-- Rather than use EventUpdater which always updates the same event,
+                                        you can use Eventer to create events and TitleChanger or Attacher to change
+                                        random events --&gt;
</ins><span class="cx">                                         &lt;dict&gt;
</span><span class="cx">                                                 &lt;key&gt;class&lt;/key&gt;
</span><span class="cx">                                                 &lt;string&gt;contrib.performance.loadtest.profiles.EventUpdater&lt;/string&gt;
</span><span class="lines">@@ -247,13 +251,13 @@
</span><span class="cx">                                                                                 &lt;!-- Half of all events will be non-recurring --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;none&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;50&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Daily and weekly are pretty common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;daily&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;25&lt;/integer&gt;
</span><span class="cx">                                                                                 &lt;key&gt;weekly&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;25&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Monthly, yearly, daily &amp; weekly limit not so common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;monthly&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;0&lt;/integer&gt;
</span><span class="lines">@@ -263,7 +267,7 @@
</span><span class="cx">                                                                                 &lt;integer&gt;0&lt;/integer&gt;
</span><span class="cx">                                                                                 &lt;key&gt;weeklylimit&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;0&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Work days pretty common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;workdays&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;0&lt;/integer&gt;
</span><span class="lines">@@ -273,6 +277,99 @@
</span><span class="cx">                                                 &lt;/dict&gt;
</span><span class="cx">                                         &lt;/dict&gt;
</span><span class="cx"> 
</span><ins>+                                        &lt;!-- Picks a random event and changes the title --&gt;
+                                        &lt;dict&gt;
+                                                &lt;key&gt;class&lt;/key&gt;
+                                                &lt;string&gt;contrib.performance.loadtest.profiles.TitleChanger&lt;/string&gt;
+
+                                                &lt;key&gt;params&lt;/key&gt;
+                                                &lt;dict&gt;
+                                                        &lt;key&gt;enabled&lt;/key&gt;
+                                                        &lt;true/&gt;
+
+                                                        &lt;!-- Define the interval (in seconds) at which this profile will use
+                                                                its client to create a new event. --&gt;
+                                                        &lt;key&gt;interval&lt;/key&gt;
+                                                        &lt;integer&gt;60&lt;/integer&gt;
+
+                                                &lt;/dict&gt;
+                                        &lt;/dict&gt;
+
+                                        &lt;!-- Picks a random event and attaches --&gt;
+                                        &lt;dict&gt;
+                                                &lt;key&gt;class&lt;/key&gt;
+                                                &lt;string&gt;contrib.performance.loadtest.profiles.Attacher&lt;/string&gt;
+
+                                                &lt;key&gt;params&lt;/key&gt;
+                                                &lt;dict&gt;
+                                                        &lt;key&gt;enabled&lt;/key&gt;
+                                                        &lt;true/&gt;
+
+                                                        &lt;!-- Define the interval (in seconds) at which this profile will use
+                                                                its client to create a new event. --&gt;
+                                                        &lt;key&gt;interval&lt;/key&gt;
+                                                        &lt;integer&gt;60&lt;/integer&gt;
+
+                                                        &lt;!-- Define the attachment size distribution. --&gt;
+                                                        &lt;key&gt;fileSizeDistribution&lt;/key&gt;
+                                                        &lt;dict&gt;
+                                                                &lt;key&gt;type&lt;/key&gt;
+                                                                &lt;string&gt;contrib.performance.stats.NormalDistribution&lt;/string&gt;
+                                                                &lt;key&gt;params&lt;/key&gt;
+                                                                &lt;dict&gt;
+                                                                        &lt;!-- mu gives the mean of the normal distribution (in seconds). --&gt;
+                                                                        &lt;key&gt;mu&lt;/key&gt;
+                                                                        &lt;integer&gt;500000&lt;/integer&gt;
+
+                                                                        &lt;!-- and sigma gives its standard deviation. --&gt;
+                                                                        &lt;key&gt;sigma&lt;/key&gt;
+                                                                        &lt;integer&gt;100000&lt;/integer&gt;
+                                                                &lt;/dict&gt;
+                                                        &lt;/dict&gt;
+
+                                                &lt;/dict&gt;
+                                        &lt;/dict&gt;
+
+                                        &lt;!-- Removes events from calendars exceeding a threshold --&gt;
+                                        &lt;dict&gt;
+                                                &lt;key&gt;class&lt;/key&gt;
+                                                &lt;string&gt;contrib.performance.loadtest.profiles.EventCountLimiter&lt;/string&gt;
+
+                                                &lt;key&gt;params&lt;/key&gt;
+                                                &lt;dict&gt;
+                                                        &lt;key&gt;enabled&lt;/key&gt;
+                                                        &lt;true/&gt;
+
+                                                        &lt;!-- Define the interval (in seconds) at which this profile will check
+                                                                for too-large collections. --&gt;
+                                                        &lt;key&gt;interval&lt;/key&gt;
+                                                        &lt;integer&gt;60&lt;/integer&gt;
+
+                                                        &lt;!-- The upper bound. --&gt;
+                                                        &lt;key&gt;eventCountLimit&lt;/key&gt;
+                                                        &lt;integer&gt;100&lt;/integer&gt;
+
+                                                &lt;/dict&gt;
+                                        &lt;/dict&gt;
+
+
+                                        &lt;!-- Shares calendars --&gt;
+                                        &lt;dict&gt;
+                                                &lt;key&gt;class&lt;/key&gt;
+                                                &lt;string&gt;contrib.performance.loadtest.profiles.CalendarSharer&lt;/string&gt;
+
+                                                &lt;key&gt;params&lt;/key&gt;
+                                                &lt;dict&gt;
+                                                        &lt;key&gt;enabled&lt;/key&gt;
+                                                        &lt;true/&gt;
+
+                                                        &lt;!-- Define the interval (in seconds) at which this profile will share calendars. --&gt;
+                                                        &lt;key&gt;interval&lt;/key&gt;
+                                                        &lt;integer&gt;300&lt;/integer&gt;
+
+                                                &lt;/dict&gt;
+                                        &lt;/dict&gt;
+
</ins><span class="cx">                                         &lt;!-- This profile invites some number of new attendees to new events. --&gt;
</span><span class="cx">                                         &lt;dict&gt;
</span><span class="cx">                                                 &lt;key&gt;class&lt;/key&gt;
</span><span class="lines">@@ -281,7 +378,7 @@
</span><span class="cx">                                                 &lt;key&gt;params&lt;/key&gt;
</span><span class="cx">                                                 &lt;dict&gt;
</span><span class="cx">                                                         &lt;key&gt;enabled&lt;/key&gt;
</span><del>-                                                        &lt;true/&gt;
</del><ins>+                                                        &lt;false/&gt;
</ins><span class="cx"> 
</span><span class="cx">                                                         &lt;!-- Define the frequency at which new invitations will be sent out. --&gt;
</span><span class="cx">                                                         &lt;key&gt;sendInvitationDistribution&lt;/key&gt;
</span><span class="lines">@@ -292,7 +389,7 @@
</span><span class="cx">                                                                 &lt;dict&gt;
</span><span class="cx">                                                                         &lt;!-- mu gives the mean of the normal distribution (in seconds). --&gt;
</span><span class="cx">                                                                         &lt;key&gt;mu&lt;/key&gt;
</span><del>-                                                                        &lt;integer&gt;60&lt;/integer&gt;
</del><ins>+                                                                        &lt;integer&gt;10&lt;/integer&gt;
</ins><span class="cx"> 
</span><span class="cx">                                                                         &lt;!-- and sigma gives its standard deviation. --&gt;
</span><span class="cx">                                                                         &lt;key&gt;sigma&lt;/key&gt;
</span><span class="lines">@@ -301,12 +398,12 @@
</span><span class="cx">                                                         &lt;/dict&gt;
</span><span class="cx"> 
</span><span class="cx">                                                         &lt;!-- Define the distribution of who will be invited to an event.
</span><del>-                                                        
</del><ins>+
</ins><span class="cx">                                                                 When inviteeClumping is turned on each invitee is based on a sample of
</span><span class="cx">                                                                 users &quot;close to&quot; the organizer based on account index. If the clumping
</span><span class="cx">                                                                 is too &quot;tight&quot; for the requested number of attendees, then invites for
</span><span class="cx">                                                                 those larger numbers will simply fail (the sim will report that situation).
</span><del>-                                                                
</del><ins>+
</ins><span class="cx">                                                                 When inviteeClumping is off invitees will be sampled across an entire
</span><span class="cx">                                                                 range of account indexes. In this case the distribution ought to be a
</span><span class="cx">                                                                 UniformIntegerDistribution with min=0 and max set to the number of accounts.
</span><span class="lines">@@ -330,13 +427,13 @@
</span><span class="cx">                                                         &lt;true/&gt;
</span><span class="cx"> 
</span><span class="cx">                                                         &lt;!-- Define the distribution of how many attendees will be invited to an event.
</span><del>-                                                        
</del><ins>+
</ins><span class="cx">                                                                 LogNormal is the best fit to observed data.
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">                                                                 For LogNormal &quot;mode&quot; is the peak, &quot;mean&quot; is the mean value.        For invites,
</span><span class="cx">                                                                 mode should typically be 1, and mean whatever matches the user behavior.
</span><del>-                                                                Our typical mean is 6.                                                         
</del><ins>+                                                                Our typical mean is 6.
</ins><span class="cx">                                                              --&gt;
</span><span class="cx">                                                         &lt;key&gt;inviteeCountDistribution&lt;/key&gt;
</span><span class="cx">                                                         &lt;dict&gt;
</span><span class="lines">@@ -418,13 +515,13 @@
</span><span class="cx">                                                                                 &lt;!-- Half of all events will be non-recurring --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;none&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;50&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Daily and weekly are pretty common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;daily&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;10&lt;/integer&gt;
</span><span class="cx">                                                                                 &lt;key&gt;weekly&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;20&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Monthly, yearly, daily &amp; weekly limit not so common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;monthly&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;2&lt;/integer&gt;
</span><span class="lines">@@ -434,7 +531,7 @@
</span><span class="cx">                                                                                 &lt;integer&gt;2&lt;/integer&gt;
</span><span class="cx">                                                                                 &lt;key&gt;weeklylimit&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;5&lt;/integer&gt;
</span><del>-                                                                                
</del><ins>+
</ins><span class="cx">                                                                                 &lt;!-- Work days pretty common --&gt;
</span><span class="cx">                                                                                 &lt;key&gt;workdays&lt;/key&gt;
</span><span class="cx">                                                                                 &lt;integer&gt;10&lt;/integer&gt;
</span><span class="lines">@@ -459,7 +556,7 @@
</span><span class="cx">                                                                 accepting it.
</span><span class="cx"> 
</span><span class="cx">                                                                 For LogNormal &quot;mode&quot; is the peak, &quot;median&quot; is the 50% cummulative value
</span><del>-                                                                (i.e., half of the user have accepted by that time).                                                                
</del><ins>+                                                                (i.e., half of the user have accepted by that time).
</ins><span class="cx">                                                         --&gt;
</span><span class="cx">                                                         &lt;key&gt;acceptDelayDistribution&lt;/key&gt;
</span><span class="cx">                                                         &lt;dict&gt;
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestconfigplist"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/config.plist        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -21,7 +21,7 @@
</span><span class="cx">         &lt;dict&gt;
</span><span class="cx">                 &lt;!-- Identify the server to be load tested. --&gt;
</span><span class="cx">                 &lt;key&gt;server&lt;/key&gt;
</span><del>-                &lt;string&gt;https://127.0.0.1:8443&lt;/string&gt;
</del><ins>+                &lt;string&gt;https://localhost:8443&lt;/string&gt;
</ins><span class="cx"> 
</span><span class="cx">                 &lt;!-- The template URI for doing initial principal lookup on. --&gt;
</span><span class="cx">                 &lt;key&gt;principalPathTemplate&lt;/key&gt;
</span><span class="lines">@@ -96,12 +96,12 @@
</span><span class="cx">                         &lt;dict&gt;
</span><span class="cx">                                 &lt;!-- groups gives the total number of groups of clients to introduce. --&gt;
</span><span class="cx">                                 &lt;key&gt;groups&lt;/key&gt;
</span><del>-                                &lt;integer&gt;20&lt;/integer&gt;
</del><ins>+                                &lt;integer&gt;10&lt;/integer&gt;
</ins><span class="cx"> 
</span><span class="cx">                                 &lt;!-- groupSize is the number of clients in each group of clients. It's
</span><span class="cx">                                         really only a &quot;smooth&quot; ramp up if this is pretty small. --&gt;
</span><span class="cx">                                 &lt;key&gt;groupSize&lt;/key&gt;
</span><del>-                                &lt;integer&gt;1&lt;/integer&gt;
</del><ins>+                                &lt;integer&gt;3&lt;/integer&gt;
</ins><span class="cx"> 
</span><span class="cx">                                 &lt;!-- Number of seconds between the introduction of each group. --&gt;
</span><span class="cx">                                 &lt;key&gt;interval&lt;/key&gt;
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">                 &lt;!-- Define some log observers to report on the load test. --&gt;
</span><span class="cx">                 &lt;key&gt;observers&lt;/key&gt;
</span><span class="cx">                 &lt;array&gt;
</span><del>-                        &lt;!-- ReportStatistics generates an end-of-run summary of the HTTP requests 
</del><ins>+                        &lt;!-- ReportStatistics generates an end-of-run summary of the HTTP requests
</ins><span class="cx">                                 made, their timings, and their results. --&gt;
</span><span class="cx">                         &lt;dict&gt;
</span><span class="cx">                                 &lt;key&gt;type&lt;/key&gt;
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx">                                         &lt;!-- The thresholds for each request type --&gt;
</span><span class="cx">                                         &lt;key&gt;thresholdsPath&lt;/key&gt;
</span><span class="cx">                                         &lt;string&gt;contrib/performance/loadtest/thresholds.json&lt;/string&gt;
</span><del>-                                        
</del><ins>+
</ins><span class="cx">                                         &lt;!-- The benchmarks for overall QoS --&gt;
</span><span class="cx">                                         &lt;key&gt;benchmarksPath&lt;/key&gt;
</span><span class="cx">                                         &lt;string&gt;contrib/performance/loadtest/benchmarks.json&lt;/string&gt;
</span><span class="lines">@@ -138,8 +138,8 @@
</span><span class="cx">                                         &lt;real&gt;1.0&lt;/real&gt;
</span><span class="cx">                                 &lt;/dict&gt;
</span><span class="cx">                         &lt;/dict&gt;
</span><del>-        
-                        &lt;!-- RequestLogger generates a realtime log of all HTTP requests made 
</del><ins>+
+                        &lt;!-- RequestLogger generates a realtime log of all HTTP requests made
</ins><span class="cx">                                 during the load test. --&gt;
</span><span class="cx">                         &lt;dict&gt;
</span><span class="cx">                                 &lt;key&gt;type&lt;/key&gt;
</span><span class="lines">@@ -148,9 +148,9 @@
</span><span class="cx">                                 &lt;dict&gt;
</span><span class="cx">                                 &lt;/dict&gt;
</span><span class="cx">                         &lt;/dict&gt;
</span><del>-        
-                        &lt;!-- OperationLogger generates an end-of-run summary of the gross operations 
-                                performed (logical operations which may span more than one HTTP request, 
</del><ins>+
+                        &lt;!-- OperationLogger generates an end-of-run summary of the gross operations
+                                performed (logical operations which may span more than one HTTP request,
</ins><span class="cx">                                 such as inviting an attendee to an event). --&gt;
</span><span class="cx">                         &lt;dict&gt;
</span><span class="cx">                                 &lt;key&gt;type&lt;/key&gt;
</span><span class="lines">@@ -160,11 +160,11 @@
</span><span class="cx">                                         &lt;!-- The thresholds for each operation type --&gt;
</span><span class="cx">                                         &lt;key&gt;thresholdsPath&lt;/key&gt;
</span><span class="cx">                                         &lt;string&gt;contrib/performance/loadtest/thresholds.json&lt;/string&gt;
</span><del>-                                        
</del><ins>+
</ins><span class="cx">                                         &lt;!-- The % of operations beyond the lag cut-off that constitute a failed test --&gt;
</span><span class="cx">                                         &lt;key&gt;lagCutoff&lt;/key&gt;
</span><span class="cx">                                         &lt;real&gt;1.0&lt;/real&gt;
</span><del>-                                        
</del><ins>+
</ins><span class="cx">                                         &lt;!-- The % of failures that constitute a failed test --&gt;
</span><span class="cx">                                         &lt;key&gt;failCutoff&lt;/key&gt;
</span><span class="cx">                                         &lt;real&gt;1.0&lt;/real&gt;
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtesticalpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/ical.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -18,7 +18,10 @@
</span><span class="cx"> 
</span><span class="cx"> from caldavclientlibrary.protocol.caldav.definitions import caldavxml
</span><span class="cx"> from caldavclientlibrary.protocol.caldav.definitions import csxml
</span><ins>+from caldavclientlibrary.protocol.calendarserver.invite import AddInvitees, RemoveInvitee, InviteUser
+from caldavclientlibrary.protocol.calendarserver.notifications import InviteNotification
</ins><span class="cx"> from caldavclientlibrary.protocol.url import URL
</span><ins>+from caldavclientlibrary.protocol.utils.xmlhelpers import BetterElementTree
</ins><span class="cx"> from caldavclientlibrary.protocol.webdav.definitions import davxml
</span><span class="cx"> from caldavclientlibrary.protocol.webdav.propfindparser import PropFindParser
</span><span class="cx"> 
</span><span class="lines">@@ -45,22 +48,27 @@
</span><span class="cx"> from twisted.python.util import FancyEqMixin
</span><span class="cx"> from twisted.web.client import Agent, ContentDecoderAgent, GzipDecoder, \
</span><span class="cx">     _DeprecatedToCurrentPolicyForHTTPS
</span><del>-from twisted.web.http import OK, MULTI_STATUS, CREATED, NO_CONTENT, PRECONDITION_FAILED, MOVED_PERMANENTLY, \
-    FORBIDDEN, FOUND
</del><ins>+from twisted.web.http import (
+    OK, MULTI_STATUS, CREATED, NO_CONTENT, PRECONDITION_FAILED,
+    MOVED_PERMANENTLY, FORBIDDEN, FOUND, NOT_FOUND
+)
</ins><span class="cx"> from twisted.web.http_headers import Headers
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.ical import Component, Property
</span><span class="cx"> 
</span><span class="cx"> from urlparse import urlparse, urlunparse, urlsplit, urljoin
</span><span class="cx"> from uuid import uuid4
</span><del>-from xml.etree import ElementTree
</del><ins>+from xml.etree.ElementTree import ElementTree, Element, SubElement, QName
</ins><span class="cx"> 
</span><ins>+from StringIO import StringIO
+
</ins><span class="cx"> import json
</span><span class="cx"> import os
</span><span class="cx"> import random
</span><span class="cx"> 
</span><del>-ElementTree.QName.__repr__ = lambda self: '&lt;QName %r&gt;' % (self.text,)
</del><ins>+QName.__repr__ = lambda self: '&lt;QName %r&gt;' % (self.text,)
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> def loadRequestBody(clientType, label):
</span><span class="cx">     return FilePath(__file__).sibling('request-data').child(clientType).child(label + '.request').getContent()
</span><span class="cx"> 
</span><span class="lines">@@ -245,19 +253,72 @@
</span><span class="cx">                 calendar.changeToken = &quot;&quot;
</span><span class="cx">         return calendar
</span><span class="cx"> 
</span><ins>+    @staticmethod
+    def addInviteeXML(uid, summary, readwrite=True):
+        return AddInvitees(None, '/', [uid], readwrite, summary=summary).request_data.text
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    @staticmethod
+    def removeInviteeXML(uid):
+        invitee = InviteUser()
+        # Usually an InviteUser is populated through .parseFromUser, but we only care about a uid
+        invitee.user_uid = uid
+        return RemoveInvitee(None, '/', invitee).request_data.text
+
+
+
+class NotificationCollection(object):
+    def __init__(self, url, changeToken):
+        self.url = url
+        self.changeToken = changeToken
+        self.notifications = {}
+        self.name = &quot;notification&quot;
+
+    def serialize(self):
+        &quot;&quot;&quot;
+        Create a dict of the data so we can serialize as JSON.
+        &quot;&quot;&quot;
+
+        result = {}
+        for attr in (&quot;url&quot;, &quot;changeToken&quot;):
+            result[attr] = getattr(self, attr)
+        result[&quot;notifications&quot;] = sorted(self.notifications.keys())
+        return result
+
+
+    @staticmethod
+    def deserialize(data, notifications):
+        &quot;&quot;&quot;
+        Convert dict (deserialized from JSON) into an L{Calendar}.
+        &quot;&quot;&quot;
+
+        coll = NotificationCollection(None, None)
+        for attr in (&quot;url&quot;, &quot;changeToken&quot;):
+            setattr(coll, attr, u2str(data[attr]))
+
+        for notification in data[&quot;notifications&quot;]:
+            url = urljoin(coll.url, notification)
+            if url in notifications:
+                coll.notifications[notification] = notifications[url]
+            else:
+                # Ughh - a notification is missing - force changeToken to empty to trigger full resync
+                coll.changeToken = &quot;&quot;
+        return coll
+
+
+
</ins><span class="cx"> class BaseClient(object):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Base interface for all simulated clients.
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><del>-    user = None         # User account details
-    _events = None      # Cache of events keyed by href
-    _calendars = None   # Cache of calendars keyed by href
-    started = False     # Whether or not startup() has been executed
-    _client_type = None # Type of this client used in logging
-    _client_id = None   # Unique id for the client itself
</del><ins>+    user = None                     # User account details
+    _events = None                  # Cache of events keyed by href
+    _calendars = None               # Cache of calendars keyed by href
+    _notificationCollection = None  # Cache of the notification collection
+    started = False                 # Whether or not startup() has been executed
+    _client_type = None             # Type of this client used in logging
+    _client_id = None               # Unique id for the client itself
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _setEvent(self, href, event):
</span><span class="lines">@@ -408,6 +469,8 @@
</span><span class="cx">     _POLL_NOTIFICATION_PROPFIND = None
</span><span class="cx">     _POLL_NOTIFICATION_PROPFIND_D1 = None
</span><span class="cx"> 
</span><ins>+    _NOTIFICATION_SYNC_REPORT = None
+
</ins><span class="cx">     _USER_LIST_PRINCIPAL_PROPERTY_SEARCH = None
</span><span class="cx">     _POST_AVAILABILITY = None
</span><span class="cx"> 
</span><span class="lines">@@ -451,6 +514,8 @@
</span><span class="cx">             calendarHomePollInterval = self.CALENDAR_HOME_POLL_INTERVAL
</span><span class="cx">         self.calendarHomePollInterval = calendarHomePollInterval
</span><span class="cx"> 
</span><ins>+        self.calendarHomeHref = None
+
</ins><span class="cx">         self.supportPush = supportPush
</span><span class="cx"> 
</span><span class="cx">         self.supportAmpPush = supportAmpPush
</span><span class="lines">@@ -728,8 +793,10 @@
</span><span class="cx">             depth='1',
</span><span class="cx">             method_label=&quot;PROPFIND{home}&quot;,
</span><span class="cx">         )
</span><del>-        calendars = self._extractCalendars(result, calendarHomeSet)
-        returnValue((calendars, result,))
</del><ins>+        calendars, notificationCollection = self._extractCalendars(
+            result, calendarHomeSet
+        )
+        returnValue((calendars, notificationCollection, result,))
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span><span class="lines">@@ -775,6 +842,10 @@
</span><span class="cx">         that from the response.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         calendars = []
</span><ins>+        notificationCollection = None
+
+        changeTag = davxml.sync_token if self.supportSync else csxml.getctag
+
</ins><span class="cx">         for href in results:
</span><span class="cx"> 
</span><span class="cx">             if href == calendarHome:
</span><span class="lines">@@ -808,7 +879,6 @@
</span><span class="cx">                             for comp in nodes[caldavxml.supported_calendar_component_set]:
</span><span class="cx">                                 componentTypes.add(comp.get(&quot;name&quot;).upper())
</span><span class="cx"> 
</span><del>-                    changeTag = davxml.sync_token if self.supportSync else csxml.getctag
</del><span class="cx">                     calendars.append(Calendar(
</span><span class="cx">                         nodeType.tag,
</span><span class="cx">                         componentTypes,
</span><span class="lines">@@ -817,9 +887,16 @@
</span><span class="cx">                         textProps.get(changeTag, None),
</span><span class="cx">                     ))
</span><span class="cx">                     break
</span><del>-        return calendars
</del><ins>+                elif nodeType.tag == csxml.notification:
+                    textProps = results[href].getTextProperties()
+                    notificationCollection = NotificationCollection(
+                        href,
+                        textProps.get(changeTag, None)
+                    )
</ins><span class="cx"> 
</span><ins>+        return calendars, notificationCollection
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     def _updateCalendar(self, calendar, newToken):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Update the local cached data for a calendar in an appropriate manner.
</span><span class="lines">@@ -1048,12 +1125,132 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     @inlineCallbacks
</span><ins>+    def _updateNotifications(self, oldToken, newToken):
+
+        fullSync = not oldToken
+
+        # Get the list of notificatinon xml resources
+
+        result = yield self._report(
+            self._notificationCollection.url,
+            self._NOTIFICATION_SYNC_REPORT % {'sync-token': oldToken},
+            depth='1',
+            allowedStatus=(MULTI_STATUS, FORBIDDEN,),
+            otherTokens=True,
+            method_label=&quot;REPORT{sync}&quot; if oldToken else &quot;REPORT{sync-init}&quot;,
+        )
+        if result is None:
+            if not fullSync:
+                fullSync = True
+                result = yield self._report(
+                    self._notificationCollection.url,
+                    self._NOTIFICATION_SYNC_REPORT % {'sync-token': ''},
+                    depth='1',
+                    otherTokens=True,
+                    method_label=&quot;REPORT{sync}&quot; if oldToken else &quot;REPORT{sync-init}&quot;,
+                )
+            else:
+                raise IncorrectResponseCode((MULTI_STATUS,), None)
+
+        result, others = result
+
+        # Scan for the sharing invites
+        inviteNotifications = []
+        toDelete = []
+        for responseHref in result:
+            if responseHref == self._notificationCollection.url:
+                continue
+
+            # try:
+            #     etag = result[responseHref].getTextProperties()[davxml.getetag]
+            # except KeyError:
+            #     # XXX Ignore things with no etag?  Seems to be dropbox.
+            #     continue
+
+            toDelete.append(responseHref)
+
+            if result[responseHref].getStatus() / 100 == 2:
+                # Get the notification
+                response = yield self._request(
+                    OK,
+                    'GET',
+                    self.root + responseHref.encode('utf-8'),
+                    method_label=&quot;GET{notification}&quot;,
+                )
+                body = yield readBody(response)
+                node = ElementTree(file=StringIO(body)).getroot()
+                if node.tag == str(csxml.notification):
+                    nurl = URL(url=responseHref)
+                    for child in node.getchildren():
+                        if child.tag == str(csxml.invite_notification):
+                            if child.find(str(csxml.invite_noresponse)) is not None:
+                                inviteNotifications.append(
+                                    InviteNotification().parseFromNotification(
+                                        nurl, child
+                                    )
+                                )
+
+        # Accept the invites
+        for notification in inviteNotifications:
+            # Create an invite-reply
+            &quot;&quot;&quot;
+            &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+            &lt;C:invite-reply xmlns:C=&quot;http://calendarserver.org/ns/&quot;&gt;
+              &lt;A:href xmlns:A=&quot;DAV:&quot;&gt;urn:x-uid:10000000-0000-0000-0000-000000000002&lt;/A:href&gt;
+              &lt;C:invite-accepted/&gt;
+              &lt;C:hosturl&gt;
+                &lt;A:href xmlns:A=&quot;DAV:&quot;&gt;/calendars/__uids__/10000000-0000-0000-0000-000000000001/A1DDC58B-651E-4B1C-872A-C6588CA09ADB&lt;/A:href&gt;
+              &lt;/C:hosturl&gt;
+              &lt;C:in-reply-to&gt;d2683fa9-7a50-4390-82bb-cbcea5e0fa86&lt;/C:in-reply-to&gt;
+              &lt;C:summary&gt;to share&lt;/C:summary&gt;
+            &lt;/C:invite-reply&gt;
+            &quot;&quot;&quot;
+            reply = Element(csxml.invite_reply)
+            href = SubElement(reply, davxml.href)
+            href.text = notification.user_uid
+            SubElement(reply, csxml.invite_accepted)
+            hosturl = SubElement(reply, csxml.hosturl)
+            href = SubElement(hosturl, davxml.href)
+            href.text = notification.hosturl
+            inReplyTo = SubElement(reply, csxml.in_reply_to)
+            inReplyTo.text = notification.uid
+            summary = SubElement(reply, csxml.summary)
+            summary.text = notification.summary
+
+            xmldoc = BetterElementTree(reply)
+            os = StringIO()
+            xmldoc.writeUTF8(os)
+            # Post to my calendar home
+            response = yield self.postXML(
+                self.calendarHomeHref,
+                os.getvalue(),
+                &quot;POST{invite-accept}&quot;
+            )
+
+        # Delete all the notification resources
+        for responseHref in toDelete:
+            response = yield self._request(
+                (NO_CONTENT, NOT_FOUND),
+                'DELETE',
+                self.root + responseHref.encode('utf-8'),
+                method_label=&quot;DELETE{invite}&quot;,
+            )
+
+        self._notificationCollection.changeToken = newToken
+
+
+
+    @inlineCallbacks
</ins><span class="cx">     def _poll(self, calendarHomeSet, firstTime):
</span><ins>+        &quot;&quot;&quot;
+        This gets called during a normal poll or in response to a push
+        &quot;&quot;&quot;
+
</ins><span class="cx">         if calendarHomeSet in self._checking:
</span><span class="cx">             returnValue(False)
</span><span class="cx">         self._checking.add(calendarHomeSet)
</span><span class="cx"> 
</span><del>-        calendars, results = yield self._calendarHomePropfind(calendarHomeSet)
</del><ins>+        calendars, notificationCollection, results = yield self._calendarHomePropfind(calendarHomeSet)
</ins><span class="cx"> 
</span><span class="cx">         # First time operations
</span><span class="cx">         if firstTime:
</span><span class="lines">@@ -1071,12 +1268,24 @@
</span><span class="cx">                 # Calendar changed - reload it
</span><span class="cx">                 yield self._updateCalendar(self._calendars[cal.url], newToken)
</span><span class="cx"> 
</span><del>-        # When there is no sync REPORT, clients have to do a full PROPFIND
-        # on the notification collection because there is no ctag
-        if self.notificationURL is not None and not self.supportSync:
-            yield self._notificationPropfind(self.notificationURL)
-            yield self._notificationChangesPropfind(self.notificationURL)
</del><ins>+        if notificationCollection is not None:
+            if self._notificationCollection:
+                oldToken = self._notificationCollection.changeToken
+            else:
+                oldToken = &quot;&quot;
+            self._notificationCollection = notificationCollection
+            newToken = notificationCollection.changeToken
+            yield self._updateNotifications(oldToken, newToken)
</ins><span class="cx"> 
</span><ins>+        # FIXME: isn't sync report the new norm, and therefore we can remove
+        # the following?
+
+        # # When there is no sync REPORT, clients have to do a full PROPFIND
+        # # on the notification collection because there is no ctag
+        # if self.notificationURL is not None and not self.supportSync:
+        #     yield self._notificationPropfind(self.notificationURL)
+        #     yield self._notificationChangesPropfind(self.notificationURL)
+
</ins><span class="cx">         # One time delegate expansion
</span><span class="cx">         if firstTime:
</span><span class="cx">             yield self._pollFirstTime2()
</span><span class="lines">@@ -1263,6 +1472,8 @@
</span><span class="cx">             calendarHome = hrefs[caldavxml.calendar_home_set].toString()
</span><span class="cx">             if calendarHome is None:
</span><span class="cx">                 raise MissingCalendarHome
</span><ins>+            else:
+                self.calendarHomeHref = calendarHome
</ins><span class="cx">             yield self._checkCalendarsForEvents(calendarHome, firstTime=True)
</span><span class="cx">             returnValue(calendarHome)
</span><span class="cx">         calendarHome = yield self._newOperation(&quot;startup: %s&quot; % (self.title,), startup())
</span><span class="lines">@@ -1327,8 +1538,8 @@
</span><span class="cx">             &quot;principalURL&quot;: self.principalURL,
</span><span class="cx">             &quot;calendars&quot;: [calendar.serialize() for calendar in sorted(self._calendars.values(), key=lambda x:x.name)],
</span><span class="cx">             &quot;events&quot;: [event.serialize() for event in sorted(self._events.values(), key=lambda x:x.url)],
</span><ins>+            &quot;notificationCollection&quot; : self._notificationCollection.serialize(),
</ins><span class="cx">         }
</span><del>-
</del><span class="cx">         # Write JSON data
</span><span class="cx">         with open(os.path.join(path, &quot;index.json&quot;), &quot;w&quot;) as f:
</span><span class="cx">             json.dump(data, f, indent=2)
</span><span class="lines">@@ -1452,18 +1663,11 @@
</span><span class="cx">             elif attendee.hasParameter('EMAIL'):
</span><span class="cx">                 email = attendee.parameterValue('EMAIL').encode(&quot;utf-8&quot;)
</span><span class="cx"> 
</span><del>-            # First try to discover some names to supply to the
-            # auto-completion
</del><ins>+            search = &quot;&lt;C:search-token&gt;{}&lt;/C:search-token&gt;&quot;.format(prefix)
+            body = self._CALENDARSERVER_PRINCIPAL_SEARCH_REPORT.format(
+                context=&quot;attendee&quot;, searchTokens=search)
</ins><span class="cx">             yield self._report(
</span><del>-                self.principalCollection,
-                self._USER_LIST_PRINCIPAL_PROPERTY_SEARCH % {
-                    'displayname': prefix,
-                    'email': prefix,
-                    'firstname': prefix,
-                    'lastname': prefix,
-                },
-                depth=None,
-                method_label=&quot;REPORT{psearch}&quot;,
</del><ins>+                '/principals/', body, depth=None, method_label=&quot;REPORT{cpsearch}&quot;
</ins><span class="cx">             )
</span><span class="cx"> 
</span><span class="cx">             # Now learn about the attendee's availability
</span><span class="lines">@@ -1475,6 +1679,7 @@
</span><span class="cx">             )
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx">     @inlineCallbacks
</span><span class="cx">     def changeEventAttendee(self, href, oldAttendee, newAttendee):
</span><span class="cx">         event = self._events[href]
</span><span class="lines">@@ -1522,7 +1727,7 @@
</span><span class="cx">         self._removeEvent(href)
</span><span class="cx"> 
</span><span class="cx">         response = yield self._request(
</span><del>-            NO_CONTENT,
</del><ins>+            (NO_CONTENT, NOT_FOUND),
</ins><span class="cx">             'DELETE',
</span><span class="cx">             self.root + href.encode('utf-8'),
</span><span class="cx">             method_label=&quot;DELETE{event}&quot;,
</span><span class="lines">@@ -1702,7 +1907,42 @@
</span><span class="cx">         returnValue(body)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    @inlineCallbacks
+    def postAttachment(self, href, content):
+        url = self.root + &quot;{0}?{1}&quot;.format(href, &quot;action=attachment-add&quot;)
+        filename = 'file-{}.txt'.format(len(content))
+        headers = Headers({
+            'Content-Disposition': ['attachment; filename=&quot;{}&quot;'.format(filename)]
+        })
+        response = yield self._request(
+            CREATED,
+            'POST',
+            url,
+            headers=headers,
+            body=StringProducer(content),
+            method_label=&quot;POST{attach}&quot;
+        )
+        body = yield readBody(response)
+        returnValue(body)
</ins><span class="cx"> 
</span><ins>+
+    @inlineCallbacks
+    def postXML(self, href, content, label):
+        headers = Headers({
+            'content-type': ['text/xml']
+        })
+        response = yield self._request(
+            (OK, CREATED, MULTI_STATUS),
+            'POST',
+            self.root + href,
+            headers=headers,
+            body=StringProducer(content),
+            method_label=label
+        )
+        body = yield readBody(response)
+        returnValue(body)
+
+
</ins><span class="cx"> class OS_X_10_6(BaseAppleClient):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Implementation of the OS X 10.6 iCal network behavior.
</span><span class="lines">@@ -1868,7 +2108,99 @@
</span><span class="cx">         returnValue(principal)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+class OS_X_10_11(BaseAppleClient):
+    &quot;&quot;&quot;
+    Implementation of the OS X 10.11 Calendar.app network behavior.
+    &quot;&quot;&quot;
</ins><span class="cx"> 
</span><ins>+    _client_type = &quot;OS X 10.11&quot;
+
+    USER_AGENT = &quot;Mac+OS+X/10.11 (15A283) CalendarAgent/361&quot;
+
+    # The default interval, used if none is specified in external
+    # configuration.  This is also the actual value used by El
+    # Capital Calendar.app.
+    CALENDAR_HOME_POLL_INTERVAL = 15 * 60  # in seconds
+
+    # The maximum number of resources to retrieve in a single multiget
+    MULTIGET_BATCH_SIZE = 50
+
+    # Override and turn on if client supports Sync REPORT
+    _SYNC_REPORT = True
+
+    # Override and turn off if client does not support attendee lookups
+    _ATTENDEE_LOOKUPS = True
+
+    # Request body data
+    _LOAD_PATH = &quot;OS_X_10_11&quot;
+
+    _STARTUP_WELL_KNOWN = loadRequestBody(_LOAD_PATH, 'startup_well_known_propfind')
+    _STARTUP_PRINCIPAL_PROPFIND_INITIAL = loadRequestBody(_LOAD_PATH, 'startup_principal_initial_propfind')
+    _STARTUP_PRINCIPAL_PROPFIND = loadRequestBody(_LOAD_PATH, 'startup_principal_propfind')
+    _STARTUP_PRINCIPALS_REPORT = loadRequestBody(_LOAD_PATH, 'startup_principals_report')
+    _STARTUP_PRINCIPAL_EXPAND = loadRequestBody(_LOAD_PATH, 'startup_principal_expand')
+
+    _STARTUP_CREATE_CALENDAR = loadRequestBody(_LOAD_PATH, 'startup_create_calendar')
+    _STARTUP_PROPPATCH_CALENDAR_COLOR = loadRequestBody(_LOAD_PATH, 'startup_calendar_color_proppatch')
+    # _STARTUP_PROPPATCH_CALENDAR_NAME = loadRequestBody(_LOAD_PATH, 'startup_calendar_displayname_proppatch')
+    _STARTUP_PROPPATCH_CALENDAR_ORDER = loadRequestBody(_LOAD_PATH, 'startup_calendar_order_proppatch')
+    _STARTUP_PROPPATCH_CALENDAR_TIMEZONE = loadRequestBody(_LOAD_PATH, 'startup_calendar_timezone_proppatch')
+
+    _POLL_CALENDARHOME_PROPFIND = loadRequestBody(_LOAD_PATH, 'poll_calendarhome_depth1_propfind')
+    _POLL_CALENDAR_PROPFIND = loadRequestBody(_LOAD_PATH, 'poll_calendar_propfind')
+    _POLL_CALENDAR_PROPFIND_D1 = loadRequestBody(_LOAD_PATH, 'poll_calendar_depth1_propfind')
+    _POLL_CALENDAR_MULTIGET_REPORT = loadRequestBody('OS_X_10_7', 'poll_calendar_multiget')
+    _POLL_CALENDAR_MULTIGET_REPORT_HREF = loadRequestBody('OS_X_10_7', 'poll_calendar_multiget_hrefs')
+    _POLL_CALENDAR_SYNC_REPORT = loadRequestBody('OS_X_10_7', 'poll_calendar_sync')
+    _POLL_NOTIFICATION_PROPFIND = loadRequestBody(_LOAD_PATH, 'poll_calendar_propfind')
+    _POLL_NOTIFICATION_PROPFIND_D1 = loadRequestBody(_LOAD_PATH, 'poll_notification_depth1_propfind')
+
+    _NOTIFICATION_SYNC_REPORT = loadRequestBody(_LOAD_PATH, 'notification_sync')
+
+    _USER_LIST_PRINCIPAL_PROPERTY_SEARCH = loadRequestBody('OS_X_10_7', 'user_list_principal_property_search')
+    _POST_AVAILABILITY = loadRequestBody('OS_X_10_7', 'post_availability')
+
+    _CALENDARSERVER_PRINCIPAL_SEARCH_REPORT = loadRequestBody(_LOAD_PATH, 'principal_search_report')
+
+
+    def _addDefaultHeaders(self, headers):
+        &quot;&quot;&quot;
+        Add the clients default set of headers to ones being used in a request.
+        Default is to add User-Agent, sub-classes should override to add other
+        client specific things, Accept etc.
+        &quot;&quot;&quot;
+
+        super(OS_X_10_11, self)._addDefaultHeaders(headers)
+        headers.setRawHeaders('Accept', ['*/*'])
+        headers.setRawHeaders('Accept-Language', ['en-us'])
+        headers.setRawHeaders('Accept-Encoding', ['gzip,deflate'])
+        headers.setRawHeaders('Connection', ['keep-alive'])
+
+
+    @inlineCallbacks
+    def startup(self):
+        # Try to read data from disk - if it succeeds self.principalURL will be set
+        self.deserialize()
+
+        if self.principalURL is None:
+            # PROPFIND well-known with redirect
+            response = yield self._startupPropfindWellKnown()
+            hrefs = response.getHrefProperties()
+            if davxml.current_user_principal in hrefs:
+                self.principalURL = hrefs[davxml.current_user_principal].toString()
+            elif davxml.principal_URL in hrefs:
+                self.principalURL = hrefs[davxml.principal_URL].toString()
+            else:
+                # PROPFIND principal path to retrieve actual principal-URL
+                response = yield self._principalPropfindInitial(self.record.uid)
+                hrefs = response.getHrefProperties()
+                self.principalURL = hrefs[davxml.principal_URL].toString()
+
+        # Using the actual principal URL, retrieve principal information
+        principal = yield self._extractPrincipalDetails()
+        returnValue(principal)
+
+
</ins><span class="cx"> class iOS_5(BaseAppleClient):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     Implementation of the iOS 5 network behavior.
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestpopulationpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/population.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/population.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -162,10 +162,11 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class CalendarClientSimulator(object):
</span><del>-    def __init__(self, records, populator, parameters, reactor, server,
</del><ins>+    def __init__(self, records, populator, random, parameters, reactor, server,
</ins><span class="cx">                  principalPathTemplate, serializationPath, workerIndex=0, workerCount=1):
</span><span class="cx">         self._records = records
</span><span class="cx">         self.populator = populator
</span><ins>+        self._random = random
</ins><span class="cx">         self.reactor = reactor
</span><span class="cx">         self.server = server
</span><span class="cx">         self.principalPathTemplate = principalPathTemplate
</span><span class="lines">@@ -184,6 +185,31 @@
</span><span class="cx">         return self._records[index]
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    def getRandomUserRecord(self, besides=None):
+        count = len(self._records)
+
+        if count == 0:
+            # No records!
+            return None
+
+        if count == 1 and besides == 0:
+            # There is only one item and caller doesn't want it!
+            return None
+
+        for i in xrange(100):
+            # Try to find one that is not &quot;besides&quot;
+            n = self._random.randint(0, count - 1)
+            if besides != n:
+                # Got it.
+                break
+        else:
+            # Give up
+            return None
+        print(&quot;SELECTION, besides=&quot;, besides, &quot;count=&quot;, count, &quot;n=&quot;, n)
+        return self._records[n]
+
+
+
</ins><span class="cx">     def _nextUserNumber(self):
</span><span class="cx">         result = self._user
</span><span class="cx">         self._user += 1
</span><span class="lines">@@ -640,7 +666,7 @@
</span><span class="cx">     parameters.addClient(
</span><span class="cx">         1, ClientType(OS_X_10_6, [Eventer, Inviter, Accepter]))
</span><span class="cx">     simulator = CalendarClientSimulator(
</span><del>-        populator, parameters, reactor, '127.0.0.1', 8008)
</del><ins>+        populator, r, parameters, reactor, '127.0.0.1', 8008)
</ins><span class="cx"> 
</span><span class="cx">     arrivalPolicy = SmoothRampUp(groups=10, groupSize=1, interval=3)
</span><span class="cx">     arrivalPolicy.run(reactor, simulator)
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestprofilespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> from twisted.python import context
</span><span class="cx"> from twisted.python.log import msg
</span><span class="cx"> from twisted.python.failure import Failure
</span><del>-from twisted.internet.defer import Deferred, succeed, fail
</del><ins>+from twisted.internet.defer import Deferred, succeed, fail, inlineCallbacks, returnValue
</ins><span class="cx"> from twisted.internet.task import LoopingCall
</span><span class="cx"> from twisted.web.http import PRECONDITION_FAILED
</span><span class="cx"> 
</span><span class="lines">@@ -40,7 +40,7 @@
</span><span class="cx"> from contrib.performance.stats import NearFutureDistribution, NormalDistribution, UniformDiscreteDistribution, mean, median
</span><span class="cx"> from contrib.performance.stats import LogNormalDistribution, RecurrenceDistribution
</span><span class="cx"> from contrib.performance.loadtest.logger import SummarizingMixin
</span><del>-from contrib.performance.loadtest.ical import IncorrectResponseCode
</del><ins>+from contrib.performance.loadtest.ical import Calendar, IncorrectResponseCode
</ins><span class="cx"> 
</span><span class="cx"> from pycalendar.datetime import DateTime
</span><span class="cx"> from pycalendar.duration import Duration
</span><span class="lines">@@ -78,9 +78,46 @@
</span><span class="cx">             cal
</span><span class="cx">             for cal
</span><span class="cx">             in self._client._calendars.itervalues()
</span><del>-            if cal.resourceType == calendarType and componentType in cal.componentTypes]
</del><ins>+            if cal.resourceType == calendarType and componentType in cal.componentTypes
+        ]
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+    def _getRandomCalendarOfType(self, componentType):
+        &quot;&quot;&quot;
+        Return a random L{Calendar} object from the current user
+        or C{None} if there are no calendars to work with
+        &quot;&quot;&quot;
+        calendars = self._calendarsOfType(caldavxml.calendar, componentType)
+        if not calendars:
+            return None
+        # Choose a random calendar
+        calendar = self.random.choice(calendars)
+        return calendar
+
+
+    def _getRandomEventOfType(self, componentType):
+        &quot;&quot;&quot;
+        Return a random L{Event} object from the current user
+        or C{None} if there are no events to work with
+        &quot;&quot;&quot;
+        calendars = self._calendarsOfType(caldavxml.calendar, componentType)
+        while calendars:
+            calendar = self.random.choice(calendars)
+            calendars.remove(calendar)
+            if not calendar.events:
+                continue
+
+            events = calendar.events.keys()
+            while events:
+                href = self.random.choice(events)
+                events.remove(href)
+                event = calendar.events[href]
+                if not event.component:
+                    continue
+                return event
+        return None
+
+
</ins><span class="cx">     def _isSelfAttendee(self, attendee):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         Try to match one of the attendee's identifiers against one of
</span><span class="lines">@@ -645,38 +682,195 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _addEvent(self):
</span><ins>+        # Don't perform any operations until the client is up and running
</ins><span class="cx">         if not self._client.started:
</span><span class="cx">             return succeed(None)
</span><span class="cx"> 
</span><del>-        calendars = self._calendarsOfType(caldavxml.calendar, &quot;VEVENT&quot;)
</del><ins>+        calendar = self._getRandomCalendarOfType('VEVENT')
</ins><span class="cx"> 
</span><del>-        while calendars:
-            calendar = self.random.choice(calendars)
-            calendars.remove(calendar)
</del><ins>+        if not calendar:
+            # No VEVENT calendars, so no new event...
+            return succeed(None)
</ins><span class="cx"> 
</span><del>-            # Copy the template event and fill in some of its fields
-            # to make a new event to create on the calendar.
-            vcalendar = self._eventTemplate.duplicate()
-            vevent = vcalendar.mainComponent()
-            uid = str(uuid4())
-            dtstart = self._eventStartDistribution.sample()
-            dtend = dtstart + Duration(seconds=self._eventDurationDistribution.sample())
-            vevent.replaceProperty(Property(&quot;CREATED&quot;, DateTime.getNowUTC()))
-            vevent.replaceProperty(Property(&quot;DTSTAMP&quot;, DateTime.getNowUTC()))
-            vevent.replaceProperty(Property(&quot;DTSTART&quot;, dtstart))
-            vevent.replaceProperty(Property(&quot;DTEND&quot;, dtend))
-            vevent.replaceProperty(Property(&quot;UID&quot;, uid))
</del><ins>+        # Copy the template event and fill in some of its fields
+        # to make a new event to create on the calendar.
+        vcalendar = self._eventTemplate.duplicate()
+        vevent = vcalendar.mainComponent()
+        uid = str(uuid4())
+        dtstart = self._eventStartDistribution.sample()
+        dtend = dtstart + Duration(seconds=self._eventDurationDistribution.sample())
+        vevent.replaceProperty(Property(&quot;CREATED&quot;, DateTime.getNowUTC()))
+        vevent.replaceProperty(Property(&quot;DTSTAMP&quot;, DateTime.getNowUTC()))
+        vevent.replaceProperty(Property(&quot;DTSTART&quot;, dtstart))
+        vevent.replaceProperty(Property(&quot;DTEND&quot;, dtend))
+        vevent.replaceProperty(Property(&quot;UID&quot;, uid))
</ins><span class="cx"> 
</span><del>-            rrule = self._recurrenceDistribution.sample()
-            if rrule is not None:
-                vevent.addProperty(Property(None, None, None, pycalendar=rrule))
</del><ins>+        rrule = self._recurrenceDistribution.sample()
+        if rrule is not None:
+            vevent.addProperty(Property(None, None, None, pycalendar=rrule))
</ins><span class="cx"> 
</span><del>-            href = '%s%s.ics' % (calendar.url, uid)
-            d = self._client.addEvent(href, vcalendar)
-            return self._newOperation(&quot;create&quot;, d)
</del><ins>+        href = '%s%s.ics' % (calendar.url, uid)
+        d = self._client.addEvent(href, vcalendar)
+        return self._newOperation(&quot;create&quot;, d)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><ins>+class EventUpdaterBase(ProfileBase):
</ins><span class="cx"> 
</span><ins>+    @inlineCallbacks
+    def action(self):
+        # Don't perform any operations until the client is up and running
+        if not self._client.started:
+            returnValue(None)
+
+        event = self._getRandomEventOfType('VEVENT')
+        if not event:
+            returnValue(None)
+        component = event.component
+        vevent = component.mainComponent()
+
+        label = yield self.modifyEvent(event.url, vevent)
+        vevent.replaceProperty(Property(&quot;DTSTAMP&quot;, DateTime.getNowUTC()))
+
+        event.component = component
+        yield self._newOperation(
+            label,
+            self._client.changeEvent(event.url)
+        )
+
+
+    def run(self):
+        self._call = LoopingCall(self.action)
+        self._call.clock = self._reactor
+        return self._call.start(self._interval)
+
+
+    def modifyEvent(self, href, vevent):
+        &quot;&quot;&quot;Overriden by subclasses&quot;&quot;&quot;
+        pass
+
+
+class TitleChanger(EventUpdaterBase):
+
+    def setParameters(
+        self,
+        enabled=True,
+        interval=60,
+        titleLengthDistribution=NormalDistribution(10, 2)
+    ):
+        self.enabled = enabled
+        self._interval = interval
+        self._titleLength = titleLengthDistribution
+
+    def modifyEvent(self, _ignore_href, vevent):
+        length = max(5, int(self._titleLength.sample()))
+        vevent.replaceProperty(Property(&quot;SUMMARY&quot;, &quot;Event&quot; + &quot;.&quot; * (length - 5)))
+        return succeed(&quot;update{title}&quot;)
+
+
+class Attacher(EventUpdaterBase):
+
+    def setParameters(
+        self,
+        enabled=True,
+        interval=60,
+        fileSizeDistribution=NormalDistribution(1024, 1),
+    ):
+        self.enabled = enabled
+        self._interval = interval
+        self._fileSize = fileSizeDistribution
+
+    @inlineCallbacks
+    def modifyEvent(self, href, vevent):
+        fileSize = int(self._fileSize.sample())
+        yield self._client.postAttachment(href, 'x' * fileSize)
+        returnValue(&quot;attach{files}&quot;)
+
+
+class EventCountLimiter(EventUpdaterBase):
+    &quot;&quot;&quot;
+    Examines the number of events in each calendar collection, and when that
+    count exceeds eventCountLimit, events are randomly removed until the count
+    falls back to the limit.
+    &quot;&quot;&quot;
+
+    def setParameters(
+        self,
+        enabled=True,
+        interval=60,
+        eventCountLimit=1000
+    ):
+        self.enabled = enabled
+        self._interval = interval
+        self._limit = eventCountLimit
+
+    @inlineCallbacks
+    def action(self):
+        # Don't perform any operations until the client is up and running
+        if not self._client.started:
+            returnValue(None)
+
+        for calendar in self._calendarsOfType(caldavxml.calendar, &quot;VEVENT&quot;):
+            while len(calendar.events) &gt; self._limit:
+                event = calendar.events[self.random.choice(calendar.events.keys())]
+                yield self._client.deleteEvent(event.url)
+
+
+
+class CalendarSharer(ProfileBase):
+    &quot;&quot;&quot;
+    A Calendar user who shares calendars to other random users.
+    &quot;&quot;&quot;
+    def setParameters(
+        self,
+        enabled=True,
+        interval=60
+    ):
+        self.enabled = enabled
+        self._interval = interval
+
+
+    def run(self):
+        self._call = LoopingCall(self.action)
+        self._call.clock = self._reactor
+        return self._call.start(self._interval)
+
+
+    @inlineCallbacks
+    def action(self):
+        # Don't perform any operations until the client is up and running
+        if not self._client.started:
+            returnValue(None)
+
+        yield self.shareCalendar()
+
+
+    @inlineCallbacks
+    def shareCalendar(self):
+
+        # pick a calendar
+        calendar = self._getRandomCalendarOfType('VEVENT')
+        if not calendar:
+            returnValue(None)
+
+        # pick a random sharee
+        shareeRecord = self._sim.getRandomUserRecord(besides=self._number)
+        if shareeRecord is None:
+            returnValue(None)
+
+        # POST the sharing invite
+        mailto = &quot;mailto:{}&quot;.format(shareeRecord.email)
+        body = Calendar.addInviteeXML(mailto, calendar.name, readwrite=True)
+        yield self._client.postXML(
+            calendar.url,
+            body,
+            label=&quot;POST{share-calendar}&quot;
+        )
+
+
+
+# Is the purpose of this profile &quot;EventUpdater&quot; simply to keep updating the same
+# resource over and over?
+
</ins><span class="cx"> class EventUpdater(ProfileBase):
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     A Calendar user who creates a new event, and then updates its alarm.
</span><span class="lines">@@ -741,6 +935,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _initEvent(self):
</span><ins>+        # Don't perform any operations until the client is up and running
</ins><span class="cx">         if not self._client.started:
</span><span class="cx">             return succeed(None)
</span><span class="cx"> 
</span><span class="lines">@@ -840,6 +1035,7 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _addTask(self):
</span><ins>+        # Don't perform any operations until the client is up and running
</ins><span class="cx">         if not self._client.started:
</span><span class="cx">             return succeed(None)
</span><span class="cx"> 
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11Profile"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/Profile (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/Profile                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/Profile        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,267 @@
</span><ins>+PROPFIND ./well-known/caldav                                -&gt;        /principals/
+        current-user-principal
+        principal-URL
+        resourcetype
+
+PROPFIND /principals/                                                -&gt;
+        current-user-principal                                                /principals/__uids__/&lt;uid&gt;
+        principal-URL                                                                ----
+        resourcetype                                                                collection
+
+OPTIONS /principals/__uids__/&lt;uid&gt;/
+
+PROPFIND /principals/__uids__/&lt;uid&gt;/
+        calendar-home-set                                                        /calendars/__uids__/&lt;uid&gt;/
+        calendar-user-address-set                                        mailto:user#@example.com
+                                                                                                urn:uuid:&lt;uid&gt;
+                                                                                                urn:x-uid:&lt;uid&gt;
+        current-user-principal                                                /principals/__uids__/&lt;uid&gt;/
+        displayname                                                                        User #
+        dropbox-home-URL                                                        /calendars/__uids__/&lt;uid&gt;/dropbox/
+        email-address-set                                                        user#@example.com
+        notification-URL                                                        /calendars/__uids__/&lt;uid&gt;/notification/
+        principal-collection-set                                        /principals/
+        principal-URL                                                                /principals/__uids__/&lt;uid&gt;/
+        resource-id                                                                        urn:x-uid:&lt;uid&gt;
+        schedule-inbox-URL                                                        /calendars/__uids__/&lt;uid&gt;/inbox/
+        schedule-outbox-URL                                                        /calendars/__uids__/&lt;uid&gt;/outbox/
+        supported-report-set                                                acl-principal-prop-set
+                                                                                                principal-match
+                                                                                                principal-property-search
+                                                                                                expand-property
+                                                                                                calendarserver-principal-search
+
+OPTIONS /principals/__uids__/&lt;uid&gt;
+
+REPORT /principals/                                                        -&gt; 
+        principal-search-property-set                                displayname
+                                                                                                email-address-set
+                                                                                                calendar-user-address-set
+                                                                                                calendar-user-type 
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/inbox/        -&gt;        
+        calendar-availability                                                ???
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/
+Depth 1
+        add-member                                                                        
+        allowed-sharing-modes                                                                        
+        autoprovisioned                                                                        
+        bulk-requests                                                                        
+        calendar-alarm                                                                        
+        calendar-color                                                                        
+        calendar-description                                                                        
+        calendar-free-busy-set                                                                        
+        calendar-order                                                                        
+        calendar-timezone                                                                        
+        current-user-privilege-set                                        all/read/read-free-busy/write/write-properties/write-content/bind/unbind/unlock/read-acl/write-acl/read-current-user-privilege-set                                
+        default-alarm-vevent-date                                                                        
+        default-alarm-vevent-datetime                                                                        
+        displayname                                                                        User #
+        getctag                                                                        
+        invite                                                                        
+        language-code                                                                        
+        location-code                                                                        
+        owner                                                                                /principals/__uids__/&lt;uid&gt;/
+        pre-publish-url                                                                        
+        publish-url                                                                        
+        push-transports                                                                        
+        pushkey                                                                                /CalDAV/localhost/&lt;uid&gt;/
+        quota-available-bytes                                                104857600
+        quota-used-bytes                                                        0
+        refreshrate                                                                        
+        resource-id                                                                        
+        resourcetype                                                                collection        
+        schedule-calendar-transp                                                                        
+        schedule-default-calendar-URL                                                                        
+        source                                                                        
+        subscribed-strip-alarms                                                                        
+        subscribed-strip-attachments                                                                        
+        subscribed-strip-todos                                                                        
+        supported-calendar-component-set                        VEVENT/VTODO                                                
+        supported-calendar-component-sets                                                                        
+        supported-report-set                                                acl-principal-prop-set/principal-match/principal-property-search/expand-property/calendarserver-principal-search/calendar-query/calendar-multiget/free-busy-query/addressbook-query/addressbook-multiget/sync-collection                        
+        sync-token                                                                        data:,36_58/&lt;hex&gt;
+         ** and more **
+
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/                -&gt;                default-alarm-vevent-date
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/                -&gt;                default-alarm-vevent-datetime
+
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        -&gt;                calendar-order
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        -&gt;                displayname
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        -&gt;                calendar-color
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        -&gt;                calendar-order
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        -&gt;                calendar-timezone
+
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;                calendar-order
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;                displayname
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;                calendar-color
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;                calendar-order
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;                calendar-timezone
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/calendar/-&gt;
+        getctag                                                                                37_63
+        sync-token                                                                        data:,37_63/&lt;hex&gt;
+
+REPORT /calendars/__uids__/&lt;uid&gt;/calendar/         -&gt;
+        getcontenttype
+        getetag
+REPORT /calendar/__uids__/&lt;uid&gt;/calendar/
+        getcontenttype
+        getetag
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/                        -&gt;
+        checksum-versions                                                        ???
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/calendar/        -&gt;
+        getctag                                                                                
+        sync-token                                                                                
+PROPFIND /calendars/__uids__/&lt;uid&gt;/calendar/
+        getcontenttype                                                                httpd/unix-directory
+        getetag                                                                                &quot;&lt;hex&gt;&quot;
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/                        -&gt; (again?) 
+        checksum-versions
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;
+        getctag
+        sync-token
+PROPFIND /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;
+        getcontenttype
+        getetag
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/inbox/        -&gt;
+        getctag
+        sync-token
+PROPFIND /calendars/__uids__/&lt;uid&gt;/inbox/        -&gt;
+        getcontenttype
+        getetag
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;
+        getctag
+        sync-token
+PROPFIND /calendars/__uids__/&lt;uid&gt;/tasks/        -&gt;
+        getcontenttype
+        getetag
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/notification/        -&gt;
+        getctag
+        sync-token
+PROPFIND /calendars/__uids__/&lt;uid&gt;/notification/        -&gt;
+        notificationtype
+        getetag
+
+REPORT /principals/__uids__/&lt;uid&gt;/
+        calendar-proxy-write-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+        calendar-proxy-read-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+
+REPORT /calendars/__uids__/&lt;uid&gt;/
+        sync-collection
+                sync-token
+                sync-level
+                *lots of properties*
+
+PROPFIND /calendars/__uids__/&lt;uid&gt;/inbox/
+        getctag
+        sync-token
+
+PROPFIND /principals/__uids__/&lt;uid&gt;/
+        calendar-proxy-write-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+        calendar-proxy-read-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+
+----------------------------------------------------------------
+Deep Refresh (CMD + SHIFT + R)
+
+PROPFIND /principals/__uids__/&lt;uid&gt;/
+        &lt;B:calendar-home-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:calendar-user-address-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:current-user-principal/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:dropbox-home-URL xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:email-address-set xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:notification-URL xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:principal-collection-set/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;A:resource-id/&gt;
+    &lt;B:schedule-inbox-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:schedule-outbox-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:supported-report-set/&gt;
+
+OPTIONS /principals/__uids__/10000000-0000-0000-0000-000000000001/
+
+REPORT /principals/
+        principal-search-property-set
+
+PROPFIND /calendars/__uids__/10000000-0000-0000-0000-000000000001/inbox/
+        calendar-availability
+
+PROPFIND /calendars/__uids__/10000000-0000-0000-0000-000000000001/
+Depth 1
+        &lt;A:add-member/&gt;
+    &lt;C:allowed-sharing-modes xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;D:autoprovisioned xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;E:bulk-requests xmlns:E=&quot;http://me.com/_namespace/&quot;/&gt;
+    &lt;B:calendar-alarm xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;D:calendar-color xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;B:calendar-description xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:calendar-free-busy-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;D:calendar-order xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;B:calendar-timezone xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:current-user-privilege-set/&gt;
+    &lt;B:default-alarm-vevent-date xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:default-alarm-vevent-datetime xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:getctag xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:invite xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;D:language-code xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;D:location-code xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;A:owner/&gt;
+    &lt;C:pre-publish-url xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:publish-url xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:push-transports xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:pushkey xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:quota-available-bytes/&gt;
+    &lt;A:quota-used-bytes/&gt;
+    &lt;D:refreshrate xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;A:resource-id/&gt;
+    &lt;A:resourcetype/&gt;
+    &lt;B:schedule-calendar-transp xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:schedule-default-calendar-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;C:source xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:subscribed-strip-alarms xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:subscribed-strip-attachments xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:subscribed-strip-todos xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:supported-calendar-component-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:supported-calendar-component-sets xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:supported-report-set/&gt;
+    &lt;A:sync-token/&gt;
+
+PROPFIND on calendar/tasks/inbox/notifications as before
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                                                        
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11StartupProfile"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/StartupProfile (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/StartupProfile                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/StartupProfile        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+PROPFIND  ./well-known/caldav                                        - startup_well_known_propfind
+
+PROPFIND  /principals/                                                        - startup_principal_initial_propfind
+
+PROPFIND  /principals/__uids__/&lt;uid&gt;/                        - startup_principal_propfind
+
+REPORT    /principals/                                                        - startup_principals_report
+
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/inbox/                - ???
+        calendar-availability                                                
+
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/                        - poll_calendar_home_depth1_propfind
+
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/                        - startup_calendarhome_default_alarm_date_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/                        - startup_calendarhome_default_alarm_datetime_proppatch
+
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        - startup_calendar_order_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        - startup_calendar_displayname_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        - startup_calendar_color_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/calendar/        - startup_calendar_timezone_proppatch
+
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/                - startup_calendar_order_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/                - startup_calendar_displayname_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/                - startup_calendar_color_proppatch
+PROPPATCH /calendars/__uids__/&lt;uid&gt;/tasks/                - startup_calendar_timezone_proppatch
+
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/calendar/        - poll_calendar_propfind
+
+REPORT   /calendars/__uids__/&lt;uid&gt;/calendar/         - startup_query_events_depth1_report.request
+
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/calendar/        - poll_calendar_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/calendar/        - poll_calendar_depth1_propfind
+
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/tasks/                - poll_calendar_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/tasks/                - poll_calendar_depth1_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/inbox/                - poll_calendar_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/inbox/                - poll_calendar_depth1_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/tasks/                - poll_calendar_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/tasks/                - poll_calendar_depth1_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/notification/        - poll_calendar_propfind
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/notification/        - poll_notification_depth1_propfind
+
+REPORT    /principals/__uids__/&lt;uid&gt;/
+        calendar-proxy-write-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+        calendar-proxy-read-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+
+REPORT    /calendars/__uids__/&lt;uid&gt;/
+        sync-collection
+                sync-token
+                sync-level
+                *lots of properties*
+
+PROPFIND  /calendars/__uids__/&lt;uid&gt;/inbox/
+        getctag
+        sync-token
+
+PROPFIND  /principals/__uids__/&lt;uid&gt;/
+        calendar-proxy-write-for
+                calendar-user-address-set
+                email-address-set
+                displayname
+        calendar-proxy-read-for
+                calendar-user-address-set
+                email-address-set
+                displayname
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11notification_multiget_report_hrefsrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_multiget_report_hrefs.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_multiget_report_hrefs.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_multiget_report_hrefs.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+  &lt;A:href xmlns:A=&quot;DAV:&quot;&gt;%(href)s&lt;/A:href&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11notification_syncrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_sync.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_sync.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/notification_sync.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:sync-collection xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:sync-token&gt;%(sync-token)s&lt;/A:sync-token&gt;
+  &lt;A:sync-level&gt;1&lt;/A:sync-level&gt;
+  &lt;A:prop&gt;
+    &lt;C:notificationtype xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:getetag/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:sync-collection&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendar_depth1_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_depth1_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_depth1_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_depth1_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;A:getcontenttype/&gt;
+    &lt;A:getetag/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendar_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendar_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;C:getctag xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:sync-token/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendarhome_depth1_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_depth1_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_depth1_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_depth1_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;A:add-member/&gt;
+    &lt;C:allowed-sharing-modes xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;D:autoprovisioned xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;E:bulk-requests xmlns:E=&quot;http://me.com/_namespace/&quot;/&gt;
+    &lt;B:calendar-alarm xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;D:calendar-color xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;B:calendar-description xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:calendar-free-busy-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;D:calendar-order xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;B:calendar-timezone xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:current-user-privilege-set/&gt;
+    &lt;B:default-alarm-vevent-date xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:default-alarm-vevent-datetime xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:getctag xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:invite xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;D:language-code xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;D:location-code xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;A:owner/&gt;
+    &lt;C:pre-publish-url xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:publish-url xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:push-transports xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:pushkey xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:quota-available-bytes/&gt;
+    &lt;A:quota-used-bytes/&gt;
+    &lt;D:refreshrate xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;A:resource-id/&gt;
+    &lt;A:resourcetype/&gt;
+    &lt;B:schedule-calendar-transp xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:schedule-default-calendar-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;C:source xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:subscribed-strip-alarms xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:subscribed-strip-attachments xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:subscribed-strip-todos xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:supported-calendar-component-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:supported-calendar-component-sets xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:supported-report-set/&gt;
+    &lt;A:sync-token/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_calendarhome_syncrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_sync.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_sync.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_calendarhome_sync.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:sync-collection xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:sync-token&gt;data:,30_1122/8bbf7c540e5fca2cc3220f114a8164f7&lt;/A:sync-token&gt;
+  &lt;A:sync-level&gt;1&lt;/A:sync-level&gt;
+  &lt;A:prop&gt;
+    &lt;C:publish-url xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:supported-calendar-component-sets xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:schedule-calendar-transp xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;C:source xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:calendar-description xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;D:location-code xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;D:autoprovisioned xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;A:quota-used-bytes/&gt;
+    &lt;C:pre-publish-url xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;D:calendar-order xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;D:refreshrate xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;C:subscribed-strip-attachments xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:push-transports xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:schedule-default-calendar-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:calendar-alarm xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:supported-calendar-component-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:owner/&gt;
+    &lt;A:add-member/&gt;
+    &lt;C:invite xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:resource-id/&gt;
+    &lt;E:bulk-requests xmlns:E=&quot;http://me.com/_namespace/&quot;/&gt;
+    &lt;B:calendar-timezone xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:supported-report-set/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:subscribed-strip-alarms xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;D:language-code xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;C:subscribed-strip-todos xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:allowed-sharing-modes xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:current-user-privilege-set/&gt;
+    &lt;B:calendar-free-busy-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:sync-token/&gt;
+    &lt;A:quota-available-bytes/&gt;
+    &lt;C:pushkey xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:default-alarm-vevent-date xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:resourcetype/&gt;
+    &lt;B:default-alarm-vevent-datetime xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;D:calendar-color xmlns:D=&quot;http://apple.com/ns/ical/&quot;/&gt;
+    &lt;C:getctag xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:sync-collection&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11poll_notification_depth1_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_notification_depth1_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_notification_depth1_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/poll_notification_depth1_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;A:getetag/&gt;
+    &lt;C:notificationtype xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11post_freebusyrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/post_freebusy.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/post_freebusy.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/post_freebusy.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+BEGIN:VCALENDAR
+VERSION:2.0
+METHOD:REPLY
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VFREEBUSY
+UID:4288F0F3-5C5B-4DF4-9AD8-B1E5FE3F5B97
+DTSTART:20150804T211500Z
+DTEND:20150804T231500Z
+ATTENDEE:urn:uuid:30000000-0000-0000-0000-000000000005
+DTSTAMP:20150727T203410Z
+ORGANIZER:mailto:user01@example.com
+END:VFREEBUSY
+END:VCALENDAR
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11principal_search_reportrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/principal_search_report.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/principal_search_report.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/principal_search_report.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;C:calendarserver-principal-search xmlns:C=&quot;http://calendarserver.org/ns/&quot; context=&quot;{context}&quot;&gt;
+  {searchTokens}
+  &lt;A:prop xmlns:A=&quot;DAV:&quot;&gt;
+    &lt;C:email-address-set/&gt;
+    &lt;B:calendar-user-type xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:calendar-user-address-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;C:last-name/&gt;
+    &lt;C:record-type/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:first-name/&gt;
+  &lt;/A:prop&gt;
+&lt;/C:calendarserver-principal-search&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11report_principal_searchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/report_principal_search.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/report_principal_search.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/report_principal_search.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;C:calendarserver-principal-search xmlns:C=&quot;http://calendarserver.org/ns/&quot; context=&quot;attendee&quot;&gt;
+  &lt;C:search-token&gt;%(search)s&lt;/C:search-token&gt;
+  &lt;A:prop xmlns:A=&quot;DAV:&quot;&gt;
+    &lt;B:calendar-user-type xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;C:email-address-set/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:first-name/&gt;
+    &lt;C:last-name/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;C:record-type/&gt;
+    &lt;B:calendar-user-address-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+  &lt;/A:prop&gt;
+&lt;/C:calendarserver-principal-search&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_color_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_color_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_color_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_color_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;D:calendar-color xmlns:D=&quot;http://apple.com/ns/ical/&quot; symbolic-color=&quot;orange&quot;&gt;#FD8208FF&lt;/D:calendar-color&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_description_proppatchrequestxml"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_description_proppatch.request.xml (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_description_proppatch.request.xml                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_description_proppatch.request.xml        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;B:calendar-description xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;some description&lt;/B:calendar-description&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_displayname_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_displayname_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_displayname_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_displayname_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;A:displayname&gt;calendar&lt;/A:displayname&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_order_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_order_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_order_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_order_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;D:calendar-order xmlns:D=&quot;http://apple.com/ns/ical/&quot;&gt;1&lt;/D:calendar-order&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_timezone_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_timezone_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_timezone_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_timezone_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;B:calendar-timezone xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;BEGIN:VCALENDAR&amp;#13;
+VERSION:2.0&amp;#13;
+PRODID:-//Apple Inc.//Mac OS X 10.11//EN&amp;#13;
+CALSCALE:GREGORIAN&amp;#13;
+BEGIN:VTIMEZONE&amp;#13;
+TZID:America/Los_Angeles&amp;#13;
+BEGIN:DAYLIGHT&amp;#13;
+TZOFFSETFROM:-0800&amp;#13;
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU&amp;#13;
+DTSTART:20070311T020000&amp;#13;
+TZNAME:PDT&amp;#13;
+TZOFFSETTO:-0700&amp;#13;
+END:DAYLIGHT&amp;#13;
+BEGIN:STANDARD&amp;#13;
+TZOFFSETFROM:-0700&amp;#13;
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU&amp;#13;
+DTSTART:20071104T020000&amp;#13;
+TZNAME:PST&amp;#13;
+TZOFFSETTO:-0800&amp;#13;
+END:STANDARD&amp;#13;
+END:VTIMEZONE&amp;#13;
+END:VCALENDAR&amp;#13;
+&lt;/B:calendar-timezone&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendar_transparent_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_transparent_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_transparent_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendar_transparent_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;B:schedule-calendar-transp xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;&lt;B:transparent/&gt;&lt;/B:schedule-calendar-transp&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
+
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;B:schedule-calendar-transp xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;&lt;B:opaque/&gt;&lt;/B:schedule-calendar-transp&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendarhome_default_alarm_date_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_date_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_date_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_date_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;B:default-alarm-vevent-date xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;BEGIN:VALARM&amp;#13;
+X-WR-ALARMUID:49F29226-D2D7-4464-AE22-0147EDEFB2B4&amp;#13;
+UID:49F29226-D2D7-4464-AE22-0147EDEFB2B4&amp;#13;
+TRIGGER:-PT15H&amp;#13;
+ATTACH;VALUE=URI:Basso&amp;#13;
+ACTION:AUDIO&amp;#13;
+END:VALARM&amp;#13;
+&lt;/B:default-alarm-vevent-date&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_calendarhome_default_alarm_datetime_proppatchrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_datetime_proppatch.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_datetime_proppatch.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_calendarhome_default_alarm_datetime_proppatch.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propertyupdate xmlns:A=&quot;DAV:&quot;&gt;&lt;A:set&gt;&lt;A:prop&gt;&lt;B:default-alarm-vevent-datetime xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;BEGIN:VALARM&amp;#13;
+X-WR-ALARMUID:4AD03A33-54A6-42BE-A157-47273DD60803&amp;#13;
+UID:4AD03A33-54A6-42BE-A157-47273DD60803&amp;#13;
+TRIGGER;VALUE=DATE-TIME:19760401T005545Z&amp;#13;
+ACTION:NONE&amp;#13;
+END:VALARM&amp;#13;
+&lt;/B:default-alarm-vevent-datetime&gt;&lt;/A:prop&gt;&lt;/A:set&gt;&lt;/A:propertyupdate&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_create_calendarrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_create_calendar.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_create_calendar.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_create_calendar.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;B:mkcalendar xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;
+  &lt;A:set xmlns:A=&quot;DAV:&quot;&gt;
+    &lt;A:prop&gt;
+      &lt;D:calendar-order xmlns:D=&quot;http://apple.com/ns/ical/&quot;&gt;{order}&lt;/D:calendar-order&gt;
+      &lt;B:supported-calendar-component-set&gt;
+        &lt;B:comp name=&quot;{component_type}&quot;/&gt;
+      &lt;/B:supported-calendar-component-set&gt;
+      &lt;D:calendar-color xmlns:D=&quot;http://apple.com/ns/ical/&quot; symbolic-color=&quot;custom&quot;&gt;#{color}&lt;/D:calendar-color&gt;
+      &lt;B:calendar-timezone&gt;BEGIN:VCALENDAR&amp;#13;
+VERSION:2.0&amp;#13;
+PRODID:-//Apple Inc.//Mac OS X 10.11//EN&amp;#13;
+CALSCALE:GREGORIAN&amp;#13;
+BEGIN:VTIMEZONE&amp;#13;
+TZID:America/Los_Angeles&amp;#13;
+BEGIN:DAYLIGHT&amp;#13;
+TZOFFSETFROM:-0800&amp;#13;
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU&amp;#13;
+DTSTART:20070311T020000&amp;#13;
+TZNAME:PDT&amp;#13;
+TZOFFSETTO:-0700&amp;#13;
+END:DAYLIGHT&amp;#13;
+BEGIN:STANDARD&amp;#13;
+TZOFFSETFROM:-0700&amp;#13;
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU&amp;#13;
+DTSTART:20071104T020000&amp;#13;
+TZNAME:PST&amp;#13;
+TZOFFSETTO:-0800&amp;#13;
+END:STANDARD&amp;#13;
+END:VTIMEZONE&amp;#13;
+END:VCALENDAR&amp;#13;
+&lt;/B:calendar-timezone&gt;
+      &lt;A:displayname&gt;{name}&lt;/A:displayname&gt;
+      &lt;B:schedule-calendar-transp&gt;
+        &lt;B:opaque/&gt;
+      &lt;/B:schedule-calendar-transp&gt;
+    &lt;/A:prop&gt;
+  &lt;/A:set&gt;
+&lt;/B:mkcalendar&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_delegate_principal_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_delegate_principal_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_delegate_principal_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_delegate_principal_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;B:allowed-calendar-component-set xmlns:B=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:calendar-home-set xmlns:C=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;C:calendar-user-address-set xmlns:C=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:current-user-principal/&gt;
+    &lt;A:displayname/&gt;
+    &lt;B:dropbox-home-URL xmlns:B=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:email-address-set xmlns:B=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;B:notification-URL xmlns:B=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:principal-collection-set/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;A:resource-id/&gt;
+    &lt;C:schedule-inbox-URL xmlns:C=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;C:schedule-outbox-URL xmlns:C=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:supported-report-set/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principal_expandrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_expand.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_expand.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_expand.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:expand-property xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:property name=&quot;calendar-proxy-read-for&quot; namespace=&quot;http://calendarserver.org/ns/&quot;&gt;
+    &lt;A:property name=&quot;calendar-user-address-set&quot; namespace=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:property name=&quot;email-address-set&quot; namespace=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:property name=&quot;displayname&quot; namespace=&quot;DAV:&quot;/&gt;
+  &lt;/A:property&gt;
+  &lt;A:property name=&quot;calendar-proxy-write-for&quot; namespace=&quot;http://calendarserver.org/ns/&quot;&gt;
+    &lt;A:property name=&quot;calendar-user-address-set&quot; namespace=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:property name=&quot;email-address-set&quot; namespace=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:property name=&quot;displayname&quot; namespace=&quot;DAV:&quot;/&gt;
+  &lt;/A:property&gt;
+&lt;/A:expand-property&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principal_initial_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_initial_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_initial_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_initial_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;A:current-user-principal/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;A:resourcetype/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principal_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principal_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;B:calendar-home-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:calendar-user-address-set xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:current-user-principal/&gt;
+    &lt;A:displayname/&gt;
+    &lt;C:dropbox-home-URL xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:email-address-set xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;C:notification-URL xmlns:C=&quot;http://calendarserver.org/ns/&quot;/&gt;
+    &lt;A:principal-collection-set/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;A:resource-id/&gt;
+    &lt;B:schedule-inbox-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;B:schedule-outbox-URL xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;/&gt;
+    &lt;A:supported-report-set/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_principals_reportrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principals_report.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principals_report.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_principals_report.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,2 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:principal-search-property-set xmlns:A=&quot;DAV:&quot;/&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_query_events_depth1_reportrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_query_events_depth1_report.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_query_events_depth1_report.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_query_events_depth1_report.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;B:calendar-query xmlns:B=&quot;urn:ietf:params:xml:ns:caldav&quot;&gt;
+  &lt;A:prop xmlns:A=&quot;DAV:&quot;&gt;
+    &lt;A:getetag/&gt;
+    &lt;A:getcontenttype/&gt;
+  &lt;/A:prop&gt;
+  &lt;B:filter&gt;
+    &lt;B:comp-filter name=&quot;VCALENDAR&quot;&gt;
+      &lt;B:comp-filter name=&quot;VEVENT&quot;&gt;
+        &lt;B:time-range start=&quot;20150630T010101Z&quot; end=&quot;20150721T010101Z&quot;/&gt;
+      &lt;/B:comp-filter&gt;
+    &lt;/B:comp-filter&gt;
+  &lt;/B:filter&gt;
+&lt;/B:calendar-query&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestrequestdataOS_X_10_11startup_well_known_propfindrequest"></a>
<div class="addfile"><h4>Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_well_known_propfind.request (0 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_well_known_propfind.request                                (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/OS_X_10_11/startup_well_known_propfind.request        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+&lt;A:propfind xmlns:A=&quot;DAV:&quot;&gt;
+  &lt;A:prop&gt;
+    &lt;A:current-user-principal/&gt;
+    &lt;A:principal-URL/&gt;
+    &lt;A:resourcetype/&gt;
+  &lt;/A:prop&gt;
+&lt;/A:propfind&gt;
</ins></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtestsimpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/sim.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/sim.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/sim.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -285,7 +285,8 @@
</span><span class="cx">             if 'clientDataSerialization' in config:
</span><span class="cx">                 serializationPath = config['clientDataSerialization']['Path']
</span><span class="cx">                 if not config['clientDataSerialization']['UseOldData']:
</span><del>-                    shutil.rmtree(serializationPath)
</del><ins>+                    if isdir(serializationPath):
+                        shutil.rmtree(serializationPath)
</ins><span class="cx">                 serializationPath = config['clientDataSerialization']['Path']
</span><span class="cx">                 if not isdir(serializationPath):
</span><span class="cx">                     try:
</span><span class="lines">@@ -412,6 +413,7 @@
</span><span class="cx">         return CalendarClientSimulator(
</span><span class="cx">             self.records,
</span><span class="cx">             populator,
</span><ins>+            Random(),
</ins><span class="cx">             self.parameters,
</span><span class="cx">             self.reactor,
</span><span class="cx">             self.server,
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtesttest_icalpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/test_ical.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/test_ical.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_ical.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -21,7 +21,7 @@
</span><span class="cx"> from caldavclientlibrary.protocol.webdav.definitions import davxml
</span><span class="cx"> 
</span><span class="cx"> from contrib.performance.httpclient import MemoryConsumer, StringProducer
</span><del>-from contrib.performance.loadtest.ical import XMPPPush, Event, Calendar, OS_X_10_6
</del><ins>+from contrib.performance.loadtest.ical import XMPPPush, Event, Calendar, OS_X_10_11, NotificationCollection
</ins><span class="cx"> from contrib.performance.loadtest.sim import _DirectoryRecord
</span><span class="cx"> 
</span><span class="cx"> from pycalendar.datetime import DateTime
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> from twisted.python.failure import Failure
</span><span class="cx"> from twisted.trial.unittest import TestCase
</span><span class="cx"> from twisted.web.client import ResponseDone
</span><del>-from twisted.web.http import OK, NO_CONTENT, CREATED, MULTI_STATUS
</del><ins>+from twisted.web.http import OK, NO_CONTENT, CREATED, MULTI_STATUS, NOT_FOUND, FORBIDDEN
</ins><span class="cx"> from twisted.web.http_headers import Headers
</span><span class="cx"> 
</span><span class="cx"> from twistedcaldav.ical import Component
</span><span class="lines">@@ -581,6 +581,7 @@
</span><span class="cx">     &lt;href&gt;/calendars/__uids__/user01/notification/&lt;/href&gt;
</span><span class="cx">     &lt;propstat&gt;
</span><span class="cx">       &lt;prop&gt;
</span><ins>+        &lt;sync-token xmlns='DAV:'&gt;SYNCTOKEN3&lt;/sync-token&gt;
</ins><span class="cx">         &lt;displayname&gt;notification&lt;/displayname&gt;
</span><span class="cx">         &lt;resourcetype&gt;
</span><span class="cx">           &lt;collection/&gt;
</span><span class="lines">@@ -742,6 +743,8 @@
</span><span class="cx">     &lt;propstat&gt;
</span><span class="cx">       &lt;prop&gt;
</span><span class="cx">         &lt;getctag xmlns='http://calendarserver.org/ns/'&gt;c2696540-4c4c-4a31-adaf-c99630776828#3&lt;/getctag&gt;
</span><ins>+        &lt;sync-token xmlns='DAV:'&gt;SYNCTOKEN1&lt;/sync-token&gt;
+
</ins><span class="cx">         &lt;displayname&gt;calendar&lt;/displayname&gt;
</span><span class="cx">         &lt;calendar-color xmlns='http://apple.com/ns/ical/'&gt;#0252D4FF&lt;/calendar-color&gt;
</span><span class="cx">         &lt;calendar-order xmlns='http://apple.com/ns/ical/'&gt;1&lt;/calendar-order&gt;
</span><span class="lines">@@ -1027,6 +1030,7 @@
</span><span class="cx">     &lt;propstat&gt;
</span><span class="cx">       &lt;prop&gt;
</span><span class="cx">         &lt;getctag xmlns='http://calendarserver.org/ns/'&gt;a483dab3-1391-445b-b1c3-5ae9dfc81c2f#0&lt;/getctag&gt;
</span><ins>+        &lt;sync-token xmlns='DAV:'&gt;SYNCTOKEN2&lt;/sync-token&gt;
</ins><span class="cx">         &lt;displayname&gt;inbox&lt;/displayname&gt;
</span><span class="cx">         &lt;supported-calendar-component-set xmlns='urn:ietf:params:xml:ns:caldav'&gt;
</span><span class="cx">           &lt;comp name='VEVENT'/&gt;
</span><span class="lines">@@ -1153,9 +1157,9 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-class OS_X_10_6Mixin:
</del><ins>+class OS_X_10_11Mixin:
</ins><span class="cx">     &quot;&quot;&quot;
</span><del>-    Mixin for L{TestCase}s for L{OS_X_10_6}.
</del><ins>+    Mixin for L{TestCase}s for L{OS_X_10_11}.
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setUp(self):
</span><span class="cx">         TimezoneCache.create()
</span><span class="lines">@@ -1164,7 +1168,7 @@
</span><span class="cx">         )
</span><span class="cx">         serializePath = self.mktemp()
</span><span class="cx">         os.mkdir(serializePath)
</span><del>-        self.client = OS_X_10_6(
</del><ins>+        self.client = OS_X_10_11(
</ins><span class="cx">             None,
</span><span class="cx">             &quot;http://127.0.0.1&quot;,
</span><span class="cx">             &quot;/principals/users/%s/&quot;,
</span><span class="lines">@@ -1185,9 +1189,9 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-class OS_X_10_6Tests(OS_X_10_6Mixin, TestCase):
</del><ins>+class OS_X_10_11Tests(OS_X_10_11Mixin, TestCase):
</ins><span class="cx">     &quot;&quot;&quot;
</span><del>-    Tests for L{OS_X_10_6}.
</del><ins>+    Tests for L{OS_X_10_11}.
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def test_parsePrincipalPROPFINDResponse(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -1230,12 +1234,12 @@
</span><span class="cx"> 
</span><span class="cx">     def test_extractCalendars(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6._extractCalendars} accepts a calendar home
</del><ins>+        L{OS_X_10_11._extractCalendars} accepts a calendar home
</ins><span class="cx">         PROPFIND response body and returns a list of calendar objects
</span><span class="cx">         constructed from the data extracted from the response.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         home = &quot;/calendars/__uids__/user01/&quot;
</span><del>-        calendars = self.client._extractCalendars(
</del><ins>+        calendars, notificationCollection = self.client._extractCalendars(
</ins><span class="cx">             self.client._parseMultiStatus(CALENDAR_HOME_PROPFIND_RESPONSE), home)
</span><span class="cx">         calendars.sort(key=lambda cal: cal.resourceType)
</span><span class="cx">         calendar, inbox = calendars
</span><span class="lines">@@ -1243,20 +1247,22 @@
</span><span class="cx">         self.assertEquals(calendar.resourceType, caldavxml.calendar)
</span><span class="cx">         self.assertEquals(calendar.name, &quot;calendar&quot;)
</span><span class="cx">         self.assertEquals(calendar.url, &quot;/calendars/__uids__/user01/calendar/&quot;)
</span><del>-        self.assertEquals(calendar.changeToken, &quot;c2696540-4c4c-4a31-adaf-c99630776828#3&quot;)
</del><ins>+        self.assertEquals(calendar.changeToken, &quot;SYNCTOKEN1&quot;)
</ins><span class="cx"> 
</span><span class="cx">         self.assertEquals(inbox.resourceType, caldavxml.schedule_inbox)
</span><span class="cx">         self.assertEquals(inbox.name, &quot;inbox&quot;)
</span><span class="cx">         self.assertEquals(inbox.url, &quot;/calendars/__uids__/user01/inbox/&quot;)
</span><del>-        self.assertEquals(inbox.changeToken, &quot;a483dab3-1391-445b-b1c3-5ae9dfc81c2f#0&quot;)
</del><ins>+        self.assertEquals(inbox.changeToken, &quot;SYNCTOKEN2&quot;)
</ins><span class="cx"> 
</span><ins>+        self.assertEquals(notificationCollection.changeToken, &quot;SYNCTOKEN3&quot;)
+
</ins><span class="cx">         self.assertEqual({}, self.client.xmpp)
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_extractCalendarsXMPP(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         If there is XMPP push information in a calendar home PROPFIND response,
</span><del>-        L{OS_X_10_6._extractCalendars} finds it and records it.
</del><ins>+        L{OS_X_10_11._extractCalendars} finds it and records it.
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         home = &quot;/calendars/__uids__/user01/&quot;
</span><span class="cx">         self.client._extractCalendars(
</span><span class="lines">@@ -1283,7 +1289,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def test_changeEventAttendee(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        OS_X_10_6.changeEventAttendee removes one attendee from an
</del><ins>+        OS_X_10_11.changeEventAttendee removes one attendee from an
</ins><span class="cx">         existing event and appends another.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         requests = self.interceptRequests()
</span><span class="lines">@@ -1317,7 +1323,7 @@
</span><span class="cx"> 
</span><span class="cx">     def test_addEvent(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6.addEvent} PUTs the event passed to it to the
</del><ins>+        L{OS_X_10_11.addEvent} PUTs the event passed to it to the
</ins><span class="cx">         server and updates local state to reflect its existence.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         requests = self.interceptRequests()
</span><span class="lines">@@ -1359,7 +1365,7 @@
</span><span class="cx">     @inlineCallbacks
</span><span class="cx">     def test_addInvite(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6.addInvite} PUTs the event passed to it to the
</del><ins>+        L{OS_X_10_11.addInvite} PUTs the event passed to it to the
</ins><span class="cx">         server and updates local state to reflect its existence, but
</span><span class="cx">         it also does attendee auto-complete and free-busy checks before
</span><span class="cx">         the PUT.
</span><span class="lines">@@ -1450,7 +1456,7 @@
</span><span class="cx"> 
</span><span class="cx">     def test_deleteEvent(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6.deleteEvent} DELETEs the event at the relative
</del><ins>+        L{OS_X_10_11.deleteEvent} DELETEs the event at the relative
</ins><span class="cx">         URL passed to it and updates local state to reflect its
</span><span class="cx">         removal.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -1467,7 +1473,7 @@
</span><span class="cx"> 
</span><span class="cx">         expectedResponseCode, method, url = req
</span><span class="cx"> 
</span><del>-        self.assertEqual(expectedResponseCode, NO_CONTENT)
</del><ins>+        self.assertEqual(expectedResponseCode, (NO_CONTENT, NOT_FOUND))
</ins><span class="cx">         self.assertEqual(method, 'DELETE')
</span><span class="cx">         self.assertEqual(url, 'http://127.0.0.1' + event.url)
</span><span class="cx">         self.assertIsInstance(url, str)
</span><span class="lines">@@ -1484,9 +1490,9 @@
</span><span class="cx"> 
</span><span class="cx">     def test_serialization(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6.serialize} properly generates a JSON document.
</del><ins>+        L{OS_X_10_11.serialize} properly generates a JSON document.
</ins><span class="cx">         &quot;&quot;&quot;
</span><del>-        clientPath = os.path.join(self.client.serializePath, &quot;user91-OS_X_10.6&quot;)
</del><ins>+        clientPath = os.path.join(self.client.serializePath, &quot;user91-OS_X_10.11&quot;)
</ins><span class="cx">         self.assertFalse(os.path.exists(clientPath))
</span><span class="cx">         indexPath = os.path.join(clientPath, &quot;index.json&quot;)
</span><span class="cx">         self.assertFalse(os.path.exists(indexPath))
</span><span class="lines">@@ -1535,14 +1541,32 @@
</span><span class="cx">         self.client._calendars[&quot;/home/calendar/&quot;].events[&quot;1.ics&quot;] = events[0]
</span><span class="cx">         self.client._calendars[&quot;/home/inbox/&quot;].events[&quot;i1.ics&quot;] = events[1]
</span><span class="cx"> 
</span><ins>+        self.client._notificationCollection = NotificationCollection(&quot;/home/notification&quot;, &quot;123&quot;)
+
</ins><span class="cx">         self.client.serialize()
</span><span class="cx">         self.assertTrue(os.path.exists(clientPath))
</span><span class="cx">         self.assertTrue(os.path.exists(indexPath))
</span><span class="cx">         def _normDict(d):
</span><del>-            return dict([(k, sorted(v, key=lambda x: x[&quot;changeToken&quot; if k == &quot;calendars&quot; else &quot;url&quot;]) if v else None,) for k, v in d.items()])
</del><ins>+            return dict([
+                (
+                    k,
+                    sorted(
+                        v,
+                        key=lambda x:
+                            x[&quot;changeToken&quot; if k == &quot;calendars&quot; else &quot;url&quot;]
+                    ) if isinstance(v, list) else v,
+                )
+                for k, v in d.items()
+            ])
</ins><span class="cx">         with open(indexPath) as f:
</span><span class="cx">             jdata = f.read()
</span><ins>+
</ins><span class="cx">         self.assertEqual(_normDict(json.loads(jdata)), _normDict(json.loads(&quot;&quot;&quot;{
</span><ins>+  &quot;notificationCollection&quot;: {
+      &quot;url&quot;: &quot;/home/notification&quot;,
+      &quot;notifications&quot;: [],
+      &quot;changeToken&quot;: &quot;123&quot;
+    },
</ins><span class="cx">   &quot;calendars&quot;: [
</span><span class="cx">     {
</span><span class="cx">       &quot;changeToken&quot;: &quot;123&quot;,
</span><span class="lines">@@ -1612,7 +1636,7 @@
</span><span class="cx"> 
</span><span class="cx">     def test_deserialization(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6.deserailize} properly parses a JSON document.
</del><ins>+        L{OS_X_10_11.deserailize} properly parses a JSON document.
</ins><span class="cx">         &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">         cal1 = &quot;&quot;&quot;BEGIN:VCALENDAR
</span><span class="lines">@@ -1645,7 +1669,7 @@
</span><span class="cx"> END:VCALENDAR
</span><span class="cx"> &quot;&quot;&quot;.replace(&quot;\n&quot;, &quot;\r\n&quot;)
</span><span class="cx"> 
</span><del>-        clientPath = os.path.join(self.client.serializePath, &quot;user91-OS_X_10.6&quot;)
</del><ins>+        clientPath = os.path.join(self.client.serializePath, &quot;user91-OS_X_10.11&quot;)
</ins><span class="cx">         os.mkdir(clientPath)
</span><span class="cx">         indexPath = os.path.join(clientPath, &quot;index.json&quot;)
</span><span class="cx">         with open(indexPath, &quot;w&quot;) as f:
</span><span class="lines">@@ -1738,32 +1762,32 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-class UpdateCalendarTests(OS_X_10_6Mixin, TestCase):
</del><ins>+class UpdateCalendarTests(OS_X_10_11Mixin, TestCase):
</ins><span class="cx">     &quot;&quot;&quot;
</span><del>-    Tests for L{OS_X_10_6._updateCalendar}.
</del><ins>+    Tests for L{OS_X_10_11._updateCalendar}.
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx">     _CALENDAR_PROPFIND_RESPONSE_BODY = &quot;&quot;&quot;\
</span><span class="cx"> &lt;?xml version='1.0' encoding='UTF-8'?&gt;
</span><del>-&lt;multistatus xmlns='DAV:'&gt;
-  &lt;response&gt;
-    &lt;href&gt;/something/anotherthing.ics&lt;/href&gt;
-    &lt;propstat&gt;
-      &lt;prop&gt;
-        &lt;resourcetype&gt;
-          &lt;collection/&gt;
-        &lt;/resourcetype&gt;
-        &lt;getetag&gt;&quot;None&quot;&lt;/getetag&gt;
-      &lt;/prop&gt;
-      &lt;status&gt;HTTP/1.1 200 OK&lt;/status&gt;
-    &lt;/propstat&gt;
-    &lt;propstat&gt;
-      &lt;prop&gt;
-      &lt;/prop&gt;
-      &lt;status&gt;HTTP/1.1 404 Not Found&lt;/status&gt;
-    &lt;/propstat&gt;
-  &lt;/response&gt;
</del><ins>+&lt;multistatus xmlns='DAV:'&gt;
</ins><span class="cx">   &lt;response&gt;
</span><ins>+    &lt;href&gt;/something/anotherthing.ics&lt;/href&gt;
+    &lt;propstat&gt;
+      &lt;prop&gt;
+        &lt;resourcetype&gt;
+          &lt;collection/&gt;
+        &lt;/resourcetype&gt;
+        &lt;getetag&gt;&quot;None&quot;&lt;/getetag&gt;
+      &lt;/prop&gt;
+      &lt;status&gt;HTTP/1.1 200 OK&lt;/status&gt;
+    &lt;/propstat&gt;
+    &lt;propstat&gt;
+      &lt;prop&gt;
+      &lt;/prop&gt;
+      &lt;status&gt;HTTP/1.1 404 Not Found&lt;/status&gt;
+    &lt;/propstat&gt;
+  &lt;/response&gt;
+  &lt;response&gt;
</ins><span class="cx">     &lt;href&gt;/something/else.ics&lt;/href&gt;
</span><span class="cx">     &lt;propstat&gt;
</span><span class="cx">       &lt;prop&gt;
</span><span class="lines">@@ -1867,7 +1891,7 @@
</span><span class="cx"> 
</span><span class="cx">     def test_eventMissing(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        If an event included in the calendar PROPFIND response no longer exists
</del><ins>+        If an event included in the calendar sync REPORT response no longer exists
</ins><span class="cx">         by the time a REPORT is issued for that event, the 404 is handled and
</span><span class="cx">         the rest of the normal update logic for that event is skipped.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -1878,9 +1902,9 @@
</span><span class="cx">         self.client._updateCalendar(calendar, &quot;1234&quot;)
</span><span class="cx">         result, req = requests.pop(0)
</span><span class="cx">         expectedResponseCode, method, url, _ignore_headers, _ignore_body = req
</span><del>-        self.assertEqual('PROPFIND', method)
</del><ins>+        self.assertEqual('REPORT', method)
</ins><span class="cx">         self.assertEqual('http://127.0.0.1/something/', url)
</span><del>-        self.assertEqual((MULTI_STATUS,), expectedResponseCode)
</del><ins>+        self.assertEqual((MULTI_STATUS, FORBIDDEN), expectedResponseCode)
</ins><span class="cx"> 
</span><span class="cx">         result.callback(
</span><span class="cx">             MemoryResponse(
</span><span class="lines">@@ -1908,7 +1932,7 @@
</span><span class="cx"> 
</span><span class="cx">     def test_multigetBatch(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        If an event included in the calendar PROPFIND response no longer exists
</del><ins>+        If an event included in the calendar sync REPORT response no longer exists
</ins><span class="cx">         by the time a REPORT is issued for that event, the 404 is handled and
</span><span class="cx">         the rest of the normal update logic for that event is skipped.
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="lines">@@ -1921,9 +1945,9 @@
</span><span class="cx">         self.client._updateCalendar(calendar, &quot;1234&quot;)
</span><span class="cx">         result, req = requests.pop(0)
</span><span class="cx">         expectedResponseCode, method, url, _ignore_headers, _ignore_body = req
</span><del>-        self.assertEqual('PROPFIND', method)
</del><ins>+        self.assertEqual('REPORT', method)
</ins><span class="cx">         self.assertEqual('http://127.0.0.1/something/', url)
</span><del>-        self.assertEqual((MULTI_STATUS,), expectedResponseCode)
</del><ins>+        self.assertEqual((MULTI_STATUS, FORBIDDEN), expectedResponseCode)
</ins><span class="cx"> 
</span><span class="cx">         result.callback(
</span><span class="cx">             MemoryResponse(
</span><span class="lines">@@ -1960,13 +1984,13 @@
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-class VFreeBusyTests(OS_X_10_6Mixin, TestCase):
</del><ins>+class VFreeBusyTests(OS_X_10_11Mixin, TestCase):
</ins><span class="cx">     &quot;&quot;&quot;
</span><del>-    Tests for L{OS_X_10_6.requestAvailability}.
</del><ins>+    Tests for L{OS_X_10_11.requestAvailability}.
</ins><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def test_requestAvailability(self):
</span><span class="cx">         &quot;&quot;&quot;
</span><del>-        L{OS_X_10_6.requestAvailability} accepts a date range and a set of
</del><ins>+        L{OS_X_10_11.requestAvailability} accepts a date range and a set of
</ins><span class="cx">         account uuids and issues a VFREEBUSY request.  It returns a Deferred
</span><span class="cx">         which fires with a dict mapping account uuids to availability range
</span><span class="cx">         information.
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtesttest_profilespy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -40,38 +40,38 @@
</span><span class="cx"> import os
</span><span class="cx"> 
</span><span class="cx"> SIMPLE_EVENT = &quot;&quot;&quot;\
</span><del>-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Apple Inc.//iCal 4.0.3//EN
-CALSCALE:GREGORIAN
-BEGIN:VTIMEZONE
-TZID:America/New_York
-BEGIN:DAYLIGHT
-TZOFFSETFROM:-0500
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-DTSTART:20070311T020000
-TZNAME:EDT
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-TZOFFSETFROM:-0400
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-DTSTART:20071104T020000
-TZNAME:EST
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-CREATED:20101018T155431Z
-UID:C98AD237-55AD-4F7D-9009-0D355D835822
-DTEND;TZID=America/New_York:20101021T130000
-TRANSP:OPAQUE
-SUMMARY:Simple event
-DTSTART;TZID=America/New_York:20101021T120000
-DTSTAMP:20101018T155438Z
-SEQUENCE:2
-END:VEVENT
-END:VCALENDAR
</del><ins>+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.3//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:America/New_York
+BEGIN:DAYLIGHT
+TZOFFSETFROM:-0500
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+DTSTART:20070311T020000
+TZNAME:EDT
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:-0400
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+DTSTART:20071104T020000
+TZNAME:EST
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20101018T155431Z
+UID:C98AD237-55AD-4F7D-9009-0D355D835822
+DTEND;TZID=America/New_York:20101021T130000
+TRANSP:OPAQUE
+SUMMARY:Simple event
+DTSTART;TZID=America/New_York:20101021T120000
+DTSTAMP:20101018T155438Z
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
</ins><span class="cx"> &quot;&quot;&quot;
</span><span class="cx"> 
</span><span class="cx"> INVITED_EVENT = &quot;&quot;&quot;\
</span><span class="lines">@@ -347,7 +347,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setUp(self):
</span><span class="cx">         self.sim = CalendarClientSimulator(
</span><del>-            AnyUser(), Populator(None), None, None, None, None, None)
</del><ins>+            AnyUser(), Populator(None), None, None, None, None, None, None)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _simpleAccount(self, userNumber, eventText):
</span><span class="lines">@@ -546,7 +546,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setUp(self):
</span><span class="cx">         self.sim = CalendarClientSimulator(
</span><del>-            AnyUser(), Populator(None), None, None, None, None, None)
</del><ins>+            AnyUser(), Populator(None), None, None, None, None, None, None)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def _simpleAccount(self, userNumber, eventText):
</span><span class="lines">@@ -716,7 +716,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setUp(self):
</span><span class="cx">         self.sim = CalendarClientSimulator(
</span><del>-            AnyUser(), Populator(None), None, None, None, None, None)
</del><ins>+            AnyUser(), Populator(None), None, None, None, None, None, None)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_enabled(self):
</span><span class="lines">@@ -983,7 +983,7 @@
</span><span class="cx">     &quot;&quot;&quot;
</span><span class="cx">     def setUp(self):
</span><span class="cx">         self.sim = CalendarClientSimulator(
</span><del>-            AnyUser(), Populator(None), None, None, None, None, None)
</del><ins>+            AnyUser(), Populator(None), None, None, None, None, None, None)
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx">     def test_enabled(self):
</span></span></pre></div>
<a id="CalendarServertrunkcontribperformanceloadtesttest_simpy"></a>
<div class="modfile"><h4>Modified: CalendarServer/trunk/contrib/performance/loadtest/test_sim.py (15296 => 15297)</h4>
<pre class="diff"><span>
<span class="info">--- CalendarServer/trunk/contrib/performance/loadtest/test_sim.py        2015-11-06 22:37:43 UTC (rev 15296)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_sim.py        2015-11-06 22:41:28 UTC (rev 15297)
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         calsim = CalendarClientSimulator(
</span><span class="cx">             [self._user('alice'), self._user('bob'), self._user('carol')],
</span><del>-            Populator(None), None, None, 'http://example.org:1234/', None, None)
</del><ins>+            Populator(None), None, None, None, 'http://example.org:1234/', None, None)
</ins><span class="cx">         users = sorted([
</span><span class="cx">             calsim._createUser(0)[0],
</span><span class="cx">             calsim._createUser(1)[0],
</span><span class="lines">@@ -137,7 +137,7 @@
</span><span class="cx">         &quot;&quot;&quot;
</span><span class="cx">         calsim = CalendarClientSimulator(
</span><span class="cx">             [self._user('alice')],
</span><del>-            Populator(None), None, None, 'http://example.org:1234/', None, None)
</del><ins>+            Populator(None), None, None, None, 'http://example.org:1234/', None, None)
</ins><span class="cx">         user, auth = calsim._createUser(0)
</span><span class="cx">         self.assertEqual(
</span><span class="cx">             auth['basic'].passwd.find_user_password('Test Realm', 'http://example.org:1234/')[1],
</span><span class="lines">@@ -182,7 +182,7 @@
</span><span class="cx">             [ProfileType(BrokenProfile, {'runResult': profileRunResult})])
</span><span class="cx">         )
</span><span class="cx">         sim = CalendarClientSimulator(
</span><del>-            [self._user('alice')], Populator(None), params, None, 'http://example.com:1234/', None, None)
</del><ins>+            [self._user('alice')], Populator(None), None, params, None, 'http://example.com:1234/', None, None)
</ins><span class="cx">         sim.add(1, 1)
</span><span class="cx">         sim.stop()
</span><span class="cx">         clientRunResult.errback(RuntimeError(&quot;Some fictional client problem&quot;))
</span></span></pre>
</div>
</div>

</body>
</html>