From 047c51921b8b09bfd81bd6e73cd31d025cf90c15 Mon Sep 17 00:00:00 2001 From: Cory Rivera Date: Mon, 20 Jul 2020 12:36:40 -0700 Subject: [PATCH] Exclude Spark notebook kernels when running on SAW devices. (#11416) --- extensions/notebook/package.json | 9 +++++--- src/sql/azdata.proposed.d.ts | 4 ++++ .../test/browser/cellToolbarActions.test.ts | 21 +++++++++++++++---- .../browser/markdownTextTransformer.test.ts | 18 ++++++++++++++-- .../test/browser/notebookEditor.test.ts | 6 +++++- .../test/browser/notebookService.test.ts | 9 ++++++-- .../notebookEditorModel.test.ts | 20 ++++++++++++++---- .../notebook/browser/notebookServiceImpl.ts | 6 ++++++ .../api/mainThreadNotebook.test.ts | 19 ++++++++++++++--- 9 files changed, 93 insertions(+), 19 deletions(-) diff --git a/extensions/notebook/package.json b/extensions/notebook/package.json index 7aef4e4873..43a900f75b 100644 --- a/extensions/notebook/package.json +++ b/extensions/notebook/package.json @@ -506,21 +506,24 @@ "displayName": "PySpark", "connectionProviderIds": [ "MSSQL" - ] + ], + "blockedOnSAW": true }, { "name": "sparkkernel", "displayName": "Spark | Scala", "connectionProviderIds": [ "MSSQL" - ] + ], + "blockedOnSAW": true }, { "name": "sparkrkernel", "displayName": "Spark | R", "connectionProviderIds": [ "MSSQL" - ] + ], + "blockedOnSAW": true }, { "name": "python3", diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index 829a55272a..7966e1dc0e 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -36,6 +36,10 @@ declare module 'azdata' { */ setTrusted(state: boolean); } + + export interface IStandardKernel { + readonly blockedOnSAW?: boolean; + } } export type SqlDbType = 'BigInt' | 'Binary' | 'Bit' | 'Char' | 'DateTime' | 'Decimal' diff --git a/src/sql/workbench/contrib/notebook/test/browser/cellToolbarActions.test.ts b/src/sql/workbench/contrib/notebook/test/browser/cellToolbarActions.test.ts index f7cf2e9ebe..08df808673 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/cellToolbarActions.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/cellToolbarActions.test.ts @@ -10,7 +10,7 @@ import { NotebookService } from 'sql/workbench/services/notebook/browser/noteboo import { INotificationService } from 'vs/platform/notification/common/notification'; import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; -import { TestLifecycleService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { CellContext } from 'sql/workbench/contrib/notebook/browser/cellViews/codeActions'; import { INotebookService } from 'sql/workbench/services/notebook/browser/notebookService'; @@ -19,6 +19,7 @@ import * as DOM from 'vs/base/browser/dom'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { ContextMenuService } from 'vs/platform/contextview/browser/contextMenuService'; import { CellModel } from 'sql/workbench/services/notebook/browser/models/cell'; +import { IProductService } from 'vs/platform/product/common/productService'; suite('CellToolbarActions', function (): void { suite('removeDuplicatedAndStartingSeparators', function (): void { @@ -88,12 +89,24 @@ suite('CellToolbarActions', function (): void { const contextMock = TypeMoq.Mock.ofType(CellContext); const cellModelMock = TypeMoq.Mock.ofType(CellModel); + instantiationService.stub(IProductService, { quality: 'stable' }); + suiteSetup(function (): void { contextMock.setup(x => x.cell).returns(() => cellModelMock.object); - const mockNotebookService = TypeMoq.Mock.ofType(NotebookService, undefined, new TestLifecycleService(), undefined, undefined, undefined, instantiationService, new MockContextKeyService(), - undefined, instantiationService, undefined, undefined, undefined, undefined, TestEnvironmentService); + let notebookService = new NotebookService( + new TestLifecycleService(), + undefined, + undefined, + undefined, + instantiationService, + undefined, + undefined, + undefined, + new MockContextKeyService(), + instantiationService.get(IProductService) + ); instantiationService.stub(INotificationService, new TestNotificationService()); - instantiationService.stub(INotebookService, mockNotebookService.object); + instantiationService.stub(INotebookService, notebookService); instantiationService.stub(IContextMenuService, TypeMoq.Mock.ofType(ContextMenuService).object); }); diff --git a/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts b/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts index 51c2b3e6ef..c38966dc4f 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/markdownTextTransformer.test.ts @@ -31,6 +31,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { IEditor } from 'vs/editor/common/editorCommon'; import { NotebookEditorStub } from 'sql/workbench/contrib/notebook/test/testCommon'; import { Range } from 'vs/editor/common/core/range'; +import { IProductService } from 'vs/platform/product/common/productService'; suite('MarkdownTextTransformer', () => { let markdownTextTransformer: MarkdownTextTransformer; @@ -53,8 +54,21 @@ suite('MarkdownTextTransformer', () => { instantiationService.stub(IEnvironmentService, TestEnvironmentService); instantiationService.stub(IStorageService, new TestStorageService()); - mockNotebookService = TypeMoq.Mock.ofType(NotebookService, undefined, new TestLifecycleService(), undefined, undefined, undefined, instantiationService, new MockContextKeyService(), - undefined, undefined, undefined, undefined, undefined, undefined, TestEnvironmentService); + instantiationService.stub(IProductService, { quality: 'stable' }); + + let notebookService = new NotebookService( + new TestLifecycleService(), + undefined, + undefined, + undefined, + instantiationService, + undefined, + undefined, + undefined, + new MockContextKeyService(), + instantiationService.get(IProductService) + ); + mockNotebookService = TypeMoq.Mock.ofInstance(notebookService); cellModel = new CellModel(undefined, undefined, mockNotebookService.object); notebookEditor = new NotebookEditorStub({ cellGuid: cellModel.cellGuid, instantiationService: instantiationService }); diff --git a/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts b/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts index 41d6b7523b..5d87a6c01b 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/notebookEditor.test.ts @@ -57,6 +57,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService'; import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { IProductService } from 'vs/platform/product/common/productService'; class NotebookModelStub extends stubs.NotebookModelStub { private _cells: Array = [new CellModel(undefined, undefined)]; @@ -681,6 +682,8 @@ function setupServices(arg: { workbenchThemeService?: WorkbenchThemeService, ins instantiationService.stub(IExtensionManagementService, 'onUninstallExtension', uninstallEvent.event); instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallEvent.event); + instantiationService.stub(IProductService, { quality: 'stable' }); + const extensionService = instantiationService.get(IExtensionService); const notebookService = new NotebookService( instantiationService.get(ILifecycleService), @@ -691,7 +694,8 @@ function setupServices(arg: { workbenchThemeService?: WorkbenchThemeService, ins instantiationService.get(IFileService), instantiationService.get(ILogService), queryManagementService, - instantiationService.get(IContextKeyService) + instantiationService.get(IContextKeyService), + instantiationService.get(IProductService) ); instantiationService.stub(INotebookService, notebookService); diff --git a/src/sql/workbench/contrib/notebook/test/browser/notebookService.test.ts b/src/sql/workbench/contrib/notebook/test/browser/notebookService.test.ts index 63cc39663f..a5d0bb9565 100644 --- a/src/sql/workbench/contrib/notebook/test/browser/notebookService.test.ts +++ b/src/sql/workbench/contrib/notebook/test/browser/notebookService.test.ts @@ -29,6 +29,7 @@ import { Registry } from 'vs/platform/registry/common/platform'; import { ExtensionManagementService } from 'vs/workbench/services/extensionManagement/common/extensionManagementService'; import { TestFileService, TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; +import { IProductService } from 'vs/platform/product/common/productService'; /** * class to mock azdata.nb.ServerManager object @@ -107,6 +108,7 @@ suite('NotebookService:', function (): void { let extensionServiceMock: TypeMoq.Mock; let testNo = 0; let sandbox: sinon.SinonSandbox; + let productService: IProductService; let installExtensionEmitter: Emitter, didInstallExtensionEmitter: Emitter, @@ -143,7 +145,10 @@ suite('NotebookService:', function (): void { instantiationService.stub(IExtensionManagementService, 'onDidUninstallExtension', didUninstallExtensionEmitter.event); extensionManagementService = instantiationService.get(IExtensionManagementService); - notebookService = new NotebookService(lifecycleService, storageService, extensionServiceMock.object, extensionManagementService, instantiationService, fileService, logServiceMock.object, queryManagementService, contextService); + instantiationService.stub(IProductService, { quality: 'stable' }); + productService = instantiationService.get(IProductService); + + notebookService = new NotebookService(lifecycleService, storageService, extensionServiceMock.object, extensionManagementService, instantiationService, fileService, logServiceMock.object, queryManagementService, contextService, productService); sandbox = sinon.sandbox.create(); }); @@ -440,7 +445,7 @@ suite('NotebookService:', function (): void { }; errorHandler.setUnexpectedErrorHandler(onUnexpectedErrorVerifier); // The following call throws an exception internally with queryManagementService parameter being undefined. - new NotebookService(lifecycleService, storageService, extensionService, extensionManagementService, instantiationService, fileService, logService, /* queryManagementService */ undefined, contextService); + new NotebookService(lifecycleService, storageService, extensionService, extensionManagementService, instantiationService, fileService, logService, /* queryManagementService */ undefined, contextService, productService); await unexpectedErrorPromise; assert.strictEqual(unexpectedErrorCalled, true, `onUnexpectedError must be have been raised when queryManagementService is undefined when calling NotebookService constructor`); }); diff --git a/src/sql/workbench/contrib/notebook/test/electron-browser/notebookEditorModel.test.ts b/src/sql/workbench/contrib/notebook/test/electron-browser/notebookEditorModel.test.ts index 0d8ec3f736..6a6995bc04 100644 --- a/src/sql/workbench/contrib/notebook/test/electron-browser/notebookEditorModel.test.ts +++ b/src/sql/workbench/contrib/notebook/test/electron-browser/notebookEditorModel.test.ts @@ -28,7 +28,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { TextFileEditorModel } from 'vs/workbench/services/textfile/common/textFileEditorModel'; import { TextFileEditorModelManager } from 'vs/workbench/services/textfile/common/textFileEditorModelManager'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; -import { TestEnvironmentService, TestLifecycleService, TestTextFileService, workbenchInstantiationService, TestTextFileEditorModelManager } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestLifecycleService, TestTextFileService, workbenchInstantiationService, TestTextFileEditorModelManager } from 'vs/workbench/test/browser/workbenchTestServices'; import { Range } from 'vs/editor/common/core/range'; import { nb } from 'azdata'; import { Emitter } from 'vs/base/common/event'; @@ -40,6 +40,7 @@ import { TestInstantiationService } from 'vs/platform/instantiation/test/common/ import { IStorageService } from 'vs/platform/storage/common/storage'; import { TestStorageService, TestTextResourcePropertiesService } from 'vs/workbench/test/common/workbenchTestServices'; import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService'; +import { IProductService } from 'vs/platform/product/common/productService'; class ServiceAccessor { @@ -74,6 +75,7 @@ suite('Notebook Editor Model', function (): void { memento.setup(x => x.getMemento(TypeMoq.It.isAny())).returns(() => void 0); let testinstantiationService = new TestInstantiationService(); testinstantiationService.stub(IStorageService, new TestStorageService()); + testinstantiationService.stub(IProductService, { quality: 'stable' }); const queryConnectionService = TypeMoq.Mock.ofType(ConnectionManagementService, TypeMoq.MockBehavior.Loose, undefined, // connection store undefined, // connection status manager @@ -107,9 +109,19 @@ suite('Notebook Editor Model', function (): void { }, undefined, undefined); }); - let mockNotebookService: TypeMoq.Mock; - mockNotebookService = TypeMoq.Mock.ofType(NotebookService, undefined, new TestLifecycleService(), undefined, undefined, undefined, instantiationService, new MockContextKeyService(), - undefined, undefined, undefined, undefined, undefined, undefined, TestEnvironmentService); + let notebookService = new NotebookService( + new TestLifecycleService(), + undefined, + undefined, + undefined, + instantiationService, + undefined, + undefined, + undefined, + new MockContextKeyService(), + testinstantiationService.get(IProductService) + ); + let mockNotebookService = TypeMoq.Mock.ofInstance(notebookService); mockNotebookService.setup(s => s.findNotebookEditor(TypeMoq.It.isAny())).returns(() => { return { diff --git a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts index 8264b27a9a..f1e428b4ef 100644 --- a/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts +++ b/src/sql/workbench/services/notebook/browser/notebookServiceImpl.ts @@ -35,6 +35,7 @@ import { NotebookChangeType } from 'sql/workbench/services/notebook/common/contr import { onUnexpectedError } from 'vs/base/common/errors'; import { notebookConstants } from 'sql/workbench/services/notebook/browser/interfaces'; import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IProductService } from 'vs/platform/product/common/productService'; export interface NotebookProviderProperties { provider: string; @@ -118,6 +119,7 @@ export class NotebookService extends Disposable implements INotebookService { @ILogService private readonly _logService: ILogService, @IQueryManagementService private readonly _queryManagementService: IQueryManagementService, @IContextKeyService private contextKeyService: IContextKeyService, + @IProductService private readonly productService: IProductService ) { super(); this._providersMemento = new Memento('notebookProviders', this._storageService); @@ -264,6 +266,10 @@ export class NotebookService extends Disposable implements INotebookService { } else { standardKernels.push(provider.standardKernels); } + // Filter out unusable kernels when running on a SAW + if (this.productService.quality === 'saw') { + standardKernels = standardKernels.filter(kernel => !kernel.blockedOnSAW); + } this._providerToStandardKernels.set(providerUpperCase, standardKernels); } diff --git a/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts b/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts index 3d5c4ea684..28aeb3f935 100644 --- a/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts +++ b/src/sql/workbench/test/electron-browser/api/mainThreadNotebook.test.ts @@ -15,10 +15,11 @@ import { NotebookService } from 'sql/workbench/services/notebook/browser/noteboo import { INotebookProvider } from 'sql/workbench/services/notebook/browser/notebookService'; import { INotebookManagerDetails, INotebookSessionDetails, INotebookKernelDetails, INotebookFutureDetails } from 'sql/workbench/api/common/sqlExtHostTypes'; import { LocalContentManager } from 'sql/workbench/services/notebook/common/localContentManager'; -import { TestLifecycleService, TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices'; import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService'; import { ExtHostNotebookShape } from 'sql/workbench/api/common/sqlExtHost.protocol'; import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { IProductService } from 'vs/platform/product/common/productService'; suite('MainThreadNotebook Tests', () => { @@ -34,8 +35,20 @@ suite('MainThreadNotebook Tests', () => { getProxy: proxyType => mockProxy.object }; const instantiationService = new TestInstantiationService(); - mockNotebookService = TypeMoq.Mock.ofType(NotebookService, undefined, new TestLifecycleService(), undefined, undefined, undefined, instantiationService, new MockContextKeyService(), - undefined, undefined, undefined, undefined, undefined, undefined, TestEnvironmentService); + instantiationService.stub(IProductService, { quality: 'stable' }); + let notebookService = new NotebookService( + new TestLifecycleService(), + undefined, + undefined, + undefined, + instantiationService, + undefined, + undefined, + undefined, + new MockContextKeyService(), + instantiationService.get(IProductService) + ); + mockNotebookService = TypeMoq.Mock.ofInstance(notebookService); notebookUri = URI.parse('file:/user/default/my.ipynb'); mainThreadNotebook = new MainThreadNotebook(extContext, mockNotebookService.object, instantiationService); });