Пример #1
0
        public void IsValidHost_should_return_expected_result(string lookupDomainName, string host, bool expectedResult)
        {
            var subject  = CreateSubject(lookupDomainName: lookupDomainName);
            var endPoint = (DnsEndPoint)EndPointHelper.Parse(host);

            var result = subject.IsValidHost(endPoint);

            result.Should().Be(expectedResult);
        }
Пример #2
0
        private IEnumerable <EndPoint> GetMembers(string elementName)
        {
            if (!_wrapped.Contains(elementName))
            {
                return(new EndPoint[0]);
            }

            return(((BsonArray)_wrapped[elementName]).Select(v => EndPointHelper.Parse((string)v)));
        }
Пример #3
0
 public void ParseFail()
 {
     Assert.Throws <ArgumentNullException>(() => EndPointHelper.Parse(null));
     Assert.Throws <ArgumentNullException>(() => EndPointHelper.Parse(""));
     Assert.Throws <ArgumentException>(() => EndPointHelper.Parse("host:"));
     Assert.Throws <ArgumentException>(() => EndPointHelper.Parse(":1234"));
     Assert.Throws <ArgumentOutOfRangeException>(() => EndPointHelper.Parse("abcd:-100"));
     Assert.Throws <ArgumentOutOfRangeException>(() => EndPointHelper.Parse("abcd:0"));
 }
Пример #4
0
        private void VerifyOutcome(BsonDocument outcome)
        {
            VerifyFields(outcome, "compatible", "logicalSessionTimeoutMinutes", "servers", "setName", "topologyType");

            var expectedTopologyType = (string)outcome["topologyType"];

            VerifyTopology(_cluster, expectedTopologyType);

            var actualDescription = _cluster.Description;

            var actualServers   = actualDescription.Servers.Select(x => x.EndPoint);
            var expectedServers = outcome["servers"].AsBsonDocument.Elements.Select(x => new
            {
                EndPoint    = EndPointHelper.Parse(x.Name),
                Description = (BsonDocument)x.Value
            });

            actualServers.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().BeEquivalentTo(expectedServers.Select(x => x.EndPoint).WithComparer(EndPointHelper.EndPointEqualityComparer));

            foreach (var actualServer in actualDescription.Servers)
            {
                var expectedServer = expectedServers.Single(x => EndPointHelper.EndPointEqualityComparer.Equals(x.EndPoint, actualServer.EndPoint));
                VerifyServerDescription(actualServer, expectedServer.Description);
            }

            if (outcome.Contains("setName"))
            {
                // TODO: assert something against setName
            }

            if (outcome.Contains("logicalSessionTimeoutMinutes"))
            {
                TimeSpan?expectedLogicalSessionTimeout;
                switch (outcome["logicalSessionTimeoutMinutes"].BsonType)
                {
                case BsonType.Null:
                    expectedLogicalSessionTimeout = null;
                    break;

                case BsonType.Int32:
                case BsonType.Int64:
                    expectedLogicalSessionTimeout = TimeSpan.FromMinutes(outcome["logicalSessionTimeoutMinutes"].ToDouble());
                    break;

                default:
                    throw new FormatException($"Invalid logicalSessionTimeoutMinutes BSON type: {outcome["setName"].BsonType}.");
                }
                actualDescription.LogicalSessionTimeout.Should().Be(expectedLogicalSessionTimeout);
            }

            if (outcome.Contains("compatible"))
            {
                var expectedIsCompatibleWithDriver = outcome["compatible"].ToBoolean();
                actualDescription.IsCompatibleWithDriver.Should().Be(expectedIsCompatibleWithDriver);
            }
        }
Пример #5
0
        private void VerifyEvent(ServerDescriptionChangedEvent actualEvent, BsonDocument expectedEvent)
        {
            VerifyFields(expectedEvent, "address", "newDescription", "previousDescription", "topologyId");
            var expectedEndPoint = EndPointHelper.Parse(expectedEvent["address"].AsString);

            actualEvent.ClusterId.Should().Be(_cluster.ClusterId);
            actualEvent.ServerId.EndPoint.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().Be(expectedEndPoint);
            VerifyServerDescription(actualEvent.OldDescription, expectedEvent["previousDescription"].AsBsonDocument);
            VerifyServerDescription(actualEvent.NewDescription, expectedEvent["newDescription"].AsBsonDocument);
        }
        private void ApplyResponse(BsonArray response)
        {
            if (response.Count != 2)
            {
                throw new FormatException($"Invalid response count: {response.Count}.");
            }

            var address       = response[0].AsString;
            var helloDocument = response[1].AsBsonDocument;
            var expectedNames = new[]
            {
                "arbiterOnly",
                "arbiters",
                "electionId",
                "hidden",
                "hosts",
                "helloOk",
                "isWritablePrimary",
                OppressiveLanguageConstants.LegacyHelloResponseIsWritablePrimaryFieldName,
                "isreplicaset",
                "logicalSessionTimeoutMinutes",
                "maxWireVersion",
                "me",
                "minWireVersion",
                "msg",
                "ok",
                "passive",
                "passives",
                "primary",
                "secondary",
                "setName",
                "setVersion",
                "topologyVersion"
            };

            JsonDrivenHelper.EnsureAllFieldsAreValid(helloDocument, expectedNames);

            var endPoint    = EndPointHelper.Parse(address);
            var helloResult = new HelloResult(helloDocument);
            var currentServerDescription = _serverFactory.GetServerDescription(endPoint);
            var newServerDescription     = currentServerDescription.With(
                canonicalEndPoint: helloResult.Me,
                electionId: helloResult.ElectionId,
                logicalSessionTimeout: helloResult.LogicalSessionTimeout,
                replicaSetConfig: helloResult.GetReplicaSetConfig(),
                state: helloResult.Wrapped.GetValue("ok", false).ToBoolean() ? ServerState.Connected : ServerState.Disconnected,
                topologyVersion: helloResult.TopologyVersion,
                type: helloResult.ServerType,
                wireVersionRange: new Range <int>(helloResult.MinWireVersion, helloResult.MaxWireVersion));

            var currentClusterDescription = _cluster.Description;

            _serverFactory.PublishDescription(newServerDescription);
            SpinWait.SpinUntil(() => !object.ReferenceEquals(_cluster.Description, currentClusterDescription), 100); // sometimes returns false and that's OK
        }
Пример #7
0
        private ClusterSettings ConfigureCluster(ClusterSettings settings, ClusterKey clusterKey)
        {
            var endPoints = clusterKey.Servers.Select(s => EndPointHelper.Parse(s.ToString()));

            return(settings.With(
                       connectionMode: clusterKey.ConnectionMode.ToCore(),
                       endPoints: Optional.Enumerable(endPoints),
                       replicaSetName: clusterKey.ReplicaSetName,
                       maxServerSelectionWaitQueueSize: clusterKey.WaitQueueSize,
                       serverSelectionTimeout: clusterKey.ServerSelectionTimeout,
                       postServerSelector: new LatencyLimitingServerSelector(clusterKey.LocalThreshold)));
        }
Пример #8
0
        public void GetValidEndPoints_should_return_expected_results(string[] srvEndPoints, string[] validEndPoints)
        {
            var lookupDomainName = "a.b.com";
            var subject          = CreateSubject(lookupDomainName: lookupDomainName);
            var srvRecords       = CreateSrvRecords(srvEndPoints);

            var result = subject.GetValidEndPoints(srvRecords);

            var expectedResult = validEndPoints.Select(x => (DnsEndPoint)EndPointHelper.Parse(x)).ToList();

            result.Should().Equal(expectedResult);
        }
Пример #9
0
        private EndPoint GetPrimary()
        {
            BsonValue primary;

            if (_wrapped.TryGetValue("primary", out primary))
            {
                // TODO: what does primary look like when there is no current primary (null, empty string)?
                return(EndPointHelper.Parse((string)primary));
            }

            return(null);
        }
        private ServerDescription BuildServerDescription(BsonDocument serverDescription, TimeSpan heartbeatInterval)
        {
            JsonDrivenHelper.EnsureAllFieldsAreValid(serverDescription, "address", "avg_rtt_ms", "tags", "type", "lastUpdateTime", "lastWrite", "maxWireVersion");

            var    endPoint             = EndPointHelper.Parse(serverDescription["address"].ToString());
            var    averageRoundTripTime = TimeSpan.FromMilliseconds(serverDescription.GetValue("avg_rtt_ms", 0.0).ToDouble());
            var    type   = GetServerType(serverDescription["type"].ToString());
            TagSet tagSet = null;

            if (serverDescription.Contains("tags"))
            {
                tagSet = BuildTagSet((BsonDocument)serverDescription["tags"]);
            }
            DateTime lastWriteTimestamp;

            if (serverDescription.Contains("lastWrite"))
            {
                lastWriteTimestamp = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(serverDescription["lastWrite"]["lastWriteDate"].ToInt64());
            }
            else
            {
                lastWriteTimestamp = _utcNow;
            }
            var      maxWireVersion   = serverDescription.GetValue("maxWireVersion", 5).ToInt32();
            var      wireVersionRange = new Range <int>(0, maxWireVersion);
            var      serverVersion    = maxWireVersion == 5 ? new SemanticVersion(3, 4, 0) : new SemanticVersion(3, 2, 0);
            DateTime lastUpdateTimestamp;

            if (serverDescription.Contains("lastUpdateTime"))
            {
                lastUpdateTimestamp = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(serverDescription.GetValue("lastUpdateTime", 0).ToInt64());
            }
            else
            {
                lastUpdateTimestamp = _utcNow;
            }

            var serverId = new ServerId(_clusterId, endPoint);

            return(new ServerDescription(
                       serverId,
                       endPoint,
                       averageRoundTripTime: averageRoundTripTime,
                       type: type,
                       lastUpdateTimestamp: lastUpdateTimestamp,
                       lastWriteTimestamp: lastWriteTimestamp,
                       heartbeatInterval: heartbeatInterval,
                       wireVersionRange: wireVersionRange,
                       version: serverVersion,
                       tags: tagSet,
                       state: ServerState.Connected));
        }
Пример #11
0
        private void ApplyResponse(BsonValue response)
        {
            var server             = (string)response[0];
            var endPoint           = EndPointHelper.Parse(server);
            var isMasterResult     = new IsMasterResult((BsonDocument)response[1]);
            var currentDescription = _serverFactory.GetServerDescription(endPoint);
            var description        = currentDescription.With(
                state: isMasterResult.Wrapped.GetValue("ok", false).ToBoolean() ? ServerState.Connected : ServerState.Disconnected,
                type: isMasterResult.ServerType,
                replicaSetConfig: isMasterResult.GetReplicaSetConfig());

            _serverFactory.PublishDescription(description);
        }
Пример #12
0
        private List <SrvRecord> CreateSrvRecords(string[] domainNames)
        {
            var srvRecords = new List <SrvRecord>();

            for (var i = 0; i < domainNames.Length; i++)
            {
                var endPoint   = (DnsEndPoint)EndPointHelper.Parse(domainNames[i]);
                var timeToLive = TimeSpan.FromHours(24);
                var srvRecord  = new SrvRecord(endPoint, timeToLive);
                srvRecords.Add(srvRecord);
            }

            return(srvRecords);
        }
        private ClusterSettings ConfigureCluster(ClusterSettings settings, ClusterKey clusterKey)
        {
            var endPoints = clusterKey.Servers.Select(s => EndPointHelper.Parse(s.ToString()));

            return(settings.With(
                       connectionMode: clusterKey.ConnectionMode.ToCore(),
                       endPoints: Optional.Enumerable(endPoints),
                       kmsProviders: Optional.Create(clusterKey.KmsProviders),
                       localThreshold: clusterKey.LocalThreshold,
                       replicaSetName: clusterKey.ReplicaSetName,
                       maxServerSelectionWaitQueueSize: clusterKey.WaitQueueSize,
                       serverSelectionTimeout: clusterKey.ServerSelectionTimeout,
                       schemaMap: Optional.Create(clusterKey.SchemaMap),
                       scheme: clusterKey.Scheme));
        }
        private ServerDescription BuildServerDescription(BsonDocument serverDescription)
        {
            var endPoint             = EndPointHelper.Parse(serverDescription["address"].ToString());
            var averageRoundTripTime = TimeSpan.FromMilliseconds(serverDescription["avg_rtt_ms"].ToDouble());
            var type   = GetServerType(serverDescription["type"].ToString());
            var tagSet = BuildTagSet((BsonDocument)serverDescription["tag_sets"][0]);

            var serverId = new ServerId(_clusterId, endPoint);

            return(new ServerDescription(serverId, endPoint,
                                         averageRoundTripTime: averageRoundTripTime,
                                         type: type,
                                         tags: tagSet,
                                         state: ServerState.Connected));
        }
Пример #15
0
        private void ApplyResponse(BsonValue response)
        {
            var server                   = (string)response[0];
            var endPoint                 = EndPointHelper.Parse(server);
            var isMasterResult           = new IsMasterResult((BsonDocument)response[1]);
            var currentServerDescription = _serverFactory.GetServerDescription(endPoint);
            var newServerDescription     = currentServerDescription.With(
                state: isMasterResult.Wrapped.GetValue("ok", false).ToBoolean() ? ServerState.Connected : ServerState.Disconnected,
                type: isMasterResult.ServerType,
                canonicalEndPoint: isMasterResult.Me,
                electionId: isMasterResult.ElectionId,
                replicaSetConfig: isMasterResult.GetReplicaSetConfig());

            var currentClusterDescription = _cluster.Description;

            _serverFactory.PublishDescription(newServerDescription);
            SpinWait.SpinUntil(() => !object.ReferenceEquals(_cluster.Description, currentClusterDescription), 100); // sometimes returns false and that's OK
        }
Пример #16
0
        private void VerifyClusterDescription(BsonDocument content, ClusterDescription description)
        {
            VerifyTopology((string)content["topologyType"], description);

            var expectedServers = ((BsonArray)content["servers"]).Select(x => new
            {
                EndPoint    = EndPointHelper.Parse((string)x["address"]),
                Description = (BsonDocument)x
            });

            var actualServers = description.Servers.Select(x => x.EndPoint);

            actualServers.Should().BeEquivalentTo(expectedServers.Select(x => x.EndPoint));

            foreach (var actualServer in description.Servers)
            {
                var expectedServer = expectedServers.Single(x => x.EndPoint.Equals(actualServer.EndPoint));
                VerifyServer(actualServer, expectedServer.Description);
            }
        }
Пример #17
0
        private void VerifyOutcome(BsonDocument outcome)
        {
            var description = _cluster.Description;

            var expectedServers = outcome["servers"].AsBsonDocument.Elements.Select(x => new
            {
                EndPoint    = EndPointHelper.Parse(x.Name),
                Description = (BsonDocument)x.Value
            });

            var actualServers = description.Servers.Select(x => x.EndPoint);

            actualServers.Should().BeEquivalentTo(expectedServers.Select(x => x.EndPoint));

            foreach (var actualServer in description.Servers)
            {
                var expectedServer = expectedServers.Single(x => EndPointHelper.Equals(x.EndPoint, actualServer.EndPoint));
                VerifyServer(actualServer, expectedServer.Description);
            }
        }
        private ClusterSettings ConfigureCluster(ClusterSettings settings, ClusterKey clusterKey)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            var endPoints            = clusterKey.Servers.Select(s => EndPointHelper.Parse(s.ToString()));
            var connectionModeSwitch = clusterKey.ConnectionModeSwitch;
            Optional <ClusterConnectionMode> connectionMode = connectionModeSwitch == ConnectionModeSwitch.UseConnectionMode ? clusterKey.ConnectionMode.ToCore() : default;
            Optional <bool?> directConnection = connectionModeSwitch == ConnectionModeSwitch.UseDirectConnection ? clusterKey.DirectConnection : default;
            return(settings.With(
                       connectionMode: connectionMode,
                       connectionModeSwitch: connectionModeSwitch,
                       directConnection: directConnection,
                       endPoints: Optional.Enumerable(endPoints),
                       kmsProviders: Optional.Create(clusterKey.KmsProviders),
                       localThreshold: clusterKey.LocalThreshold,
                       replicaSetName: clusterKey.ReplicaSetName,
                       maxServerSelectionWaitQueueSize: clusterKey.WaitQueueSize,
                       serverSelectionTimeout: clusterKey.ServerSelectionTimeout,
                       schemaMap: Optional.Create(clusterKey.SchemaMap),
                       scheme: clusterKey.Scheme));

#pragma warning restore CS0618 // Type or member is obsolete
        }
        protected FailPoint ConfigureFailPoint(BsonDocument test, IMongoClient client)
        {
            if (test.TryGetValue(FailPointKey, out var failPoint))
            {
                Logger.Debug("Configuring failpoint");

                ConfigureFailPointCommand(failPoint.AsBsonDocument);

                var cluster = client.Cluster;

                var settings = client.Settings.Clone();
                ConfigureClientSettings(settings, test);

#pragma warning disable CS0618 // Type or member is obsolete
                if (settings.ConnectionModeSwitch == ConnectionModeSwitch.UseDirectConnection &&
#pragma warning restore CS0618 // Type or member is obsolete
                    settings.DirectConnection == true)
                {
                    var serverAddress = EndPointHelper.Parse(settings.Server.ToString());

                    var selector = new EndPointServerSelector(serverAddress);
                    _failPointServer = cluster.SelectServer(selector, CancellationToken.None);
                }
                else
                {
                    _failPointServer = cluster.SelectServer(WritableServerSelector.Instance, CancellationToken.None);
                }

                var session = NoCoreSession.NewHandle();
                var command = failPoint.AsBsonDocument;

                return(FailPoint.Configure(_failPointServer, session, command));
            }

            return(null);
        }
Пример #20
0
        public void Parse(string value, IPEndPoint expected)
        {
            var ep = EndPointHelper.Parse(value);

            Assert.Equal(expected, ep);
        }
Пример #21
0
        private void VerifyOutcome(BsonDocument outcome, string phaseDescription)
        {
            var expectedNames = new[]
            {
                "compatible",
                "logicalSessionTimeoutMinutes",
                "pool",
                "servers",
                "setName",
                "topologyType",
                "topologyVersion",
                "maxSetVersion",
                "maxElectionId"
            };

            JsonDrivenHelper.EnsureAllFieldsAreValid(outcome, expectedNames);

            var expectedTopologyType = (string)outcome["topologyType"];

            VerifyTopology(_cluster, expectedTopologyType, phaseDescription);

            var actualDescription = _cluster.Description;

            var actualServersEndpoints = actualDescription.Servers.Select(x => x.EndPoint).ToList();
            var expectedServers        = outcome["servers"].AsBsonDocument.Elements.Select(x => new
            {
                EndPoint    = EndPointHelper.Parse(x.Name),
                Description = (BsonDocument)x.Value
            });

            actualServersEndpoints.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().BeEquivalentTo(expectedServers.Select(x => x.EndPoint).WithComparer(EndPointHelper.EndPointEqualityComparer));

            var actualServers = actualServersEndpoints.Select(endpoint => _serverFactory.GetServer(endpoint));

            foreach (var actualServerDescription in actualDescription.Servers)
            {
                var expectedServer = expectedServers.Single(x => EndPointHelper.EndPointEqualityComparer.Equals(x.EndPoint, actualServerDescription.EndPoint));
                VerifyServerDescription(actualServerDescription, expectedServer.Description, phaseDescription);
                VerifyServerPropertiesNotInServerDescription(_serverFactory.GetServer(actualServerDescription.EndPoint), expectedServer.Description, phaseDescription);
            }
            if (outcome.TryGetValue("maxSetVersion", out var maxSetVersion))
            {
                if (_cluster is MultiServerCluster multiServerCluster)
                {
                    multiServerCluster._maxElectionInfo_setVersion().Should().Be(maxSetVersion.AsInt32);
                }
                else
                {
                    throw new Exception($"Expected MultiServerCluster but got {_cluster.GetType()}");
                }
            }
            if (outcome.TryGetValue("maxElectionId", out var maxElectionId))
            {
                if (_cluster is MultiServerCluster multiServerCluster)
                {
                    multiServerCluster._maxElectionInfo_electionId().Should().Be(new ElectionId((ObjectId)maxElectionId));
                }
                else
                {
                    throw new Exception($"Expected MultiServerCluster but got {_cluster.GetType()}");
                }
            }

            if (outcome.Contains("setName"))
            {
                // TODO: assert something against setName
            }

            if (outcome.Contains("logicalSessionTimeoutMinutes"))
            {
                TimeSpan?expectedLogicalSessionTimeout;
                switch (outcome["logicalSessionTimeoutMinutes"].BsonType)
                {
                case BsonType.Null:
                    expectedLogicalSessionTimeout = null;
                    break;

                case BsonType.Int32:
                case BsonType.Int64:
                    expectedLogicalSessionTimeout = TimeSpan.FromMinutes(outcome["logicalSessionTimeoutMinutes"].ToDouble());
                    break;

                default:
                    throw new FormatException($"Invalid logicalSessionTimeoutMinutes BSON type: {outcome["setName"].BsonType}.");
                }
                actualDescription.LogicalSessionTimeout.Should().Be(expectedLogicalSessionTimeout);
            }

            if (outcome.Contains("compatible"))
            {
                var expectedIsCompatibleWithDriver = outcome["compatible"].ToBoolean();
                actualDescription.IsCompatibleWithDriver.Should().Be(expectedIsCompatibleWithDriver);
            }
        }
Пример #22
0
        private void VerifyServerDescription(ServerDescription actualDescription, BsonDocument expectedDescription)
        {
            VerifyFields(expectedDescription, "address", "arbiters", "hosts", "passives", "primary", "setName", "type");

            var expectedType = expectedDescription["type"].AsString;

            switch (expectedType)
            {
            case "RSPrimary":
                actualDescription.Type.Should().Be(ServerType.ReplicaSetPrimary);
                break;

            case "RSSecondary":
                actualDescription.Type.Should().Be(ServerType.ReplicaSetSecondary);
                break;

            case "RSArbiter":
                actualDescription.Type.Should().Be(ServerType.ReplicaSetArbiter);
                break;

            case "RSGhost":
                actualDescription.Type.Should().Be(ServerType.ReplicaSetGhost);
                break;

            case "RSOther":
                actualDescription.Type.Should().Be(ServerType.ReplicaSetOther);
                break;

            case "Mongos":
                actualDescription.Type.Should().Be(ServerType.ShardRouter);
                break;

            case "Standalone":
                actualDescription.Type.Should().Be(ServerType.Standalone);
                break;

            default:
                actualDescription.Type.Should().Be(ServerType.Unknown);
                break;
            }

            if (expectedDescription.Contains("setName"))
            {
                string expectedSetName;
                switch (expectedDescription["setName"].BsonType)
                {
                case BsonType.Null: expectedSetName = null; break;

                case BsonType.String: expectedSetName = expectedDescription["setName"].AsString; break;

                default: throw new FormatException($"Invalid setName BSON type: {expectedDescription["setName"].BsonType}.");
                }
                actualDescription.ReplicaSetConfig?.Name.Should().Be(expectedSetName);
            }

            var expectedAddress  = expectedDescription["address"].AsString;
            var expectedEndpoint = EndPointHelper.Parse(expectedAddress);

            actualDescription.EndPoint.WithComparer(EndPointHelper.EndPointEqualityComparer).Should().Be(expectedEndpoint);

            if (expectedDescription.Contains("arbiters"))
            {
                // TODO: assert something against arbiters
            }

            if (expectedDescription.Contains("hosts"))
            {
                // TODO: assert something against hosts
            }

            if (expectedDescription.Contains("passives"))
            {
                // TODO: assert something against passives
            }

            if (expectedDescription.Contains("primary"))
            {
                var actualPrimary   = actualDescription.ReplicaSetConfig.Primary;
                var expectedPrimary = EndPointHelper.Parse(expectedDescription["primary"].AsString);
                actualPrimary.Should().Be(expectedPrimary);
            }
        }
Пример #23
0
        private void ApplyApplicationError(BsonDocument applicationError)
        {
            var expectedKeys = new[]
            {
                "address",
                "generation", // optional
                "maxWireVersion",
                "when",
                "type",
                "response" // optional
            };

            JsonDrivenHelper.EnsureAllFieldsAreValid(applicationError, expectedKeys);
            var       address            = applicationError["address"].AsString;
            var       endPoint           = EndPointHelper.Parse(address);
            var       server             = (Server)_serverFactory.GetServer(endPoint);
            var       connectionId       = new ConnectionId(server.ServerId);
            var       type               = applicationError["type"].AsString;
            var       maxWireVersion     = applicationError["maxWireVersion"].AsInt32;
            Exception simulatedException = null;

            switch (type)
            {
            case "command":
                var response = applicationError["response"].AsBsonDocument;
                var command  = new BsonDocument("Link", "start!");
                simulatedException = ExceptionMapper.MapNotPrimaryOrNodeIsRecovering(connectionId, command, response, "errmsg");
                Ensure.IsNotNull(simulatedException, nameof(simulatedException));
                break;

            case "network":
            {
                var innerException = CoreExceptionHelper.CreateException("IOExceptionWithNetworkUnreachableSocketException");
                simulatedException = new MongoConnectionException(connectionId, "Ignorance, yet knowledge.", innerException);
                break;
            }

            case "timeout":
            {
                var innerException = CoreExceptionHelper.CreateException("IOExceptionWithTimedOutSocketException");
                simulatedException = new MongoConnectionException(connectionId, "Chaos, yet harmony.", innerException);
                break;
            }

            default:
                throw new ArgumentException($"Unsupported value of {type} for type");
            }

            var mockConnection = new Mock <IConnectionHandle>();
            var isMasterResult = new IsMasterResult(new BsonDocument {
                { "compressors", new BsonArray() }
            });
            var serverVersion   = WireVersionHelper.MapWireVersionToServerVersion(maxWireVersion);
            var buildInfoResult = new BuildInfoResult(new BsonDocument {
                { "version", serverVersion }
            });

            mockConnection.SetupGet(c => c.Description)
            .Returns(new ConnectionDescription(connectionId, isMasterResult, buildInfoResult));
            var generation = applicationError.Contains("generation") ? applicationError["generation"].AsInt32 : 0;

            mockConnection.SetupGet(c => c.Generation).Returns(generation);
            var when = applicationError["when"].AsString;

            switch (when)
            {
            case "beforeHandshakeCompletes":
                server.HandleBeforeHandshakeCompletesException(mockConnection.Object, simulatedException);
                break;

            case "afterHandshakeCompletes":
                server.HandleChannelException(mockConnection.Object, simulatedException);
                break;

            default:
                throw new ArgumentException($"Unsupported value of {when} for when.");
            }
        }