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

source_changes at macosforge.org source_changes at macosforge.org
Tue Jul 19 20:12:26 PDT 2011


Revision: 7806
          http://trac.macosforge.org/projects/calendarserver/changeset/7806
Author:   cdaboo at apple.com
Date:     2011-07-19 20:12:26 -0700 (Tue, 19 Jul 2011)
Log Message:
-----------
Allow profiles to be disabled via config parameter. Clean/format some XML.

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

Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.plist	2011-07-19 21:38:22 UTC (rev 7805)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist	2011-07-20 03:12:26 UTC (rev 7806)
@@ -18,268 +18,261 @@
 
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
-  <dict>
-    <!-- Identify the server to be load tested. -->
-    <key>server</key>
-    <string>https://127.0.0.1:8443/</string>
+	<dict>
+		<!-- Identify the server to be load tested. -->
+		<key>server</key>
+		<string>https://127.0.0.1:8443/</string>
 
-    <!-- Define the credentials of the clients which will be used to load test
-         the server.  These credentials must already be valid on the
-         server. -->
-    <key>accounts</key>
-    <dict>
-      <!-- The loader is the fully-qualified Python name of a callable which
-           returns a list of directory service records defining all of the
-           client accounts to use.
+		<!-- Define the credentials of the clients which will be used to load test 
+			the server. These credentials must already be valid on the server. -->
+		<key>accounts</key>
+		<dict>
+			<!-- The loader is the fully-qualified Python name of a callable which 
+				returns a list of directory service records defining all of the client accounts 
+				to use. contrib.performance.loadtest.sim.recordsFromCSVFile reads username, 
+				password, mailto triples from a CSV file and returns them as a list of faked 
+				directory service records. -->
+			<key>loader</key>
+			<string>contrib.performance.loadtest.sim.recordsFromCSVFile</string>
 
-	   contrib.performance.loadtest.sim.recordsFromCSVFile reads username, password, mailto
-	   triples from a CSV file and returns them as a list of faked
-	   directory service records. -->
-      <key>loader</key>
-      <string>contrib.performance.loadtest.sim.recordsFromCSVFile</string>
+			<!-- Keyword arguments may be passed to the loader. -->
+			<key>params</key>
+			<dict>
+				<!-- recordsFromCSVFile interprets the path relative to the config.plist, 
+					to make it independent of the script's working directory while still allowing 
+					a relative path. This isn't a great solution. -->
+				<key>path</key>
+				<string>contrib/performance/loadtest/accounts.csv</string>
+			</dict>
+		</dict>
 
-      <!-- Keyword arguments may be passed to the loader. -->
-      <key>params</key>
-      <dict>
-        <!-- recordsFromCSVFile interprets the path relative to the
-             config.plist, to make it independent of the script's working
-             directory while still allowing a relative path.  This isn't
-             a great solution. -->
-	<key>path</key>
-	<string>contrib/performance/loadtest/accounts.csv</string>
-      </dict>
-    </dict>
+		<!-- Define how many clients will participate in the load test and how 
+			they will show up. -->
+		<key>arrival</key>
+		<dict>
 
-    <!-- Define how many clients will participate in the load test and how they
-         will show up. -->
-    <key>arrival</key>
-    <dict>
+			<!-- Specify a class which creates new clients and introduces them into 
+				the test. contrib.performance.loadtest.population.SmoothRampUp introduces 
+				groups of new clients at fixed intervals up to a maximum. The size of the 
+				group, interval, and maximum are configured by the parameters below. The 
+				total number of clients is groups * groupSize, which needs to be no larger 
+				than the number of credentials created in the accounts section. -->
+			<key>factory</key>
+			<string>contrib.performance.loadtest.population.SmoothRampUp</string>
 
-      <!-- Specify a class which creates new clients and introduces them into the test.
+			<key>params</key>
+			<dict>
+				<!-- groups gives the total number of groups of clients to introduce. -->
+				<key>groups</key>
+				<integer>99</integer>
 
-	   contrib.performance.loadtest.population.SmoothRampUp introduces groups of new clients at
-	   fixed intervals up to a maximum.  The size of the group, interval,
-	   and maximum are configured by the parameters below.  The total
-	   number of clients is groups * groupSize, which needs to be no larger
-	   than the number of credentials created in the accounts section.  -->
-      <key>factory</key>
-      <string>contrib.performance.loadtest.population.SmoothRampUp</string>
+				<!-- groupSize is the number of clients in each group of clients. It's 
+					really only a "smooth" ramp up if this is pretty small. -->
+				<key>groupSize</key>
+				<integer>1</integer>
 
-      <key>params</key>
-      <dict>
-	<!-- groups gives the total number of groups of clients to introduce.-->
-	<key>groups</key>
-	<integer>99</integer>
+				<!-- Number of seconds between the introduction of each group. -->
+				<key>interval</key>
+				<integer>3</integer>
+			</dict>
 
-	<!-- groupSize is the number of clients in each group of clients.  It's
-	     really only a "smooth" ramp up if this is pretty small. -->
-	<key>groupSize</key>
-	<integer>1</integer>
+		</dict>
 
-	<!-- Number of seconds between the introduction of each group. -->
-	<key>interval</key>
-	<integer>3</integer>
-      </dict>
+		<!-- Define the kinds of software and user behavior the load simulation 
+			will simulate. -->
+		<key>clients</key>
 
-    </dict>
+		<!-- Have as many different kinds of software and user behavior configurations 
+			as you want. Each is a dict -->
+		<array>
 
-    <!-- Define the kinds of software and user behavior the load simulation
-         will simulate. -->
-    <key>clients</key>
+			<dict>
 
-    <!-- Have as many different kinds of software and user behavior
-         configurations as you want.  Each is a dict  -->
-    <array>
+				<!-- Here is a Snow Leopard iCal simulator. -->
+				<key>software</key>
+				<string>contrib.performance.loadtest.ical.SnowLeopard</string>
 
-      <dict>
+				<!-- Arguments to use to initialize the SnowLeopard instance. -->
+				<key>params</key>
+				<dict>
+					<!-- SnowLeopard can poll the calendar home at some interval. This is 
+						in seconds. -->
+					<key>calendarHomePollInterval</key>
+					<integer>30</integer>
 
-	<!-- Here is a Snow Leopard iCal simulator. -->
-	<key>software</key>
-	<string>contrib.performance.loadtest.ical.SnowLeopard</string>
+					<!-- If the server advertises xmpp push, SnowLeopard can wait for notifications 
+						about calendar home changes instead of polling for them periodically. If 
+						this option is true, then look for the server advertisement for xmpp push 
+						and use it if possible. Still fall back to polling if there is no xmpp push 
+						advertised. -->
+					<key>supportPush</key>
+					<false />
+				</dict>
 
-	<!-- Arguments to use to initialize the SnowLeopard instance. -->
-	<key>params</key>
-	<dict>
-	  <!-- SnowLeopard can poll the calendar home at some interval.  This
-               is in seconds. -->
-	  <key>calendarHomePollInterval</key>
-	  <integer>30</integer>
+				<!-- The profiles define certain types of user behavior on top of the 
+					client software being simulated. -->
+				<key>profiles</key>
+				<array>
 
-	  <!-- If the server advertises xmpp push, SnowLeopard can wait for
-	       notifications about calendar home changes instead of polling for
-	       them periodically.  If this option is true, then look for the
-	       server advertisement for xmpp push and use it if possible.
-	       Still fall back to polling if there is no xmpp push
-	       advertised. -->
-	  <key>supportPush</key>
-	  <false/>
-	</dict>
+					<!-- First an event-creating profile, which will periodically create 
+						new events at a random time on a random calendar. -->
+					<dict>
+						<key>class</key>
+						<string>contrib.performance.loadtest.profiles.Eventer</string>
 
-	<!-- The profiles define certain types of user behavior on top of the
-	     client software being simulated.  -->
-	<key>profiles</key>
-	<array>
+						<key>params</key>
+						<dict>
+							<key>enabled</key>
+							<true/>
 
-	  <!-- First an event-creating profile, which will periodically create
-	       new events at a random time on a random calendar. -->
-	  <dict>
-	    <key>class</key>
-	    <string>contrib.performance.loadtest.profiles.Eventer</string>
+							<!-- Define the interval (in seconds) at which this profile will use 
+								its client to create a new event. -->
+							<key>interval</key>
+							<integer>60</integer>
 
-	    <key>params</key>
-	    <dict>
-	      <!-- Define the interval (in seconds) at which this profile will
-	           use its client to create a new event. -->
-	      <key>interval</key>
-	      <integer>60</integer>
+							<!-- Define how start times (DTSTART) for the randomly generated events 
+								will be selected. This is an example of a "Distribution" parameter. The value 
+								for most "Distribution" parameters are interchangeable and extensible. -->
+							<key>eventStartDistribution</key>
+							<dict>
 
-	      <!-- Define how start times (DTSTART) for the randomly generated
-	           events will be selected.  This is an example of a
-	           "Distribution" parameter.  The value for most "Distribution"
-	           parameters are interchangeable and extensible.  -->
-	      <key>eventStartDistribution</key>
-	      <dict>
+								<!-- This distribution is pretty specialized. It produces timestamps 
+									in the near future, limited to certain days of the week and certain hours 
+									of the day. -->
+								<key>type</key>
+								<string>contrib.performance.stats.WorkDistribution</string>
 
-		<!-- This distribution is pretty specialized.  It produces
-		     timestamps in the near future, limited to certain days of
-		     the week and certain hours of the day. -->
-		<key>type</key>
-		<string>contrib.performance.stats.WorkDistribution</string>
+								<key>params</key>
+								<dict>
+									<!-- These are the days of the week the distribution will use. -->
+									<key>daysOfWeek</key>
+									<array>
+										<string>mon</string>
+										<string>tue</string>
+										<string>wed</string>
+										<string>thu</string>
+										<string>fri</string>
+									</array>
 
-		<key>params</key>
-		<dict>
-		  <!-- These are the days of the week the distribution will
-		       use. -->
-		  <key>daysOfWeek</key>
-		  <array>
-		    <string>mon</string>
-		    <string>tue</string>
-		    <string>wed</string>
-		    <string>thu</string>
-		    <string>fri</string>
-		  </array>
+									<!-- The earliest hour of a day at which an event might be scheduled. -->
+									<key>beginHour</key>
+									<integer>8</integer>
 
-		  <!-- The earliest hour of a day at which an event might be
-		       scheduled. -->
-		  <key>beginHour</key>
-		  <integer>8</integer>
+									<!-- And the latest hour of a day (at which an event will be scheduled 
+										to begin!). -->
+									<key>endHour</key>
+									<integer>16</integer>
 
-		  <!-- And the latest hour of a day (at which an event will be
-                       scheduled to begin!). -->
-		  <key>endHour</key>
-		  <integer>16</integer>
+									<!-- The timezone in which the event is scheduled. (XXX Does this 
+										really work right?) -->
+									<key>tzname</key>
+									<string>America/Los_Angeles</string>
+								</dict>
+							</dict>
+						</dict>
+					</dict>
 
-                  <!-- The timezone in which the event is scheduled.
-                       (XXX Does this really work right?) -->
-                  <key>tzname</key>
-                  <string>America/Los_Angeles</string>
-		</dict>
-	      </dict>
-	    </dict>
-	  </dict>
+					<!-- This profile invites new attendees to existing events. -->
+					<dict>
+						<key>class</key>
+						<string>contrib.performance.loadtest.profiles.Inviter</string>
 
-	  <!-- This profile invites new attendees to existing events. -->
-	  <dict>
-	    <key>class</key>
-	    <string>contrib.performance.loadtest.profiles.Inviter</string>
-	    
-	    <key>params</key>
-	    <dict>
-	      <!-- Define the frequency at which new invitations will be sent
-	           out. -->
-	      <key>sendInvitationDistribution</key>
-	      <dict>
-		<key>type</key>
-		<string>contrib.performance.stats.NormalDistribution</string>
-		<key>params</key>
-		<dict>
-		  <!-- mu gives the mean of the normal distribution (in
-		       seconds). -->
-		  <key>mu</key>
-		  <integer>60</integer>
+						<key>params</key>
+						<dict>
+							<key>enabled</key>
+							<true/>
 
-		  <!-- and sigma gives its standard deviation. -->
-		  <key>sigma</key>
-		  <integer>5</integer>
-		</dict>
-	      </dict>
+							<!-- Define the frequency at which new invitations will be sent out. -->
+							<key>sendInvitationDistribution</key>
+							<dict>
+								<key>type</key>
+								<string>contrib.performance.stats.NormalDistribution</string>
+								<key>params</key>
+								<dict>
+									<!-- mu gives the mean of the normal distribution (in seconds). -->
+									<key>mu</key>
+									<integer>60</integer>
 
-	      <!-- Define the distribution of who will be invited to an event.
-	           Each set of credentials loaded by the load tester has an
-	           index; samples from this distribution will be added to that
-	           index to arrive at the index of some other credentials,
-	           which will be the target of the invitation. -->
-	      <key>inviteeDistanceDistribution</key>
-	      <dict>
-		<key>type</key>
-		<string>contrib.performance.stats.UniformIntegerDistribution</string>
-		<key>params</key>
-		<dict>
-		  <!-- The minimum value (inclusive) of the uniform
-		       distribution. -->
-		  <key>min</key>
-		  <integer>-100</integer>
-		  <!-- The maximum value (exclusive) of the uniform
-		       distribution. -->
-		  <key>max</key>
-		  <integer>101</integer>
-		</dict>
-	      </dict>
-	    </dict>
+									<!-- and sigma gives its standard deviation. -->
+									<key>sigma</key>
+									<integer>5</integer>
+								</dict>
+							</dict>
 
-	  </dict>
+							<!-- Define the distribution of who will be invited to an event. Each 
+								set of credentials loaded by the load tester has an index; samples from this 
+								distribution will be added to that index to arrive at the index of some other 
+								credentials, which will be the target of the invitation. -->
+							<key>inviteeDistanceDistribution</key>
+							<dict>
+								<key>type</key>
+								<string>contrib.performance.stats.UniformIntegerDistribution</string>
+								<key>params</key>
+								<dict>
+									<!-- The minimum value (inclusive) of the uniform distribution. -->
+									<key>min</key>
+									<integer>-100</integer>
+									<!-- The maximum value (exclusive) of the uniform distribution. -->
+									<key>max</key>
+									<integer>101</integer>
+								</dict>
+							</dict>
+						</dict>
+					</dict>
 
-	  <!-- This profile accepts invitations to events. -->
-	  <dict>
-	    <key>class</key>
-	    <string>contrib.performance.loadtest.profiles.Accepter</string>
+					<!-- This profile accepts invitations to events, handles cancels, and
+					     handles replies received. -->
+					<dict>
+						<key>class</key>
+						<string>contrib.performance.loadtest.profiles.Accepter</string>
 
-	    <key>params</key>
-	    <dict>
-	      <!-- Define how long to wait after seeing a new invitation before
-	           accepting it. -->
-	      <key>acceptDelayDistribution</key>
-	      <dict>
-		<key>type</key>
-		<string>contrib.performance.stats.NormalDistribution</string>
-		<key>params</key>
-		<dict>
-		  <!-- mean -->
-		  <key>mu</key>
-		  <integer>360</integer>
-		  <!-- standard deviation --> 
-		  <key>sigma</key>
-		  <integer>60</integer>
-		</dict>
-	      </dict>
-	    </dict>
-	  
-	  </dict>
-	</array>
+						<key>params</key>
+						<dict>
+							<key>enabled</key>
+							<true/>
 
-	<!-- Determine the frequency at which this client configuration will
-	     appear in the clients which are created by the load tester. -->
-	<key>weight</key>
-	<integer>1</integer>
-      </dict>
-    </array>
+							<!-- Define how long to wait after seeing a new invitation before 
+								accepting it. -->
+							<key>acceptDelayDistribution</key>
+							<dict>
+								<key>type</key>
+								<string>contrib.performance.stats.NormalDistribution</string>
+								<key>params</key>
+								<dict>
+									<!-- mean -->
+									<key>mu</key>
+									<integer>360</integer>
+									<!-- standard deviation -->
+									<key>sigma</key>
+									<integer>60</integer>
+								</dict>
+							</dict>
+						</dict>
+					</dict>
+				</array>
 
-    <!-- Define some log observers to report on the load test. -->
-    <key>observers</key>
-    <array>
-      <!-- ReportStatistics generates an end-of-run summary of the HTTP
-           requests made, their timings, and their results. -->
-      <string>contrib.performance.loadtest.population.ReportStatistics</string>
+				<!-- Determine the frequency at which this client configuration will 
+					appear in the clients which are created by the load tester. -->
+				<key>weight</key>
+				<integer>1</integer>
+			</dict>
+		</array>
 
-      <!-- RequestLogger generates a realtime log of all HTTP requests made
-           during the load test. -->
-      <string>contrib.performance.loadtest.ical.RequestLogger</string>
+		<!-- Define some log observers to report on the load test. -->
+		<key>observers</key>
+		<array>
+			<!-- ReportStatistics generates an end-of-run summary of the HTTP requests 
+				made, their timings, and their results. -->
+			<string>contrib.performance.loadtest.population.ReportStatistics</string>
 
-      <!-- OperationLogger generates an end-of-run summary of the gross
-           operations performed (logical operations which may span more than
-           one HTTP request, such as inviting an attendee to an event). -->
-      <string>contrib.performance.loadtest.profiles.OperationLogger</string>
-    </array>
+			<!-- RequestLogger generates a realtime log of all HTTP requests made 
+				during the load test. -->
+			<string>contrib.performance.loadtest.ical.RequestLogger</string>
 
-  </dict>
+			<!-- OperationLogger generates an end-of-run summary of the gross operations 
+				performed (logical operations which may span more than one HTTP request, 
+				such as inviting an attendee to an event). -->
+			<string>contrib.performance.loadtest.profiles.OperationLogger</string>
+		</array>
+	</dict>
 </plist>

Modified: CalendarServer/trunk/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/population.py	2011-07-19 21:38:22 UTC (rev 7805)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py	2011-07-20 03:12:26 UTC (rev 7806)
@@ -129,7 +129,7 @@
     def _cycle(self, elements):
         while True:
             for (weight, value) in elements:
-                for i in range(weight):
+                for _ignore_i in range(weight):
                     yield value
 
 
@@ -191,9 +191,9 @@
 
 
     def add(self, numClients):
-        for n in range(numClients):
+        for _ignore_n in range(numClients):
             number = self._nextUserNumber()
-            user, auth = self._createUser(number)
+            _ignore_user, auth = self._createUser(number)
 
             clientType = self._pop.next()
             reactor = loggedReactor(self.reactor)
@@ -203,8 +203,10 @@
             d.addErrback(self._clientFailure, reactor)
 
             for profileType in clientType.profileTypes:
-                d = profileType(reactor, self, client, number).run()
-                d.addErrback(self._profileFailure, profileType, reactor)
+                profile = profileType(reactor, self, client, number)
+                if profile.enabled:
+                    d = profile.run()
+                    d.addErrback(self._profileFailure, profileType, reactor)
         msg(type="status", clientCount=self._user - 1)
 
 
@@ -323,7 +325,7 @@
         self.printMiscellaneous({'users': self.countUsers()})
         self.printHeader([
                 (label, width)
-                for (label, width, fmt)
+                for (label, width, _ignore_fmt)
                 in self._fields])
         self.printData(
             [fmt for (label, width, fmt) in self._fields],

Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2011-07-19 21:38:22 UTC (rev 7805)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2011-07-20 03:12:26 UTC (rev 7806)
@@ -134,9 +134,13 @@
     """
     A Calendar user who invites and de-invites other users to events.
     """
-    def setParameters(self,
-                      sendInvitationDistribution=NormalDistribution(600, 60),
-                      inviteeDistanceDistribution=UniformDiscreteDistribution(range(-10, 11))):
+    def setParameters(
+        self,
+        enabled=True,
+        sendInvitationDistribution=NormalDistribution(600, 60),
+        inviteeDistanceDistribution=UniformDiscreteDistribution(range(-10, 11))
+    ):
+        self.enabled = enabled
         self._sendInvitationDistribution = sendInvitationDistribution
         self._inviteeDistanceDistribution = inviteeDistanceDistribution
 
@@ -244,7 +248,12 @@
     A Calendar user who accepts invitations to events. As well as accepting requests, this
     will also remove cancels and replies.
     """
-    def setParameters(self, acceptDelayDistribution=NormalDistribution(1200, 60)):
+    def setParameters(
+        self,
+        enabled=True,
+        acceptDelayDistribution=NormalDistribution(1200, 60)
+    ):
+        self.enabled = enabled
         self._accepting = set()
         self._acceptDelayDistribution = acceptDelayDistribution
 
@@ -430,13 +439,19 @@
 END:VEVENT
 END:VCALENDAR
 """))[0]
+
     def setParameters(
-        self, interval=25,
+        self,
+        enabled=True,
+        interval=25,
         eventStartDistribution=NearFutureDistribution(),
         eventDurationDistribution=UniformDiscreteDistribution([
-                15 * 60, 30 * 60,
-                45 * 60, 60 * 60,
-                120 * 60])):
+            15 * 60, 30 * 60,
+            45 * 60, 60 * 60,
+            120 * 60
+        ])
+    ):
+        self.enabled = enabled
         self._interval = interval
         self._eventStartDistribution = eventStartDistribution
         self._eventDurationDistribution = eventDurationDistribution

Modified: CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py	2011-07-19 21:38:22 UTC (rev 7805)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py	2011-07-20 03:12:26 UTC (rev 7806)
@@ -277,6 +277,16 @@
         return vevent, event, calendar, client
 
 
+    def test_enabled(self):
+        userNumber = 13
+        client = StubClient(userNumber)
+
+        inviter = Inviter(None, self.sim, client, userNumber, **{"enabled":False})
+        self.assertEqual(inviter.enabled, False)
+
+        inviter = Inviter(None, self.sim, client, userNumber, **{"enabled":True})
+        self.assertEqual(inviter.enabled, True)
+
     def test_doNotAddAttendeeToInbox(self):
         """
         When the only calendar with any events is a schedule inbox, no
@@ -445,6 +455,16 @@
             AnyUser(), Populator(None), None, None, None)
 
 
+    def test_enabled(self):
+        userNumber = 13
+        client = StubClient(userNumber)
+
+        accepter = Accepter(None, self.sim, client, userNumber, **{"enabled":False})
+        self.assertEqual(accepter.enabled, False)
+
+        accepter = Accepter(None, self.sim, client, userNumber, **{"enabled":True})
+        self.assertEqual(accepter.enabled, True)
+
     def test_ignoreEventOnUnknownCalendar(self):
         """
         If an event on an unknown calendar changes, it is ignored.
@@ -547,7 +567,7 @@
         client._setEvent(inboxEvent.url, inboxEvent)
 
         accepter = Accepter(clock, self.sim, client, userNumber)
-        accepter.setParameters(Deterministic(randomDelay))
+        accepter.setParameters(acceptDelayDistribution=Deterministic(randomDelay))
         accepter.eventChanged(event.url)
         clock.advance(randomDelay)
 
@@ -583,7 +603,7 @@
         event = Event(calendarURL + u'1234.ics', None, vevent)
         client._events[event.url] = event
         accepter = Accepter(clock, self.sim, client, userNumber)
-        accepter.setParameters(Deterministic(randomDelay))
+        accepter.setParameters(acceptDelayDistribution=Deterministic(randomDelay))
         accepter.eventChanged(event.url)
         clock.advance(randomDelay)
 
@@ -626,7 +646,7 @@
         client._setEvent(event.url, event)
 
         accepter = Accepter(clock, self.sim, client, userNumber)
-        accepter.setParameters(Deterministic(randomDelay))
+        accepter.setParameters(acceptDelayDistribution=Deterministic(randomDelay))
 
         client.rescheduled.add(event.url)
 
@@ -647,6 +667,16 @@
             AnyUser(), Populator(None), None, None, None)
 
 
+    def test_enabled(self):
+        userNumber = 13
+        client = StubClient(userNumber)
+
+        eventer = Eventer(None, self.sim, client, None, **{"enabled":False})
+        self.assertEqual(eventer.enabled, False)
+
+        eventer = Eventer(None, self.sim, client, None, **{"enabled":True})
+        self.assertEqual(eventer.enabled, True)
+
     def test_doNotAddEventOnInbox(self):
         """
         When the only calendar is a schedule inbox, no attempt is made
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110719/beb8fe18/attachment-0001.html>


More information about the calendarserver-changes mailing list