From d162ae083c3f97a04d40d8dfc334a2ee857b38ea Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Mon, 3 Feb 2025 14:06:12 +1100 Subject: [PATCH 1/2] Fix failing, re-enable skipped and move tests --- .../contributedKerneFinder.node.unit.test.ts | 14 +- .../cdnWidgetScriptSourceProvider.ts | 2 +- ...cdnWidgetScriptSourceProvider.unit.test.ts | 125 +++--------------- .../common/experiments/service.unit.test.ts | 27 ---- .../interactiveDebugging.vscode.common.ts | 58 -------- 5 files changed, 30 insertions(+), 196 deletions(-) diff --git a/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts b/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts index 3108a357235..51bac9abeee 100644 --- a/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts +++ b/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts @@ -834,10 +834,10 @@ import { setPythonApi } from '../../../platform/interpreter/helpers'; condaEnv1 ].forEach((activePythonEnv) => { suite(activePythonEnv ? `With active Python (${activePythonEnv.id})` : 'without active Python', () => { - setup(function () { - // Flaky windows unit tests. https://github.com/microsoft/vscode-jupyter/issues/13462 - return this.skip(); - }); + // setup(function () { + // // Flaky windows unit tests. https://github.com/microsoft/vscode-jupyter/issues/13462 + // return this.skip(); + // }); /** * As we're using a push model, we need to wait for the events to get triggered. * How many events do we need to wait for is not deterministic (well for tests it is, but its too complex). @@ -915,9 +915,9 @@ import { setPythonApi } from '../../../platform/interpreter/helpers'; }); test('If two kernelspecs share the same interpreter, but have different env variables, then both should be listed', async function () { // https://github.com/microsoft/vscode-jupyter/issues/13236 - if (os.platform() === 'win32') { - return this.skip(); - } + // if (os.platform() === 'win32') { + // return this.skip(); + // } const testData: TestData = { interpreters: [ { diff --git a/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.ts b/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.ts index 9c1bb91d6b3..7c2fdf01bd1 100644 --- a/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.ts +++ b/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.ts @@ -22,7 +22,7 @@ export const GlobalStateKeyToTrackIfUserConfiguredCDNAtLeastOnce = 'IPYWidgetCDN export const GlobalStateKeyToNeverWarnAboutScriptsNotFoundOnCDN = 'IPYWidgetNotFoundOnCDN'; export const GlobalStateKeyToNeverWarnAboutNoNetworkAccess = 'IPYWidgetNoNetWorkAccess'; -function moduleNameToCDNUrl(cdn: string, moduleName: string, moduleVersion: string) { +export function moduleNameToCDNUrl(cdn: string, moduleName: string, moduleVersion: string) { let packageName = moduleName; let fileName = 'index'; // default filename // if a '/' is present, like 'foo/bar', packageName is changed to 'foo', and path to 'bar' diff --git a/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.unit.test.ts b/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.unit.test.ts index a45ebd107e1..5519342438e 100644 --- a/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.unit.test.ts +++ b/src/notebooks/controllers/ipywidgets/scriptSourceProvider/cdnWidgetScriptSourceProvider.unit.test.ts @@ -1,31 +1,24 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import * as sinon from 'sinon'; import { assert } from 'chai'; -import * as fs from 'fs-extra'; -import nock from 'nock'; -import * as path from '../../../../platform/vscode-path/path'; -import { Readable } from 'stream'; import { anything, deepEqual, instance, mock, verify, when } from 'ts-mockito'; -import { ConfigurationTarget, Disposable, Memento, Uri } from 'vscode'; +import { ConfigurationTarget, Disposable, Memento, type WorkspaceConfiguration } from 'vscode'; import { JupyterSettings } from '../../../../platform/common/configSettings'; import { ConfigurationService } from '../../../../platform/common/configuration/service.node'; import { IConfigurationService, IDisposable, WidgetCDNs } from '../../../../platform/common/types'; -import { noop } from '../../../../platform/common/utils/misc'; -import { EXTENSION_ROOT_DIR } from '../../../../platform/constants.node'; import { CDNWidgetScriptSourceProvider, GlobalStateKeyToNeverWarnAboutNoNetworkAccess, - GlobalStateKeyToTrackIfUserConfiguredCDNAtLeastOnce + GlobalStateKeyToTrackIfUserConfiguredCDNAtLeastOnce, + moduleNameToCDNUrl } from './cdnWidgetScriptSourceProvider'; import { IWidgetScriptSourceProvider } from '../types'; import { dispose } from '../../../../platform/common/utils/lifecycle'; import { Common, DataScience } from '../../../../platform/common/utils/localize'; -import { computeHash } from '../../../../platform/common/crypto'; import { mockedVSCodeNamespaces, resetVSCodeMocks } from '../../../../test/vscode-mock'; - -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, , @typescript-eslint/no-explicit-any, , no-console */ -const sanitize = require('sanitize-filename'); +import { HttpClient } from '../../../../platform/common/net/httpClient'; const unpgkUrl = 'https://unpkg.com/'; const jsdelivrUrl = 'https://cdn.jsdelivr.net/npm/'; @@ -50,18 +43,6 @@ suite('ipywidget - CDN', () => { teardown(() => (disposables = dispose(disposables))); - function createStreamFromString(str: string) { - const readable = new Readable(); - readable._read = noop; - readable.push(str); - readable.push(null); - return readable; - } - - async function generateScriptName(moduleName: string, moduleVersion: string) { - const hash = sanitize(await computeHash(`${moduleName}${moduleVersion}`, 'SHA-256')); - return Uri.file(path.join(EXTENSION_ROOT_DIR, 'temp', 'scripts', hash, 'index.js')).toString(); - } test('Prompt to use CDN', async () => { when( mockedVSCodeNamespaces.window.showInformationMessage( @@ -319,28 +300,30 @@ suite('ipywidget - CDN', () => { // Nock seems to fail randomly on CI builds. See bug // https://github.com/microsoft/vscode-python/issues/11442 // eslint-disable-next-line no-invalid-this - suite.skip(cdn, () => { + suite(cdn, () => { const moduleName = 'HelloWorld'; const moduleVersion = '1'; - let baseUrl = ''; let scriptUri = ''; + const disposables: IDisposable[] = []; setup(async () => { - baseUrl = cdn === 'unpkg.com' ? unpgkUrl : jsdelivrUrl; - scriptUri = await generateScriptName(moduleName, moduleVersion); + const baseUrl = cdn === 'unpkg.com' ? unpgkUrl : jsdelivrUrl; + scriptUri = moduleNameToCDNUrl(baseUrl, moduleName, moduleVersion); + const workspaceConfig = mock(); + when(workspaceConfig.get('proxy', anything())).thenReturn(''); + when(mockedVSCodeNamespaces.workspace.getConfiguration('http')).thenReturn( + instance(workspaceConfig) + ); }); teardown(() => { + sinon.restore(); + resetVSCodeMocks(); scriptSourceProvider.dispose(); - nock.cleanAll(); + dispose(disposables); + disposables.length = 0; }); - test('Ensure widget script is downloaded once and cached', async () => { + test('Verify script source', async () => { updateCDNSettings(cdn); - let downloadCount = 0; - nock(baseUrl) - .get(/.*/) - .reply(200, () => { - downloadCount += 1; - return createStreamFromString('foo'); - }); + sinon.stub(HttpClient.prototype, 'exists').resolves(true); const value = await scriptSourceProvider.getWidgetScriptSource(moduleName, moduleVersion); @@ -349,20 +332,10 @@ suite('ipywidget - CDN', () => { scriptUri, source: 'cdn' }); - - const value2 = await scriptSourceProvider.getWidgetScriptSource(moduleName, moduleVersion); - - assert.deepEqual(value2, { - moduleName: 'HelloWorld', - scriptUri, - source: 'cdn' - }); - - assert.equal(downloadCount, 1, 'Downloaded more than once'); }); test('No script source if package does not exist on CDN', async () => { updateCDNSettings(cdn); - nock(baseUrl).get(/.*/).replyWithError('404'); + sinon.stub(HttpClient.prototype, 'exists').resolves(false); const value = await scriptSourceProvider.getWidgetScriptSource(moduleName, moduleVersion); @@ -377,61 +350,7 @@ suite('ipywidget - CDN', () => { ? ([cdn, 'jsdelivr.com'] as WidgetCDNs[]) : ([cdn, 'unpkg.com'] as WidgetCDNs[]); updateCDNSettings(cdns[0], cdns[1]); - // Make only one cdn available - // when(httpClient.exists(anything())).thenCall((a) => { - // if (a.includes(cdn[0])) { - // return true; - // } - // return false; - // }); - nock(baseUrl) - .get(/.*/) - .reply(200, () => { - return createStreamFromString('foo'); - }); - const value = await scriptSourceProvider.getWidgetScriptSource(moduleName, moduleVersion); - - assert.deepEqual(value, { - moduleName: 'HelloWorld', - scriptUri, - source: 'cdn' - }); - }); - - test('Retry if busy', async () => { - let retryCount = 0; - updateCDNSettings(cdn); - // when(httpClient.exists(anything())).thenResolve(true); - nock(baseUrl).get(/.*/).twice().replyWithError('Not found'); - nock(baseUrl) - .get(/.*/) - .thrice() - .reply(200, () => { - retryCount = 3; - return createStreamFromString('foo'); - }); - - // Then see if we can get it still. - const value = await scriptSourceProvider.getWidgetScriptSource(moduleName, moduleVersion); - - assert.deepEqual(value, { - moduleName: 'HelloWorld', - scriptUri, - source: 'cdn' - }); - assert.equal(retryCount, 3, 'Did not actually retry'); - }); - test('Script source already on disk', async () => { - updateCDNSettings(cdn); - // Make nobody available - // when(httpClient.exists(anything())).thenResolve(true); - - // Write to where the file should eventually end up - const filePath = Uri.parse(scriptUri).fsPath; - await fs.createFile(filePath); - await fs.writeFile(filePath, 'foo'); - - // Then see if we can get it still. + sinon.stub(HttpClient.prototype, 'exists').resolves(true); const value = await scriptSourceProvider.getWidgetScriptSource(moduleName, moduleVersion); assert.deepEqual(value, { diff --git a/src/platform/common/experiments/service.unit.test.ts b/src/platform/common/experiments/service.unit.test.ts index 872bb6030b4..35c21218ddc 100644 --- a/src/platform/common/experiments/service.unit.test.ts +++ b/src/platform/common/experiments/service.unit.test.ts @@ -100,20 +100,6 @@ suite('Experimentation service', () => { telemetryEvents = []; }); - test.skip('If the opt-in and opt-out arrays are empty, return the value from the experimentation framework for a given experiment', async () => { - configureSettings(true, [], []); - - const experimentService = new ExperimentService( - instance(configurationService), - instance(appEnvironment), - globalMemento - ); - const result = await experimentService.inExperiment(experiment); - - assert.isTrue(result); - sinon.assert.notCalled(sendTelemetryEventStub); - }); - test('If the experiment setting is disabled, inExperiment should return false', async () => { configureSettings(false, [], []); @@ -165,19 +151,6 @@ suite('Experimentation service', () => { } as any); }); - test.skip('If the service is enabled and the opt-out array is empty,return the value from the experimentation framework for a given experiment', async () => { - configureSettings(true, [], []); - - const experimentService = new ExperimentService( - instance(configurationService), - instance(appEnvironment), - globalMemento - ); - const result = await experimentService.getExperimentValue(experiment); - - assert.equal(result, 'value'); - }); - test('If the experiment setting is disabled, getExperimentValue should return undefined', async () => { configureSettings(false, [], []); diff --git a/src/test/datascience/interactiveDebugging.vscode.common.ts b/src/test/datascience/interactiveDebugging.vscode.common.ts index be3ea3a5c96..2a2e437b88b 100644 --- a/src/test/datascience/interactiveDebugging.vscode.common.ts +++ b/src/test/datascience/interactiveDebugging.vscode.common.ts @@ -90,64 +90,6 @@ export function sharedIWDebuggerTests( await closeNotebooksAndCleanUpAfterTests(disposables); }); - // TODO: This should be a testMandatory - test.skip('Debug a cell from a python file @mandatory', async () => { - // #11917 - // Run a cell to get IW open - const source = 'print(42)'; - const { activeInteractiveWindow, untitledPythonFile } = await submitFromPythonFile( - interactiveWindowProvider, - source, - disposables - ); - await waitForLastCellToComplete(activeInteractiveWindow); - - // Add some more text - const editor = vscode.window.visibleTextEditors.find((e) => e.document.uri === untitledPythonFile.uri); - assert.ok(editor, `Couldn't find python file`); - await editor?.edit((b) => { - b.insert(new vscode.Position(1, 0), '\n# %%\n\n\nprint(43)'); - }); - - let codeLenses = await waitForCodeLenses(untitledPythonFile.uri, Commands.DebugCell); - let stopped = false; - let stoppedOnLine5 = false; - debugAdapterTracker = { - onDidSendMessage: (message) => { - if (message.event == 'stopped') { - stopped = true; - } - if (message.command == 'stackTrace' && !stoppedOnLine5) { - stoppedOnLine5 = message.body.stackFrames[0].line == 5; - } - } - }; - - // Try debugging the cell - assert.ok(codeLenses, `No code lenses found`); - assert.equal(codeLenses.length, 3, `Wrong number of code lenses found`); - const args = codeLenses[2].command!.arguments || []; - vscode.commands.executeCommand(codeLenses[2].command!.command, ...args).then(noop, noop); - - // Wait for breakpoint to be hit - await waitForCondition( - async () => { - return vscode.debug.activeDebugSession != undefined && stopped; - }, - defaultNotebookTestTimeout, - `Never hit stop event when waiting for debug cell` - ); - - // Verify we are on the 'print(43)' line (might take a second for UI to update after stop event) - await waitForCondition( - async () => { - return stoppedOnLine5; - }, - defaultNotebookTestTimeout, - `Cursor did not move to expected line when hitting breakpoint` - ); - }); - test('Run a cell and step into breakpoint', async function () { // Define the function const source = 'def foo():\n print("foo")'; From 59f8da1c01c4b42050e865dd74c826547c640ffc Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Mon, 3 Feb 2025 14:59:16 +1100 Subject: [PATCH 2/2] Oops --- src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts b/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts index 51bac9abeee..344537280b9 100644 --- a/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts +++ b/src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts @@ -4,7 +4,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { assert } from 'chai'; -import * as os from 'os'; import * as path from '../../../platform/vscode-path/path'; import * as uriPath from '../../../platform/vscode-path/resources'; import * as sinon from 'sinon';