Skip to content

Commit

Permalink
refactor(NODE-3845): update load balancer config (#3089)
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Feb 2, 2022
1 parent c63a21b commit 6970871
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 49 deletions.
6 changes: 4 additions & 2 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ functions:
AUTH=${AUTH} SSL=${SSL} \
ORCHESTRATION_FILE=${ORCHESTRATION_FILE} \
REQUIRE_API_VERSION=${REQUIRE_API_VERSION} \
LOAD_BALANCER=${LOAD_BALANCER} \
bash ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
- command: expansions.update
params:
Expand Down Expand Up @@ -201,7 +202,7 @@ functions:
TOPOLOGY="${TOPOLOGY}" \
SKIP_DEPS=${SKIP_DEPS|1} \
NO_EXIT=${NO_EXIT|1} \
FAKE_MONGODB_SERVICE_ID="true" \
LOAD_BALANCER="${LOAD_BALANCER}" \
bash ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
run checks:
- command: shell.exec
Expand Down Expand Up @@ -972,8 +973,9 @@ tasks:
- func: install dependencies
- func: bootstrap mongo-orchestration
vars:
VERSION: '5.0'
VERSION: latest
TOPOLOGY: sharded_cluster
LOAD_BALANCER: 'true'
- func: start-load-balancer
- func: run-lb-tests
- func: stop-load-balancer
Expand Down
3 changes: 2 additions & 1 deletion .evergreen/config.yml.in
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ functions:
AUTH=${AUTH} SSL=${SSL} \
ORCHESTRATION_FILE=${ORCHESTRATION_FILE} \
REQUIRE_API_VERSION=${REQUIRE_API_VERSION} \
LOAD_BALANCER=${LOAD_BALANCER} \
bash ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
# run-orchestration generates expansion file with the MONGODB_URI for the cluster
- command: expansions.update
Expand Down Expand Up @@ -225,7 +226,7 @@ functions:
TOPOLOGY="${TOPOLOGY}" \
SKIP_DEPS=${SKIP_DEPS|1} \
NO_EXIT=${NO_EXIT|1} \
FAKE_MONGODB_SERVICE_ID="true" \
LOAD_BALANCER="${LOAD_BALANCER}" \
bash ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh

"run checks":
Expand Down
5 changes: 3 additions & 2 deletions .evergreen/generate_evergreen_tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ TASKS.push(
{
func: 'bootstrap mongo-orchestration',
vars: {
VERSION: '5.0',
TOPOLOGY: 'sharded_cluster'
VERSION: 'latest',
TOPOLOGY: 'sharded_cluster',
LOAD_BALANCER: 'true'
}
},
{ func: 'start-load-balancer' },
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ else
. $DRIVERS_TOOLS/.evergreen/csfle/set-temp-creds.sh
fi

SINGLE_MONGOS_LB_URI=${SINGLE_MONGOS_LB_URI} MULTI_MONGOS_LB_URI=${MULTI_MONGOS_LB_URI} MONGODB_API_VERSION=${MONGODB_API_VERSION} MONGODB_UNIFIED_TOPOLOGY=${UNIFIED} MONGODB_URI=${MONGODB_URI} npm run ${TEST_NPM_SCRIPT}
SINGLE_MONGOS_LB_URI=${SINGLE_MONGOS_LB_URI} MULTI_MONGOS_LB_URI=${MULTI_MONGOS_LB_URI} MONGODB_API_VERSION=${MONGODB_API_VERSION} MONGODB_UNIFIED_TOPOLOGY=${UNIFIED} MONGODB_URI=${MONGODB_URI} LOAD_BALANCER=${LOAD_BALANCER} npm run ${TEST_NPM_SCRIPT}
6 changes: 4 additions & 2 deletions global.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import type { TestConfiguration } from './test/tools/unified-spec-runner/runner';

type WithExclusion<T extends string> = `!${T}`
/** Defined in test/tools/runner/filters/mongodb_topology_filter.js (topologyTypeToString) */
type TopologyTypes = 'single' | 'replicaset' | 'sharded' | 'load-balanced';
type TopologyTypeRequirement = WithExclusion<TopologyTypes> | WithExclusion<TopologyTypes>[]

interface MongoDBMetadataUI {
requires?: {
topology?: TopologyTypes | TopologyTypes[];
topology?: TopologyTypeRequirement;
mongodb?: string;
os?: NodeJS.Platform | `!${NodeJS.Platform}`;
apiVersion?: '1';
Expand Down Expand Up @@ -58,7 +60,7 @@ declare global {
* - my test
* - TODO(NODE-XXXX): Feature implementation impending!
* ```
*
*
* You can also skip a set of tests via beforeEach:
* ```
* beforeEach(() => {
Expand Down
8 changes: 0 additions & 8 deletions src/cmap/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ const AUTH_PROVIDERS = new Map<AuthMechanism | string, AuthProvider>([
[AuthMechanism.MONGODB_X509, new X509()]
]);

const FAKE_MONGODB_SERVICE_ID =
typeof process.env.FAKE_MONGODB_SERVICE_ID === 'string' &&
process.env.FAKE_MONGODB_SERVICE_ID.toLowerCase() === 'true';

/** @public */
export type Stream = Socket | TLSSocket;

Expand Down Expand Up @@ -163,10 +159,6 @@ function performInitialHandshake(
}

if (options.loadBalanced) {
// TODO: Durran: Remove when server support exists. (NODE-3431)
if (FAKE_MONGODB_SERVICE_ID) {
response.serviceId = response.topologyVersion.processId;
}
if (!response.serviceId) {
return callback(
new MongoCompatibilityError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Connection', function () {

describe('Connection - functional/cmap', function () {
it('should execute a command against a server', {
metadata: { requires: { apiVersion: false } },
metadata: { requires: { apiVersion: false, topology: '!load-balanced' } },
test: function (done) {
const connectOptions = Object.assign(
{ connectionType: Connection },
Expand All @@ -38,7 +38,7 @@ describe('Connection', function () {
});

it('should emit command monitoring events', {
metadata: { requires: { apiVersion: false } },
metadata: { requires: { apiVersion: false, topology: '!load-balanced' } },
test: function (done) {
const connectOptions = Object.assign(
{ connectionType: Connection, monitorCommands: true },
Expand Down
2 changes: 1 addition & 1 deletion test/integration/node-specific/topology.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { expect } = require('chai');

describe('Topology', function () {
it('should correctly track states of a topology', {
metadata: { requires: { apiVersion: false } }, // apiVersion not supported by newTopology()
metadata: { requires: { apiVersion: false, topology: '!load-balanced' } }, // apiVersion not supported by newTopology()
test: function (done) {
const topology = this.configuration.newTopology();

Expand Down
20 changes: 19 additions & 1 deletion test/tools/runner/filters/mongodb_topology_filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,25 @@ class MongoDBTopologyFilter {
);
}

return topologies.some(topology => topology === this.runtimeTopology);
const isExclusion = topologies[0][0] === '!';
if (isExclusion) {
if (!topologies.every(topology => topology.startsWith('!'))) {
// Not every topology starts with !
throw new Error('Cannot combine inclusion with exclusion of topologies');
}

// Every excluded topology does not equal the current (prefix !)
return topologies.every(topology => topology !== `!${this.runtimeTopology}`);
} else {
// inclusion list
if (topologies.some(topology => topology.startsWith('!'))) {
// Some topologies start with !
throw new Error('Cannot combine exclusion with inclusion of topologies');
}

// At least some (one) of the included topologies equals the current
return topologies.some(topology => topology === this.runtimeTopology);
}
}
}

Expand Down
5 changes: 4 additions & 1 deletion test/tools/runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ before(async function () {
context.multiMongosLoadBalancerUri = MULTI_MONGOS_LB_URI;
}

this.configuration = new TestConfiguration(MONGODB_URI, context);
this.configuration = new TestConfiguration(
loadBalanced ? SINGLE_MONGOS_LB_URI : MONGODB_URI,
context
);
await client.close();
});

Expand Down
4 changes: 3 additions & 1 deletion test/tools/unified-spec-runner/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ export class FailPointMap extends Map<string, Document> {
const entries = Array.from(this.entries());
await Promise.all(
entries.map(async ([hostAddress, configureFailPoint]) => {
if (process.env.SERVERLESS) hostAddress += '?loadBalanced=true';
if (process.env.SERVERLESS || process.env.LOAD_BALANCER) {
hostAddress += '?loadBalanced=true';
}
const client = getClient(hostAddress);
try {
await client.connect();
Expand Down
61 changes: 34 additions & 27 deletions test/unit/sdam/topology.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,37 +458,44 @@ describe('Topology (unit)', function () {
this.sinon.restore();
});

it('should schedule monitoring if no suitable server is found', function (done) {
const topology = new Topology('someserver:27019');
const requestCheck = this.sinon.stub(Server.prototype, 'requestCheck');

// satisfy the initial connect, then restore the original method
const selectServer = this.sinon
.stub(Topology.prototype, 'selectServer')
.callsFake(function (selector, options, callback) {
const server = Array.from(this.s.servers.values())[0];
selectServer.restore();
callback(null, server);
});

this.sinon.stub(Server.prototype, 'connect').callsFake(function () {
this.s.state = 'connected';
this.emit('connect');
});
it('should schedule monitoring if no suitable server is found', {
metadata: { requires: { topology: '!load-balanced' } },
test: function (done) {
const topology = new Topology('someserver:27019');
const requestCheck = this.sinon.stub(Server.prototype, 'requestCheck');

topology.connect(() => {
topology.selectServer(ReadPreference.secondary, { serverSelectionTimeoutMS: 1000 }, err => {
expect(err).to.exist;
expect(err).to.match(/Server selection timed out/);
expect(err).to.have.property('reason');
// satisfy the initial connect, then restore the original method
const selectServer = this.sinon
.stub(Topology.prototype, 'selectServer')
.callsFake(function (selector, options, callback) {
const server = Array.from(this.s.servers.values())[0];
selectServer.restore();
callback(null, server);
});

// When server is created `connect` is called on the monitor. When server selection
// occurs `requestCheck` will be called for an immediate check.
expect(requestCheck).property('callCount').to.equal(1);
this.sinon.stub(Server.prototype, 'connect').callsFake(function () {
this.s.state = 'connected';
this.emit('connect');
});

topology.close(done);
topology.connect(() => {
topology.selectServer(
ReadPreference.secondary,
{ serverSelectionTimeoutMS: 1000 },
err => {
expect(err).to.exist;
expect(err).to.match(/Server selection timed out/);
expect(err).to.have.property('reason');

// When server is created `connect` is called on the monitor. When server selection
// occurs `requestCheck` will be called for an immediate check.
expect(requestCheck).property('callCount').to.equal(1);

topology.close(done);
}
);
});
});
}
});

it('should disallow selection when the topology is explicitly closed', function (done) {
Expand Down

0 comments on commit 6970871

Please sign in to comment.