@react-native-windows/telemetry 0.73.0 → 0.74.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/lib-commonjs/e2etest/telemetry.test.d.ts +28 -28
  2. package/lib-commonjs/e2etest/telemetry.test.js +496 -496
  3. package/lib-commonjs/index.d.ts +11 -11
  4. package/lib-commonjs/index.js +26 -26
  5. package/lib-commonjs/telemetry.d.ts +84 -84
  6. package/lib-commonjs/telemetry.js +370 -370
  7. package/lib-commonjs/telemetry.js.map +1 -1
  8. package/lib-commonjs/test/basePropUtils.test.d.ts +7 -7
  9. package/lib-commonjs/test/basePropUtils.test.js +137 -137
  10. package/lib-commonjs/test/errorUtils.test.d.ts +7 -7
  11. package/lib-commonjs/test/errorUtils.test.js +159 -159
  12. package/lib-commonjs/test/projectUtils.test.d.ts +7 -7
  13. package/lib-commonjs/test/projectUtils.test.js +87 -87
  14. package/lib-commonjs/test/sanitizeUtils.test.d.ts +7 -7
  15. package/lib-commonjs/test/sanitizeUtils.test.js +97 -97
  16. package/lib-commonjs/test/versionUtils.test.d.ts +7 -7
  17. package/lib-commonjs/test/versionUtils.test.js +114 -114
  18. package/lib-commonjs/utils/basePropUtils.d.ts +81 -81
  19. package/lib-commonjs/utils/basePropUtils.js +173 -173
  20. package/lib-commonjs/utils/errorUtils.d.ts +87 -87
  21. package/lib-commonjs/utils/errorUtils.js +178 -178
  22. package/lib-commonjs/utils/optionUtils.d.ts +45 -45
  23. package/lib-commonjs/utils/optionUtils.js +95 -95
  24. package/lib-commonjs/utils/projectUtils.d.ts +50 -50
  25. package/lib-commonjs/utils/projectUtils.js +186 -186
  26. package/lib-commonjs/utils/sanitizeUtils.d.ts +12 -12
  27. package/lib-commonjs/utils/sanitizeUtils.js +81 -81
  28. package/lib-commonjs/utils/versionUtils.d.ts +38 -38
  29. package/lib-commonjs/utils/versionUtils.js +155 -155
  30. package/package.json +14 -16
@@ -1,497 +1,497 @@
1
- "use strict";
2
- /**
3
- * Copyright (c) Microsoft Corporation.
4
- * Licensed under the MIT License.
5
- *
6
- * @format
7
- */
8
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
- if (k2 === undefined) k2 = k;
10
- var desc = Object.getOwnPropertyDescriptor(m, k);
11
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
- desc = { enumerable: true, get: function() { return m[k]; } };
13
- }
14
- Object.defineProperty(o, k2, desc);
15
- }) : (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- o[k2] = m[k];
18
- }));
19
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
- Object.defineProperty(o, "default", { enumerable: true, value: v });
21
- }) : function(o, v) {
22
- o["default"] = v;
23
- });
24
- var __importStar = (this && this.__importStar) || function (mod) {
25
- if (mod && mod.__esModule) return mod;
26
- var result = {};
27
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
- __setModuleDefault(result, mod);
29
- return result;
30
- };
31
- Object.defineProperty(exports, "__esModule", { value: true });
32
- exports.TelemetryTest = void 0;
33
- const path = __importStar(require("path"));
34
- const telemetry_1 = require("../telemetry");
35
- const basePropUtils = __importStar(require("../utils/basePropUtils"));
36
- const errorUtils = __importStar(require("../utils/errorUtils"));
37
- const projectUtils = __importStar(require("../utils/projectUtils"));
38
- const versionUtils = __importStar(require("../utils/versionUtils"));
39
- class TelemetryTest extends telemetry_1.Telemetry {
40
- /** Run at the beginning of each test. */
41
- static async startTest(options) {
42
- TelemetryTest.hasTestTelemetryProviders = false;
43
- TelemetryTest.testTelemetryProvidersRan = false;
44
- if (TelemetryTest.isEnabled()) {
45
- telemetry_1.Telemetry.reset();
46
- }
47
- // Ensure that we don't actually fire events when testing
48
- telemetry_1.Telemetry.isTest = true;
49
- await telemetry_1.Telemetry.setup(options);
50
- }
51
- /** Run at the end of each test where telemetry was fired. */
52
- static endTest(finalCallback) {
53
- var _a;
54
- (_a = telemetry_1.Telemetry.client) === null || _a === void 0 ? void 0 : _a.flush({
55
- callback: _ => {
56
- if (TelemetryTest.hasTestTelemetryProviders) {
57
- expect(TelemetryTest.testTelemetryProvidersRan).toBe(true);
58
- }
59
- if (finalCallback) {
60
- finalCallback();
61
- }
62
- },
63
- });
64
- }
65
- /** Sets that the telemetry provider has run. */
66
- static setTestTelemetryProvidersRan() {
67
- TelemetryTest.testTelemetryProvidersRan = true;
68
- }
69
- /** Retrieves the value of a common property.*/
70
- static getCommonProperty(key) {
71
- var _a;
72
- return (_a = TelemetryTest.client) === null || _a === void 0 ? void 0 : _a.commonProperties[key];
73
- }
74
- /** Retrieves the version of the specified tool/package. */
75
- static getVersion(key) {
76
- return key in TelemetryTest.versionsProp
77
- ? TelemetryTest.versionsProp[key]
78
- : null;
79
- }
80
- /** Retrieves the value of the preserveErrorMessages option. */
81
- static getPreserveErrorMessages() {
82
- return TelemetryTest.options.preserveErrorMessages;
83
- }
84
- /** Adds a telemetry processor, usually for verifying the envelope. */
85
- static addTelemetryProcessor(telemetryProcessor) {
86
- var _a;
87
- (_a = TelemetryTest.client) === null || _a === void 0 ? void 0 : _a.addTelemetryProcessor(telemetryProcessor);
88
- TelemetryTest.hasTestTelemetryProviders = true;
89
- }
90
- }
91
- exports.TelemetryTest = TelemetryTest;
92
- test('setup() verify session id is valid and a common property', async () => {
93
- await TelemetryTest.startTest();
94
- const sessionId = TelemetryTest.getSessionId();
95
- expect(sessionId).toBeDefined();
96
- expect(sessionId).toHaveLength(32);
97
- expect(sessionId).toBe(basePropUtils.getSessionId());
98
- expect(TelemetryTest.getCommonProperty('sessionId')).toBe(sessionId);
99
- TelemetryTest.endTest();
100
- });
101
- test('setup() verify static common property values with async sources', async () => {
102
- await TelemetryTest.startTest();
103
- const props = {
104
- deviceId: basePropUtils.deviceId,
105
- deviceLocale: basePropUtils.deviceLocale,
106
- };
107
- for (const key in props) {
108
- if (!(key in Object.prototype)) {
109
- const value = TelemetryTest.getCommonProperty(key);
110
- expect(value).toBeDefined();
111
- expect(value).toBe(await props[key]());
112
- }
113
- }
114
- TelemetryTest.endTest();
115
- });
116
- test('setup() verify static common property values with sync sources', async () => {
117
- await TelemetryTest.startTest();
118
- const props = {
119
- deviceArchitecture: () => basePropUtils.deviceArchitecture(),
120
- devicePlatform: () => basePropUtils.devicePlatform(),
121
- deviceNumCPUs: () => basePropUtils.deviceNumCPUs().toString(),
122
- deviceTotalMemory: () => basePropUtils.deviceTotalMemory().toString(),
123
- ciCaptured: () => basePropUtils.captureCI().toString(),
124
- ciType: () => basePropUtils.ciType(),
125
- isMsftInternal: () => basePropUtils.isMsftInternal().toString(),
126
- sampleRate: () => basePropUtils.sampleRate().toString(),
127
- isTest: () => 'true',
128
- };
129
- for (const key in props) {
130
- if (!(key in Object.prototype)) {
131
- const value = TelemetryTest.getCommonProperty(key);
132
- expect(value).toBeDefined();
133
- expect(value).toBe(props[key]());
134
- }
135
- }
136
- TelemetryTest.endTest();
137
- });
138
- test('setup() verify other common property values are defined', async () => {
139
- await TelemetryTest.startTest();
140
- const props = ['deviceDiskFreeSpace'];
141
- for (const key of props) {
142
- const value = TelemetryTest.getCommonProperty(key);
143
- expect(value).toBeDefined();
144
- }
145
- TelemetryTest.endTest();
146
- });
147
- test('setup() verify tool versions are populated', async () => {
148
- await TelemetryTest.startTest();
149
- const props = {
150
- node: versionUtils.getNodeVersion,
151
- npm: versionUtils.getNpmVersion,
152
- yarn: versionUtils.getYarnVersion,
153
- VisualStudio: versionUtils.getVisualStudioVersion,
154
- };
155
- for (const key in props) {
156
- if (!(key in Object.prototype)) {
157
- const value = await props[key]();
158
- expect(value).toBe(TelemetryTest.getVersion(key));
159
- }
160
- }
161
- TelemetryTest.endTest();
162
- });
163
- test('tryUpdateVersionsProp() returns true for adding a new version', async () => {
164
- await TelemetryTest.startTest();
165
- const name = 'test';
166
- const version = '1.0';
167
- expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => version)).toBe(true);
168
- expect(TelemetryTest.getVersion(name)).toBe(version);
169
- TelemetryTest.endTest();
170
- });
171
- test('tryUpdateVersionsProp() returns false for adding an existing version with refresh is false', async () => {
172
- await TelemetryTest.startTest();
173
- const name = 'test';
174
- const version = '1.0';
175
- expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => version)).toBe(true);
176
- let getValueCalled = false;
177
- expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => {
178
- getValueCalled = true;
179
- return version;
180
- })).toBe(false);
181
- expect(getValueCalled).toBe(false);
182
- TelemetryTest.endTest();
183
- });
184
- test('tryUpdateVersionsProp() returns true for adding an existing version with refresh is true', async () => {
185
- await TelemetryTest.startTest();
186
- const name = 'test';
187
- const version = '1.0';
188
- expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => version)).toBe(true);
189
- let getValueCalled = false;
190
- expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => {
191
- getValueCalled = true;
192
- return version;
193
- }, true)).toBe(true);
194
- expect(getValueCalled).toBe(true);
195
- TelemetryTest.endTest();
196
- });
197
- /** Returns the CommandStartInfo for our fake 'test-command'. */
198
- function getTestCommandStartInfo() {
199
- return {
200
- commandName: 'test-command',
201
- args: {
202
- testArg1: 'true',
203
- testArg2: '10',
204
- testArg3: 'testValue',
205
- },
206
- options: {
207
- testArg0: 'unsetArg',
208
- testArg1: true,
209
- testArg2: 10,
210
- testArg3: 'testValue',
211
- },
212
- defaultOptions: {
213
- testArg0: 'unsetArg',
214
- testArg1: false,
215
- testArg2: 0,
216
- testArg3: 'defaultValue',
217
- },
218
- };
219
- }
220
- /** Returns the CommandEndInfo for our fake 'test-command'. */
221
- function getTestCommandEndInfo(resultCode) {
222
- return {
223
- resultCode,
224
- };
225
- }
226
- function getTestCommandProjectInfo() {
227
- return {
228
- id: projectUtils.getProjectId('test-app-project'),
229
- platforms: ['windows'],
230
- rnwLang: 'cpp',
231
- usesTS: true,
232
- usesRNConfig: false,
233
- jsEngine: 'Chakra',
234
- rnwSource: 'Source',
235
- dependencies: [
236
- {
237
- id: projectUtils.getProjectId('test-module-project'),
238
- platforms: ['android', 'windows'],
239
- rnwLang: 'cpp',
240
- },
241
- ],
242
- };
243
- }
244
- function getExtraProps() {
245
- return {
246
- extraProp1: true,
247
- extraProp2: 1234,
248
- extraProp3: 'test',
249
- extraProp4: ['test'],
250
- extraProp5: {
251
- nestedProp1: true,
252
- nestedProp2: 1234,
253
- },
254
- };
255
- }
256
- /** Asynchronously waits the number in ms. */
257
- async function promiseDelay(ms) {
258
- return new Promise(resolve => setTimeout(resolve, ms));
259
- }
260
- /** The body of the fake 'test-command' which will throw the provided error. */
261
- async function testCommandBody(errorToThrow) {
262
- await promiseDelay(100);
263
- if (errorToThrow) {
264
- throw errorToThrow;
265
- }
266
- }
267
- /** Runs the complete 'test-command' with the right Telemetry setup and cleanup. */
268
- async function runTestCommandE2E(commandBody) {
269
- TelemetryTest.startCommand(getTestCommandStartInfo());
270
- TelemetryTest.setProjectInfo(getTestCommandProjectInfo());
271
- let errorCode = 'Success';
272
- let caughtError;
273
- try {
274
- await commandBody();
275
- }
276
- catch (ex) {
277
- caughtError = ex instanceof Error ? ex : new Error(String(ex));
278
- errorCode =
279
- caughtError instanceof errorUtils.CodedError
280
- ? caughtError.type
281
- : 'Unknown';
282
- TelemetryTest.trackException(caughtError);
283
- }
284
- TelemetryTest.endCommand(getTestCommandEndInfo(errorCode), getExtraProps());
285
- }
286
- /** Verifies the contents of events fired during the 'test-command'. */
287
- function verifyTestCommandTelemetryProcessor(caughtErrors, expectedResultCode, expectedError) {
288
- return (envelope, _) => {
289
- var _a, _b, _c, _d;
290
- try {
291
- // Processor has run, so the test can (potentially) pass
292
- TelemetryTest.setTestTelemetryProvidersRan();
293
- // Verify roleInstance has been removed
294
- expect(envelope.tags['ai.cloud.roleInstance']).toBeUndefined();
295
- const properties = (_a = envelope.data.baseData) === null || _a === void 0 ? void 0 : _a.properties;
296
- expect(properties).toBeDefined();
297
- // Verify basics
298
- expect(properties.commandName).toBe('test-command');
299
- // Verify versions info
300
- const versions = JSON.parse(properties.versions);
301
- expect(versions).toBeDefined();
302
- // Verify project info
303
- const project = JSON.parse(properties.project);
304
- expect(project).toStrictEqual(getTestCommandProjectInfo());
305
- expect(Object.keys(versions).length).toBeGreaterThan(0);
306
- for (const key of Object.keys(versions)) {
307
- expect(versions[key]).toBe(TelemetryTest.getVersion(key));
308
- }
309
- if (envelope.data.baseType === 'ExceptionData') {
310
- // Verify event name
311
- expect(properties.eventName).toBe(telemetry_1.CodedErrorEventName);
312
- // Verify exception info
313
- const exceptions = (_b = envelope.data.baseData) === null || _b === void 0 ? void 0 : _b.exceptions;
314
- expect(exceptions).toBeDefined();
315
- expect(exceptions.length).toBe(1);
316
- expect(exceptions[0].message).toBeDefined();
317
- expect(exceptions[0].message).not.toBe('');
318
- expect(exceptions[0].message).toBe(TelemetryTest.getPreserveErrorMessages()
319
- ? errorUtils.sanitizeErrorMessage((expectedError === null || expectedError === void 0 ? void 0 : expectedError.message) || 'None')
320
- : '[Removed]');
321
- // Verify coded error info
322
- const codedError = JSON.parse(properties.codedError);
323
- expect(codedError).toBeDefined();
324
- expect(codedError.type).toBe(expectedError instanceof errorUtils.CodedError
325
- ? expectedError.type
326
- : 'Unknown');
327
- expect(codedError.data).toStrictEqual((_c = expectedError.data) !== null && _c !== void 0 ? _c : {});
328
- }
329
- else {
330
- // Verify event name
331
- expect((_d = envelope.data.baseData) === null || _d === void 0 ? void 0 : _d.name).toBe(telemetry_1.CommandEventName);
332
- expect(properties.eventName).toBe(telemetry_1.CommandEventName);
333
- // Verify command info
334
- const expectedInfo = getTestCommandStartInfo();
335
- const command = JSON.parse(properties.command);
336
- expect(command).toBeDefined();
337
- expect(command.args).toStrictEqual(expectedInfo.args);
338
- expect(command.options).toStrictEqual(expectedInfo.options);
339
- expect(command.defaultOptions).toStrictEqual(expectedInfo.defaultOptions);
340
- expect(command.durationInSecs).toBeGreaterThan(0);
341
- expect(command.resultCode).toBe(expectedResultCode !== null && expectedResultCode !== void 0 ? expectedResultCode : 'Success');
342
- // Verify extra props
343
- const extraProps = getExtraProps();
344
- expect(JSON.parse(properties.extraProps)).toStrictEqual(extraProps);
345
- }
346
- }
347
- catch (ex) {
348
- caughtErrors.push(ex instanceof Error ? ex : new Error(String(ex)));
349
- }
350
- return true;
351
- };
352
- }
353
- test('Telemetry run test command end to end, verify event fires', async () => {
354
- await TelemetryTest.startTest();
355
- // AI eats errors thrown in telemetry processors
356
- const caughtErrors = [];
357
- TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors));
358
- await runTestCommandE2E(testCommandBody);
359
- TelemetryTest.endTest(() => {
360
- // Check if any errors were thrown
361
- expect(caughtErrors).toHaveLength(0);
362
- });
363
- });
364
- const testTelemetryOptions = [
365
- { preserveErrorMessages: false },
366
- { preserveErrorMessages: true },
367
- ];
368
- test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError, verify events fire %s', async (options) => {
369
- await TelemetryTest.startTest(options);
370
- const expectedError = new errorUtils.CodedError('MSBuildError', 'test error');
371
- // AI eats errors thrown in telemetry processors
372
- const caughtErrors = [];
373
- TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError));
374
- await runTestCommandE2E(() => testCommandBody(expectedError));
375
- TelemetryTest.endTest(() => {
376
- // Check if any errors were thrown
377
- expect(caughtErrors).toHaveLength(0);
378
- });
379
- });
380
- test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError (with error in message), verify events fire %s', async (options) => {
381
- await TelemetryTest.startTest(options);
382
- const expectedError = new errorUtils.CodedError('MSBuildError', 'error FOO2020: test error');
383
- // AI eats errors thrown in telemetry processors
384
- const caughtErrors = [];
385
- TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError));
386
- await runTestCommandE2E(() => testCommandBody(expectedError));
387
- TelemetryTest.endTest(() => {
388
- // Check if any errors were thrown
389
- expect(caughtErrors).toHaveLength(0);
390
- });
391
- });
392
- test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError (with data), verify events fire %s', async (options) => {
393
- await TelemetryTest.startTest(options);
394
- const expectedError = new errorUtils.CodedError('MSBuildError', 'test error', { foo: 42 });
395
- // AI eats errors thrown in telemetry processors
396
- const caughtErrors = [];
397
- TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError));
398
- await runTestCommandE2E(() => testCommandBody(expectedError));
399
- TelemetryTest.endTest(() => {
400
- // Check if any errors were thrown
401
- expect(caughtErrors).toHaveLength(0);
402
- });
403
- });
404
- test.each(testTelemetryOptions)('Telemetry run test command end to end with Error, verify events fire %s', async (options) => {
405
- await TelemetryTest.startTest(options);
406
- const expectedError = new Error('error FOO2020: test error');
407
- // AI eats errors thrown in telemetry processors
408
- const caughtErrors = [];
409
- TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, 'Unknown', expectedError));
410
- await runTestCommandE2E(() => testCommandBody(expectedError));
411
- TelemetryTest.endTest(() => {
412
- // Check if any errors were thrown
413
- expect(caughtErrors).toHaveLength(0);
414
- });
415
- });
416
- test.each(testTelemetryOptions)('Telemetry run test command end to end with Error (no message), verify events fire %s', async (options) => {
417
- await TelemetryTest.startTest(options);
418
- const expectedError = new Error();
419
- // AI eats errors thrown in telemetry processors
420
- const caughtErrors = [];
421
- TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, 'Unknown', expectedError));
422
- await runTestCommandE2E(() => testCommandBody(expectedError));
423
- TelemetryTest.endTest(() => {
424
- // Check if any errors were thrown
425
- expect(caughtErrors).toHaveLength(0);
426
- });
427
- });
428
- function b(s) {
429
- throw new Error('hello ' + s);
430
- }
431
- function a(s) {
432
- b(s);
433
- }
434
- /** Verifies the contents of an exception's message and stack frames */
435
- function getVerifyStackTelemetryProcessor(caughtErrors, expectedError) {
436
- return (envelope, _) => {
437
- try {
438
- // Processor has run, so the test can (potentially) pass
439
- TelemetryTest.setTestTelemetryProvidersRan();
440
- if (envelope.data.baseType === 'ExceptionData') {
441
- const data = envelope.data.baseData;
442
- expect(data.exceptions).toBeDefined();
443
- expect(data.exceptions.length).toBe(1);
444
- expect(data.exceptions[0].message).toBeDefined();
445
- expect(data.exceptions[0].message).not.toBe('');
446
- expect(data.exceptions[0].message).toBe(TelemetryTest.getPreserveErrorMessages()
447
- ? errorUtils.sanitizeErrorMessage(expectedError.message || 'None')
448
- : '[Removed]');
449
- const stack = data.exceptions[0].parsedStack;
450
- expect(stack).toBeDefined();
451
- expect(stack.length).toBeGreaterThan(2);
452
- const filename = path.relative(process.cwd(), __filename);
453
- expect(stack[0].method).toEqual('b');
454
- expect(stack[1].method).toEqual('b');
455
- expect(stack[2].method).toEqual('a');
456
- expect(stack[0].fileName).toEqual(`[project_dir]\\???.ts(${filename.length})`);
457
- expect(stack[1].fileName).toEqual(`[project_dir]\\???.ts(${filename.length})`);
458
- expect(stack[2].fileName).toEqual(`[project_dir]\\???.ts(${filename.length})`);
459
- }
460
- }
461
- catch (ex) {
462
- caughtErrors.push(ex instanceof Error ? ex : new Error(String(ex)));
463
- }
464
- return true;
465
- };
466
- }
467
- test.each(testTelemetryOptions)('Telemetry run test command end to end with Error, verify sanitized message and stack %s', async (options) => {
468
- await TelemetryTest.startTest(options);
469
- const expectedError = new Error('hello world');
470
- // AI eats errors thrown in telemetry processors
471
- const caughtErrors = [];
472
- TelemetryTest.addTelemetryProcessor(getVerifyStackTelemetryProcessor(caughtErrors, expectedError));
473
- await runTestCommandE2E(async () => {
474
- await promiseDelay(100);
475
- a('world');
476
- });
477
- TelemetryTest.endTest(() => {
478
- // Check if any errors were thrown
479
- expect(caughtErrors).toHaveLength(0);
480
- });
481
- });
482
- test.each(testTelemetryOptions)('Telemetry run test command end to end with Error, verify sanitized message with path and stack %s', async (options) => {
483
- await TelemetryTest.startTest(options);
484
- const expectedError = new Error(`hello ${process.cwd()}`);
485
- // AI eats errors thrown in telemetry processors
486
- const caughtErrors = [];
487
- TelemetryTest.addTelemetryProcessor(getVerifyStackTelemetryProcessor(caughtErrors, expectedError));
488
- await runTestCommandE2E(async () => {
489
- await promiseDelay(100);
490
- a(process.cwd());
491
- });
492
- TelemetryTest.endTest(() => {
493
- // Check if any errors were thrown
494
- expect(caughtErrors).toHaveLength(0);
495
- });
496
- });
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation.
4
+ * Licensed under the MIT License.
5
+ *
6
+ * @format
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
31
+ Object.defineProperty(exports, "__esModule", { value: true });
32
+ exports.TelemetryTest = void 0;
33
+ const path = __importStar(require("path"));
34
+ const telemetry_1 = require("../telemetry");
35
+ const basePropUtils = __importStar(require("../utils/basePropUtils"));
36
+ const errorUtils = __importStar(require("../utils/errorUtils"));
37
+ const projectUtils = __importStar(require("../utils/projectUtils"));
38
+ const versionUtils = __importStar(require("../utils/versionUtils"));
39
+ class TelemetryTest extends telemetry_1.Telemetry {
40
+ /** Run at the beginning of each test. */
41
+ static async startTest(options) {
42
+ TelemetryTest.hasTestTelemetryProviders = false;
43
+ TelemetryTest.testTelemetryProvidersRan = false;
44
+ if (TelemetryTest.isEnabled()) {
45
+ telemetry_1.Telemetry.reset();
46
+ }
47
+ // Ensure that we don't actually fire events when testing
48
+ telemetry_1.Telemetry.isTest = true;
49
+ await telemetry_1.Telemetry.setup(options);
50
+ }
51
+ /** Run at the end of each test where telemetry was fired. */
52
+ static endTest(finalCallback) {
53
+ var _a;
54
+ (_a = telemetry_1.Telemetry.client) === null || _a === void 0 ? void 0 : _a.flush({
55
+ callback: _ => {
56
+ if (TelemetryTest.hasTestTelemetryProviders) {
57
+ expect(TelemetryTest.testTelemetryProvidersRan).toBe(true);
58
+ }
59
+ if (finalCallback) {
60
+ finalCallback();
61
+ }
62
+ },
63
+ });
64
+ }
65
+ /** Sets that the telemetry provider has run. */
66
+ static setTestTelemetryProvidersRan() {
67
+ TelemetryTest.testTelemetryProvidersRan = true;
68
+ }
69
+ /** Retrieves the value of a common property.*/
70
+ static getCommonProperty(key) {
71
+ var _a;
72
+ return (_a = TelemetryTest.client) === null || _a === void 0 ? void 0 : _a.commonProperties[key];
73
+ }
74
+ /** Retrieves the version of the specified tool/package. */
75
+ static getVersion(key) {
76
+ return key in TelemetryTest.versionsProp
77
+ ? TelemetryTest.versionsProp[key]
78
+ : null;
79
+ }
80
+ /** Retrieves the value of the preserveErrorMessages option. */
81
+ static getPreserveErrorMessages() {
82
+ return TelemetryTest.options.preserveErrorMessages;
83
+ }
84
+ /** Adds a telemetry processor, usually for verifying the envelope. */
85
+ static addTelemetryProcessor(telemetryProcessor) {
86
+ var _a;
87
+ (_a = TelemetryTest.client) === null || _a === void 0 ? void 0 : _a.addTelemetryProcessor(telemetryProcessor);
88
+ TelemetryTest.hasTestTelemetryProviders = true;
89
+ }
90
+ }
91
+ exports.TelemetryTest = TelemetryTest;
92
+ test('setup() verify session id is valid and a common property', async () => {
93
+ await TelemetryTest.startTest();
94
+ const sessionId = TelemetryTest.getSessionId();
95
+ expect(sessionId).toBeDefined();
96
+ expect(sessionId).toHaveLength(32);
97
+ expect(sessionId).toBe(basePropUtils.getSessionId());
98
+ expect(TelemetryTest.getCommonProperty('sessionId')).toBe(sessionId);
99
+ TelemetryTest.endTest();
100
+ });
101
+ test('setup() verify static common property values with async sources', async () => {
102
+ await TelemetryTest.startTest();
103
+ const props = {
104
+ deviceId: basePropUtils.deviceId,
105
+ deviceLocale: basePropUtils.deviceLocale,
106
+ };
107
+ for (const key in props) {
108
+ if (!(key in Object.prototype)) {
109
+ const value = TelemetryTest.getCommonProperty(key);
110
+ expect(value).toBeDefined();
111
+ expect(value).toBe(await props[key]());
112
+ }
113
+ }
114
+ TelemetryTest.endTest();
115
+ });
116
+ test('setup() verify static common property values with sync sources', async () => {
117
+ await TelemetryTest.startTest();
118
+ const props = {
119
+ deviceArchitecture: () => basePropUtils.deviceArchitecture(),
120
+ devicePlatform: () => basePropUtils.devicePlatform(),
121
+ deviceNumCPUs: () => basePropUtils.deviceNumCPUs().toString(),
122
+ deviceTotalMemory: () => basePropUtils.deviceTotalMemory().toString(),
123
+ ciCaptured: () => basePropUtils.captureCI().toString(),
124
+ ciType: () => basePropUtils.ciType(),
125
+ isMsftInternal: () => basePropUtils.isMsftInternal().toString(),
126
+ sampleRate: () => basePropUtils.sampleRate().toString(),
127
+ isTest: () => 'true',
128
+ };
129
+ for (const key in props) {
130
+ if (!(key in Object.prototype)) {
131
+ const value = TelemetryTest.getCommonProperty(key);
132
+ expect(value).toBeDefined();
133
+ expect(value).toBe(props[key]());
134
+ }
135
+ }
136
+ TelemetryTest.endTest();
137
+ });
138
+ test('setup() verify other common property values are defined', async () => {
139
+ await TelemetryTest.startTest();
140
+ const props = ['deviceDiskFreeSpace'];
141
+ for (const key of props) {
142
+ const value = TelemetryTest.getCommonProperty(key);
143
+ expect(value).toBeDefined();
144
+ }
145
+ TelemetryTest.endTest();
146
+ });
147
+ test('setup() verify tool versions are populated', async () => {
148
+ await TelemetryTest.startTest();
149
+ const props = {
150
+ node: versionUtils.getNodeVersion,
151
+ npm: versionUtils.getNpmVersion,
152
+ yarn: versionUtils.getYarnVersion,
153
+ VisualStudio: versionUtils.getVisualStudioVersion,
154
+ };
155
+ for (const key in props) {
156
+ if (!(key in Object.prototype)) {
157
+ const value = await props[key]();
158
+ expect(value).toBe(TelemetryTest.getVersion(key));
159
+ }
160
+ }
161
+ TelemetryTest.endTest();
162
+ });
163
+ test('tryUpdateVersionsProp() returns true for adding a new version', async () => {
164
+ await TelemetryTest.startTest();
165
+ const name = 'test';
166
+ const version = '1.0';
167
+ expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => version)).toBe(true);
168
+ expect(TelemetryTest.getVersion(name)).toBe(version);
169
+ TelemetryTest.endTest();
170
+ });
171
+ test('tryUpdateVersionsProp() returns false for adding an existing version with refresh is false', async () => {
172
+ await TelemetryTest.startTest();
173
+ const name = 'test';
174
+ const version = '1.0';
175
+ expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => version)).toBe(true);
176
+ let getValueCalled = false;
177
+ expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => {
178
+ getValueCalled = true;
179
+ return version;
180
+ })).toBe(false);
181
+ expect(getValueCalled).toBe(false);
182
+ TelemetryTest.endTest();
183
+ });
184
+ test('tryUpdateVersionsProp() returns true for adding an existing version with refresh is true', async () => {
185
+ await TelemetryTest.startTest();
186
+ const name = 'test';
187
+ const version = '1.0';
188
+ expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => version)).toBe(true);
189
+ let getValueCalled = false;
190
+ expect(await TelemetryTest.tryUpdateVersionsProp(name, async () => {
191
+ getValueCalled = true;
192
+ return version;
193
+ }, true)).toBe(true);
194
+ expect(getValueCalled).toBe(true);
195
+ TelemetryTest.endTest();
196
+ });
197
+ /** Returns the CommandStartInfo for our fake 'test-command'. */
198
+ function getTestCommandStartInfo() {
199
+ return {
200
+ commandName: 'test-command',
201
+ args: {
202
+ testArg1: 'true',
203
+ testArg2: '10',
204
+ testArg3: 'testValue',
205
+ },
206
+ options: {
207
+ testArg0: 'unsetArg',
208
+ testArg1: true,
209
+ testArg2: 10,
210
+ testArg3: 'testValue',
211
+ },
212
+ defaultOptions: {
213
+ testArg0: 'unsetArg',
214
+ testArg1: false,
215
+ testArg2: 0,
216
+ testArg3: 'defaultValue',
217
+ },
218
+ };
219
+ }
220
+ /** Returns the CommandEndInfo for our fake 'test-command'. */
221
+ function getTestCommandEndInfo(resultCode) {
222
+ return {
223
+ resultCode,
224
+ };
225
+ }
226
+ function getTestCommandProjectInfo() {
227
+ return {
228
+ id: projectUtils.getProjectId('test-app-project'),
229
+ platforms: ['windows'],
230
+ rnwLang: 'cpp',
231
+ usesTS: true,
232
+ usesRNConfig: false,
233
+ jsEngine: 'Chakra',
234
+ rnwSource: 'Source',
235
+ dependencies: [
236
+ {
237
+ id: projectUtils.getProjectId('test-module-project'),
238
+ platforms: ['android', 'windows'],
239
+ rnwLang: 'cpp',
240
+ },
241
+ ],
242
+ };
243
+ }
244
+ function getExtraProps() {
245
+ return {
246
+ extraProp1: true,
247
+ extraProp2: 1234,
248
+ extraProp3: 'test',
249
+ extraProp4: ['test'],
250
+ extraProp5: {
251
+ nestedProp1: true,
252
+ nestedProp2: 1234,
253
+ },
254
+ };
255
+ }
256
+ /** Asynchronously waits the number in ms. */
257
+ async function promiseDelay(ms) {
258
+ return new Promise(resolve => setTimeout(resolve, ms));
259
+ }
260
+ /** The body of the fake 'test-command' which will throw the provided error. */
261
+ async function testCommandBody(errorToThrow) {
262
+ await promiseDelay(100);
263
+ if (errorToThrow) {
264
+ throw errorToThrow;
265
+ }
266
+ }
267
+ /** Runs the complete 'test-command' with the right Telemetry setup and cleanup. */
268
+ async function runTestCommandE2E(commandBody) {
269
+ TelemetryTest.startCommand(getTestCommandStartInfo());
270
+ TelemetryTest.setProjectInfo(getTestCommandProjectInfo());
271
+ let errorCode = 'Success';
272
+ let caughtError;
273
+ try {
274
+ await commandBody();
275
+ }
276
+ catch (ex) {
277
+ caughtError = ex instanceof Error ? ex : new Error(String(ex));
278
+ errorCode =
279
+ caughtError instanceof errorUtils.CodedError
280
+ ? caughtError.type
281
+ : 'Unknown';
282
+ TelemetryTest.trackException(caughtError);
283
+ }
284
+ TelemetryTest.endCommand(getTestCommandEndInfo(errorCode), getExtraProps());
285
+ }
286
+ /** Verifies the contents of events fired during the 'test-command'. */
287
+ function verifyTestCommandTelemetryProcessor(caughtErrors, expectedResultCode, expectedError) {
288
+ return (envelope, _) => {
289
+ var _a, _b, _c, _d;
290
+ try {
291
+ // Processor has run, so the test can (potentially) pass
292
+ TelemetryTest.setTestTelemetryProvidersRan();
293
+ // Verify roleInstance has been removed
294
+ expect(envelope.tags['ai.cloud.roleInstance']).toBeUndefined();
295
+ const properties = (_a = envelope.data.baseData) === null || _a === void 0 ? void 0 : _a.properties;
296
+ expect(properties).toBeDefined();
297
+ // Verify basics
298
+ expect(properties.commandName).toBe('test-command');
299
+ // Verify versions info
300
+ const versions = JSON.parse(properties.versions);
301
+ expect(versions).toBeDefined();
302
+ // Verify project info
303
+ const project = JSON.parse(properties.project);
304
+ expect(project).toStrictEqual(getTestCommandProjectInfo());
305
+ expect(Object.keys(versions).length).toBeGreaterThan(0);
306
+ for (const key of Object.keys(versions)) {
307
+ expect(versions[key]).toBe(TelemetryTest.getVersion(key));
308
+ }
309
+ if (envelope.data.baseType === 'ExceptionData') {
310
+ // Verify event name
311
+ expect(properties.eventName).toBe(telemetry_1.CodedErrorEventName);
312
+ // Verify exception info
313
+ const exceptions = (_b = envelope.data.baseData) === null || _b === void 0 ? void 0 : _b.exceptions;
314
+ expect(exceptions).toBeDefined();
315
+ expect(exceptions.length).toBe(1);
316
+ expect(exceptions[0].message).toBeDefined();
317
+ expect(exceptions[0].message).not.toBe('');
318
+ expect(exceptions[0].message).toBe(TelemetryTest.getPreserveErrorMessages()
319
+ ? errorUtils.sanitizeErrorMessage((expectedError === null || expectedError === void 0 ? void 0 : expectedError.message) || 'None')
320
+ : '[Removed]');
321
+ // Verify coded error info
322
+ const codedError = JSON.parse(properties.codedError);
323
+ expect(codedError).toBeDefined();
324
+ expect(codedError.type).toBe(expectedError instanceof errorUtils.CodedError
325
+ ? expectedError.type
326
+ : 'Unknown');
327
+ expect(codedError.data).toStrictEqual((_c = expectedError.data) !== null && _c !== void 0 ? _c : {});
328
+ }
329
+ else {
330
+ // Verify event name
331
+ expect((_d = envelope.data.baseData) === null || _d === void 0 ? void 0 : _d.name).toBe(telemetry_1.CommandEventName);
332
+ expect(properties.eventName).toBe(telemetry_1.CommandEventName);
333
+ // Verify command info
334
+ const expectedInfo = getTestCommandStartInfo();
335
+ const command = JSON.parse(properties.command);
336
+ expect(command).toBeDefined();
337
+ expect(command.args).toStrictEqual(expectedInfo.args);
338
+ expect(command.options).toStrictEqual(expectedInfo.options);
339
+ expect(command.defaultOptions).toStrictEqual(expectedInfo.defaultOptions);
340
+ expect(command.durationInSecs).toBeGreaterThan(0);
341
+ expect(command.resultCode).toBe(expectedResultCode !== null && expectedResultCode !== void 0 ? expectedResultCode : 'Success');
342
+ // Verify extra props
343
+ const extraProps = getExtraProps();
344
+ expect(JSON.parse(properties.extraProps)).toStrictEqual(extraProps);
345
+ }
346
+ }
347
+ catch (ex) {
348
+ caughtErrors.push(ex instanceof Error ? ex : new Error(String(ex)));
349
+ }
350
+ return true;
351
+ };
352
+ }
353
+ test('Telemetry run test command end to end, verify event fires', async () => {
354
+ await TelemetryTest.startTest();
355
+ // AI eats errors thrown in telemetry processors
356
+ const caughtErrors = [];
357
+ TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors));
358
+ await runTestCommandE2E(testCommandBody);
359
+ TelemetryTest.endTest(() => {
360
+ // Check if any errors were thrown
361
+ expect(caughtErrors).toHaveLength(0);
362
+ });
363
+ });
364
+ const testTelemetryOptions = [
365
+ { preserveErrorMessages: false },
366
+ { preserveErrorMessages: true },
367
+ ];
368
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError, verify events fire %s', async (options) => {
369
+ await TelemetryTest.startTest(options);
370
+ const expectedError = new errorUtils.CodedError('MSBuildError', 'test error');
371
+ // AI eats errors thrown in telemetry processors
372
+ const caughtErrors = [];
373
+ TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError));
374
+ await runTestCommandE2E(() => testCommandBody(expectedError));
375
+ TelemetryTest.endTest(() => {
376
+ // Check if any errors were thrown
377
+ expect(caughtErrors).toHaveLength(0);
378
+ });
379
+ });
380
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError (with error in message), verify events fire %s', async (options) => {
381
+ await TelemetryTest.startTest(options);
382
+ const expectedError = new errorUtils.CodedError('MSBuildError', 'error FOO2020: test error');
383
+ // AI eats errors thrown in telemetry processors
384
+ const caughtErrors = [];
385
+ TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError));
386
+ await runTestCommandE2E(() => testCommandBody(expectedError));
387
+ TelemetryTest.endTest(() => {
388
+ // Check if any errors were thrown
389
+ expect(caughtErrors).toHaveLength(0);
390
+ });
391
+ });
392
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with CodedError (with data), verify events fire %s', async (options) => {
393
+ await TelemetryTest.startTest(options);
394
+ const expectedError = new errorUtils.CodedError('MSBuildError', 'test error', { foo: 42 });
395
+ // AI eats errors thrown in telemetry processors
396
+ const caughtErrors = [];
397
+ TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, expectedError.type, expectedError));
398
+ await runTestCommandE2E(() => testCommandBody(expectedError));
399
+ TelemetryTest.endTest(() => {
400
+ // Check if any errors were thrown
401
+ expect(caughtErrors).toHaveLength(0);
402
+ });
403
+ });
404
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with Error, verify events fire %s', async (options) => {
405
+ await TelemetryTest.startTest(options);
406
+ const expectedError = new Error('error FOO2020: test error');
407
+ // AI eats errors thrown in telemetry processors
408
+ const caughtErrors = [];
409
+ TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, 'Unknown', expectedError));
410
+ await runTestCommandE2E(() => testCommandBody(expectedError));
411
+ TelemetryTest.endTest(() => {
412
+ // Check if any errors were thrown
413
+ expect(caughtErrors).toHaveLength(0);
414
+ });
415
+ });
416
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with Error (no message), verify events fire %s', async (options) => {
417
+ await TelemetryTest.startTest(options);
418
+ const expectedError = new Error();
419
+ // AI eats errors thrown in telemetry processors
420
+ const caughtErrors = [];
421
+ TelemetryTest.addTelemetryProcessor(verifyTestCommandTelemetryProcessor(caughtErrors, 'Unknown', expectedError));
422
+ await runTestCommandE2E(() => testCommandBody(expectedError));
423
+ TelemetryTest.endTest(() => {
424
+ // Check if any errors were thrown
425
+ expect(caughtErrors).toHaveLength(0);
426
+ });
427
+ });
428
+ function b(s) {
429
+ throw new Error('hello ' + s);
430
+ }
431
+ function a(s) {
432
+ b(s);
433
+ }
434
+ /** Verifies the contents of an exception's message and stack frames */
435
+ function getVerifyStackTelemetryProcessor(caughtErrors, expectedError) {
436
+ return (envelope, _) => {
437
+ try {
438
+ // Processor has run, so the test can (potentially) pass
439
+ TelemetryTest.setTestTelemetryProvidersRan();
440
+ if (envelope.data.baseType === 'ExceptionData') {
441
+ const data = envelope.data.baseData;
442
+ expect(data.exceptions).toBeDefined();
443
+ expect(data.exceptions.length).toBe(1);
444
+ expect(data.exceptions[0].message).toBeDefined();
445
+ expect(data.exceptions[0].message).not.toBe('');
446
+ expect(data.exceptions[0].message).toBe(TelemetryTest.getPreserveErrorMessages()
447
+ ? errorUtils.sanitizeErrorMessage(expectedError.message || 'None')
448
+ : '[Removed]');
449
+ const stack = data.exceptions[0].parsedStack;
450
+ expect(stack).toBeDefined();
451
+ expect(stack.length).toBeGreaterThan(2);
452
+ const filename = path.relative(process.cwd(), __filename);
453
+ expect(stack[0].method).toEqual('b');
454
+ expect(stack[1].method).toEqual('b');
455
+ expect(stack[2].method).toEqual('a');
456
+ expect(stack[0].fileName).toEqual(`[project_dir]\\???.ts(${filename.length})`);
457
+ expect(stack[1].fileName).toEqual(`[project_dir]\\???.ts(${filename.length})`);
458
+ expect(stack[2].fileName).toEqual(`[project_dir]\\???.ts(${filename.length})`);
459
+ }
460
+ }
461
+ catch (ex) {
462
+ caughtErrors.push(ex instanceof Error ? ex : new Error(String(ex)));
463
+ }
464
+ return true;
465
+ };
466
+ }
467
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with Error, verify sanitized message and stack %s', async (options) => {
468
+ await TelemetryTest.startTest(options);
469
+ const expectedError = new Error('hello world');
470
+ // AI eats errors thrown in telemetry processors
471
+ const caughtErrors = [];
472
+ TelemetryTest.addTelemetryProcessor(getVerifyStackTelemetryProcessor(caughtErrors, expectedError));
473
+ await runTestCommandE2E(async () => {
474
+ await promiseDelay(100);
475
+ a('world');
476
+ });
477
+ TelemetryTest.endTest(() => {
478
+ // Check if any errors were thrown
479
+ expect(caughtErrors).toHaveLength(0);
480
+ });
481
+ });
482
+ test.each(testTelemetryOptions)('Telemetry run test command end to end with Error, verify sanitized message with path and stack %s', async (options) => {
483
+ await TelemetryTest.startTest(options);
484
+ const expectedError = new Error(`hello ${process.cwd()}`);
485
+ // AI eats errors thrown in telemetry processors
486
+ const caughtErrors = [];
487
+ TelemetryTest.addTelemetryProcessor(getVerifyStackTelemetryProcessor(caughtErrors, expectedError));
488
+ await runTestCommandE2E(async () => {
489
+ await promiseDelay(100);
490
+ a(process.cwd());
491
+ });
492
+ TelemetryTest.endTest(() => {
493
+ // Check if any errors were thrown
494
+ expect(caughtErrors).toHaveLength(0);
495
+ });
496
+ });
497
497
  //# sourceMappingURL=telemetry.test.js.map