Skip to content

Commit d43d9fd

Browse files
added tests
1 parent 0c93ca2 commit d43d9fd

File tree

7 files changed

+95
-42
lines changed

7 files changed

+95
-42
lines changed

src/cmap/connect.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
type ConnectionOptions,
2626
CryptoConnection
2727
} from './connection';
28-
import { addAllEnvClientMetadata, type ClientMetadata } from './handshake/client_metadata';
28+
import { addContainerMetadata } from './handshake/client_metadata';
2929
import {
3030
MAX_SUPPORTED_SERVER_VERSION,
3131
MAX_SUPPORTED_WIRE_VERSION,
@@ -183,7 +183,7 @@ export interface HandshakeDocument extends Document {
183183
ismaster?: boolean;
184184
hello?: boolean;
185185
helloOk?: boolean;
186-
client: ClientMetadata;
186+
client: Document;
187187
compression: string[];
188188
saslSupportedMechs?: string;
189189
loadBalanced?: boolean;
@@ -200,11 +200,11 @@ export async function prepareHandshakeDocument(
200200
const options = authContext.options;
201201
const compressors = options.compressors ? options.compressors : [];
202202
const { serverApi } = authContext.connection;
203-
const clientMetadata = await addAllEnvClientMetadata(options.internalMetadata);
203+
const clientMetadata = await addContainerMetadata(options.metadata);
204204
const handshakeDoc: HandshakeDocument = {
205205
[serverApi?.version || options.loadBalanced === true ? 'hello' : LEGACY_HELLO_COMMAND]: 1,
206206
helloOk: true,
207-
client: clientMetadata.toObject(),
207+
client: clientMetadata,
208208
compression: compressors
209209
};
210210

src/cmap/connection.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ import {
5757
type WriteProtocolMessageType
5858
} from './commands';
5959
import type { Stream } from './connect';
60-
import type { ClientMetadata, LimitedSizeDocument } from './handshake/client_metadata';
60+
import type { ClientMetadata } from './handshake/client_metadata';
6161
import { StreamDescription, type StreamDescriptionOptions } from './stream_description';
6262
import { type CompressorName, decompressResponse } from './wire_protocol/compression';
6363
import { onData } from './wire_protocol/on_data';
@@ -119,8 +119,6 @@ export interface ConnectionOptions
119119
cancellationToken?: CancellationToken;
120120
metadata: ClientMetadata;
121121
/** @internal */
122-
internalMetadata: LimitedSizeDocument;
123-
/** @internal */
124122
mongoLogger?: MongoLogger | undefined;
125123
}
126124

src/cmap/handshake/client_metadata.ts

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { promises as fs } from 'fs';
22
import * as os from 'os';
33
import * as process from 'process';
44

5-
import { BSON, Int32 } from '../../bson';
5+
import { BSON, type Document, Int32 } from '../../bson';
66
import { MongoInvalidArgumentError } from '../../error';
77
import type { MongoOptions } from '../../mongo_client';
88

@@ -72,13 +72,13 @@ export class LimitedSizeDocument {
7272
return true;
7373
}
7474

75-
toObject(): ClientMetadata {
75+
toObject(): Document {
7676
return BSON.deserialize(BSON.serialize(this.document), {
7777
promoteLongs: false,
7878
promoteBuffers: false,
7979
promoteValues: false,
8080
useBigInt64: false
81-
}) as ClientMetadata;
81+
});
8282
}
8383
}
8484

@@ -95,7 +95,7 @@ export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMe
9595
let metadataDocument = new LimitedSizeDocument(512);
9696
metadataDocument = addNonEnvClientMetadata(options, metadataDocument);
9797
metadataDocument = addFAASOnlyEnvClientMetadata(metadataDocument);
98-
return metadataDocument.toObject();
98+
return metadataDocument.toObject() as ClientMetadata;
9999
}
100100

101101
/** @internal */
@@ -173,9 +173,7 @@ function addFAASOnlyEnvClientMetadata(metadataDocument: LimitedSizeDocument): Li
173173
let isDocker: boolean;
174174
let dockerPromise: any;
175175
/** @internal */
176-
export async function addAllEnvClientMetadata(metadataDocument: LimitedSizeDocument) {
177-
const faasEnv = getFAASEnv();
178-
176+
export async function addContainerMetadata(originalMetadata: ClientMetadata) {
179177
async function getContainerMetadata() {
180178
const containerMetadata: Record<string, any> = {};
181179
if (isDocker == null) {
@@ -201,18 +199,30 @@ export async function addAllEnvClientMetadata(metadataDocument: LimitedSizeDocum
201199
}
202200

203201
const containerMetadata = await getContainerMetadata();
204-
const envMetadata = faasEnv ?? new Map();
205-
envMetadata.set('container', containerMetadata);
206-
if (envMetadata != null) {
207-
if (!metadataDocument.ifItFitsItSits('env', envMetadata)) {
208-
for (const key of envMetadata.keys()) {
209-
envMetadata.delete(key);
210-
if (envMetadata.size === 0) break;
211-
if (metadataDocument.ifItFitsItSits('env', envMetadata)) break;
202+
if (Object.keys(containerMetadata).length === 0) return originalMetadata;
203+
204+
const extendedMetadata = new LimitedSizeDocument(512);
205+
206+
let envMetadata = { container: containerMetadata };
207+
if ('env' in originalMetadata) {
208+
envMetadata = { ...originalMetadata['env'], ...envMetadata };
209+
}
210+
211+
for (const [key, val] of Object.entries(originalMetadata)) {
212+
if (key !== 'env') {
213+
extendedMetadata.ifItFitsItSits(key, val);
214+
} else {
215+
if (!extendedMetadata.ifItFitsItSits('env', envMetadata)) {
216+
extendedMetadata.ifItFitsItSits('env', val);
212217
}
213218
}
214219
}
215-
return metadataDocument;
220+
221+
if (!('env' in originalMetadata)) {
222+
extendedMetadata.ifItFitsItSits('env', envMetadata);
223+
}
224+
225+
return extendedMetadata.toObject();
216226
}
217227

218228
/**

src/connection_string.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { URLSearchParams } from 'url';
55
import type { Document } from './bson';
66
import { MongoCredentials } from './cmap/auth/mongo_credentials';
77
import { AUTH_MECHS_AUTH_SRC_EXTERNAL, AuthMechanism } from './cmap/auth/providers';
8-
import { LimitedSizeDocument, addNonEnvClientMetadata, makeClientMetadata } from './cmap/handshake/client_metadata';
8+
import { makeClientMetadata } from './cmap/handshake/client_metadata';
99
import { Compressor, type CompressorName } from './cmap/wire_protocol/compression';
1010
import { Encrypter } from './encrypter';
1111
import {
@@ -544,7 +544,6 @@ export function parseOptions(
544544
);
545545

546546
mongoOptions.metadata = makeClientMetadata(mongoOptions);
547-
mongoOptions.internalMetadata = addNonEnvClientMetadata(mongoOptions, new LimitedSizeDocument(512));
548547

549548
return mongoOptions;
550549
}

src/mongo_client.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
import { AuthMechanism } from './cmap/auth/providers';
1515
import type { LEGAL_TCP_SOCKET_OPTIONS, LEGAL_TLS_SOCKET_OPTIONS } from './cmap/connect';
1616
import type { Connection } from './cmap/connection';
17-
import type { ClientMetadata, LimitedSizeDocument } from './cmap/handshake/client_metadata';
17+
import type { ClientMetadata } from './cmap/handshake/client_metadata';
1818
import type { CompressorName } from './cmap/wire_protocol/compression';
1919
import { parseOptions, resolveSRVRecord } from './connection_string';
2020
import { MONGO_CLIENT_EVENTS } from './constants';
@@ -897,11 +897,4 @@ export interface MongoOptions
897897
* TODO: NODE-5671 - remove internal flag
898898
*/
899899
mongodbLogPath?: 'stderr' | 'stdout' | MongoDBLogWritable;
900-
901-
/**
902-
* @internal
903-
* Metadata as BSON bytes.
904-
* Does not contain any environment information.
905-
*/
906-
internalMetadata: LimitedSizeDocument;
907900
}

src/sdam/topology.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { BSONSerializeOptions, Document } from '../bson';
44
import type { MongoCredentials } from '../cmap/auth/mongo_credentials';
55
import type { ConnectionEvents, DestroyOptions } from '../cmap/connection';
66
import type { CloseOptions, ConnectionPoolEvents } from '../cmap/connection_pool';
7-
import type { ClientMetadata, LimitedSizeDocument } from '../cmap/handshake/client_metadata';
7+
import type { ClientMetadata } from '../cmap/handshake/client_metadata';
88
import { DEFAULT_OPTIONS, FEATURE_FLAGS } from '../connection_string';
99
import {
1010
CLOSE,
@@ -158,7 +158,6 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
158158
directConnection: boolean;
159159
loadBalanced: boolean;
160160
metadata: ClientMetadata;
161-
internalMetadata: LimitedSizeDocument;
162161
serverMonitoringMode: ServerMonitoringMode;
163162
/** MongoDB server API version */
164163
serverApi?: ServerApi;

test/unit/cmap/connect.test.ts

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { expect } from 'chai';
2+
import { promises as fs } from 'fs';
3+
import * as sinon from 'sinon';
24

35
import {
46
CancellationToken,
@@ -26,7 +28,7 @@ const CONNECT_DEFAULTS = {
2628
loadBalanced: false
2729
};
2830

29-
describe('Connect Tests', function () {
31+
describe('Connect Tests', async function () {
3032
context('when PLAIN auth enabled', () => {
3133
const test: {
3234
server?: any;
@@ -185,9 +187,9 @@ describe('Connect Tests', function () {
185187
expect(error).to.be.instanceOf(MongoNetworkError);
186188
});
187189

188-
context('prepareHandshakeDocument', () => {
190+
context('prepareHandshakeDocument', async () => {
189191
context('when serverApi.version is present', () => {
190-
const options = {};
192+
const options = { ...CONNECT_DEFAULTS };
191193
const authContext = {
192194
connection: { serverApi: { version: '1' } },
193195
options
@@ -200,7 +202,7 @@ describe('Connect Tests', function () {
200202
});
201203

202204
context('when serverApi is not present', () => {
203-
const options = {};
205+
const options = { ...CONNECT_DEFAULTS };
204206
const authContext = {
205207
connection: {},
206208
options
@@ -216,7 +218,7 @@ describe('Connect Tests', function () {
216218
context('when loadBalanced is not set as an option', () => {
217219
const authContext = {
218220
connection: {},
219-
options: {}
221+
options: { ...CONNECT_DEFAULTS }
220222
};
221223

222224
it('does not set loadBalanced on the handshake document', async () => {
@@ -238,7 +240,7 @@ describe('Connect Tests', function () {
238240
context('when loadBalanced is set to false', () => {
239241
const authContext = {
240242
connection: {},
241-
options: { loadBalanced: false }
243+
options: { ...CONNECT_DEFAULTS, loadBalanced: false }
242244
};
243245

244246
it('does not set loadBalanced on the handshake document', async () => {
@@ -260,7 +262,7 @@ describe('Connect Tests', function () {
260262
context('when loadBalanced is set to true', () => {
261263
const authContext = {
262264
connection: {},
263-
options: { loadBalanced: true }
265+
options: { ...CONNECT_DEFAULTS, loadBalanced: true }
264266
};
265267

266268
it('sets loadBalanced on the handshake document', async () => {
@@ -279,5 +281,57 @@ describe('Connect Tests', function () {
279281
});
280282
});
281283
});
284+
285+
describe('containers', async () => {
286+
const authContext = {
287+
connection: {},
288+
options: { ...CONNECT_DEFAULTS }
289+
};
290+
context('when container is present', async () => {
291+
292+
context('when both kubernetes and docker are present', async () => {
293+
beforeEach(() => {
294+
process.env.KUBERNETES_SERVICE_HOST = 'I exist';
295+
const stub = sinon.stub(fs, 'access');
296+
stub.callsFake(async function () {});
297+
});
298+
afterEach(() => {
299+
process.env.KUBERNETES_SERVICE_HOST = '';
300+
sinon.restore();
301+
});
302+
it('should include both in client.env.container properly', async () => {
303+
const handshakeDocument = await prepareHandshakeDocument(authContext);
304+
expect(handshakeDocument.client.env.container.orchestrator).to.equal('kubernetes');
305+
expect(handshakeDocument.client.env.container.runtime).to.equal('docker');
306+
});
307+
});
308+
context('when only kubernetes is present', async () => {
309+
beforeEach(() => {
310+
process.env.KUBERNETES_SERVICE_HOST = 'I exist';
311+
});
312+
afterEach(() => {
313+
process.env.KUBERNETES_SERVICE_HOST = '';
314+
});
315+
it(`should include { orchestrator: 'kubernetes'} in client.env.container`, async () => {
316+
const handshakeDocument = await prepareHandshakeDocument(authContext);
317+
expect(handshakeDocument.client.env.container.orchestrator).to.equal('kubernetes');
318+
});
319+
});
320+
context('when only docker is present', async () => {
321+
beforeEach(() => {
322+
const stub = sinon.stub(fs, 'access');
323+
stub.callsFake(async function () {});
324+
});
325+
afterEach(() => {
326+
process.env.KUBERNETES_SERVICE_HOST = '';
327+
sinon.restore();
328+
});
329+
it(`should include { runtime: 'docker'} in client.env.container`, async () => {
330+
const handshakeDocument = await prepareHandshakeDocument(authContext);
331+
expect(handshakeDocument.client.env.container.runtime).to.equal('docker');
332+
});
333+
});
334+
});
335+
});
282336
});
283337
});

0 commit comments

Comments
 (0)