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); }
private IEnumerable <EndPoint> GetMembers(string elementName) { if (!_wrapped.Contains(elementName)) { return(new EndPoint[0]); } return(((BsonArray)_wrapped[elementName]).Select(v => EndPointHelper.Parse((string)v))); }
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")); }
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); } }
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 }
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))); }
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); }
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)); }
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); }
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)); }
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 }
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); } }
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); }
public void Parse(string value, IPEndPoint expected) { var ep = EndPointHelper.Parse(value); Assert.Equal(expected, ep); }
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); } }
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); } }
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."); } }