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(telemetry): report host_id for atlas COMPASS-8092 #763

Merged
merged 2 commits into from
Jul 26, 2024
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
16 changes: 8 additions & 8 deletions src/telemetry/connectionTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const { version } = require('../../package.json');
export type NewConnectionTelemetryEventProperties = {
auth_strategy?: string;
is_atlas?: boolean;
atlas_host_id?: string | null;
is_localhost?: boolean;
is_data_lake?: boolean;
is_enterprise?: boolean;
Expand Down Expand Up @@ -55,12 +56,7 @@ async function getHostnameForConnection(
return hostname;
}

async function getCloudInfoFromDataService(
dataService: DataService
): Promise<CloudInfo> {
const hostname = await getHostnameForConnection(
dataService.getConnectionString()
);
async function getCloudInfoFromHostname(hostname?: string): Promise<CloudInfo> {
const cloudInfo: {
isAws?: boolean;
isAzure?: boolean;
Expand Down Expand Up @@ -109,16 +105,20 @@ export async function getConnectionTelemetryProperties(
const authMechanism = connectionString.searchParams.get('authMechanism');
const username = connectionString.username ? 'DEFAULT' : 'NONE';
const authStrategy = authMechanism ?? username;
const hostname = await getHostnameForConnection(connectionString);

const [instance, cloudInfo] = await Promise.all([
dataService.instance(),
getCloudInfoFromDataService(dataService),
getCloudInfoFromHostname(hostname),
]);
const isAtlas = mongoDBBuildInfo.isAtlas(connectionString.toString());
const atlasHostId = isAtlas ? hostname : null;

preparedProperties = {
...preparedProperties,
auth_strategy: authStrategy,
is_atlas: mongoDBBuildInfo.isAtlas(connectionString.toString()),
is_atlas: isAtlas,
alenakhineika marked this conversation as resolved.
Show resolved Hide resolved
atlas_host_id: atlasHostId,
is_localhost: mongoDBBuildInfo.isLocalhost(connectionString.toString()),
is_data_lake: instance.dataLake.isDataLake,
is_enterprise: instance.build.isEnterprise,
Expand Down
113 changes: 99 additions & 14 deletions src/test/suite/telemetry/connectionTelemetry.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { before, after, beforeEach, afterEach } from 'mocha';
import { before, beforeEach, afterEach } from 'mocha';
import { connect } from 'mongodb-data-service';
import { expect } from 'chai';
import sinon from 'sinon';
import type { DataService } from 'mongodb-data-service';
import mongoDBBuildInfo from 'mongodb-build-info';

import * as getCloudInfoModule from 'mongodb-cloud-info';

Expand All @@ -13,16 +14,14 @@ import { TEST_DATABASE_URI } from '../dbTestHelper';
suite('ConnectionTelemetry Controller Test Suite', function () {
suite('with mock data service', function () {
this.timeout(8000);
let dataServiceStub: DataService;
const sandbox = sinon.createSandbox();
let dataServiceStub;
let getConnectionStringStub;
let isAtlasStub;

before(() => {
const getConnectionStringStub = sandbox.stub();
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
username: 'authMechanism',
} as unknown as ReturnType<DataService['getConnectionString']>);
getConnectionStringStub = sandbox.stub();
isAtlasStub = sinon.stub(mongoDBBuildInfo, 'isAtlas');

const instanceStub = sandbox.stub();
instanceStub.resolves({
Expand All @@ -46,11 +45,51 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
);
});

after(() => {
afterEach(() => {
sandbox.restore();
});

test('it returns atlas_host_id hostname for atlas clusters', async () => {
isAtlasStub.returns(true);
getConnectionStringStub.returns({
hosts: ['test-data-sets-a011bb.test.net'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_FORM
);

expect(instanceTelemetry.is_atlas).to.equal(true);
expect(instanceTelemetry.atlas_host_id).to.equal(
'test-data-sets-a011bb.test.net'
);
});

test('it returns atlas_host_id null for non atlas clusters', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_FORM
);

expect(instanceTelemetry.is_atlas).to.equal(false);
expect(instanceTelemetry.atlas_host_id).to.equal(null);
});

test('it returns is_used_connect_screen true when the connection type is form', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_FORM
Expand All @@ -62,6 +101,12 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
});

test('it returns is_used_command_palette true when the connection type is string', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_STRING
Expand All @@ -73,6 +118,12 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
});

test('it returns is_used_saved_connection true when the connection type is id', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_ID
Expand All @@ -83,7 +134,13 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
expect(instanceTelemetry.is_used_saved_connection).to.equal(true);
});

test('it has is_localhost false for a remote connection', async () => {
test('it returns is_localhost false for a remote connection', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_STRING
Expand All @@ -92,22 +149,50 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
expect(instanceTelemetry.is_localhost).to.equal(false);
});

test('it has a default is atlas false', async () => {
test('it returns DEFAULT when auth mechanism undefined and username is specified', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
username: 'Artishok',
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_STRING
);

expect(instanceTelemetry.is_atlas).to.equal(false);
expect(instanceTelemetry.auth_strategy).to.equal('DEFAULT');
});

test('it has a default driver auth mechanism undefined', async () => {
test('it returns NONE when auth mechanism undefined and username undefined', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => null },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_STRING
);

expect(instanceTelemetry.auth_strategy).to.equal('DEFAULT');
expect(instanceTelemetry.auth_strategy).to.equal('NONE');
});

test('it returns authMechanism when specified', async () => {
isAtlasStub.returns(false);
getConnectionStringStub.returns({
hosts: ['localhost:27088'],
searchParams: { get: () => 'SCRAM-SHA-1' },
} as unknown as ReturnType<DataService['getConnectionString']>);

const instanceTelemetry = await getConnectionTelemetryProperties(
dataServiceStub,
ConnectionTypes.CONNECTION_STRING
);

expect(instanceTelemetry.auth_strategy).to.equal('SCRAM-SHA-1');
});
});

Expand Down
Loading