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

<!--
    Copyright (c) 2011-2017 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>
		<!-- Identify the server to be load tested. -->
		<key>servers</key>
		<dict>
			<key>PodA</key>
			<dict>
				<key>enabled</key>
				<true/>

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

				<key>ampPushHosts</key>
				<array>
					<string>localhost</string>
			    </array>
				<key>ampPushPort</key>
				<integer>62311</integer>

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

				<!-- Identify the server to be load tested. -->
				<key>uri</key>
				<string>https://localhost:8543</string>

				<key>ampPushHosts</key>
				<array>
					<string>localhost</string>
			    </array>
				<key>ampPushPort</key>
				<integer>62312</integer>

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


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

				<!-- When there are accounts for multiple pods, interleave the accounts for each
					pod so that the arrival mechanism will cycle clients between each pod. -->
				<key>interleavePods</key>
				<true/>
			</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>20</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>

					<!-- There must be at least one push operation -->
					<key>failIfNoPush</key>
					<true/>
				</dict>
			</dict>
		</array>
	</dict>
</plist>
