Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-5199): add alternative runtime detection to client metadata #3647

Merged
merged 2 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2343,7 +2343,7 @@ tasks:
commands:
- func: install dependencies
vars:
NODE_LTS_NAME: erbium
NODE_LTS_NAME: hydrogen
- func: check types
vars:
TS_VERSION: next
Expand All @@ -2363,7 +2363,7 @@ tasks:
commands:
- func: install dependencies
vars:
NODE_LTS_NAME: erbium
NODE_LTS_NAME: hydrogen
- func: check types
vars:
TS_VERSION: current
Expand All @@ -2373,7 +2373,7 @@ tasks:
commands:
- func: install dependencies
vars:
NODE_LTS_NAME: erbium
NODE_LTS_NAME: hydrogen
- func: check types
vars:
TS_VERSION: 4.1.6
Expand Down
4 changes: 2 additions & 2 deletions .evergreen/generate_evergreen_tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ function* makeTypescriptTasks() {
{
func: 'install dependencies',
vars: {
NODE_LTS_NAME: LOWEST_LTS
NODE_LTS_NAME: LATEST_LTS
}
},
{
Expand All @@ -514,7 +514,7 @@ function* makeTypescriptTasks() {
{
func: 'install dependencies',
vars: {
NODE_LTS_NAME: LOWEST_LTS
NODE_LTS_NAME: LATEST_LTS
}
},
{ func: 'run typescript next' }
Expand Down
46 changes: 41 additions & 5 deletions src/cmap/handshake/client_metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ export function makeClientMetadata(options: MakeClientMetadataOptions): ClientMe
);
}

const platformInfo =
platform.length > 0
? `Node.js ${process.version}, ${os.endianness()}|${platform}`
: `Node.js ${process.version}, ${os.endianness()}`;
let runtimeInfo = getRuntimeInfo();
if (platform.length > 0) {
runtimeInfo = `${runtimeInfo}|${platform}`;
}

if (!metadataDocument.ifItFitsItSits('platform', platformInfo)) {
if (!metadataDocument.ifItFitsItSits('platform', runtimeInfo)) {
throw new MongoInvalidArgumentError(
'Unable to include driverInfo platform, metadata cannot exceed 512 bytes'
);
Expand Down Expand Up @@ -234,3 +234,39 @@ export function getFAASEnv(): Map<string, string | Int32> | null {

return null;
}

/**
* @internal
* This type represents the global Deno object and the minimal type contract we expect it to satisfy.
*/
declare const Deno: { version?: { deno?: string } } | undefined;

/**
* @internal
* This type represents the global Bun object and the minimal type contract we expect it to satisfy.
*/
declare const Bun: { (): void; version?: string } | undefined;

/**
* @internal
* Get current JavaScript runtime platform
*
* NOTE: The version information fetching is intentionally written defensively
* to avoid having a released driver version that becomes incompatible
* with a future change to these global objects.
*/
function getRuntimeInfo(): string {
if ('Deno' in globalThis) {
const version = typeof Deno?.version?.deno === 'string' ? Deno?.version?.deno : '0.0.0-unknown';

return `Deno v${version}, ${os.endianness()}`;
}

if ('Bun' in globalThis) {
const version = typeof Bun?.version === 'string' ? Bun?.version : '0.0.0-unknown';

return `Bun v${version}, ${os.endianness()}`;
}

return `Node.js ${process.version}, ${os.endianness()}`;
}
88 changes: 88 additions & 0 deletions test/unit/cmap/handshake/client_metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,94 @@ describe('client metadata module', () => {
});
});
});

context('when globalThis indicates alternative runtime', () => {
context('deno', () => {
afterEach(() => {
expect(delete globalThis.Deno, 'failed to delete Deno global').to.be.true;
});

it('sets platform to Deno', () => {
globalThis.Deno = { version: { deno: '1.2.3' } };
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Deno v1.2.3, LE');
});

it('sets platform to Deno with driverInfo.platform', () => {
globalThis.Deno = { version: { deno: '1.2.3' } };
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
expect(metadata.platform).to.equal('Deno v1.2.3, LE|myPlatform');
});

it('ignores version if Deno.version.deno is not a string', () => {
globalThis.Deno = { version: { deno: 1 } };
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
});

it('ignores version if Deno.version does not have a deno property', () => {
globalThis.Deno = { version: { somethingElse: '1.2.3' } };
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
});

it('ignores version if Deno.version is null', () => {
globalThis.Deno = { version: null };
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
});

it('ignores version if Deno is nullish', () => {
globalThis.Deno = null;
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Deno v0.0.0-unknown, LE');
});
});

context('bun', () => {
afterEach(() => {
expect(delete globalThis.Bun, 'failed to delete Bun global').to.be.true;
});

it('sets platform to Bun', () => {
globalThis.Bun = class {
static version = '1.2.3';
};
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Bun v1.2.3, LE');
});

it('sets platform to Bun with driverInfo.platform', () => {
globalThis.Bun = class {
static version = '1.2.3';
};
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
expect(metadata.platform).to.equal('Bun v1.2.3, LE|myPlatform');
});

it('ignores version if Bun.version is not a string', () => {
globalThis.Bun = class {
static version = 1;
};
const metadata = makeClientMetadata({ driverInfo: {} });
expect(metadata.platform).to.equal('Bun v0.0.0-unknown, LE');
});

it('ignores version if Bun.version is not a string and sets driverInfo.platform', () => {
globalThis.Bun = class {
static version = 1;
};
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
expect(metadata.platform).to.equal('Bun v0.0.0-unknown, LE|myPlatform');
});

it('ignores version if Bun is nullish', () => {
globalThis.Bun = null;
const metadata = makeClientMetadata({ driverInfo: { platform: 'myPlatform' } });
expect(metadata.platform).to.equal('Bun v0.0.0-unknown, LE|myPlatform');
});
});
});
});

describe('FAAS metadata application to handshake', () => {
Expand Down