public async Task DefaultMaxIsNumberOfNodes()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.FailAlways())
				.ClientCalls(r => r.OnPort(9209).SucceedAlways())
				.StaticConnectionPool()
				.Settings(s => s.DisablePing())
			);

			audit = await audit.TraceCall(
				new ClientCall {
					{ BadResponse, 9200 },
					{ BadResponse, 9201 },
					{ BadResponse, 9202 },
					{ BadResponse, 9203 },
					{ BadResponse, 9204 },
					{ BadResponse, 9205 },
					{ BadResponse, 9206 },
					{ BadResponse, 9207 },
					{ BadResponse, 9208 },
					{ HealthyResponse, 9209 }
				}
			);
		}
		/** == Unexpected exceptions 
		* When a client call throws an exception that the IConnction can not handle, this exception will bubble
		* out the client as an UnexpectedElasticsearchClientException, regardless whether the client is configured to throw or not.
		* An IConnection is in charge of knowning what exceptions it can recover from or not. The default IConnection that is based on WebRequest can and 
		* will recover from WebExceptions but others will be grounds for immediately exiting the pipeline.
		*/

		[U] public async Task UnexpectedExceptionsBubbleOut()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.SucceedAlways())
				.ClientCalls(r => r.OnPort(9201).FailAlways(new Exception("boom!")))
				.StaticConnectionPool()
				.Settings(s => s.DisablePing())
			);

			audit = await audit.TraceCall(
				new ClientCall {
					{ AuditEvent.HealthyResponse, 9200 },
				}
			);

			audit = await audit.TraceUnexpectedException(
				new ClientCall {
					{ AuditEvent.BadResponse, 9201 },
				},
				(e) =>
				{
					e.FailureReason.Should().Be(PipelineFailure.Unexpected);
					e.InnerException.Should().NotBeNull();
					e.InnerException.Message.Should().Be("boom!");
				}
			);
		}
		public async Task OnlyCallsForcedNode()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.SucceedAlways())
				.ClientCalls(r => r.OnPort(9208).FailAlways())
				.StaticConnectionPool()
				.Settings(s => s.DisablePing())
			);

			audit = await audit.TraceCall(
				new ClientCall(r => r.ForceNode(new Uri("http://localhost:9208"))) {
					{ BadResponse, 9208 }
				}
			);
		}
		[U] public async Task DisablePing()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.SucceedAlways())
				.SniffingConnectionPool()
				.Settings(s => s.SniffOnStartup())
			);

			audit = await audit.TraceCall(
				new ClientCall(r=>r.DisablePing()) {
					{ SniffOnStartup },
					{ SniffSuccess, 9200 },
					{ HealthyResponse, 9200 }
				}
            );
		}
		public async Task Http503FallsOver()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.FailAlways(503))
				.ClientCalls(r => r.OnPort(9201).SucceedAlways())
				.StaticConnectionPool()
				.Settings(s => s.DisablePing())
			);

			audit = await audit.TraceCall(
				new ClientCall {
					{ BadResponse, 9200 },
					{ HealthyResponse, 9201 },
				}
			);
		}
		public async Task DoesNotRetryOnSingleNodeConnectionPool()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.FailAlways().Takes(TimeSpan.FromSeconds(3)))
				.ClientCalls(r => r.OnPort(9209).SucceedAlways())
				.SingleNodeConnection()
				.Settings(s => s.DisablePing().MaximumRetries(10))
			);

			audit = await audit.TraceCall(
				new ClientCall(r => r.MaxRetries(10)) {
					{ BadResponse, 9200 }
				}
			);

		}
		public async Task FixedMaximumNumberOfRetries()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.FailAlways())
				.ClientCalls(r => r.OnPort(9209).SucceedAlways())
				.StaticConnectionPool()
				.Settings(s => s.DisablePing().MaximumRetries(5))
			);

			audit = await audit.TraceCall(
				new ClientCall(r => r.MaxRetries(2)) {
					{ BadResponse, 9200 },
					{ BadResponse, 9201 },
					{ BadResponse, 9202 },
					{ MaxRetriesReached }
				}
			);
		}
		public async Task ASniffOnStartupHappens()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.Sniff(s => s.Fails(Always))
				.Sniff(s => s.OnPort(9202).Succeeds(Always))
				.SniffingConnectionPool()
				.AllDefaults()
			);

			 await audit.TraceCall(new ClientCall
			 {
				{ SniffOnStartup},
				{ SniffFailure, 9200},
				{ SniffFailure, 9201},
				{ SniffSuccess, 9202},
				{ PingSuccess , 9200},
				{ HealthyResponse, 9200}
			});
		}
		public async Task SniffPrefersMasterNodesButStillFailsOver()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(new[] {
					new Node(new Uri("http://localhost:9200")) { MasterEligable = true },
					new Node(new Uri("http://localhost:9201")) { MasterEligable = true },
					new Node(new Uri("http://localhost:9202")) { MasterEligable = false },
				})
				.Sniff(s => s.Fails(Always))
				.Sniff(s => s.OnPort(9202).Succeeds(Always))
				.SniffingConnectionPool()
				.AllDefaults()
			);

			await audit.TraceCall(new ClientCall {
				{ SniffOnStartup},
				{ SniffFailure, 9200},
				{ SniffFailure, 9201},
				{ SniffSuccess, 9202},
				{ PingSuccess, 9200},
				{ HealthyResponse, 9200}
			});
		}
		/** Finally, let's demonstrate disabling both sniff and ping on the request */
		[U] public async Task DisableSniffAndPing()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.SucceedAlways())
				.SniffingConnectionPool()
				.Settings(s => s.SniffOnStartup())
			);

			audit = await audit.TraceCall(
				new ClientCall(r=>r.DisableSniffing().DisablePing()) // <1> diable ping and sniff
				{
					{ HealthyResponse, 9200 } // <2> no ping or sniff before the call
				}
            );
		}
		public async Task RespectsOveralRequestTimeout()
		{
			var audit = new Auditor(() => Framework.Cluster
				.Nodes(10)
				.ClientCalls(r => r.FailAlways().Takes(TimeSpan.FromSeconds(10)))
				.ClientCalls(r => r.OnPort(9209).SucceedAlways())
				.StaticConnectionPool()
				.Settings(s => s.DisablePing().RequestTimeout(TimeSpan.FromSeconds(20)))
			);

			audit = await audit.TraceCall(
				new ClientCall {
					{ BadResponse, 9200 },
					{ BadResponse, 9201 },
					{ MaxTimeoutReached }
				}
			);
		}