-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10461 from OfficeDev/aochengwang/testtool-binary2
feat: expose test tool checker for VS
- Loading branch information
Showing
8 changed files
with
388 additions
and
1 deletion.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
packages/fx-core/src/common/deps-checker/coreDepsLoggerAdapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
import { LogLevel, LogProvider } from "@microsoft/teamsfx-api"; | ||
import os from "os"; | ||
import { DepsLogger } from "./depsLogger"; | ||
|
||
export class CoreDepsLoggerAdapter implements DepsLogger { | ||
private detailLogLines: string[] = []; | ||
private logProvider: LogProvider; | ||
|
||
public constructor(logProvider: LogProvider) { | ||
this.logProvider = logProvider; | ||
} | ||
|
||
public debug(message: string): void { | ||
this.addToDetailCache(LogLevel.Debug, message); | ||
} | ||
|
||
public info(message: string): void { | ||
this.addToDetailCache(LogLevel.Info, message); | ||
this.logProvider.info(message); | ||
} | ||
|
||
public warning(message: string): void { | ||
this.addToDetailCache(LogLevel.Warning, message); | ||
this.logProvider.warning(message); | ||
} | ||
|
||
public error(message: string): void { | ||
this.addToDetailCache(LogLevel.Error, message); | ||
this.logProvider.error(message); | ||
} | ||
|
||
public appendLine(message: string): void { | ||
this.logProvider.log(LogLevel.Info, message); | ||
} | ||
|
||
public append(message: string): void { | ||
this.logProvider.log(LogLevel.Info, message); | ||
} | ||
|
||
public cleanup(): void { | ||
this.detailLogLines = []; | ||
} | ||
|
||
public printDetailLog(): void { | ||
this.logProvider.error(this.detailLogLines.join(os.EOL)); | ||
} | ||
|
||
private addToDetailCache(level: LogLevel, message: string): void { | ||
const line = `${String(LogLevel[level])} ${new Date().toISOString()}: ${message}`; | ||
this.detailLogLines.push(line); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
packages/fx-core/src/common/deps-checker/coreDepsTelemetryAdapter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
import { DepsTelemetry } from "./depsTelemetry"; | ||
import { SystemError, TelemetryReporter, UserError } from "@microsoft/teamsfx-api"; | ||
import os from "os"; | ||
import { DepsCheckerEvent, TelemetryMessurement } from "./constant"; | ||
import { TelemetryProperty, fillInTelemetryPropsForFxError } from "../telemetry"; | ||
import { TelemetryMeasurement } from "../../component/utils/depsChecker/common"; | ||
|
||
export class CoreDepsTelemetryAdapter implements DepsTelemetry { | ||
private readonly _telemetryComponentType = "core:debug:envchecker"; | ||
private readonly _telemetryReporter: TelemetryReporter; | ||
|
||
constructor(telemetryReporter: TelemetryReporter) { | ||
this._telemetryReporter = telemetryReporter; | ||
} | ||
|
||
public sendEvent( | ||
eventName: DepsCheckerEvent, | ||
properties: { [key: string]: string } = {}, | ||
timecost?: number | ||
): void { | ||
this.addCommonProps(properties); | ||
const measurements: { [p: string]: number } = {}; | ||
|
||
if (timecost) { | ||
measurements[TelemetryMessurement.completionTime] = timecost; | ||
} | ||
|
||
this._telemetryReporter.sendTelemetryEvent(eventName, properties, measurements); | ||
} | ||
|
||
public async sendEventWithDuration( | ||
eventName: DepsCheckerEvent, | ||
action: () => Promise<void> | ||
): Promise<void> { | ||
const start = performance.now(); | ||
await action(); | ||
// use seconds instead of milliseconds | ||
const timecost = Number(((performance.now() - start) / 1000).toFixed(2)); | ||
this.sendEvent(eventName, {}, timecost); | ||
} | ||
|
||
public sendUserErrorEvent(eventName: DepsCheckerEvent, errorMessage: string): void { | ||
const properties: { [key: string]: string } = {}; | ||
const error = new UserError(this._telemetryComponentType, eventName, errorMessage); | ||
fillInTelemetryPropsForFxError(properties, error); | ||
this._telemetryReporter.sendTelemetryErrorEvent(eventName, { | ||
...this.addCommonProps(), | ||
...properties, | ||
}); | ||
} | ||
|
||
public sendSystemErrorEvent( | ||
eventName: DepsCheckerEvent, | ||
errorMessage: string, | ||
errorStack: string | ||
): void { | ||
const properties: { [key: string]: string } = {}; | ||
const error = new SystemError( | ||
this._telemetryComponentType, | ||
eventName, | ||
`errorMsg=${errorMessage},errorStack=${errorStack}` | ||
); | ||
error.stack = errorStack; | ||
fillInTelemetryPropsForFxError(properties, error); | ||
this._telemetryReporter.sendTelemetryErrorEvent(eventName, { | ||
...this.addCommonProps(), | ||
...properties, | ||
}); | ||
} | ||
|
||
private addCommonProps(properties: { [key: string]: string } = {}): { [key: string]: string } { | ||
properties[TelemetryMeasurement.OSArch] = os.arch(); | ||
properties[TelemetryMeasurement.OSRelease] = os.release(); | ||
properties[TelemetryProperty.Component] = this._telemetryComponentType; | ||
return properties; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
packages/fx-core/tests/common/deps-checker/coreDepsLoggerAdapter.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
/** | ||
* @author Aocheng Wang <aochengwang@microsoft.com> | ||
*/ | ||
import "mocha"; | ||
|
||
import chai from "chai"; | ||
import * as sinon from "sinon"; | ||
import { LogProvider } from "@microsoft/teamsfx-api"; | ||
import { CoreDepsLoggerAdapter } from "../../../src/common/deps-checker/coreDepsLoggerAdapter"; | ||
|
||
describe("CoreDepsLoggerAdapter", () => { | ||
const sandbox = sinon.createSandbox(); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
}); | ||
|
||
it("append", () => { | ||
// Arrange | ||
let text = ""; | ||
const stub = sandbox.stub().callsFake((_level, _text: string) => (text = _text)); | ||
const logProvider = { log: stub } as any as LogProvider; | ||
|
||
// Act | ||
const adapter = new CoreDepsLoggerAdapter(logProvider); | ||
adapter.append("test"); | ||
|
||
// Assert | ||
chai.assert.match(text, /test/); | ||
}); | ||
|
||
it("appendLine", () => { | ||
// Arrange | ||
let text = ""; | ||
const stub = sandbox.stub().callsFake((_level, _text: string) => (text = _text)); | ||
const logProvider = { log: stub } as any as LogProvider; | ||
|
||
// Act | ||
const adapter = new CoreDepsLoggerAdapter(logProvider); | ||
adapter.appendLine("test"); | ||
|
||
// Assert | ||
chai.assert.match(text, /test/); | ||
}); | ||
|
||
it("error", () => { | ||
// Arrange | ||
let text = ""; | ||
const stub = sandbox.stub().callsFake((_text: string) => (text = _text)); | ||
const logProvider = { error: stub } as any as LogProvider; | ||
|
||
// Act | ||
const adapter = new CoreDepsLoggerAdapter(logProvider); | ||
adapter.error("test"); | ||
|
||
// Assert | ||
chai.assert.match(text, /test/); | ||
}); | ||
|
||
it("info", () => { | ||
// Arrange | ||
let text = ""; | ||
const stub = sandbox.stub().callsFake((_text: string) => (text = _text)); | ||
const logProvider = { info: stub } as any as LogProvider; | ||
|
||
// Act | ||
const adapter = new CoreDepsLoggerAdapter(logProvider); | ||
adapter.info("test"); | ||
|
||
// Assert | ||
chai.assert.match(text, /test/); | ||
}); | ||
|
||
it("warning", () => { | ||
// Arrange | ||
let text = ""; | ||
const stub = sandbox.stub().callsFake((_text: string) => (text = _text)); | ||
const logProvider = { warning: stub } as any as LogProvider; | ||
|
||
// Act | ||
const adapter = new CoreDepsLoggerAdapter(logProvider); | ||
adapter.warning("test"); | ||
|
||
// Assert | ||
chai.assert.match(text, /test/); | ||
}); | ||
|
||
it("debug", () => { | ||
// Arrange | ||
let text = ""; | ||
const stub = sandbox.stub().callsFake((_text: string) => (text = _text)); | ||
const logProvider = { error: stub } as any as LogProvider; | ||
|
||
// Act | ||
const adapter = new CoreDepsLoggerAdapter(logProvider); | ||
adapter.debug("error"); | ||
adapter.printDetailLog(); | ||
|
||
// Assert | ||
chai.assert.match(text, /error/); | ||
}); | ||
}); |
82 changes: 82 additions & 0 deletions
82
packages/fx-core/tests/common/deps-checker/coreDepsTelemetryAdapter.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
/** | ||
* @author Aocheng Wang <aochengwang@microsoft.com> | ||
*/ | ||
import "mocha"; | ||
|
||
import chai from "chai"; | ||
import os from "os"; | ||
import * as sinon from "sinon"; | ||
import { TelemetryReporter } from "@microsoft/teamsfx-api"; | ||
import { CoreDepsTelemetryAdapter } from "../../../src/common/deps-checker/coreDepsTelemetryAdapter"; | ||
import { DepsCheckerEvent } from "../../../src/common/deps-checker/constant"; | ||
|
||
describe("CoreDepsTelemetryAdapter", () => { | ||
const sandbox = sinon.createSandbox(); | ||
|
||
beforeEach(() => { | ||
sandbox.stub(os, "arch").returns("mock"); | ||
sandbox.stub(os, "release").returns("mock"); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
}); | ||
|
||
it("sendEvent", () => { | ||
// Arrange | ||
const stub = sandbox.stub(); | ||
const reporter = { sendTelemetryEvent: stub } as any as TelemetryReporter; | ||
|
||
// Act | ||
const adapter = new CoreDepsTelemetryAdapter(reporter); | ||
adapter.sendEvent(DepsCheckerEvent.dotnetAlreadyInstalled, { property1: "value1" }, 42); | ||
|
||
// Assert | ||
sinon.assert.calledWith( | ||
stub, | ||
DepsCheckerEvent.dotnetAlreadyInstalled, | ||
{ | ||
component: "core:debug:envchecker", | ||
["os-arch"]: "mock", | ||
["os-release"]: "mock", | ||
property1: "value1", | ||
}, | ||
{ ["completion-time"]: 42 } | ||
); | ||
}); | ||
it("sendUserErrorEvent", () => { | ||
// Arrange | ||
let eventName = ""; | ||
const telemetryReporter = { | ||
sendTelemetryErrorEvent(_eventName: string) { | ||
eventName = _eventName; | ||
}, | ||
} as any as TelemetryReporter; | ||
|
||
// Act | ||
const adapter = new CoreDepsTelemetryAdapter(telemetryReporter); | ||
adapter.sendUserErrorEvent(DepsCheckerEvent.dotnetAlreadyInstalled, "error"); | ||
|
||
// Assert | ||
chai.assert.equal(eventName, DepsCheckerEvent.dotnetAlreadyInstalled); | ||
}); | ||
it("sendSystemErrorEvent", () => { | ||
// Arrange | ||
let eventName = ""; | ||
const telemetryReporter = { | ||
sendTelemetryErrorEvent(_eventName: string) { | ||
eventName = _eventName; | ||
}, | ||
} as any as TelemetryReporter; | ||
|
||
// Act | ||
const adapter = new CoreDepsTelemetryAdapter(telemetryReporter); | ||
adapter.sendUserErrorEvent(DepsCheckerEvent.dotnetAlreadyInstalled, "error"); | ||
|
||
// Assert | ||
chai.assert.equal(eventName, DepsCheckerEvent.dotnetAlreadyInstalled); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.