Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79 (#14050)

* Merge from vscode 2c306f762bf9c3db82dc06c7afaa56ef46d72f79

* Fix breaks

* Extension management fixes

* Fix breaks in windows bundling

* Fix/skip failing tests

* Update distro

* Add clear to nuget.config

* Add hygiene task

* Bump distro

* Fix hygiene issue

* Add build to hygiene exclusion

* Update distro

* Update hygiene

* Hygiene exclusions

* Update tsconfig

* Bump distro for server breaks

* Update build config

* Update darwin path

* Add done calls to notebook tests

* Skip failing tests

* Disable smoke tests
This commit is contained in:
Karl Burtram
2021-02-09 16:15:05 -08:00
committed by GitHub
parent 6f192f9af5
commit ce612a3d96
1929 changed files with 68012 additions and 34564 deletions

View File

@@ -5,7 +5,7 @@
import { toDisposable } from 'vs/base/common/lifecycle';
import { globals } from 'vs/base/common/platform';
import BaseErrorTelemetry, { ErrorEvent } from '../common/errorTelemetry';
import BaseErrorTelemetry, { ErrorEvent } from 'vs/platform/telemetry/common/errorTelemetry';
export default class ErrorTelemetry extends BaseErrorTelemetry {
protected installErrorListeners(): void {

View File

@@ -1,87 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import * as Platform from 'vs/base/common/platform';
import * as uuid from 'vs/base/common/uuid';
import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtils';
import { mixin } from 'vs/base/common/objects';
import { firstSessionDateStorageKey, lastSessionDateStorageKey, machineIdKey } from 'vs/platform/telemetry/common/telemetry';
import product from 'vs/platform/product/common/product'; // {{SQL CARBON EDIT}}
export async function resolveWorkbenchCommonProperties(
storageService: IStorageService,
commit: string | undefined,
version: string | undefined,
remoteAuthority?: string,
resolveAdditionalProperties?: () => { [key: string]: any }
): Promise<{ [name: string]: string | undefined }> {
const result: { [name: string]: string | undefined; } = Object.create(null);
const firstSessionDate = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL)!;
const lastSessionDate = storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL)!;
let machineId = storageService.get(machineIdKey, StorageScope.GLOBAL);
if (!machineId) {
machineId = uuid.generateUuid();
storageService.store(machineIdKey, machineId, StorageScope.GLOBAL);
}
/**
* Note: In the web, session date information is fetched from browser storage, so these dates are tied to a specific
* browser and not the machine overall.
*/
// __GDPR__COMMON__ "common.firstSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.firstSessionDate'] = firstSessionDate;
// __GDPR__COMMON__ "common.lastSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.lastSessionDate'] = lastSessionDate || '';
// __GDPR__COMMON__ "common.isNewSession" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.isNewSession'] = !lastSessionDate ? '1' : '0';
// __GDPR__COMMON__ "common.remoteAuthority" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
result['common.remoteAuthority'] = cleanRemoteAuthority(remoteAuthority);
// __GDPR__COMMON__ "common.machineId" : { "endPoint": "MacAddressHash", "classification": "EndUserPseudonymizedInformation", "purpose": "FeatureInsight" }
result['common.machineId'] = machineId;
// __GDPR__COMMON__ "sessionID" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['sessionID'] = uuid.generateUuid() + Date.now();
// __GDPR__COMMON__ "commitHash" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
result['commitHash'] = commit;
// __GDPR__COMMON__ "version" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['version'] = version;
// __GDPR__COMMON__ "common.platform" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.platform'] = Platform.PlatformToString(Platform.platform);
// __GDPR__COMMON__ "common.product" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
result['common.product'] = 'web';
// __GDPR__COMMON__ "common.userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.userAgent'] = Platform.userAgent;
result['quality'] = product.quality || 'dev'; // {{SQL CARBON EDIT}} Add quality
// dynamic properties which value differs on each call
let seq = 0;
const startTime = Date.now();
Object.defineProperties(result, {
// __GDPR__COMMON__ "timestamp" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
'timestamp': {
get: () => new Date(),
enumerable: true
},
// __GDPR__COMMON__ "common.timesincesessionstart" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
'common.timesincesessionstart': {
get: () => Date.now() - startTime,
enumerable: true
},
// __GDPR__COMMON__ "common.sequence" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
'common.sequence': {
get: () => seq++,
enumerable: true
}
});
if (resolveAdditionalProperties) {
mixin(result, resolveAdditionalProperties());
}
return result;
}

View File

@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILogger, ILoggerService } from 'vs/platform/log/common/log';
import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils';
export class TelemetryLogAppender extends Disposable implements ITelemetryAppender {
private readonly logger: ILogger;
constructor(
@ILoggerService loggerService: ILoggerService,
@IEnvironmentService environmentService: IEnvironmentService
) {
super();
this.logger = this._register(loggerService.getLogger(environmentService.telemetryLogResource));
this.logger.info('The below are logs for every telemetry event sent from VS Code once the log level is set to trace.');
this.logger.info('===========================================================');
}
flush(): Promise<any> {
return Promise.resolve(undefined);
}
log(eventName: string, data: any): void {
this.logger.trace(`telemetry/${eventName}`, validateTelemetryData(data));
}
}

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import product from 'vs/platform/product/common/product';
import { localize } from 'vs/nls';
import { escapeRegExpCharacters } from 'vs/base/common/strings';
import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
@@ -207,6 +208,7 @@ export class TelemetryService implements ITelemetryService {
const TELEMETRY_SECTION_ID = 'telemetry';
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
'id': TELEMETRY_SECTION_ID,
'order': 110,
@@ -215,7 +217,10 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
'properties': {
'telemetry.enableTelemetry': {
'type': 'boolean',
'description': localize('telemetry.enableTelemetry', "Enable usage data and errors to be sent to a Microsoft online service."),
'markdownDescription':
!product.privacyStatementUrl ?
localize('telemetry.enableTelemetry', "Enable usage data and errors to be sent to a Microsoft online service.") :
localize('telemetry.enableTelemetryMd', "Enable usage data and errors to be sent to a Microsoft online service. Read our privacy statement [here]({0}).", product.privacyStatementUrl),
'default': true,
'tags': ['usesOnlineServices']
}

View File

@@ -6,7 +6,6 @@
import { IDisposable } from 'vs/base/common/lifecycle';
import { IConfigurationService, ConfigurationTarget, ConfigurationTargetToString } from 'vs/platform/configuration/common/configuration';
import { ITelemetryService, ITelemetryInfo, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { ILogService } from 'vs/platform/log/common/log';
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
import { safeStringify } from 'vs/base/common/objects';
import { isObject } from 'vs/base/common/types';
@@ -55,26 +54,6 @@ export function combinedAppender(...appenders: ITelemetryAppender[]): ITelemetry
export const NullAppender: ITelemetryAppender = { log: () => null, flush: () => Promise.resolve(null) };
export class LogAppender implements ITelemetryAppender {
private commonPropertiesRegex = /^sessionID$|^version$|^timestamp$|^commitHash$|^common\./;
constructor(@ILogService private readonly _logService: ILogService) { }
flush(): Promise<any> {
return Promise.resolve(undefined);
}
log(eventName: string, data: any): void {
const strippedData: { [key: string]: any } = {};
Object.keys(data).forEach(key => {
if (!this.commonPropertiesRegex.test(key)) {
strippedData[key] = data[key];
}
});
this._logService.trace(`telemetry/${eventName}`, strippedData);
}
}
/* __GDPR__FRAGMENT__
"URIDescriptor" : {
"mimeType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },

View File

@@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import * as appInsights from 'applicationinsights';
import { onUnexpectedError } from 'vs/base/common/errors';
import { mixin } from 'vs/base/common/objects';
import { ITelemetryAppender, validateTelemetryData } from 'vs/platform/telemetry/common/telemetryUtils';
import { ILogService } from 'vs/platform/log/common/log';
function getClient(aiKey: string): appInsights.TelemetryClient {
async function getClient(aiKey: string): Promise<appInsights.TelemetryClient> {
const appInsights = await import('applicationinsights');
let client: appInsights.TelemetryClient;
if (appInsights.defaultClient) {
client = new appInsights.TelemetryClient(aiKey);
@@ -37,23 +37,49 @@ function getClient(aiKey: string): appInsights.TelemetryClient {
export class AppInsightsAppender implements ITelemetryAppender {
private _aiClient?: appInsights.TelemetryClient;
private _aiClient: string | appInsights.TelemetryClient | undefined;
private _asyncAIClient: Promise<appInsights.TelemetryClient> | null;
constructor(
private _eventPrefix: string,
private _defaultData: { [key: string]: any } | null,
aiKeyOrClientFactory: string | (() => appInsights.TelemetryClient), // allow factory function for testing
@ILogService private _logService?: ILogService
) {
if (!this._defaultData) {
this._defaultData = Object.create(null);
}
if (typeof aiKeyOrClientFactory === 'string') {
this._aiClient = getClient(aiKeyOrClientFactory);
} else if (typeof aiKeyOrClientFactory === 'function') {
if (typeof aiKeyOrClientFactory === 'function') {
this._aiClient = aiKeyOrClientFactory();
} else {
this._aiClient = aiKeyOrClientFactory;
}
this._asyncAIClient = null;
}
private _withAIClient(callback: (aiClient: appInsights.TelemetryClient) => void): void {
if (!this._aiClient) {
return;
}
if (typeof this._aiClient !== 'string') {
callback(this._aiClient);
return;
}
if (!this._asyncAIClient) {
this._asyncAIClient = getClient(this._aiClient);
}
this._asyncAIClient.then(
(aiClient) => {
callback(aiClient);
},
(err) => {
onUnexpectedError(err);
console.error(err);
}
);
}
log(eventName: string, data?: any): void {
@@ -63,25 +89,24 @@ export class AppInsightsAppender implements ITelemetryAppender {
data = mixin(data, this._defaultData);
data = validateTelemetryData(data);
if (this._logService) {
this._logService.trace(`telemetry/${eventName}`, data);
}
this._aiClient.trackEvent({
this._withAIClient((aiClient) => aiClient.trackEvent({
name: this._eventPrefix + '/' + eventName,
properties: data.properties,
measurements: data.measurements
});
}));
}
flush(): Promise<any> {
if (this._aiClient) {
return new Promise(resolve => {
this._aiClient!.flush({
callback: () => {
// all data flushed
this._aiClient = undefined;
resolve(undefined);
}
this._withAIClient((aiClient) => {
aiClient.flush({
callback: () => {
// all data flushed
this._aiClient = undefined;
resolve(undefined);
}
});
});
});
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { onUnexpectedError, setUnexpectedErrorHandler } from 'vs/base/common/errors';
import BaseErrorTelemetry from '../common/errorTelemetry';
import BaseErrorTelemetry from 'vs/platform/telemetry/common/errorTelemetry';
export default class ErrorTelemetry extends BaseErrorTelemetry {
protected installErrorListeners(): void {

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { readdirSync } from 'vs/base/node/pfs';
import { statSync, readFileSync } from 'fs';
import { join } from 'vs/base/common/path';
@@ -43,4 +42,4 @@ export function buildTelemetryMessage(appRoot: string, extensionsPath?: string):
contents = readFileSync(join(appRoot, 'telemetry-extensions.json')).toString();
mergeTelemetry(contents, 'vscode-extensions');
return JSON.stringify(mergedTelemetry, null, 4);
}
}

View File

@@ -1,62 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
import { instanceStorageKey, firstSessionDateStorageKey, lastSessionDateStorageKey } from 'vs/platform/telemetry/common/telemetry';
import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtils';
import product from 'vs/platform/product/common/product'; // {{ SQL CARBON EDIT }}
export async function resolveWorkbenchCommonProperties(
storageService: IStorageService,
commit: string | undefined,
version: string | undefined,
machineId: string,
msftInternalDomains: string[] | undefined,
installSourcePath: string,
remoteAuthority?: string
): Promise<{ [name: string]: string | boolean | undefined }> {
const result = await resolveCommonProperties(commit, version, machineId, msftInternalDomains, installSourcePath, undefined);
const instanceId = storageService.get(instanceStorageKey, StorageScope.GLOBAL)!;
const firstSessionDate = storageService.get(firstSessionDateStorageKey, StorageScope.GLOBAL)!;
const lastSessionDate = storageService.get(lastSessionDateStorageKey, StorageScope.GLOBAL)!;
// __GDPR__COMMON__ "common.version.shell" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
result['common.version.shell'] = process.versions && process.versions['electron'];
// __GDPR__COMMON__ "common.version.renderer" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
result['common.version.renderer'] = process.versions && process.versions['chrome'];
// __GDPR__COMMON__ "common.firstSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.firstSessionDate'] = firstSessionDate;
// __GDPR__COMMON__ "common.lastSessionDate" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.lastSessionDate'] = lastSessionDate || '';
// __GDPR__COMMON__ "common.isNewSession" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.isNewSession'] = !lastSessionDate ? '1' : '0';
// __GDPR__COMMON__ "common.instanceId" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
result['common.instanceId'] = instanceId;
// __GDPR__COMMON__ "common.remoteAuthority" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
result['common.remoteAuthority'] = cleanRemoteAuthority(remoteAuthority);
result['common.application.name'] = product.nameLong; // {{SQL CARBON EDIT}}
setUsageDates(storageService);
return result;
}
// {{SQL CARBON EDIT}}
function setUsageDates(storageService: IStorageService): void {
// daily last usage date
const appStartDate = new Date('January 1, 2000');
const dailyLastUseDate = storageService.get('telemetry.dailyLastUseDate', StorageScope.GLOBAL, appStartDate.toUTCString());
storageService.store('telemetry.dailyLastUseDate', dailyLastUseDate, StorageScope.GLOBAL);
// weekly last usage date
const weeklyLastUseDate = storageService.get('telemetry.weeklyLastUseDate', StorageScope.GLOBAL, appStartDate.toUTCString());
storageService.store('telemetry.weeklyLastUseDate', weeklyLastUseDate, StorageScope.GLOBAL);
// monthly last usage date
const monthlyLastUseDate = storageService.get('telemetry.monthlyLastUseDate', StorageScope.GLOBAL, appStartDate.toUTCString());
storageService.store('telemetry.monthlyLastUseDate', monthlyLastUseDate, StorageScope.GLOBAL);
}

View File

@@ -1,62 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/browser/workbenchCommonProperties';
import { IStorageService, InMemoryStorageService } from 'vs/platform/storage/common/storage';
suite('Browser Telemetry - common properties', function () {
const commit: string = (undefined)!;
const version: string = (undefined)!;
let testStorageService: IStorageService;
setup(() => {
testStorageService = new InMemoryStorageService();
});
test('mixes in additional properties', async function () {
const resolveCommonTelemetryProperties = () => {
return {
'userId': '1'
};
};
const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, undefined, resolveCommonTelemetryProperties);
assert.ok('commitHash' in props);
assert.ok('sessionID' in props);
assert.ok('timestamp' in props);
assert.ok('common.platform' in props);
assert.ok('common.timesincesessionstart' in props);
assert.ok('common.sequence' in props);
assert.ok('version' in props);
assert.ok('common.firstSessionDate' in props, 'firstSessionDate');
assert.ok('common.lastSessionDate' in props, 'lastSessionDate');
assert.ok('common.isNewSession' in props, 'isNewSession');
assert.ok('common.machineId' in props, 'machineId');
assert.equal(props['userId'], '1');
});
test('mixes in additional dyanmic properties', async function () {
let i = 1;
const resolveCommonTelemetryProperties = () => {
return Object.defineProperties({}, {
'userId': {
get: () => {
return i++;
},
enumerable: true
}
});
};
const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, undefined, resolveCommonTelemetryProperties);
assert.equal(props['userId'], '1');
const props2 = await resolveWorkbenchCommonProperties(testStorageService, commit, version, undefined, resolveCommonTelemetryProperties);
assert.equal(props2['userId'], '2');
});
});

View File

@@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { LogLevel, ILoggerService, AbstractLogService, DEFAULT_LOG_LEVEL, ILogger } from 'vs/platform/log/common/log';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogAppender';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
class TestTelemetryLogger extends AbstractLogService implements ILogger {
declare readonly _serviceBrand: undefined;
public logs: string[] = [];
constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
super();
this.setLevel(logLevel);
}
trace(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Trace) {
this.logs.push(message + JSON.stringify(args));
}
}
debug(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Debug) {
this.logs.push(message);
}
}
info(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Info) {
this.logs.push(message);
}
}
warn(message: string | Error, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Warning) {
this.logs.push(message.toString());
}
}
error(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Error) {
this.logs.push(message);
}
}
critical(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Critical) {
this.logs.push(message);
}
}
dispose(): void { }
flush(): void { }
}
class TestTelemetryLoggerService implements ILoggerService {
_serviceBrand: undefined;
logger: TestTelemetryLogger;
constructor(logLevel: LogLevel) {
this.logger = new TestTelemetryLogger(logLevel);
}
getLogger(): ILogger {
return this.logger;
}
}
suite('TelemetryLogAdapter', () => {
test('Do not Log Telemetry if log level is not trace', async () => {
const testLoggerService = new TestTelemetryLoggerService(DEFAULT_LOG_LEVEL);
const testObject = new TelemetryLogAppender(testLoggerService, new TestInstantiationService().stub(IEnvironmentService, {}));
testObject.log('testEvent', { hello: 'world', isTrue: true, numberBetween1And3: 2 });
assert.equal(testLoggerService.logger.logs.length, 2);
});
test('Log Telemetry if log level is trace', async () => {
const testLoggerService = new TestTelemetryLoggerService(LogLevel.Trace);
const testObject = new TelemetryLogAppender(testLoggerService, new TestInstantiationService().stub(IEnvironmentService, {}));
testObject.log('testEvent', { hello: 'world', isTrue: true, numberBetween1And3: 2 });
assert.equal(testLoggerService.logger.logs[2], 'telemetry/testEvent' + JSON.stringify([{
properties: {
hello: 'world',
},
measurements: {
isTrue: 1, numberBetween1And3: 2
}
}]));
});
});

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
import { ILogService, AbstractLogService, LogLevel, DEFAULT_LOG_LEVEL } from 'vs/platform/log/common/log';
import { TelemetryClient, Contracts } from 'applicationinsights';
class AppInsightsMock extends TelemetryClient {
@@ -27,56 +26,6 @@ class AppInsightsMock extends TelemetryClient {
}
}
class TestableLogService extends AbstractLogService implements ILogService {
declare readonly _serviceBrand: undefined;
public logs: string[] = [];
constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
super();
this.setLevel(logLevel);
}
trace(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Trace) {
this.logs.push(message + JSON.stringify(args));
}
}
debug(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Debug) {
this.logs.push(message);
}
}
info(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Info) {
this.logs.push(message);
}
}
warn(message: string | Error, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Warning) {
this.logs.push(message.toString());
}
}
error(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Error) {
this.logs.push(message);
}
}
critical(message: string, ...args: any[]): void {
if (this.getLevel() <= LogLevel.Critical) {
this.logs.push(message);
}
}
dispose(): void { }
flush(): void { }
}
suite('AIAdapter', () => {
let appInsightsMock: AppInsightsMock;
let adapter: AppInsightsAppender;
@@ -181,26 +130,4 @@ suite('AIAdapter', () => {
assert.equal(appInsightsMock.events[0].measurements!['nestedObj.testMeasurement'], 1);
});
test('Do not Log Telemetry if log level is not trace', () => {
const logService = new TestableLogService(LogLevel.Info);
adapter = new AppInsightsAppender(prefix, { 'common.platform': 'Windows' }, () => appInsightsMock, logService);
adapter.log('testEvent', { hello: 'world', isTrue: true, numberBetween1And3: 2 });
assert.equal(logService.logs.length, 0);
});
test('Log Telemetry if log level is trace', () => {
const logService = new TestableLogService(LogLevel.Trace);
adapter = new AppInsightsAppender(prefix, { 'common.platform': 'Windows' }, () => appInsightsMock, logService);
adapter.log('testEvent', { hello: 'world', isTrue: true, numberBetween1And3: 2 });
assert.equal(logService.logs.length, 1);
assert.equal(logService.logs[0], 'telemetry/testEvent' + JSON.stringify([{
properties: {
hello: 'world',
'common.platform': 'Windows'
},
measurements: {
isTrue: 1, numberBetween1And3: 2
}
}]));
});
});

View File

@@ -1,84 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import * as path from 'vs/base/common/path';
import * as os from 'os';
import * as fs from 'fs';
import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties';
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
import { IStorageService, StorageScope, InMemoryStorageService } from 'vs/platform/storage/common/storage';
import { mkdirp, rimraf, RimRafMode } from 'vs/base/node/pfs';
import { timeout } from 'vs/base/common/async';
suite('Telemetry - common properties', function () {
const parentDir = getRandomTestPath(os.tmpdir(), 'vsctests', 'telemetryservice');
const installSource = path.join(parentDir, 'installSource');
const commit: string = (undefined)!;
const version: string = (undefined)!;
let testStorageService: IStorageService;
setup(() => {
testStorageService = new InMemoryStorageService();
});
teardown(done => {
rimraf(parentDir, RimRafMode.MOVE).then(done, done);
});
test.skip('default', async function () { // {{SQL CARBON EDIT}} skip test
await mkdirp(parentDir);
fs.writeFileSync(installSource, 'my.install.source');
const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource);
assert.ok('commitHash' in props);
assert.ok('sessionID' in props);
assert.ok('timestamp' in props);
assert.ok('common.platform' in props);
assert.ok('common.nodePlatform' in props);
assert.ok('common.nodeArch' in props);
assert.ok('common.timesincesessionstart' in props);
assert.ok('common.sequence' in props);
// assert.ok('common.version.shell' in first.data); // only when running on electron
// assert.ok('common.version.renderer' in first.data);
assert.ok('common.platformVersion' in props, 'platformVersion');
assert.ok('version' in props);
assert.equal(props['common.source'], 'my.install.source');
assert.ok('common.firstSessionDate' in props, 'firstSessionDate');
assert.ok('common.lastSessionDate' in props, 'lastSessionDate'); // conditional, see below, 'lastSessionDate'ow
assert.ok('common.isNewSession' in props, 'isNewSession');
// machine id et al
assert.ok('common.instanceId' in props, 'instanceId');
assert.ok('common.machineId' in props, 'machineId');
fs.unlinkSync(installSource);
const props_1 = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource);
assert.ok(!('common.source' in props_1));
});
test.skip('lastSessionDate when aviablale', async function () { // {{SQL CARBON EDIT}} skip test
testStorageService.store('telemetry.lastSessionDate', new Date().toUTCString(), StorageScope.GLOBAL);
const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource);
assert.ok('common.lastSessionDate' in props); // conditional, see below
assert.ok('common.isNewSession' in props);
assert.equal(props['common.isNewSession'], 0);
});
test.skip('values chance on ask', async function () { // {{SQL CARBON EDIT}} skip test
const props = await resolveWorkbenchCommonProperties(testStorageService, commit, version, 'someMachineId', undefined, installSource);
let value1 = props['common.sequence'];
let value2 = props['common.sequence'];
assert.ok(value1 !== value2, 'seq');
value1 = props['timestamp'];
value2 = props['timestamp'];
assert.ok(value1 !== value2, 'timestamp');
value1 = props['common.timesincesessionstart'];
await timeout(10);
value2 = props['common.timesincesessionstart'];
assert.ok(value1 !== value2, 'timesincesessionstart');
});
});