Skip to content

Commit b13dbcb

Browse files
feat(telemetry): report host_id for atlas COMPASS-8092 (#763)
* feat(telemetry): report host_id for atlas in VSCode COMPASS-8092 * test: add atlas host test and clean up
1 parent 8b93760 commit b13dbcb

File tree

2 files changed

+107
-22
lines changed

2 files changed

+107
-22
lines changed

src/telemetry/connectionTelemetry.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const { version } = require('../../package.json');
1414
export type NewConnectionTelemetryEventProperties = {
1515
auth_strategy?: string;
1616
is_atlas?: boolean;
17+
atlas_host_id?: string | null;
1718
is_localhost?: boolean;
1819
is_data_lake?: boolean;
1920
is_enterprise?: boolean;
@@ -55,12 +56,7 @@ async function getHostnameForConnection(
5556
return hostname;
5657
}
5758

58-
async function getCloudInfoFromDataService(
59-
dataService: DataService
60-
): Promise<CloudInfo> {
61-
const hostname = await getHostnameForConnection(
62-
dataService.getConnectionString()
63-
);
59+
async function getCloudInfoFromHostname(hostname?: string): Promise<CloudInfo> {
6460
const cloudInfo: {
6561
isAws?: boolean;
6662
isAzure?: boolean;
@@ -109,16 +105,20 @@ export async function getConnectionTelemetryProperties(
109105
const authMechanism = connectionString.searchParams.get('authMechanism');
110106
const username = connectionString.username ? 'DEFAULT' : 'NONE';
111107
const authStrategy = authMechanism ?? username;
108+
const hostname = await getHostnameForConnection(connectionString);
112109

113110
const [instance, cloudInfo] = await Promise.all([
114111
dataService.instance(),
115-
getCloudInfoFromDataService(dataService),
112+
getCloudInfoFromHostname(hostname),
116113
]);
114+
const isAtlas = mongoDBBuildInfo.isAtlas(connectionString.toString());
115+
const atlasHostId = isAtlas ? hostname : null;
117116

118117
preparedProperties = {
119118
...preparedProperties,
120119
auth_strategy: authStrategy,
121-
is_atlas: mongoDBBuildInfo.isAtlas(connectionString.toString()),
120+
is_atlas: isAtlas,
121+
atlas_host_id: atlasHostId,
122122
is_localhost: mongoDBBuildInfo.isLocalhost(connectionString.toString()),
123123
is_data_lake: instance.dataLake.isDataLake,
124124
is_enterprise: instance.build.isEnterprise,

src/test/suite/telemetry/connectionTelemetry.test.ts

Lines changed: 99 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { before, after, beforeEach, afterEach } from 'mocha';
1+
import { before, beforeEach, afterEach } from 'mocha';
22
import { connect } from 'mongodb-data-service';
33
import { expect } from 'chai';
44
import sinon from 'sinon';
55
import type { DataService } from 'mongodb-data-service';
6+
import mongoDBBuildInfo from 'mongodb-build-info';
67

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

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

1922
before(() => {
20-
const getConnectionStringStub = sandbox.stub();
21-
getConnectionStringStub.returns({
22-
hosts: ['localhost:27088'],
23-
searchParams: { get: () => null },
24-
username: 'authMechanism',
25-
} as unknown as ReturnType<DataService['getConnectionString']>);
23+
getConnectionStringStub = sandbox.stub();
24+
isAtlasStub = sinon.stub(mongoDBBuildInfo, 'isAtlas');
2625

2726
const instanceStub = sandbox.stub();
2827
instanceStub.resolves({
@@ -46,11 +45,51 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
4645
);
4746
});
4847

49-
after(() => {
48+
afterEach(() => {
5049
sandbox.restore();
5150
});
5251

52+
test('it returns atlas_host_id hostname for atlas clusters', async () => {
53+
isAtlasStub.returns(true);
54+
getConnectionStringStub.returns({
55+
hosts: ['test-data-sets-a011bb.test.net'],
56+
searchParams: { get: () => null },
57+
} as unknown as ReturnType<DataService['getConnectionString']>);
58+
59+
const instanceTelemetry = await getConnectionTelemetryProperties(
60+
dataServiceStub,
61+
ConnectionTypes.CONNECTION_FORM
62+
);
63+
64+
expect(instanceTelemetry.is_atlas).to.equal(true);
65+
expect(instanceTelemetry.atlas_host_id).to.equal(
66+
'test-data-sets-a011bb.test.net'
67+
);
68+
});
69+
70+
test('it returns atlas_host_id null for non atlas clusters', async () => {
71+
isAtlasStub.returns(false);
72+
getConnectionStringStub.returns({
73+
hosts: ['localhost:27088'],
74+
searchParams: { get: () => null },
75+
} as unknown as ReturnType<DataService['getConnectionString']>);
76+
77+
const instanceTelemetry = await getConnectionTelemetryProperties(
78+
dataServiceStub,
79+
ConnectionTypes.CONNECTION_FORM
80+
);
81+
82+
expect(instanceTelemetry.is_atlas).to.equal(false);
83+
expect(instanceTelemetry.atlas_host_id).to.equal(null);
84+
});
85+
5386
test('it returns is_used_connect_screen true when the connection type is form', async () => {
87+
isAtlasStub.returns(false);
88+
getConnectionStringStub.returns({
89+
hosts: ['localhost:27088'],
90+
searchParams: { get: () => null },
91+
} as unknown as ReturnType<DataService['getConnectionString']>);
92+
5493
const instanceTelemetry = await getConnectionTelemetryProperties(
5594
dataServiceStub,
5695
ConnectionTypes.CONNECTION_FORM
@@ -62,6 +101,12 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
62101
});
63102

64103
test('it returns is_used_command_palette true when the connection type is string', async () => {
104+
isAtlasStub.returns(false);
105+
getConnectionStringStub.returns({
106+
hosts: ['localhost:27088'],
107+
searchParams: { get: () => null },
108+
} as unknown as ReturnType<DataService['getConnectionString']>);
109+
65110
const instanceTelemetry = await getConnectionTelemetryProperties(
66111
dataServiceStub,
67112
ConnectionTypes.CONNECTION_STRING
@@ -73,6 +118,12 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
73118
});
74119

75120
test('it returns is_used_saved_connection true when the connection type is id', async () => {
121+
isAtlasStub.returns(false);
122+
getConnectionStringStub.returns({
123+
hosts: ['localhost:27088'],
124+
searchParams: { get: () => null },
125+
} as unknown as ReturnType<DataService['getConnectionString']>);
126+
76127
const instanceTelemetry = await getConnectionTelemetryProperties(
77128
dataServiceStub,
78129
ConnectionTypes.CONNECTION_ID
@@ -83,7 +134,13 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
83134
expect(instanceTelemetry.is_used_saved_connection).to.equal(true);
84135
});
85136

86-
test('it has is_localhost false for a remote connection', async () => {
137+
test('it returns is_localhost false for a remote connection', async () => {
138+
isAtlasStub.returns(false);
139+
getConnectionStringStub.returns({
140+
hosts: ['localhost:27088'],
141+
searchParams: { get: () => null },
142+
} as unknown as ReturnType<DataService['getConnectionString']>);
143+
87144
const instanceTelemetry = await getConnectionTelemetryProperties(
88145
dataServiceStub,
89146
ConnectionTypes.CONNECTION_STRING
@@ -92,22 +149,50 @@ suite('ConnectionTelemetry Controller Test Suite', function () {
92149
expect(instanceTelemetry.is_localhost).to.equal(false);
93150
});
94151

95-
test('it has a default is atlas false', async () => {
152+
test('it returns DEFAULT when auth mechanism undefined and username is specified', async () => {
153+
isAtlasStub.returns(false);
154+
getConnectionStringStub.returns({
155+
hosts: ['localhost:27088'],
156+
searchParams: { get: () => null },
157+
username: 'Artishok',
158+
} as unknown as ReturnType<DataService['getConnectionString']>);
159+
96160
const instanceTelemetry = await getConnectionTelemetryProperties(
97161
dataServiceStub,
98162
ConnectionTypes.CONNECTION_STRING
99163
);
100164

101-
expect(instanceTelemetry.is_atlas).to.equal(false);
165+
expect(instanceTelemetry.auth_strategy).to.equal('DEFAULT');
102166
});
103167

104-
test('it has a default driver auth mechanism undefined', async () => {
168+
test('it returns NONE when auth mechanism undefined and username undefined', async () => {
169+
isAtlasStub.returns(false);
170+
getConnectionStringStub.returns({
171+
hosts: ['localhost:27088'],
172+
searchParams: { get: () => null },
173+
} as unknown as ReturnType<DataService['getConnectionString']>);
174+
105175
const instanceTelemetry = await getConnectionTelemetryProperties(
106176
dataServiceStub,
107177
ConnectionTypes.CONNECTION_STRING
108178
);
109179

110-
expect(instanceTelemetry.auth_strategy).to.equal('DEFAULT');
180+
expect(instanceTelemetry.auth_strategy).to.equal('NONE');
181+
});
182+
183+
test('it returns authMechanism when specified', async () => {
184+
isAtlasStub.returns(false);
185+
getConnectionStringStub.returns({
186+
hosts: ['localhost:27088'],
187+
searchParams: { get: () => 'SCRAM-SHA-1' },
188+
} as unknown as ReturnType<DataService['getConnectionString']>);
189+
190+
const instanceTelemetry = await getConnectionTelemetryProperties(
191+
dataServiceStub,
192+
ConnectionTypes.CONNECTION_STRING
193+
);
194+
195+
expect(instanceTelemetry.auth_strategy).to.equal('SCRAM-SHA-1');
111196
});
112197
});
113198

0 commit comments

Comments
 (0)