protected async Task <List <ProcessNode> > CreateCluster(string[] peers, IDictionary <string, string> customSettings = null, X509Certificate2 certificate = null)
        {
            var processes = new List <ProcessNode>();

            foreach (var peer in peers)
            {
                processes.Add(await GetServerAsync(peer));
            }

            var chosenOne = processes[0];

            using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(chosenOne.Url, certificate))
                using (requestExecutor.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                {
                    foreach (var processNode in processes)
                    {
                        if (processNode == chosenOne)
                        {
                            continue;
                        }

                        var addCommand = new AddClusterNodeCommand(processNode.Url);
                        await requestExecutor.ExecuteAsync(addCommand, context);
                    }

                    var clusterCreated = await WaitForValueAsync(async() =>
                    {
                        var clusterTopology = new GetClusterTopologyCommand();
                        await requestExecutor.ExecuteAsync(clusterTopology, context);
                        return(clusterTopology.Result.Topology.Members.Count);
                    }, peers.Length);

                    Assert.True(clusterCreated == peers.Length, "Failed to create initial cluster");
                }

            return(processes);
        }
        protected async Task <(RavenServer Leader, List <ProcessNode> Peers, List <RavenServer> LocalPeers)> CreateMixedCluster(
            string[] peers, int localPeers = 0, IDictionary <string, string> customSettings = null, X509Certificate2 certificate = null)
        {
            var leaderServer = GetNewServer(new ServerCreationOptions {
                CustomSettings = customSettings
            });
            await leaderServer.ServerStore.EnsureNotPassiveAsync(leaderServer.WebUrl);

            var nodeAdded       = new ManualResetEvent(false);
            var expectedMembers = 2;

            leaderServer.ServerStore.Engine.TopologyChanged += (sender, clusterTopology) =>
            {
                var count = expectedMembers;
                if (clusterTopology.Promotables.Count == 0 && clusterTopology.Members.Count == count)
                {
                    var result = Interlocked.CompareExchange(ref expectedMembers, count + 1, count);
                    if (result == count)
                    {
                        nodeAdded.Set();
                    }
                }
            };

            using (leaderServer.ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
                using (var requestExecutor = ClusterRequestExecutor.CreateForSingleNode(leaderServer.WebUrl, certificate))
                {
                    var local = new List <RavenServer>();

                    for (int i = 0; i < localPeers; i++)
                    {
                        var peer = GetNewServer(new ServerCreationOptions {
                            CustomSettings = customSettings
                        });
                        var addCommand = new AddClusterNodeCommand(peer.WebUrl);
                        await requestExecutor.ExecuteAsync(addCommand, context);

                        Assert.True(nodeAdded.WaitOne(TimeSpan.FromSeconds(30)));
                        nodeAdded.Reset();
                        local.Add(peer);
                    }

                    var processes = new List <ProcessNode>();
                    foreach (var peer in peers)
                    {
                        processes.Add(await GetServerAsync(peer));
                    }

                    foreach (var processNode in processes)
                    {
                        var addCommand = new AddClusterNodeCommand(processNode.Url);
                        await requestExecutor.ExecuteAsync(addCommand, context);

                        Assert.True(nodeAdded.WaitOne(TimeSpan.FromSeconds(30)));
                        nodeAdded.Reset();
                    }

                    Assert.Equal(peers.Length + localPeers + 1, leaderServer.ServerStore.GetClusterTopology().Members.Count);
                    return(leaderServer, processes, local);
                }
        }