diff --git a/.github/workflows/actions/test-and-build/action.yaml b/.github/workflows/actions/test-and-build/action.yaml index b847cb0e0..f10658fa0 100644 --- a/.github/workflows/actions/test-and-build/action.yaml +++ b/.github/workflows/actions/test-and-build/action.yaml @@ -68,6 +68,7 @@ runs: - name: Run Tests env: NODE_OPTIONS: "--max_old_space_size=4096" + MDB_IS_TEST: "true" run: | npm run test shell: bash diff --git a/.github/workflows/draft-release.yaml b/.github/workflows/draft-release.yaml index 70c290198..0a5cf2990 100644 --- a/.github/workflows/draft-release.yaml +++ b/.github/workflows/draft-release.yaml @@ -96,6 +96,7 @@ jobs: GARASIGN_USERNAME: ${{ secrets.GARASIGN_USERNAME }} SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + MDB_IS_TEST: "true" - name: Create Draft Release run: | diff --git a/.github/workflows/test-and-build-from-fork.yaml b/.github/workflows/test-and-build-from-fork.yaml index 44aad4fe1..62493f282 100644 --- a/.github/workflows/test-and-build-from-fork.yaml +++ b/.github/workflows/test-and-build-from-fork.yaml @@ -40,4 +40,5 @@ jobs: env: NODE_OPTIONS: "--max_old_space_size=4096" SEGMENT_KEY: "test-segment-key" + MDB_IS_TEST: "true" run: npm run test diff --git a/.github/workflows/test-and-build.yaml b/.github/workflows/test-and-build.yaml index 5399eef5f..4aa0e1b29 100644 --- a/.github/workflows/test-and-build.yaml +++ b/.github/workflows/test-and-build.yaml @@ -48,3 +48,4 @@ jobs: GARASIGN_USERNAME: ${{ secrets.GARASIGN_USERNAME }} SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + MDB_IS_TEST: "true" diff --git a/.vscode/launch.json b/.vscode/launch.json index 533cbba63..95c2c7a51 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -53,10 +53,11 @@ "--extensionTestsPath=${workspaceFolder}/out/test/suite" ], "env": { - "MOCHA_GREP": "${input:mochaGrep}" + "MOCHA_GREP": "${input:mochaGrep}", + "MDB_IS_TEST": "true" }, "outFiles": ["${workspaceFolder}/out/**/*.js"], - "preLaunchTask": "npm: compile:extension", + "preLaunchTask": "npm: compile:extension" } ], "inputs": [ diff --git a/package.json b/package.json index dae69987e..0f168de13 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "watch:extension-bundles": "webpack --mode development --watch", "pretest": "npm run compile", "test": "npm run test-webview && npm run test-extension", - "test-extension": "cross-env NODE_OPTIONS=--no-force-async-hooks-checks xvfb-maybe node ./out/test/runTest.js", + "test-extension": "cross-env MDB_IS_TEST=true NODE_OPTIONS=--no-force-async-hooks-checks xvfb-maybe node ./out/test/runTest.js", "test-webview": "mocha -r ts-node/register --grep=\"${MOCHA_GREP}\" --file ./src/test/setup-webview.ts src/test/suite/views/webview-app/**/*.test.tsx", "ai-accuracy-tests": "env TS_NODE_FILES=true mocha -r ts-node/register --grep=\"${MOCHA_GREP}\" --file ./src/test/ai-accuracy-tests/test-setup.ts ./src/test/ai-accuracy-tests/ai-accuracy-tests.ts", "analyze-bundle": "webpack --mode production --analyze", diff --git a/src/connectionController.ts b/src/connectionController.ts index b68a5debf..87c7ecf15 100644 --- a/src/connectionController.ts +++ b/src/connectionController.ts @@ -729,6 +729,7 @@ export default class ConnectionController { if (!this._activeDataService) { log.error('Unable to disconnect: no active connection'); + this._disconnecting = false; return false; } diff --git a/src/extension.ts b/src/extension.ts index ae53f7f9b..a4c10e239 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -21,7 +21,9 @@ debug.log = log.debug.bind(log); import MDBExtensionController from './mdbExtensionController'; -let mdbExtension: MDBExtensionController; +let mdbExtension: MDBExtensionController | undefined; + +const isUnderTest = process.env.MDB_IS_TEST === 'true'; // Called when our extension is activated. // See "activationEvents" in `package.json` for the events that cause activation. @@ -51,13 +53,24 @@ export async function activate( }, }); - mdbExtension = new MDBExtensionController(context, { - shouldTrackTelemetry: true, - }); - await mdbExtension.activate(); + // Solution to VSCODE-700. If we are running tests, don't activate the extension. + // This avoids registering multiple providers when running the tests, which causes errors in recent versions of vscode. + if (isUnderTest) { + log.info( + 'Skipping MDBExtensionController activation because MDB_IS_TEST is set.', + ); + return; + } - // Add our extension to a list of disposables for when we are deactivated. - context.subscriptions.push(mdbExtension); + if (!mdbExtension) { + mdbExtension = new MDBExtensionController(context, { + shouldTrackTelemetry: true, + }); + await mdbExtension.activate(); + + // Add our extension to a list of disposables for when we are deactivated. + context.subscriptions.push(mdbExtension); + } } // Called when our extension is deactivated. diff --git a/src/test/runTest.ts b/src/test/runTest.ts index 79278b9a1..3b07e0f0a 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -39,7 +39,7 @@ async function main(): Promise { // Download VS Code, unzip it and run the integration test await runTests({ - version: '1.103.2', // TODO(VSCODE-700) Once we fix the test setup issues, we should revert this to 'insiders' + version: 'insiders', extensionDevelopmentPath, extensionTestsPath, launchArgs: [testWorkspace, '--disable-extensions'], diff --git a/src/test/suite/connectionController.test.ts b/src/test/suite/connectionController.test.ts index 01eb20102..35a9bb2fb 100644 --- a/src/test/suite/connectionController.test.ts +++ b/src/test/suite/connectionController.test.ts @@ -42,7 +42,7 @@ const sleep = (ms: number): Promise => { }; suite('Connection Controller Test Suite', function () { - this.timeout(5000); + this.timeout(10000); const extensionContextStub = new ExtensionContextStub(); const testStorageController = new StorageController(extensionContextStub); @@ -73,6 +73,8 @@ suite('Connection Controller Test Suite', function () { extensionContextStub._workspaceState = {}; extensionContextStub._globalState = {}; + testConnectionController.cancelConnectionAttempt(); + await testConnectionController.disconnect(); testConnectionController.clearAllConnections(); diff --git a/src/test/suite/editors/playgroundSelectionCodeActionProvider.test.ts b/src/test/suite/editors/playgroundSelectionCodeActionProvider.test.ts index cd00309fd..c1c3d5e56 100644 --- a/src/test/suite/editors/playgroundSelectionCodeActionProvider.test.ts +++ b/src/test/suite/editors/playgroundSelectionCodeActionProvider.test.ts @@ -3,7 +3,6 @@ import { beforeEach, afterEach } from 'mocha'; import chai from 'chai'; import sinon from 'sinon'; import PlaygroundSelectionCodeActionProvider from '../../../editors/playgroundSelectionCodeActionProvider'; -import { LanguageServerController } from '../../../language'; import { mdbTestExtension } from '../stubbableMdbExtension'; import { PlaygroundController } from '../../../editors'; import { TEST_DATABASE_URI } from '../dbTestHelper'; @@ -32,11 +31,6 @@ suite('Playground Selection Code Action Provider Test Suite', function () { let testActiveTextEditor; beforeEach(async () => { - sandbox.replace( - mdbTestExtension.testExtensionController, - '_languageServerController', - new LanguageServerController(extensionContextStub), - ); sandbox.stub(vscode.window, 'showInformationMessage'); sandbox.stub( mdbTestExtension.testExtensionController._telemetryService, @@ -79,7 +73,6 @@ suite('Playground Selection Code Action Provider Test Suite', function () { .getConfiguration('mdb') .update('confirmRunAll', false); - await mdbTestExtension.testExtensionController._languageServerController.startLanguageServer(); await mdbTestExtension.testExtensionController._playgroundController._activeConnectionChanged(); testActiveTextEditor = sandbox.stub(vscode.window, 'activeTextEditor'); diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts index e3bbec7dd..13de8b55e 100644 --- a/src/test/suite/index.ts +++ b/src/test/suite/index.ts @@ -54,11 +54,21 @@ export async function run(): Promise { try { // Run the mocha test. mocha.run((failures) => { - if (failures > 0) { - e(new Error(`${failures} tests failed.`)); - } else { - c(); - } + // Deactivate the extension to properly clean up the language server + void mdbTestExtension.testExtensionController + .deactivate() + .then(() => { + if (failures > 0) { + e(new Error(`${failures} tests failed.`)); + } else { + c(); + } + }) + .catch((deactivateErr) => { + console.error('Error deactivating extension:'); + console.error(deactivateErr); + e(deactivateErr); + }); }); } catch (mochaRunErr) { console.error('Error running mocha tests:'); diff --git a/src/test/suite/language/languageServerController.test.ts b/src/test/suite/language/languageServerController.test.ts index df406b942..57d4a4b1d 100644 --- a/src/test/suite/language/languageServerController.test.ts +++ b/src/test/suite/language/languageServerController.test.ts @@ -11,7 +11,6 @@ import chaiAsPromised from 'chai-as-promised'; import PlaygroundSelectionCodeActionProvider from '../../../editors/playgroundSelectionCodeActionProvider'; import ConnectionController from '../../../connectionController'; import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; -import { LanguageServerController } from '../../../language'; import { mdbTestExtension } from '../stubbableMdbExtension'; import { PlaygroundController } from '../../../editors'; import PlaygroundResultProvider from '../../../editors/playgroundResultProvider'; @@ -21,6 +20,7 @@ import { TEST_DATABASE_URI } from '../dbTestHelper'; import { TelemetryService } from '../../../telemetry'; import { ExtensionContextStub } from '../stubs'; import ExportToLanguageCodeLensProvider from '../../../editors/exportToLanguageCodeLensProvider'; +import type { LanguageServerController } from '../../../language'; const expect = chai.expect; @@ -58,9 +58,9 @@ suite('Language Server Controller Test Suite', () => { const sandbox = sinon.createSandbox(); before(async () => { - languageServerControllerStub = new LanguageServerController( - extensionContextStub, - ); + languageServerControllerStub = + mdbTestExtension.testExtensionController._languageServerController; + const testExportToLanguageCodeLensProvider = new ExportToLanguageCodeLensProvider(testPlaygroundResultProvider); @@ -73,7 +73,6 @@ suite('Language Server Controller Test Suite', () => { playgroundSelectionCodeActionProvider: testCodeActionProvider, exportToLanguageCodeLensProvider: testExportToLanguageCodeLensProvider, }); - await languageServerControllerStub.startLanguageServer(); await testPlaygroundController._activeConnectionChanged(); }); diff --git a/src/test/suite/views/webviewController.test.ts b/src/test/suite/views/webviewController.test.ts index b5ae67721..a6cdf6ae2 100644 --- a/src/test/suite/views/webviewController.test.ts +++ b/src/test/suite/views/webviewController.test.ts @@ -157,9 +157,9 @@ suite('Webview Test Suite', () => { suite('when oidc device auth flow setting is enabled', function () { let originalDeviceAuthFlow; before(async function () { - originalDeviceAuthFlow = vscode.workspace.getConfiguration( - 'mdb.showOIDCDeviceAuthFlow', - ); + originalDeviceAuthFlow = vscode.workspace + .getConfiguration('mdb') + .get('showOIDCDeviceAuthFlow'); await vscode.workspace .getConfiguration('mdb')