Skip to content

Commit 26ad568

Browse files
authored
feat: Disable all telemetry. (#202)
1 parent 4b6ec72 commit 26ad568

File tree

5 files changed

+35
-159
lines changed

5 files changed

+35
-159
lines changed

src/interactive-window/shiftEnterBanner.unit.test.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ import {
1010
isTestExecution,
1111
isUnitTestExecution,
1212
setTestExecution,
13-
setUnitTestExecution,
14-
Telemetry
13+
setUnitTestExecution
1514
} from '../platform/common/constants';
1615
import {
1716
IConfigurationService,
@@ -61,10 +60,7 @@ suite('Interactive Shift Enter Banner', () => {
6160

6261
config.verifyAll();
6362

64-
expect(Reporter.eventNames).to.deep.equal([
65-
Telemetry.ShiftEnterBannerShown,
66-
Telemetry.EnableInteractiveShiftEnter
67-
]);
63+
// Telemetry verification removed as telemetry is now disabled
6864
});
6965

7066
test("Shift Enter Banner don't check Jupyter when disabled", async () => {
@@ -89,10 +85,7 @@ suite('Interactive Shift Enter Banner', () => {
8985

9086
config.verifyAll();
9187

92-
expect(Reporter.eventNames).to.deep.equal([
93-
Telemetry.ShiftEnterBannerShown,
94-
Telemetry.DisableInteractiveShiftEnter
95-
]);
88+
// Telemetry verification removed as telemetry is now disabled
9689
});
9790
});
9891

src/platform/common/experiments/telemetry.unit.test.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,14 @@ import * as Telemetry from '../../../platform/telemetry/index';
99
suite('Experimentation telemetry', () => {
1010
const event = 'SomeEventName';
1111

12-
let telemetryEvents: { eventName: string; properties: object }[] = [];
13-
let sendTelemetryEventStub: sinon.SinonStub;
1412
let setSharedPropertyStub: sinon.SinonStub;
1513
let experimentTelemetry: ExperimentationTelemetry;
1614
let eventProperties: Map<string, string>;
1715

1816
setup(() => {
19-
sendTelemetryEventStub = sinon
20-
.stub(Telemetry, 'sendTelemetryEvent')
21-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
22-
.callsFake((eventName: string, _, properties: any) => {
23-
const telemetry = { eventName, properties };
24-
telemetryEvents.push(telemetry);
25-
});
17+
sinon.stub(Telemetry, 'sendTelemetryEvent').callsFake(() => {
18+
// Stub for telemetry (now disabled)
19+
});
2620
setSharedPropertyStub = sinon.stub(Telemetry, 'setSharedProperty');
2721

2822
eventProperties = new Map<string, string>();
@@ -33,21 +27,13 @@ suite('Experimentation telemetry', () => {
3327
});
3428

3529
teardown(() => {
36-
telemetryEvents = [];
3730
sinon.restore();
3831
});
3932

40-
test('Calling postEvent should send a telemetry event', () => {
41-
experimentTelemetry.postEvent(event, eventProperties);
42-
43-
sinon.assert.calledOnce(sendTelemetryEventStub);
44-
assert.equal(telemetryEvents.length, 1);
45-
assert.deepEqual(telemetryEvents[0], {
46-
eventName: event,
47-
properties: {
48-
foo: 'one',
49-
bar: 'two'
50-
}
33+
test('Calling postEvent should not throw (telemetry disabled)', () => {
34+
// Telemetry is now disabled, so we just verify the method doesn't throw
35+
assert.doesNotThrow(() => {
36+
experimentTelemetry.postEvent(event, eventProperties);
5137
});
5238
});
5339

src/platform/telemetry/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ function isTelemetrySupported(): boolean {
4141
* @returns {boolean}
4242
*/
4343
export function isTelemetryDisabled(): boolean {
44-
const settings = workspace.getConfiguration('telemetry').inspect<boolean>('enableTelemetry')!;
45-
return settings.globalValue === false ? true : false;
44+
return true;
4645
}
4746

4847
export function onDidChangeTelemetryEnablement(handler: (enabled: boolean) => void): Disposable {

src/platform/telemetry/index.unit.test.ts

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,13 @@
44
/* eslint-disable , , @typescript-eslint/no-explicit-any */
55
import * as sinon from 'sinon';
66
import { expect } from 'chai';
7-
import { instance, mock, reset, verify, when } from 'ts-mockito';
8-
import { Disposable, WorkspaceConfiguration } from 'vscode';
7+
import { Disposable } from 'vscode';
98
import { EXTENSION_ROOT_DIR } from '../constants.node';
10-
import {
11-
_resetSharedProperties,
12-
getTelemetryReporter,
13-
isTelemetryDisabled,
14-
sendTelemetryEvent,
15-
setSharedProperty
16-
} from '../../telemetry';
9+
import { _resetSharedProperties, getTelemetryReporter, sendTelemetryEvent, setSharedProperty } from '../../telemetry';
1710
import { isUnitTestExecution, isTestExecution, setTestExecution, setUnitTestExecution } from '../common/constants';
1811
import { sleep } from '../../test/core';
1912
import { waitForCondition } from '../../test/common';
20-
import { mockedVSCodeNamespaces, resetVSCodeMocks } from '../../test/vscode-mock';
13+
import { resetVSCodeMocks } from '../../test/vscode-mock';
2114
import { IDisposable } from '../common/types';
2215
import { dispose } from '../common/utils/lifecycle';
2316

@@ -80,35 +73,7 @@ suite('Telemetry', () => {
8073
_resetSharedProperties();
8174
});
8275

83-
const testsForisTelemetryDisabled = [
84-
{
85-
testName: 'Returns true when globalValue is set to false',
86-
settings: { globalValue: false },
87-
expectedResult: true
88-
},
89-
{
90-
testName: 'Returns false otherwise',
91-
settings: {},
92-
expectedResult: false
93-
}
94-
];
95-
96-
suite('Function isTelemetryDisabled()', () => {
97-
testsForisTelemetryDisabled.forEach((testParams) => {
98-
test(testParams.testName, async () => {
99-
const workspaceConfig = mock<WorkspaceConfiguration>();
100-
reset(mockedVSCodeNamespaces.workspace);
101-
when(mockedVSCodeNamespaces.workspace.getConfiguration('telemetry')).thenReturn(
102-
instance(workspaceConfig)
103-
);
104-
when(workspaceConfig.inspect<string>('enableTelemetry')).thenReturn(testParams.settings as any);
105-
106-
expect(isTelemetryDisabled()).to.equal(testParams.expectedResult);
107-
108-
verify(mockedVSCodeNamespaces.workspace.getConfiguration('telemetry')).once();
109-
});
110-
});
111-
});
76+
// Note: isTelemetryDisabled() tests removed as telemetry is now permanently disabled
11277

11378
test('Send Telemetry', async () => {
11479
const eventName = 'Testing';

src/standalone/import-export/importTracker.unit.test.ts

Lines changed: 20 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
/* eslint-disable , , @typescript-eslint/no-explicit-any, no-multi-str, no-trailing-spaces */
55
import * as sinon from 'sinon';
66
import * as fakeTimers from '@sinonjs/fake-timers';
7-
import { assert, expect } from 'chai';
87
import { when } from 'ts-mockito';
98
import { Disposable, EventEmitter, NotebookCellKind, NotebookDocument } from 'vscode';
109

@@ -18,11 +17,8 @@ import {
1817
} from '../../platform/common/constants';
1918
import { dispose } from '../../platform/common/utils/lifecycle';
2019
import { IDisposable } from '../../platform/common/types';
21-
import { EventName } from '../../platform/telemetry/constants';
22-
import { getTelemetrySafeHashedString } from '../../platform/telemetry/helpers';
2320
import { ImportTracker } from './importTracker';
24-
import { ResourceTypeTelemetryProperty, getTelemetryReporter } from '../../telemetry';
25-
import { waitForCondition } from '../../test/common';
21+
import { getTelemetryReporter } from '../../telemetry';
2622
import { createMockedNotebookDocument } from '../../test/datascience/editor-integration/helpers';
2723
import { mockedVSCodeNamespaces } from '../../test/vscode-mock';
2824
import { EmptyEvent } from '../../platform/common/utils/events';
@@ -35,15 +31,6 @@ suite(`Import Tracker`, async () => {
3531
let onDidOpenNbEvent: EventEmitter<NotebookDocument>;
3632
let onDidCloseNbEvent: EventEmitter<NotebookDocument>;
3733
let onDidSaveNbEvent: EventEmitter<NotebookDocument>;
38-
let pandasHash: string;
39-
let elephasHash: string;
40-
let kerasHash: string;
41-
let pysparkHash: string;
42-
let sparkdlHash: string;
43-
let numpyHash: string;
44-
let scipyHash: string;
45-
let sklearnHash: string;
46-
let randomHash: string;
4734
let disposables: IDisposable[] = [];
4835
let clock: fakeTimers.InstalledClock;
4936

@@ -52,46 +39,11 @@ suite(`Import Tracker`, async () => {
5239
public static properties: Record<string, string>[] = [];
5340
public static measures: {}[] = [];
5441

55-
public static async expectHashes(
56-
when: 'onExecution' | 'onOpenCloseOrSave' = 'onOpenCloseOrSave',
57-
resourceType: ResourceTypeTelemetryProperty['resourceType'] = undefined,
58-
...hashes: string[]
59-
) {
42+
// Telemetry is now disabled, so this method just ensures the tracker doesn't crash
43+
public static async expectHashes() {
6044
clock.tick(1);
6145
void clock.runAllAsync();
62-
if (hashes.length > 0) {
63-
await waitForCondition(
64-
async () => {
65-
expect(Reporter.eventNames).to.contain(EventName.HASHED_PACKAGE_NAME);
66-
return true;
67-
},
68-
1_000,
69-
'Hashed package name event not sent'
70-
);
71-
expect(Reporter.eventNames).to.contain(EventName.HASHED_PACKAGE_NAME);
72-
await waitForCondition(
73-
async () => {
74-
Reporter.properties.filter((item) => Object.keys(item).length).length === hashes.length;
75-
return true;
76-
},
77-
1_000,
78-
() =>
79-
`Incorrect number of hashed package name events sent. Expected ${hashes.length}, got ${
80-
Reporter.properties.filter((item) => Object.keys(item).length).length
81-
}, with values ${JSON.stringify(
82-
Reporter.properties.filter((item) => Object.keys(item).length)
83-
)}`
84-
);
85-
}
86-
const properties = Reporter.properties.filter((item) => Object.keys(item).length);
87-
const expected = resourceType
88-
? hashes.map((hash) => ({ hashedNamev2: hash, when, resourceType }))
89-
: hashes.map((hash) => ({ hashedNamev2: hash, when }));
90-
assert.deepEqual(
91-
properties.sort((a, b) => a.hashedNamev2.localeCompare(b.hashedNamev2)),
92-
expected.sort((a, b) => a.hashedNamev2.localeCompare(b.hashedNamev2)),
93-
`Hashes not sent correctly, expected ${JSON.stringify(expected)} but got ${JSON.stringify(properties)}`
94-
);
46+
// Telemetry verification removed as telemetry is now disabled
9547
}
9648

9749
public sendTelemetryEvent(eventName: string, properties?: {}, measures?: {}) {
@@ -100,17 +52,6 @@ suite(`Import Tracker`, async () => {
10052
Reporter.measures.push(measures!);
10153
}
10254
}
103-
suiteSetup(async () => {
104-
pandasHash = await getTelemetrySafeHashedString('pandas');
105-
elephasHash = await getTelemetrySafeHashedString('elephas');
106-
kerasHash = await getTelemetrySafeHashedString('keras');
107-
pysparkHash = await getTelemetrySafeHashedString('pyspark');
108-
sparkdlHash = await getTelemetrySafeHashedString('sparkdl');
109-
numpyHash = await getTelemetrySafeHashedString('numpy');
110-
scipyHash = await getTelemetrySafeHashedString('scipy');
111-
sklearnHash = await getTelemetrySafeHashedString('sklearn');
112-
randomHash = await getTelemetrySafeHashedString('random');
113-
});
11455
setup(() => {
11556
const reporter = getTelemetryReporter();
11657
sinon.stub(reporter, 'sendTelemetryEvent').callsFake((eventName: string, properties?: {}, measures?: {}) => {
@@ -159,21 +100,21 @@ suite(`Import Tracker`, async () => {
159100
const nb = createMockedNotebookDocument([{ kind: NotebookCellKind.Code, languageId: 'python', value: code }]);
160101
onDidOpenNbEvent.fire(nb);
161102

162-
await Reporter.expectHashes('onOpenCloseOrSave', 'notebook', pandasHash);
103+
await Reporter.expectHashes();
163104
});
164105
test('Close document', async () => {
165106
const code = `import pandas\r\n`;
166107
const nb = createMockedNotebookDocument([{ kind: NotebookCellKind.Code, languageId: 'python', value: code }]);
167108
onDidCloseNbEvent.fire(nb);
168109

169-
await Reporter.expectHashes('onOpenCloseOrSave', 'notebook', pandasHash);
110+
await Reporter.expectHashes();
170111
});
171112
test('Save document', async () => {
172113
const code = `import pandas\r\n`;
173114
const nb = createMockedNotebookDocument([{ kind: NotebookCellKind.Code, languageId: 'python', value: code }]);
174115
onDidSaveNbEvent.fire(nb);
175116

176-
await Reporter.expectHashes('onOpenCloseOrSave', 'notebook', pandasHash);
117+
await Reporter.expectHashes();
177118
});
178119

179120
test('Already opened documents', async () => {
@@ -183,13 +124,9 @@ suite(`Import Tracker`, async () => {
183124

184125
await importTracker.activate();
185126

186-
await Reporter.expectHashes('onOpenCloseOrSave', 'notebook', pandasHash);
127+
await Reporter.expectHashes();
187128
});
188-
async function testImports(
189-
code: string,
190-
notebookType: typeof JupyterNotebookView | typeof InteractiveWindowView,
191-
...expectedPackageHashes: string[]
192-
) {
129+
async function testImports(code: string, notebookType: typeof JupyterNotebookView | typeof InteractiveWindowView) {
193130
const nb = createMockedNotebookDocument(
194131
[{ kind: NotebookCellKind.Code, languageId: 'python', value: code }],
195132
undefined,
@@ -200,11 +137,7 @@ suite(`Import Tracker`, async () => {
200137

201138
await importTracker.activate();
202139

203-
await Reporter.expectHashes(
204-
'onOpenCloseOrSave',
205-
notebookType === 'jupyter-notebook' ? 'notebook' : 'interactive',
206-
...expectedPackageHashes
207-
);
140+
await Reporter.expectHashes();
208141
}
209142
test('from <pkg>._ import _, _', async () => {
210143
const code = `
@@ -226,7 +159,7 @@ suite(`Import Tracker`, async () => {
226159
227160
weights = adapter.retrieve_keras_weights(java_model)
228161
model.set_weights(weights)`;
229-
await testImports(code, 'jupyter-notebook', elephasHash, kerasHash);
162+
await testImports(code, 'jupyter-notebook');
230163
});
231164

232165
test('from <pkg>._ import _', async () => {
@@ -247,7 +180,7 @@ suite(`Import Tracker`, async () => {
247180
evaluator = MulticlassClassificationEvaluator(metricName="accuracy")
248181
print("Training set accuracy = " + str(evaluator.evaluate(predictionAndLabels)))`;
249182

250-
await testImports(code, 'interactive', pysparkHash, sparkdlHash);
183+
await testImports(code, 'interactive');
251184
});
252185

253186
test('import <pkg> as _', async () => {
@@ -263,7 +196,7 @@ suite(`Import Tracker`, async () => {
263196
df.Age = categories
264197
return df`;
265198

266-
await testImports(code, 'interactive', pandasHash, numpyHash, randomHash);
199+
await testImports(code, 'interactive');
267200
});
268201

269202
test('from <pkg> import _', async () => {
@@ -277,12 +210,12 @@ suite(`Import Tracker`, async () => {
277210
y = np.array([r * np.sin(theta) for r in radius])
278211
z = np.array([drumhead_height(1, 1, r, theta, 0.5) for r in radius])`;
279212

280-
await testImports(code, 'interactive', scipyHash);
213+
await testImports(code, 'interactive');
281214
});
282215

283216
test('from <pkg> import _ as _', async () => {
284217
const code = `from pandas import DataFrame as df`;
285-
await testImports(code, 'jupyter-notebook', pandasHash);
218+
await testImports(code, 'jupyter-notebook');
286219
});
287220

288221
test('import <pkg1>, <pkg2>', async () => {
@@ -295,7 +228,7 @@ suite(`Import Tracker`, async () => {
295228
x = np.array([r * np.cos(theta) for r in radius])
296229
y = np.array([r * np.sin(theta) for r in radius])
297230
z = np.array([drumhead_height(1, 1, r, theta, 0.5) for r in radius])`;
298-
await testImports(code, 'interactive', sklearnHash, pandasHash);
231+
await testImports(code, 'interactive');
299232
});
300233

301234
test('Import from within a function', async () => {
@@ -309,14 +242,14 @@ suite(`Import Tracker`, async () => {
309242
y = np.array([r * np.sin(theta) for r in radius])
310243
z = np.array([drumhead_height(1, 1, r, theta, 0.5) for r in radius])`;
311244

312-
await testImports(code, 'interactive', sklearnHash);
245+
await testImports(code, 'interactive');
313246
});
314247

315248
test('Do not send the same package twice', async () => {
316249
const code = `
317250
import pandas
318251
import pandas`;
319-
await testImports(code, 'interactive', pandasHash);
252+
await testImports(code, 'interactive');
320253
});
321254

322255
test('Ignore relative imports', async () => {
@@ -328,7 +261,7 @@ suite(`Import Tracker`, async () => {
328261
const nb = createMockedNotebookDocument([{ kind: NotebookCellKind.Code, languageId: 'python', value: code }]);
329262
notebookCellExecutions.changeCellState(nb.cellAt(0), NotebookCellExecutionState.Pending);
330263

331-
await Reporter.expectHashes('onExecution', 'notebook', numpyHash);
264+
await Reporter.expectHashes();
332265

333266
// Executing the cell multiple will have no effect, the telemetry is only sent once.
334267
notebookCellExecutions.changeCellState(nb.cellAt(0), NotebookCellExecutionState.Pending);
@@ -338,6 +271,6 @@ suite(`Import Tracker`, async () => {
338271
notebookCellExecutions.changeCellState(nb.cellAt(0), NotebookCellExecutionState.Executing);
339272
notebookCellExecutions.changeCellState(nb.cellAt(0), NotebookCellExecutionState.Idle);
340273

341-
await Reporter.expectHashes('onExecution', 'notebook', numpyHash);
274+
await Reporter.expectHashes();
342275
});
343276
});

0 commit comments

Comments
 (0)