diff --git a/src/change_stream.ts b/src/change_stream.ts index f5b94bdd560..22330e8595e 100644 --- a/src/change_stream.ts +++ b/src/change_stream.ts @@ -18,6 +18,7 @@ import { MongoClient } from './mongo_client'; import { type InferIdType, TypedEventEmitter } from './mongo_types'; import type { AggregateOptions } from './operations/aggregate'; import type { OperationParent } from './operations/command'; +import { DeprioritizedServers } from './sdam/server_selection'; import type { ServerSessionId } from './sessions'; import { CSOTTimeoutContext, type TimeoutContext } from './timeout'; import { type AnyOptions, getTopology, type MongoDBNamespace, squashError } from './utils'; @@ -1073,7 +1074,8 @@ export class ChangeStream< try { await topology.selectServer(this.cursor.readPreference, { operationName: 'reconnect topology in change stream', - timeoutContext: this.timeoutContext + timeoutContext: this.timeoutContext, + deprioritizedServers: new DeprioritizedServers() }); this.cursor = this._createChangeStreamCursor(this.cursor.resumeOptions); } catch { diff --git a/src/index.ts b/src/index.ts index 75acf17c68b..8f5c4cfa60e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -588,7 +588,7 @@ export type { TagSet, TopologyVersion } from './sdam/server_description'; -export type { ServerSelector } from './sdam/server_selection'; +export type { DeprioritizedServers, ServerSelector } from './sdam/server_selection'; export type { SrvPoller, SrvPollerEvents, SrvPollerOptions } from './sdam/srv_polling'; export type { ConnectOptions, diff --git a/src/mongo_client.ts b/src/mongo_client.ts index d93fba761af..970f0f88061 100644 --- a/src/mongo_client.ts +++ b/src/mongo_client.ts @@ -48,7 +48,7 @@ import type { ReadConcern, ReadConcernLevel, ReadConcernLike } from './read_conc import { ReadPreference, type ReadPreferenceMode } from './read_preference'; import type { ServerMonitoringMode } from './sdam/monitor'; import type { TagSet } from './sdam/server_description'; -import { readPreferenceServerSelector } from './sdam/server_selection'; +import { DeprioritizedServers, readPreferenceServerSelector } from './sdam/server_selection'; import type { SrvPoller } from './sdam/srv_polling'; import { Topology, type TopologyEvents } from './sdam/topology'; import { ClientSession, type ClientSessionOptions, ServerSessionPool } from './sessions'; @@ -789,7 +789,7 @@ export class MongoClient extends TypedEventEmitter implements // to avoid the server selection timeout. const selector = readPreferenceServerSelector(ReadPreference.primaryPreferred); const serverDescriptions = Array.from(topologyDescription.servers.values()); - const servers = selector(topologyDescription, serverDescriptions); + const servers = selector(topologyDescription, serverDescriptions, new DeprioritizedServers()); if (servers.length !== 0) { const endSessions = Array.from(client.s.sessionPool.sessions, ({ id }) => id); if (endSessions.length !== 0) { diff --git a/src/operations/execute_operation.ts b/src/operations/execute_operation.ts index d833623d148..b6ddbba2b66 100644 --- a/src/operations/execute_operation.ts +++ b/src/operations/execute_operation.ts @@ -17,8 +17,8 @@ import { } from '../error'; import type { MongoClient } from '../mongo_client'; import { ReadPreference } from '../read_preference'; -import type { ServerDescription } from '../sdam/server_description'; import { + DeprioritizedServers, sameServerSelector, secondaryWritableServerSelector, type ServerSelector @@ -207,7 +207,8 @@ async function tryOperation ServerDescription[]; +/** @internal */ +export class DeprioritizedServers { + private deprioritized: Set = new Set(); + + constructor(descriptions?: Iterable) { + for (const description of descriptions ?? []) { + this.add(description); + } + } + + add({ address }: ServerDescription) { + this.deprioritized.add(address); + } + + has({ address }: ServerDescription): boolean { + return this.deprioritized.has(address); + } +} + +function filterDeprioritized( + candidates: ServerDescription[], + deprioritized: DeprioritizedServers +): ServerDescription[] { + const filtered = candidates.filter(candidate => !deprioritized.has(candidate)); + + return filtered.length ? filtered : candidates; +} + /** * Returns a server selector that selects for writable servers */ export function writableServerSelector(): ServerSelector { return function writableServer( topologyDescription: TopologyDescription, - servers: ServerDescription[] + servers: ServerDescription[], + deprioritized: DeprioritizedServers ): ServerDescription[] { - return latencyWindowReducer( - topologyDescription, - servers.filter((s: ServerDescription) => s.isWritable) + const eligibleServers = filterDeprioritized( + servers.filter(({ isWritable }) => isWritable), + deprioritized ); + + return latencyWindowReducer(topologyDescription, eligibleServers); }; } @@ -39,8 +70,9 @@ export function writableServerSelector(): ServerSelector { */ export function sameServerSelector(description?: ServerDescription): ServerSelector { return function sameServerSelector( - topologyDescription: TopologyDescription, - servers: ServerDescription[] + _topologyDescription: TopologyDescription, + servers: ServerDescription[], + _deprioritized: DeprioritizedServers ): ServerDescription[] { if (!description) return []; // Filter the servers to match the provided description only if @@ -113,7 +145,7 @@ function maxStalenessReducer( primaryFilter )[0]; - return servers.reduce((result: ServerDescription[], server: ServerDescription) => { + return servers.filter((server: ServerDescription) => { const stalenessMS = server.lastUpdateTime - server.lastWriteDate - @@ -122,12 +154,8 @@ function maxStalenessReducer( const staleness = stalenessMS / 1000; const maxStalenessSeconds = readPreference.maxStalenessSeconds ?? 0; - if (staleness <= maxStalenessSeconds) { - result.push(server); - } - - return result; - }, []); + return staleness <= maxStalenessSeconds; + }); } if (topologyDescription.type === TopologyType.ReplicaSetNoPrimary) { @@ -139,40 +167,38 @@ function maxStalenessReducer( s.lastWriteDate > max.lastWriteDate ? s : max ); - return servers.reduce((result: ServerDescription[], server: ServerDescription) => { + return servers.filter((server: ServerDescription) => { const stalenessMS = sMax.lastWriteDate - server.lastWriteDate + topologyDescription.heartbeatFrequencyMS; const staleness = stalenessMS / 1000; const maxStalenessSeconds = readPreference.maxStalenessSeconds ?? 0; - if (staleness <= maxStalenessSeconds) { - result.push(server); - } - - return result; - }, []); + return staleness <= maxStalenessSeconds; + }); } return servers; } /** - * Determines whether a server's tags match a given set of tags + * Determines whether a server's tags match a given set of tags. + * + * A tagset matches the server's tags if every k-v pair in the tagset + * is also in the server's tagset. + * + * Note that this does not requires that every k-v pair in the server's tagset is also + * in the client's tagset. The server's tagset is required only to be a superset of the + * client's tags. + * + * @see https://github.com/mongodb/specifications/blob/master/source/server-selection/server-selection.md#tag_sets * * @param tagSet - The requested tag set to match * @param serverTags - The server's tags */ function tagSetMatch(tagSet: TagSet, serverTags: TagSet) { - const keys = Object.keys(tagSet); - const serverTagKeys = Object.keys(serverTags); - for (let i = 0; i < keys.length; ++i) { - const key = keys[i]; - if (serverTagKeys.indexOf(key) === -1 || serverTags[key] !== tagSet[key]) { - return false; - } - } - - return true; + return Object.entries(tagSet).every( + ([key, value]) => serverTags[key] != null && serverTags[key] === value + ); } /** @@ -183,24 +209,17 @@ function tagSetMatch(tagSet: TagSet, serverTags: TagSet) { * @returns The list of servers matching the requested tags */ function tagSetReducer( - readPreference: ReadPreference, + { tags }: ReadPreference, servers: ServerDescription[] ): ServerDescription[] { - if ( - readPreference.tags == null || - (Array.isArray(readPreference.tags) && readPreference.tags.length === 0) - ) { + if (tags == null || tags.length === 0) { + // empty tag sets match all servers return servers; } - for (let i = 0; i < readPreference.tags.length; ++i) { - const tagSet = readPreference.tags[i]; - const serversMatchingTagset = servers.reduce( - (matched: ServerDescription[], server: ServerDescription) => { - if (tagSetMatch(tagSet, server.tags)) matched.push(server); - return matched; - }, - [] + for (const tagSet of tags) { + const serversMatchingTagset = servers.filter((s: ServerDescription) => + tagSetMatch(tagSet, s.tags) ); if (serversMatchingTagset.length) { @@ -231,10 +250,7 @@ function latencyWindowReducer( ); const high = low + topologyDescription.localThresholdMS; - return servers.reduce((result: ServerDescription[], server: ServerDescription) => { - if (server.roundTripTime <= high && server.roundTripTime >= low) result.push(server); - return result; - }, []); + return servers.filter(server => server.roundTripTime <= high && server.roundTripTime >= low); } // filters @@ -258,6 +274,107 @@ function loadBalancerFilter(server: ServerDescription): boolean { return server.type === ServerType.LoadBalancer; } +function isDeprioritizedFactory( + deprioritized: DeprioritizedServers +): (server: ServerDescription) => boolean { + return server => + // if any deprioritized servers equal the server, here we are. + !deprioritized.has(server); +} + +function secondarySelector( + readPreference: ReadPreference, + topologyDescription: TopologyDescription, + servers: ServerDescription[], + deprioritized: DeprioritizedServers +) { + const mode = readPreference.mode; + switch (mode) { + case 'primary': + // Note: no need to filter for deprioritized servers. A replica set has only one primary; that means that + // we are in one of two scenarios: + // 1. deprioritized servers is empty - return the primary. + // 2. deprioritized servers contains the primary - return the primary. + return servers.filter(primaryFilter); + case 'primaryPreferred': { + const primary = servers.filter(primaryFilter); + + // If there is a primary and it is not deprioritized, use the primary. Otherwise, + // check for secondaries. + const eligiblePrimary = primary.filter(isDeprioritizedFactory(deprioritized)); + if (eligiblePrimary.length) { + return eligiblePrimary; + } + + // If we make it here, we either have: + // 1. a deprioritized primary + // 2. no eligible primary + // secondaries take precedence of deprioritized primaries. + const secondaries = tagSetReducer( + readPreference, + maxStalenessReducer(readPreference, topologyDescription, servers.filter(secondaryFilter)) + ); + + const eligibleSecondaries = secondaries.filter(isDeprioritizedFactory(deprioritized)); + if (eligibleSecondaries.length) { + return latencyWindowReducer(topologyDescription, eligibleSecondaries); + } + + // if we make it here, we have no primaries or secondaries that not deprioritized. + // prefer the primary (which may not exist, if the topology has no primary). + // otherwise, return the secondaries (which also may not exist, but there is nothing else to check here). + return primary.length ? primary : latencyWindowReducer(topologyDescription, secondaries); + } + case 'nearest': { + const eligible = filterDeprioritized( + tagSetReducer( + readPreference, + maxStalenessReducer(readPreference, topologyDescription, servers.filter(nearestFilter)) + ), + deprioritized + ); + return latencyWindowReducer(topologyDescription, eligible); + } + case 'secondary': + case 'secondaryPreferred': { + const secondaries = tagSetReducer( + readPreference, + maxStalenessReducer(readPreference, topologyDescription, servers.filter(secondaryFilter)) + ); + const eligibleSecondaries = secondaries.filter(isDeprioritizedFactory(deprioritized)); + + if (eligibleSecondaries.length) { + return latencyWindowReducer(topologyDescription, eligibleSecondaries); + } + + // we have no eligible secondaries, try for a primary if we can. + if (mode === ReadPreference.SECONDARY_PREFERRED) { + const primary = servers.filter(primaryFilter); + + // unlike readPreference=primary, here we do filter for deprioritized servers. + // if the primary is deprioritized, deprioritized secondaries take precedence. + const eligiblePrimary = primary.filter(isDeprioritizedFactory(deprioritized)); + if (eligiblePrimary.length) return eligiblePrimary; + + // we have no eligible primary nor secondaries that have not been deprioritized + return secondaries.length + ? latencyWindowReducer(topologyDescription, secondaries) + : primary; + } + + // return all secondaries in the latency window. + return latencyWindowReducer(topologyDescription, secondaries); + } + + default: { + const _exhaustiveCheck: never = mode; + throw new MongoRuntimeError( + `unexpected readPreference=${mode} (should never happen). Please report a bug in the Node driver Jira project.` + ); + } + } +} + /** * Returns a function which selects servers based on a provided read preference * @@ -271,53 +388,28 @@ export function readPreferenceServerSelector(readPreference: ReadPreference): Se return function readPreferenceServers( topologyDescription: TopologyDescription, servers: ServerDescription[], - deprioritized: ServerDescription[] = [] + deprioritized: DeprioritizedServers ): ServerDescription[] { - if (topologyDescription.type === TopologyType.LoadBalanced) { - return servers.filter(loadBalancerFilter); - } - - if (topologyDescription.type === TopologyType.Unknown) { - return []; - } - - if (topologyDescription.type === TopologyType.Single) { - return latencyWindowReducer(topologyDescription, servers.filter(knownFilter)); - } - - if (topologyDescription.type === TopologyType.Sharded) { - const filtered = servers.filter(server => { - return !deprioritized.includes(server); - }); - const selectable = filtered.length > 0 ? filtered : deprioritized; - return latencyWindowReducer(topologyDescription, selectable.filter(knownFilter)); - } - - const mode = readPreference.mode; - if (mode === ReadPreference.PRIMARY) { - return servers.filter(primaryFilter); - } - - if (mode === ReadPreference.PRIMARY_PREFERRED) { - const result = servers.filter(primaryFilter); - if (result.length) { - return result; + switch (topologyDescription.type) { + case 'Single': + return latencyWindowReducer(topologyDescription, servers.filter(knownFilter)); + case 'ReplicaSetNoPrimary': + case 'ReplicaSetWithPrimary': + return secondarySelector(readPreference, topologyDescription, servers, deprioritized); + case 'Sharded': { + const selectable = filterDeprioritized(servers, deprioritized); + return latencyWindowReducer(topologyDescription, selectable.filter(knownFilter)); + } + case 'Unknown': + return []; + case 'LoadBalanced': + return servers.filter(loadBalancerFilter); + default: { + const _exhaustiveCheck: never = topologyDescription.type; + throw new MongoRuntimeError( + `unexpected topology type: ${topologyDescription.type} (this should never happen). Please file a bug in the Node driver Jira project.` + ); } } - - const filter = mode === ReadPreference.NEAREST ? nearestFilter : secondaryFilter; - const selectedServers = latencyWindowReducer( - topologyDescription, - tagSetReducer( - readPreference, - maxStalenessReducer(readPreference, topologyDescription, servers.filter(filter)) - ) - ); - - if (mode === ReadPreference.SECONDARY_PREFERRED && selectedServers.length === 0) { - return servers.filter(primaryFilter); - } - - return selectedServers; }; } diff --git a/src/sdam/topology.ts b/src/sdam/topology.ts index eba356b020e..8cbe8357dce 100644 --- a/src/sdam/topology.ts +++ b/src/sdam/topology.ts @@ -70,7 +70,11 @@ import { import type { ServerMonitoringMode } from './monitor'; import { Server, type ServerEvents, type ServerOptions } from './server'; import { compareTopologyVersion, ServerDescription } from './server_description'; -import { readPreferenceServerSelector, type ServerSelector } from './server_selection'; +import { + DeprioritizedServers, + readPreferenceServerSelector, + type ServerSelector +} from './server_selection'; import { ServerSelectionFailedEvent, ServerSelectionStartedEvent, @@ -105,7 +109,7 @@ export interface ServerSelectionRequest { cancelled: boolean; operationName: string; waitingLogged: boolean; - previousServer?: ServerDescription; + deprioritizedServers: DeprioritizedServers; } /** @internal */ @@ -169,7 +173,9 @@ export interface SelectServerOptions { serverSelectionTimeoutMS?: number; session?: ClientSession; operationName: string; - previousServer?: ServerDescription; + + /** @internal */ + deprioritizedServers: DeprioritizedServers; /** * @internal * TODO(NODE-6496): Make this required by making ChangeStream use LegacyTimeoutContext @@ -455,7 +461,8 @@ export class Topology extends TypedEventEmitter { const selectServerOptions = { operationName: 'handshake', ...options, - timeoutContext + timeoutContext, + deprioritizedServers: new DeprioritizedServers() }; try { @@ -605,7 +612,7 @@ export class Topology extends TypedEventEmitter { startTime: processTimeMS(), operationName: options.operationName, waitingLogged: false, - previousServer: options.previousServer + deprioritizedServers: options.deprioritizedServers }; const abortListener = addAbortListener(options.signal, function () { @@ -957,13 +964,9 @@ function processWaitQueue(topology: Topology) { let selectedDescriptions; try { const serverSelector = waitQueueMember.serverSelector; - const previousServer = waitQueueMember.previousServer; + const deprioritizedServers = waitQueueMember.deprioritizedServers; selectedDescriptions = serverSelector - ? serverSelector( - topology.description, - serverDescriptions, - previousServer ? [previousServer] : [] - ) + ? serverSelector(topology.description, serverDescriptions, deprioritizedServers) : serverDescriptions; } catch (selectorError) { if ( diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedNearest.json b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedNearest.json new file mode 100644 index 00000000000..464e542c542 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedNearest.json @@ -0,0 +1,63 @@ +{ + "topology_description": { + "type": "ReplicaSetNoPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Nearest", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} + diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedNearest.yml b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedNearest.yml new file mode 100644 index 00000000000..9297b98a32f --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedNearest.yml @@ -0,0 +1,26 @@ +topology_description: + type: ReplicaSetNoPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc +operation: read +read_preference: + mode: Nearest + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimary.json b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimary.json new file mode 100644 index 00000000000..4726045de80 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimary.json @@ -0,0 +1,40 @@ +{ + "topology_description": { + "type": "ReplicaSetNoPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Primary" + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [], + "in_latency_window": [] +} + diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimary.yml b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimary.yml new file mode 100644 index 00000000000..6d29358f3c2 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimary.yml @@ -0,0 +1,22 @@ +topology_description: + type: ReplicaSetNoPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc +operation: read +read_preference: + mode: Primary +deprioritized_servers: +- *1 +suitable_servers: [] +in_latency_window: [] diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimaryPreferred.json new file mode 100644 index 00000000000..ef9444e5952 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimaryPreferred.json @@ -0,0 +1,63 @@ +{ + "topology_description": { + "type": "ReplicaSetNoPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "PrimaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} + diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimaryPreferred.yml new file mode 100644 index 00000000000..cb08766a3d0 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedPrimaryPreferred.yml @@ -0,0 +1,26 @@ +topology_description: + type: ReplicaSetNoPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc +operation: read +read_preference: + mode: PrimaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondary.json b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondary.json new file mode 100644 index 00000000000..fbd5456ad6d --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondary.json @@ -0,0 +1,63 @@ +{ + "topology_description": { + "type": "ReplicaSetNoPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Secondary", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} + diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondary.yml b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondary.yml new file mode 100644 index 00000000000..08ca00c0ab0 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondary.yml @@ -0,0 +1,26 @@ +topology_description: + type: ReplicaSetNoPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc +operation: read +read_preference: + mode: Secondary + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondaryPreferred.json new file mode 100644 index 00000000000..d8d92261e1b --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondaryPreferred.json @@ -0,0 +1,63 @@ +{ + "topology_description": { + "type": "ReplicaSetNoPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} + diff --git a/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondaryPreferred.yml new file mode 100644 index 00000000000..0ae92459ae6 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetNoPrimary/read/DeprioritizedSecondaryPreferred.yml @@ -0,0 +1,26 @@ +topology_description: + type: ReplicaSetNoPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc +operation: read +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllPrimaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllPrimaryPreferred.json new file mode 100644 index 00000000000..095537ba1a5 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllPrimaryPreferred.json @@ -0,0 +1,84 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "PrimaryPreferred", + "tag_sets": [ + {} + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllPrimaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllPrimaryPreferred.yml new file mode 100644 index 00000000000..f63605889ef --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllPrimaryPreferred.yml @@ -0,0 +1,34 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 5 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: PrimaryPreferred + tag_sets: + - {} +deprioritized_servers: +- *1 +- *2 +- *3 +suitable_servers: +- *3 +in_latency_window: +- *3 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllSecondaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllSecondaryPreferred.json new file mode 100644 index 00000000000..b29ba2bc800 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllSecondaryPreferred.json @@ -0,0 +1,100 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + {} + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllSecondaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllSecondaryPreferred.yml new file mode 100644 index 00000000000..37e9e055ca2 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedAllSecondaryPreferred.yml @@ -0,0 +1,36 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 5 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: SecondaryPreferred + tag_sets: + - {} +deprioritized_servers: +- *1 +- *2 +- *3 +suitable_servers: +- *1 +- *2 +in_latency_window: +- *1 +- *2 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedNearest.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedNearest.json new file mode 100644 index 00000000000..5b9d0fa538d --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedNearest.json @@ -0,0 +1,78 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Nearest", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedNearest.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedNearest.yml new file mode 100644 index 00000000000..3dcb9bffdc5 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedNearest.yml @@ -0,0 +1,33 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 26 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: Nearest + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *3 +- *2 +in_latency_window: +- *3 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimary.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimary.json new file mode 100644 index 00000000000..a1ef5b200fe --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimary.json @@ -0,0 +1,65 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Primary" + }, + "deprioritized_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimary.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimary.yml new file mode 100644 index 00000000000..a4c09ba3d49 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimary.yml @@ -0,0 +1,30 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 5 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: Primary +deprioritized_servers: +- *3 +suitable_servers: +- *3 +in_latency_window: +- *3 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimaryPreferred.json new file mode 100644 index 00000000000..367d19e66d1 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimaryPreferred.json @@ -0,0 +1,84 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "PrimaryPreferred", + "tag_sets": [ + {} + ] + }, + "deprioritized_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimaryPreferred.yml new file mode 100644 index 00000000000..83551a51bbf --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedPrimaryPreferred.yml @@ -0,0 +1,34 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 5 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: PrimaryPreferred + tag_sets: + - {} +deprioritized_servers: +- *3 +suitable_servers: +- *1 +- *2 +in_latency_window: +- *1 +- *2 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondary.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondary.json new file mode 100644 index 00000000000..32080807a1a --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondary.json @@ -0,0 +1,86 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Secondary", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondary.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondary.yml new file mode 100644 index 00000000000..cfcedf3a579 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondary.yml @@ -0,0 +1,34 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 26 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: Secondary + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +- *2 +suitable_servers: +- *1 +- *2 +in_latency_window: +- *1 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondaryPreferred.json new file mode 100644 index 00000000000..1fd6c654f06 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondaryPreferred.json @@ -0,0 +1,78 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondaryPreferred.yml new file mode 100644 index 00000000000..1db29405f95 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/read/DeprioritizedSecondaryPreferred.yml @@ -0,0 +1,33 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - &1 + address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - &2 + address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc + - &3 + address: a:27017 + avg_rtt_ms: 5 + type: RSPrimary + tags: + data_center: nyc +operation: read +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +- *2 +suitable_servers: +- *3 +in_latency_window: +- *3 diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/write/DeprioritizedSecondaryPreferred.json b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/write/DeprioritizedSecondaryPreferred.json new file mode 100644 index 00000000000..0f3642aa209 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/write/DeprioritizedSecondaryPreferred.json @@ -0,0 +1,70 @@ +{ + "topology_description": { + "type": "ReplicaSetWithPrimary", + "servers": [ + { + "address": "b:27017", + "avg_rtt_ms": 5, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "c:27017", + "avg_rtt_ms": 100, + "type": "RSSecondary", + "tags": { + "data_center": "nyc" + } + }, + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 26, + "type": "RSPrimary", + "tags": { + "data_center": "nyc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/write/DeprioritizedSecondaryPreferred.yml b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/write/DeprioritizedSecondaryPreferred.yml new file mode 100644 index 00000000000..cb0d7acbb33 --- /dev/null +++ b/test/spec/server-selection/server_selection/ReplicaSetWithPrimary/write/DeprioritizedSecondaryPreferred.yml @@ -0,0 +1,30 @@ +topology_description: + type: ReplicaSetWithPrimary + servers: + - address: b:27017 + avg_rtt_ms: 5 + type: RSSecondary + tags: + data_center: nyc + - address: c:27017 + avg_rtt_ms: 100 + type: RSSecondary + tags: + data_center: nyc + - &1 + address: a:27017 + avg_rtt_ms: 26 + type: RSPrimary + tags: + data_center: nyc +operation: write +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *3 +in_latency_window: +- *3 diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedNearest.json b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedNearest.json new file mode 100644 index 00000000000..1aa730cd21d --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedNearest.json @@ -0,0 +1,47 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 10, + "type": "Mongos" + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Nearest", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 10, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 10, + "type": "Mongos" + } + ] +} diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedNearest.yml b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedNearest.yml new file mode 100644 index 00000000000..27fd8fc6934 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedNearest.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 10 + type: Mongos +operation: read +read_preference: + mode: Nearest + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimary.json b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimary.json new file mode 100644 index 00000000000..0017e28a467 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimary.json @@ -0,0 +1,43 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Primary" + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimary.yml b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimary.yml new file mode 100644 index 00000000000..a7bfee07d82 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimary.yml @@ -0,0 +1,20 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: read +read_preference: + mode: Primary +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimaryPreferred.json b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimaryPreferred.json new file mode 100644 index 00000000000..7540492b4d1 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimaryPreferred.json @@ -0,0 +1,48 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "PrimaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimaryPreferred.yml b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimaryPreferred.yml new file mode 100644 index 00000000000..3452acdeff9 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedPrimaryPreferred.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: read +read_preference: + mode: PrimaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondary.json b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondary.json new file mode 100644 index 00000000000..a476695d06b --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondary.json @@ -0,0 +1,48 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "Secondary", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondary.yml b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondary.yml new file mode 100644 index 00000000000..5db76672384 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondary.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: read +read_preference: + mode: Secondary + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondaryPreferred.json b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondaryPreferred.json new file mode 100644 index 00000000000..effca47d2df --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondaryPreferred.json @@ -0,0 +1,48 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondaryPreferred.yml b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondaryPreferred.yml new file mode 100644 index 00000000000..a07e44b55ff --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/read/DeprioritizedSecondaryPreferred.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: read +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedNearest.json b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedNearest.json new file mode 100644 index 00000000000..5cc2cc5477d --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedNearest.json @@ -0,0 +1,47 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 10, + "type": "Mongos" + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "Nearest", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 10, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 10, + "type": "Mongos" + } + ] +} diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedNearest.yml b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedNearest.yml new file mode 100644 index 00000000000..af8ca190d6d --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedNearest.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 10 + type: Mongos +operation: write +read_preference: + mode: Nearest + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimary.json b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimary.json new file mode 100644 index 00000000000..faae97e51f8 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimary.json @@ -0,0 +1,43 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "Primary" + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimary.yml b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimary.yml new file mode 100644 index 00000000000..7fc405c3f2f --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimary.yml @@ -0,0 +1,20 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: write +read_preference: + mode: Primary +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimaryPreferred.json b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimaryPreferred.json new file mode 100644 index 00000000000..37546302462 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimaryPreferred.json @@ -0,0 +1,48 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "PrimaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimaryPreferred.yml b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimaryPreferred.yml new file mode 100644 index 00000000000..cf2359cc449 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedPrimaryPreferred.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: write +read_preference: + mode: PrimaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondary.json b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondary.json new file mode 100644 index 00000000000..905c8df90a6 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondary.json @@ -0,0 +1,48 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "Secondary", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondary.yml b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondary.yml new file mode 100644 index 00000000000..06888b0bb7a --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondary.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: write +read_preference: + mode: Secondary + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondaryPreferred.json b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondaryPreferred.json new file mode 100644 index 00000000000..47e55ca20de --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondaryPreferred.json @@ -0,0 +1,48 @@ +{ + "topology_description": { + "type": "Sharded", + "servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + }, + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "g:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "suitable_servers": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ], + "in_latency_window": [ + { + "address": "h:27017", + "avg_rtt_ms": 5, + "type": "Mongos" + } + ] +} + diff --git a/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondaryPreferred.yml b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondaryPreferred.yml new file mode 100644 index 00000000000..8c1abf2cec0 --- /dev/null +++ b/test/spec/server-selection/server_selection/Sharded/write/DeprioritizedSecondaryPreferred.yml @@ -0,0 +1,22 @@ +topology_description: + type: Sharded + servers: + - &1 + address: g:27017 + avg_rtt_ms: 5 + type: Mongos + - &2 + address: h:27017 + avg_rtt_ms: 5 + type: Mongos +operation: write +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *2 +in_latency_window: +- *2 diff --git a/test/spec/server-selection/server_selection/Single/read/Deprioritized.json b/test/spec/server-selection/server_selection/Single/read/Deprioritized.json new file mode 100644 index 00000000000..c76fc6c7719 --- /dev/null +++ b/test/spec/server-selection/server_selection/Single/read/Deprioritized.json @@ -0,0 +1,54 @@ +{ + "topology_description": { + "type": "Single", + "servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ] + }, + "operation": "read", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/Single/read/Deprioritized.yml b/test/spec/server-selection/server_selection/Single/read/Deprioritized.yml new file mode 100644 index 00000000000..463a7a55354 --- /dev/null +++ b/test/spec/server-selection/server_selection/Single/read/Deprioritized.yml @@ -0,0 +1,20 @@ +topology_description: + type: Single + servers: + - &1 + address: a:27017 + avg_rtt_ms: 5 + type: Standalone + tags: + data_center: dc +operation: read +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *1 +in_latency_window: +- *1 diff --git a/test/spec/server-selection/server_selection/Single/write/Deprioritized.json b/test/spec/server-selection/server_selection/Single/write/Deprioritized.json new file mode 100644 index 00000000000..099076f2da8 --- /dev/null +++ b/test/spec/server-selection/server_selection/Single/write/Deprioritized.json @@ -0,0 +1,54 @@ +{ + "topology_description": { + "type": "Single", + "servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ] + }, + "operation": "write", + "read_preference": { + "mode": "SecondaryPreferred", + "tag_sets": [ + { + "data_center": "nyc" + } + ] + }, + "deprioritized_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ], + "suitable_servers": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ], + "in_latency_window": [ + { + "address": "a:27017", + "avg_rtt_ms": 5, + "type": "Standalone", + "tags": { + "data_center": "dc" + } + } + ] +} diff --git a/test/spec/server-selection/server_selection/Single/write/Deprioritized.yml b/test/spec/server-selection/server_selection/Single/write/Deprioritized.yml new file mode 100644 index 00000000000..08780151c97 --- /dev/null +++ b/test/spec/server-selection/server_selection/Single/write/Deprioritized.yml @@ -0,0 +1,20 @@ +topology_description: + type: Single + servers: + - &1 + address: a:27017 + avg_rtt_ms: 5 + type: Standalone + tags: + data_center: dc +operation: write +read_preference: + mode: SecondaryPreferred + tag_sets: + - data_center: nyc +deprioritized_servers: +- *1 +suitable_servers: +- *1 +in_latency_window: +- *1 diff --git a/test/tools/utils.ts b/test/tools/utils.ts index d092fe2eca6..47d92411c88 100644 --- a/test/tools/utils.ts +++ b/test/tools/utils.ts @@ -285,7 +285,12 @@ export function topologyWithPlaceholderClient( options: Partial ): Topology { return new Topology( - new MongoClient('mongodb://iLoveJavaScript'), + new MongoClient( + 'mongodb://iLoveJavaScript', + options.serverSelectionTimeoutMS + ? { serverSelectionTimeoutMS: options.serverSelectionTimeoutMS } + : {} + ), seeds, options as TopologyOptions ); diff --git a/test/unit/assorted/server_selection_latency_window_utils.ts b/test/unit/assorted/server_selection_latency_window_utils.ts index da4e8463569..2b6a38392f9 100644 --- a/test/unit/assorted/server_selection_latency_window_utils.ts +++ b/test/unit/assorted/server_selection_latency_window_utils.ts @@ -6,6 +6,7 @@ import { join } from 'path'; import { ReadPreference } from '../../../src/read_preference'; import { type ServerType, STATE_CONNECTED, type TopologyType } from '../../../src/sdam/common'; import { type Server } from '../../../src/sdam/server'; +import { DeprioritizedServers } from '../../../src/sdam/server_selection'; import { type Topology } from '../../../src/sdam/topology'; import { topologyWithPlaceholderClient } from '../../tools/utils'; import { serverDescriptionFromDefinition } from './server_selection_spec_helper'; @@ -134,7 +135,10 @@ export async function runServerSelectionLatencyWindowTest(test: ServerSelectionL const selectedServers: Server[] = []; for (let i = 0; i < test.iterations; ++i) { - const server: Server = await topology.selectServer(ReadPreference.NEAREST, {}); + const server: Server = await topology.selectServer(ReadPreference.NEAREST, { + deprioritizedServers: new DeprioritizedServers(), + operationName: 'test operation' + }); selectedServers.push(server); } diff --git a/test/unit/assorted/server_selection_logic_spec_utils.ts b/test/unit/assorted/server_selection_logic_spec_utils.ts index 62a31fba189..685da3a1102 100644 --- a/test/unit/assorted/server_selection_logic_spec_utils.ts +++ b/test/unit/assorted/server_selection_logic_spec_utils.ts @@ -11,7 +11,9 @@ import { import { type ServerType, type TopologyType } from '../../../src/sdam/common'; import { type ServerDescription, type TagSet } from '../../../src/sdam/server_description'; import { + DeprioritizedServers, readPreferenceServerSelector, + type ServerSelector, writableServerSelector } from '../../../src/sdam/server_selection'; import { TopologyDescription } from '../../../src/sdam/topology_description'; @@ -41,6 +43,7 @@ interface ServerSelectionLogicTest { */ suitable_servers: never; in_latency_window: ServerSelectionLogicTestServer[]; + deprioritized_servers?: ServerSelectionLogicTestServer[]; } function readPreferenceFromDefinition(definition) { @@ -96,8 +99,11 @@ export function runServerSelectionLogicTest(testDefinition: ServerSelectionLogic const expectedServers = serverDescriptionsToMap( testDefinition.in_latency_window.map(s => serverDescriptionFromDefinition(s)) ); + const deprioritized = new DeprioritizedServers( + testDefinition.deprioritized_servers?.map(s => serverDescriptionFromDefinition(s, allHosts)) + ); - let selector; + let selector: ServerSelector; if (testDefinition.operation === 'write') { selector = writableServerSelector(); } else if (testDefinition.operation === 'read' || testDefinition.read_preference) { @@ -107,10 +113,11 @@ export function runServerSelectionLogicTest(testDefinition: ServerSelectionLogic expect.fail('test operation was neither read nor write, and no read preference was provided.'); } - const result = selector(topologyDescription, serversInTopology); + const result = selector(topologyDescription, serversInTopology, deprioritized); expect(result.length).to.equal(expectedServers.size); + // console.error({ result, expectedServers }); for (const server of result) { const expectedServer = expectedServers.get(server.address); expect(expectedServer).to.exist; diff --git a/test/unit/assorted/server_selection_spec_helper.js b/test/unit/assorted/server_selection_spec_helper.js index a110ae3d117..ea294df6d57 100644 --- a/test/unit/assorted/server_selection_spec_helper.js +++ b/test/unit/assorted/server_selection_spec_helper.js @@ -137,7 +137,11 @@ export async function executeServerSelectionTest(testDefinition) { // default to serverSelectionTimeoutMS of `100` for unit tests try { - const server = await topology.selectServer(selector, { serverSelectionTimeoutMS: 50 }); + const server = await topology.selectServer(selector, { + serverSelectionTimeoutMS: 50, + deprioritizedServers: new ServerSelectors.DeprioritizedServers(), + operationName: 'test operation' + }); if (testDefinition.error) throw new Error('Expected an error, but found none!'); if (expectedServers.length === 0 && server !== null) { diff --git a/test/unit/error.test.ts b/test/unit/error.test.ts index 34428b0666f..c860d142775 100644 --- a/test/unit/error.test.ts +++ b/test/unit/error.test.ts @@ -34,6 +34,7 @@ import { type TopologyOptions } from '../../src/index'; import { RunCommandOperation } from '../../src/operations/run_command'; +import { DeprioritizedServers } from '../../src/sdam/server_selection'; import { type Topology } from '../../src/sdam/topology'; import { TimeoutContext } from '../../src/timeout'; import { isHello, ns, setDifference } from '../../src/utils'; @@ -383,7 +384,13 @@ describe('MongoErrors', () => { ); return replSet .connect() - .then(topology => topology.selectServer('primary', { timeoutContext })) + .then(topology => + topology.selectServer('primary', { + timeoutContext, + deprioritizedServers: new DeprioritizedServers(), + operationName: 'test operation' + }) + ) .then(server => server.command(op, timeoutContext)) .then( () => expect.fail('expected command to fail'), @@ -426,7 +433,11 @@ describe('MongoErrors', () => { Object.assign({}, RAW_USER_WRITE_CONCERN_CMD), {} ); - const server = await topology.selectServer('primary', { timeoutContext }); + const server = await topology.selectServer('primary', { + timeoutContext, + deprioritizedServers: new DeprioritizedServers(), + operationName: 'test operation' + }); try { await server.command(op, timeoutContext); } catch (err) { diff --git a/test/unit/sdam/server_selection.test.ts b/test/unit/sdam/server_selection.test.ts index 4c0a45985de..f911ae34186 100644 --- a/test/unit/sdam/server_selection.test.ts +++ b/test/unit/sdam/server_selection.test.ts @@ -7,8 +7,8 @@ import { ReadPreference } from '../../../src/read_preference'; import { TopologyType } from '../../../src/sdam/common'; import { ServerDescription } from '../../../src/sdam/server_description'; import { + DeprioritizedServers, MIN_SECONDARY_WRITE_WIRE_VERSION, - readPreferenceServerSelector, sameServerSelector, secondaryWritableServerSelector } from '../../../src/sdam/server_selection'; @@ -28,19 +28,10 @@ describe('server selection', function () { secondary: true, ok: 1 }); - const secondaryTwo = new ServerDescription('127.0.0.1:27024', { - setName: 'test', - secondary: true, - ok: 1 - }); const mongos = new ServerDescription('127.0.0.1:27019', { msg: 'isdbgrid', ok: 1 }); - const mongosTwo = new ServerDescription('127.0.0.1:27023', { - msg: 'isdbgrid', - ok: 1 - }); const loadBalancer = new ServerDescription('127.0.0.1:27020', { ok: 1 }, { loadBalanced: true }); const single = new ServerDescription('127.0.0.1:27021', { isWritablePrimary: true, @@ -50,93 +41,6 @@ describe('server selection', function () { ok: 0 }); - describe('#readPreferenceServerSelector', function () { - let selector; - let servers; - - context('when the topology is sharded', function () { - const topologyDescription = new TopologyDescription( - TopologyType.Sharded, - new Map(), - 'test', - MIN_SECONDARY_WRITE_WIRE_VERSION, - new ObjectId(), - MIN_SECONDARY_WRITE_WIRE_VERSION - ); - - beforeEach(function () { - selector = readPreferenceServerSelector(ReadPreference.secondaryPreferred); - }); - - context('when there are deprioritized servers', function () { - context('when there are other servers', function () { - beforeEach(function () { - servers = selector(topologyDescription, [mongos], [mongosTwo]); - }); - - it('returns a server from the other servers', function () { - expect(servers).to.deep.equal([mongos]); - }); - }); - - context('when there are no other servers', function () { - beforeEach(function () { - servers = selector(topologyDescription, [], [mongosTwo]); - }); - - it('returns a server from the deprioritized servers', function () { - expect(servers).to.deep.equal([mongosTwo]); - }); - }); - }); - - context('when there are no deprioritised servers', function () { - beforeEach(function () { - servers = selector(topologyDescription, [mongos]); - }); - - it('returns a server from the other servers', function () { - expect(servers).to.deep.equal([mongos]); - }); - }); - }); - - context('when the topology is not sharded', function () { - const topologyDescription = new TopologyDescription( - TopologyType.ReplicaSetWithPrimary, - new Map(), - 'test', - MIN_SECONDARY_WRITE_WIRE_VERSION, - new ObjectId(), - MIN_SECONDARY_WRITE_WIRE_VERSION - ); - - beforeEach(function () { - selector = readPreferenceServerSelector(ReadPreference.secondary); - }); - - context('when there are deprioritized servers', function () { - beforeEach(function () { - servers = selector(topologyDescription, [secondaryTwo], [secondary]); - }); - - it('selects from all server lists', function () { - expect(servers).to.contain.oneOf([secondary, secondaryTwo]); - }); - }); - - context('when there are no deprioritised servers', function () { - beforeEach(function () { - servers = selector(topologyDescription, [secondary], []); - }); - - it('selects from all non-deprioritised servers', function () { - expect(servers).to.deep.equal([secondary]); - }); - }); - }); - }); - describe('#sameServerSelector', function () { const topologyDescription = sinon.stub(); const serverDescriptions = new Map(); @@ -211,7 +115,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('uses the provided read preference', function () { expect(servers).to.deep.equal([secondary]); @@ -220,7 +128,11 @@ describe('server selection', function () { context('when a read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a primary', function () { expect(servers).to.deep.equal([primary]); @@ -243,7 +155,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION - 1, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a primary', function () { expect(servers).to.deep.equal([primary]); @@ -252,7 +168,11 @@ describe('server selection', function () { context('when read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION - 1); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a primary', function () { expect(servers).to.deep.equal([primary]); @@ -270,7 +190,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION ); const selector = secondaryWritableServerSelector(undefined, ReadPreference.secondary); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a primary', function () { expect(servers).to.deep.equal([primary]); @@ -297,7 +221,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a mongos', function () { expect(servers).to.deep.equal([mongos]); @@ -306,7 +234,11 @@ describe('server selection', function () { context('when a read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a mongos', function () { expect(servers).to.deep.equal([mongos]); @@ -329,7 +261,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION - 1, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a mongos', function () { expect(servers).to.deep.equal([mongos]); @@ -338,7 +274,11 @@ describe('server selection', function () { context('when read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION - 1); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a mongos', function () { expect(servers).to.deep.equal([mongos]); @@ -356,7 +296,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION ); const selector = secondaryWritableServerSelector(); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a mongos', function () { expect(servers).to.deep.equal([mongos]); @@ -383,7 +327,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a load balancer', function () { expect(servers).to.deep.equal([loadBalancer]); @@ -392,7 +340,11 @@ describe('server selection', function () { context('when a read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a load balancer', function () { expect(servers).to.deep.equal([loadBalancer]); @@ -415,7 +367,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION - 1, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a load balancer', function () { expect(servers).to.deep.equal([loadBalancer]); @@ -424,7 +380,11 @@ describe('server selection', function () { context('when read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION - 1); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a load balancer', function () { expect(servers).to.deep.equal([loadBalancer]); @@ -442,7 +402,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION ); const selector = secondaryWritableServerSelector(); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a load balancer', function () { expect(servers).to.deep.equal([loadBalancer]); @@ -469,7 +433,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a standalone', function () { expect(servers).to.deep.equal([single]); @@ -478,7 +446,11 @@ describe('server selection', function () { context('when a read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a standalone', function () { expect(servers).to.deep.equal([single]); @@ -501,7 +473,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION - 1, ReadPreference.secondary ); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a standalone', function () { expect(servers).to.deep.equal([single]); @@ -510,7 +486,11 @@ describe('server selection', function () { context('when read preference is not provided', function () { const selector = secondaryWritableServerSelector(MIN_SECONDARY_WRITE_WIRE_VERSION - 1); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a standalone', function () { expect(servers).to.deep.equal([single]); @@ -528,7 +508,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION ); const selector = secondaryWritableServerSelector(); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); it('selects a standalone', function () { expect(servers).to.deep.equal([single]); @@ -581,7 +565,11 @@ describe('server selection', function () { MIN_SECONDARY_WRITE_WIRE_VERSION ); const selector = secondaryWritableServerSelector(); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); expect(servers).to.have.lengthOf(2); const selectedAddresses = new Set(servers.map(({ address }) => address)); expect(selectedAddresses.has(serverDescription1.address)).to.be.true; @@ -600,7 +588,11 @@ describe('server selection', function () { { localThresholdMS: 5 } ); const selector = secondaryWritableServerSelector(); - const servers = selector(topologyDescription, Array.from(serverDescriptions.values())); + const servers = selector( + topologyDescription, + Array.from(serverDescriptions.values()), + new DeprioritizedServers() + ); expect(servers).to.have.lengthOf(1); const selectedAddresses = new Set(servers.map(({ address }) => address)); expect(selectedAddresses.has(serverDescription1.address)).to.be.true; diff --git a/test/unit/sdam/topology.test.ts b/test/unit/sdam/topology.test.ts index cf0511a8437..a148aa953a9 100644 --- a/test/unit/sdam/topology.test.ts +++ b/test/unit/sdam/topology.test.ts @@ -446,11 +446,9 @@ describe('Topology (unit)', function () { describe('selectServer()', function () { it('should schedule monitoring if no suitable server is found', async function () { - const topology = topologyWithPlaceholderClient( - 'someserver:27019', - {}, - { serverSelectionTimeoutMS: 10 } - ); + const topology = topologyWithPlaceholderClient('someserver:27019', { + serverSelectionTimeoutMS: 10 + }); const requestCheck = sinon.stub(Server.prototype, 'requestCheck'); sinon.stub(Server.prototype, 'connect').callsFake(function () {