diff --git a/extensions/notebook/src/test/model/notebookManager.test.ts b/extensions/notebook/src/test/model/notebookManager.test.ts new file mode 100644 index 0000000000..494edd26cb --- /dev/null +++ b/extensions/notebook/src/test/model/notebookManager.test.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as should from 'should'; +import * as TypeMoq from 'typemoq'; +import * as vscode from 'vscode'; +import * as azdata from 'azdata'; +import 'mocha'; + +import { LocalJupyterServerManager, ServerInstanceFactory, IServerManagerOptions } from '../../jupyter/jupyterServerManager'; +import { JupyterServerInstallation } from '../../jupyter/jupyterServerInstallation'; +import { Deferred } from '../../common/promise'; +import { ApiWrapper } from '../../common/apiWrapper'; +import { MockExtensionContext } from '../common/stubs'; +import { JupyterSessionManager } from '../../jupyter/jupyterSessionManager'; +import { JupyterNotebookManager } from '../../jupyter/jupyterNotebookManager'; +import { initInstallAndInstance } from './serverManager.test'; + +describe('Jupyter Notebook Manager', function (): void { + const pythonKernelSpec: azdata.nb.IKernelSpec = { + name: 'python3', + display_name: 'Python 3' + }; + let expectedPath = 'my/notebook.ipynb'; + let serverManager: LocalJupyterServerManager; + let sessionManager: JupyterSessionManager; + let notebookManager: JupyterNotebookManager; + let deferredInstall: Deferred; + let mockApiWrapper: TypeMoq.IMock; + let mockExtensionContext: MockExtensionContext; + let mockFactory: TypeMoq.IMock; + let serverManagerOptions: IServerManagerOptions; + beforeEach(() => { + mockExtensionContext = new MockExtensionContext(); + mockApiWrapper = TypeMoq.Mock.ofType(ApiWrapper); + mockApiWrapper.setup(a => a.showErrorMessage(TypeMoq.It.isAny())); + mockApiWrapper.setup(a => a.getWorkspacePathFromUri(TypeMoq.It.isAny())).returns(() => undefined); + mockFactory = TypeMoq.Mock.ofType(ServerInstanceFactory); + + deferredInstall = new Deferred(); + let mockInstall = TypeMoq.Mock.ofType(JupyterServerInstallation, undefined, undefined, '/root'); + mockInstall.setup(j => j.promptForPythonInstall(TypeMoq.It.isAny())).returns(() => deferredInstall.promise); + mockInstall.object.execOptions = { env: Object.assign({}, process.env) }; + + serverManagerOptions = { + documentPath: expectedPath, + jupyterInstallation: mockInstall.object, + extensionContext: mockExtensionContext, + apiWrapper: mockApiWrapper.object, + factory: mockFactory.object + }; + serverManager = new LocalJupyterServerManager(serverManagerOptions); + + sessionManager = new JupyterSessionManager(); + notebookManager = new JupyterNotebookManager(serverManager, sessionManager); + }); + + it('Server settings should be set', async function (): Promise { + should(notebookManager.serverSettings).be.undefined(); + let expectedUri = vscode.Uri.parse('http://localhost:1234?token=abcdefghijk'); + initInstallAndInstance(expectedUri, mockFactory); + deferredInstall.resolve(); + + // When I start the server + await serverManager.startServer(pythonKernelSpec); + should(notebookManager.serverSettings.baseUrl).equal('http://localhost:1234', 'Server settings did not match expected value'); + }); + + it('Session Manager should exist', async function (): Promise { + should(notebookManager.sessionManager).deepEqual(sessionManager); + }); + + it('Server Manager should exist', async function (): Promise { + should(notebookManager.serverManager).deepEqual(serverManager); + }); + + it('Content manager should always be undefined', async function (): Promise { + should(notebookManager.contentManager).be.undefined(); + let expectedUri = vscode.Uri.parse('http://localhost:1234?token=abcdefghijk'); + initInstallAndInstance(expectedUri, mockFactory); + deferredInstall.resolve(); + + // When I start the server + await serverManager.startServer(pythonKernelSpec); + should(notebookManager.contentManager).be.undefined(); + }); + + it('Session and server managers should be shutdown/stopped on dispose', async function(): Promise { + let sessionManager = TypeMoq.Mock.ofType(); + let serverManager = TypeMoq.Mock.ofType(); + notebookManager = new JupyterNotebookManager(serverManager.object, sessionManager.object, mockApiWrapper.object); + sessionManager.setup(s => s.shutdownAll()).returns(() => new Promise((resolve) => resolve())); + serverManager.setup(s => s.stopServer()).returns(() => new Promise((resolve) => resolve())); + + // After I dispose the notebook manager + notebookManager.dispose(); + + // Session and server managers should be shutdown/stopped + sessionManager.verify((s) => s.shutdownAll(), TypeMoq.Times.once()); + serverManager.verify((s) => s.stopServer(), TypeMoq.Times.once()); + }); +}); diff --git a/extensions/notebook/src/test/model/serverManager.test.ts b/extensions/notebook/src/test/model/serverManager.test.ts index fe4971ba20..fbc076b3ed 100644 --- a/extensions/notebook/src/test/model/serverManager.test.ts +++ b/extensions/notebook/src/test/model/serverManager.test.ts @@ -64,7 +64,7 @@ describe('Local Jupyter Server Manager', function (): void { it('Should configure and start install', async function (): Promise { // Given an install and instance that start with no issues let expectedUri = vscode.Uri.parse('http://localhost:1234?token=abcdefghijk'); - let mockServerInstance = initInstallAndInstance(expectedUri); + let mockServerInstance = initInstallAndInstance(expectedUri, mockFactory); deferredInstall.resolve(); // When I start the server @@ -89,7 +89,7 @@ describe('Local Jupyter Server Manager', function (): void { it('Should call stop on server instance', async function (): Promise { // Given an install and instance that start with no issues let expectedUri = vscode.Uri.parse('http://localhost:1234?token=abcdefghijk'); - let mockServerInstance = initInstallAndInstance(expectedUri); + let mockServerInstance = initInstallAndInstance(expectedUri, mockFactory); mockServerInstance.setup(s => s.stop()).returns(() => Promise.resolve()); deferredInstall.resolve(); @@ -104,7 +104,7 @@ describe('Local Jupyter Server Manager', function (): void { it('Should call stop when extension is disposed', async function (): Promise { // Given an install and instance that start with no issues let expectedUri = vscode.Uri.parse('http://localhost:1234?token=abcdefghijk'); - let mockServerInstance = initInstallAndInstance(expectedUri); + let mockServerInstance = initInstallAndInstance(expectedUri, mockFactory); mockServerInstance.setup(s => s.stop()).returns(() => Promise.resolve()); deferredInstall.resolve(); @@ -116,13 +116,13 @@ describe('Local Jupyter Server Manager', function (): void { // Then I expect stop to have been called on the server instance mockServerInstance.verify(s => s.stop(), TypeMoq.Times.once()); }); - - function initInstallAndInstance(uri: vscode.Uri): TypeMoq.IMock { - let mockServerInstance = TypeMoq.Mock.ofType(JupyterServerInstanceStub); - mockFactory.setup(f => f.createInstance(TypeMoq.It.isAny())).returns(() => mockServerInstance.object); - mockServerInstance.setup(s => s.configure()).returns(() => Promise.resolve()); - mockServerInstance.setup(s => s.start()).returns(() => Promise.resolve()); - mockServerInstance.setup(s => s.uri).returns(() => uri); - return mockServerInstance; - } }); + +export function initInstallAndInstance(uri: vscode.Uri, mockFactory: TypeMoq.IMock): TypeMoq.IMock { + let mockServerInstance = TypeMoq.Mock.ofType(JupyterServerInstanceStub); + mockFactory.setup(f => f.createInstance(TypeMoq.It.isAny())).returns(() => mockServerInstance.object); + mockServerInstance.setup(s => s.configure()).returns(() => Promise.resolve()); + mockServerInstance.setup(s => s.start()).returns(() => Promise.resolve()); + mockServerInstance.setup(s => s.uri).returns(() => uri); + return mockServerInstance; +}