diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index fcf05eadee2..e670cfb4209 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -564,7 +564,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme const extensionTestsPath = originalFSPath(extensionTestsLocationURI); // Require the test runner via node require from the provided path - const testRunner: ITestRunner | INewTestRunner | undefined = await this._loadCommonJSModule(null, URI.file(extensionTestsPath), new ExtensionActivationTimesBuilder(false)); + const testRunner: ITestRunner | INewTestRunner | undefined = await this._loadCommonJSModule(null, extensionTestsLocationURI, new ExtensionActivationTimesBuilder(false)); if (!testRunner || typeof testRunner.run !== 'function') { throw new Error(nls.localize('extensionTestError', "Path {0} does not point to a valid extension test runner.", extensionTestsPath)); diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts index 1a198ff62e6..681e77fa6c7 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts @@ -357,7 +357,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, - extensionTestsLocationURI: undefined, // never run extension tests in web worker extension host + extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, globalStorageHome: this._environmentService.globalStorageHome, workspaceStorageHome: this._environmentService.workspaceStorageHome, webviewResourceRoot: this._environmentService.webviewResourceRoot, diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index dce8ded86a2..f05902b8399 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -32,6 +32,7 @@ import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace import { ExtensionKindController } from 'vs/workbench/services/extensions/common/extensionsUtil'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { Schemas } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; const hasOwnProperty = Object.hasOwnProperty; const NO_OP_VOID_PROMISE = Promise.resolve(undefined); @@ -428,18 +429,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx return; } - // TODO: Use `this._registry` and `this._runningLocation` to better determine which extension host should launch the test runner - let extensionHostManager: ExtensionHostManager | null = null; - if (this._environmentService.extensionTestsLocationURI.scheme === Schemas.vscodeRemote) { - extensionHostManager = this._getExtensionHostManager(ExtensionHostKind.Remote); - } - if (!extensionHostManager) { - // When a debugger attaches to the extension host, it will surface all console.log messages from the extension host, - // but not necessarily from the window. So it would be best if any errors get printed to the console of the extension host. - // That is why here we use the local process extension host even for non-file URIs - extensionHostManager = this._getExtensionHostManager(ExtensionHostKind.LocalProcess); - } - + const extensionHostManager = this.findTestExtensionHost(this._environmentService.extensionTestsLocationURI); if (!extensionHostManager) { const msg = nls.localize('extensionTestError', "No extension host found that can launch the test runner at {0}.", this._environmentService.extensionTestsLocationURI.toString()); console.error(msg); @@ -447,6 +437,7 @@ export abstract class AbstractExtensionService extends Disposable implements IEx return; } + let exitCode: number; try { exitCode = await extensionHostManager.extensionTestsExecute(); @@ -459,6 +450,40 @@ export abstract class AbstractExtensionService extends Disposable implements IEx this._onExtensionHostExit(exitCode); } + private findTestExtensionHost(testLocation: URI): ExtensionHostManager | undefined | null { + let extensionHostKind: ExtensionHostKind | undefined; + + for (const extension of this._registry.getAllExtensionDescriptions()) { + if (isEqualOrParent(testLocation, extension.extensionLocation)) { + const runningLocation = this._runningLocation.get(ExtensionIdentifier.toKey(extension.identifier)); + if (runningLocation === ExtensionRunningLocation.LocalProcess) { + extensionHostKind = ExtensionHostKind.LocalProcess; + } else if (runningLocation === ExtensionRunningLocation.LocalWebWorker) { + extensionHostKind = ExtensionHostKind.LocalWebWorker; + } else if (runningLocation === ExtensionRunningLocation.Remote) { + extensionHostKind = ExtensionHostKind.Remote; + } + break; + } + } + if (extensionHostKind === undefined) { + // not sure if we should support that, but it was possible to have an test outside an extension + + if (testLocation.scheme === Schemas.vscodeRemote) { + extensionHostKind = ExtensionHostKind.Remote; + } else { + // When a debugger attaches to the extension host, it will surface all console.log messages from the extension host, + // but not necessarily from the window. So it would be best if any errors get printed to the console of the extension host. + // That is why here we use the local process extension host even for non-file URIs + extensionHostKind = ExtensionHostKind.LocalProcess; + } + } + if (extensionHostKind !== undefined) { + return this._getExtensionHostManager(extensionHostKind); + } + return undefined; + } + private _releaseBarrier(): void { this._installedExtensionsReady.open(); this._onDidRegisterExtensions.fire(undefined);