<?xml version="1.0" encoding="UTF-8"?>

<!--
    Copyright (c) 2011-2014 Apple Inc. All rights reserved.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<!-- This is a distributed orchestrator configuration; 'workers' is a list of
							shell commands to run sub-processes.
							-->
		<key>workers</key>
		<array>
			<string>./python contrib/performance/loadtest/ampsim.py</string>
			<string>./python contrib/performance/loadtest/ampsim.py</string>
			<string>./python contrib/performance/loadtest/ampsim.py</string>
			<string>./python contrib/performance/loadtest/ampsim.py</string>
			<string>./python contrib/performance/loadtest/ampsim.py</string>
			<string>./python contrib/performance/loadtest/ampsim.py</string>
		</array>

		<!-- Identify the server to be load tested. -->
		<key>server</key>
		<string>https://127.0.0.1:8443</string>

		<!-- The template URI for doing initial principal lookup on. -->
		<key>principalPathTemplate</key>
		<string>/principals/users/%s/</string>

		<!-- Configure Admin Web UI. -->
		<key>webadmin</key>
		<dict>
			<key>enabled</key>
			<true/>
			
			<key>HTTPPort</key>
			<integer>8080</integer>
		</dict>

		<!--  Define whether server supports stats socket. -->
		<key>serverStats</key>
		<dict>
			<key>enabled</key>
			<true/>
			<key>Port</key>
			<integer>8100</integer>
		</dict>

		<!--  Define whether client data should be re-used. It will always be saved to the specified path.-->
		<key>clientDataSerialization</key>
		<dict>
			<key>UseOldData</key>
			<true/>
			<key>Path</key>
			<string>/tmp/sim</string>
		</dict>

		<!-- 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>

			<!-- 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>

			<!-- 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>

			<key>params</key>
			<dict>
				<!-- groups gives the total number of groups of clients to introduce. -->
				<key>groups</key>
				<integer>99</integer>

				<!-- 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>

				<!-- Number of seconds between the introduction of each group. -->
				<key>interval</key>
				<integer>3</integer>

				<!-- Number of clients each user is assigned to. -->
				<!-- Set weight of clients to 1 if this is > 1. Number of clients must match this value if > 1. -->
				<key>clientsPerUser</key>
				<integer>1</integer>
			</dict>

		</dict>

		<!-- 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. -->
			<dict>
				<key>type</key>
				<string>contrib.performance.loadtest.population.ReportStatistics</string>
				<key>params</key>
				<dict>
					<!-- The thresholds for each request type -->
					<key>thresholdsPath</key>
					<string>contrib/performance/loadtest/thresholds.json</string>
					
					<!-- The benchmarks for overall QoS -->
					<key>benchmarksPath</key>
					<string>contrib/performance/loadtest/benchmarks.json</string>

					<!-- The % of failures that constitute a failed test -->
					<key>failCutoff</key>
					<real>1.0</real>
				</dict>
			</dict>
	
			<!-- RequestLogger generates a realtime log of all HTTP requests made 
				during the load test. -->
			<dict>
				<key>type</key>
				<string>contrib.performance.loadtest.ical.RequestLogger</string>
				<key>params</key>
				<dict>
				</dict>
			</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). -->
			<dict>
				<key>type</key>
				<string>contrib.performance.loadtest.profiles.OperationLogger</string>
				<key>params</key>
				<dict>
					<!-- The thresholds for each operation type -->
					<key>thresholdsPath</key>
					<string>contrib/performance/loadtest/thresholds.json</string>
					
					<!-- The % of operations beyond the lag cut-off that constitute a failed test -->
					<key>lagCutoff</key>
					<real>1.0</real>
					
					<!-- The % of failures that constitute a failed test -->
					<key>failCutoff</key>
					<real>1.0</real>
				</dict>
			</dict>
		</array>
	</dict>
</plist>
