Add additional error handling to Python installation for Notebooks (#4891)

* Also enabled integration tests for python installation.
This commit is contained in:
Cory Rivera
2019-04-10 17:09:28 -07:00
committed by GitHub
parent 8315dacda4
commit 1870d83081
10 changed files with 193 additions and 135 deletions

View File

@@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const testRunner = require('vscode/lib/testrunner');
const suite = 'Notebook Extension Integration Tests';
const options: any = {
ui: 'bdd',
useColors: true,
timeout: 600000
};
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
options.reporter = 'mocha-multi-reporters';
options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
}
};
}
testRunner.configure(options);
export = testRunner;

View File

@@ -6,16 +6,17 @@
'use strict';
import * as should from 'should';
import * as assert from 'assert';
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as tempWrite from 'temp-write';
import * as assert from 'assert';
import 'mocha';
import { JupyterController } from '../jupyter/jupyterController';
import { INotebook, CellTypes } from '../contracts/content';
import JupyterServerInstallation from '../jupyter/jupyterServerInstallation';
describe('Notebook Integration Test', function (): void {
describe('Notebook Extension Integration Tests', function () {
this.timeout(600000);
let expectedNotebookContent: INotebook = {
@@ -35,12 +36,34 @@ describe('Notebook Integration Test', function (): void {
nbformat_minor: 2
};
let installComplete = false;
let pythonInstallDir = process.env.PYTHON_TEST_PATH;
let jupyterController: JupyterController;
before(async function () {
assert.ok(pythonInstallDir, 'Python install directory was not defined.');
let notebookExtension: vscode.Extension<any>;
while (true) {
notebookExtension = vscode.extensions.getExtension('Microsoft.notebook');
if (notebookExtension && notebookExtension.isActive) {
break;
} else {
await new Promise(resolve => { setTimeout(resolve, 1000); });
}
}
jupyterController = notebookExtension.exports.getJupyterController() as JupyterController;
await jupyterController.jupyterInstallation.startInstallProcess(false, pythonInstallDir);
installComplete = true;
});
it('Should connect to local notebook server with result 2', async function () {
this.timeout(60000);
should(installComplete).be.true('Python setup did not complete.');
should(JupyterServerInstallation.getPythonInstallPath(jupyterController.jupyterInstallation.apiWrapper)).be.equal(pythonInstallDir);
let pythonNotebook = Object.assign({}, expectedNotebookContent, { metadata: { kernelspec: { name: 'python3', display_name: 'Python 3' } } });
let uri = writeNotebookToFile(pythonNotebook);
await ensureJupyterInstalled();
let notebook = await azdata.nb.showNotebookDocument(uri);
should(notebook.document.cells).have.length(1);
@@ -51,82 +74,13 @@ describe('Notebook Integration Test', function (): void {
let result = (<azdata.nb.IExecuteResult>cellOutputs[0]).data['text/plain'];
should(result).equal('2');
try {
// TODO support closing the editor. Right now this prompts and there's no override for this. Need to fix in core
// Close the editor using the recommended vscode API
//await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
}
catch (e) { }
});
it('Should connect to remote spark server with result 2', async function () {
this.timeout(240000);
let uri = writeNotebookToFile(expectedNotebookContent);
await ensureJupyterInstalled();
// Given a connection to a server exists
let connectionProfile = await connectToSparkIntegrationServer();
// When I open a Spark notebook and run the cell
let notebook = await azdata.nb.showNotebookDocument(uri, {
connectionProfile: connectionProfile
});
should(notebook.document.cells).have.length(1);
let ran = await notebook.runCell(notebook.document.cells[0]);
should(ran).be.true('Notebook runCell failed');
// Then I expect to get the output result of 1+1, executed remotely against the Spark endpoint
let cellOutputs = notebook.document.cells[0].contents.outputs;
should(cellOutputs).have.length(4);
let sparkResult = (<azdata.nb.IStreamResult>cellOutputs[3]).text;
should(sparkResult).equal('2');
try {
// TODO support closing the editor. Right now this prompts and there's no override for this. Need to fix in core
// Close the editor using the recommended vscode API
//await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
}
catch (e) { }
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
});
});
async function connectToSparkIntegrationServer(): Promise<azdata.IConnectionProfile> {
assert.ok(process.env.BACKEND_HOSTNAME, 'BACKEND_HOSTNAME, BACKEND_USERNAME, BACKEND_PWD must be set using ./tasks/setbackenvariables.sh or .\\tasks\\setbackendvaraibles.bat');
let connInfo: azdata.connection.Connection = {
options: {
'host': process.env.BACKEND_HOSTNAME,
'groupId': 'C777F06B-202E-4480-B475-FA416154D458',
'knoxport': '',
'user': process.env.BACKEND_USERNAME,
'password': process.env.BACKEND_PWD
},
providerName: 'HADOOP_KNOX',
connectionId: 'abcd1234',
};
connInfo['savePassword'] = true;
let result = await azdata.connection.connect(<any>connInfo as azdata.IConnectionProfile);
should(result.connected).be.true();
should(result.connectionId).not.be.undefined();
should(result.connectionId).not.be.empty();
should(result.errorMessage).be.undefined();
let activeConnections = await azdata.connection.getActiveConnections();
should(activeConnections).have.length(1);
return <azdata.IConnectionProfile><any>connInfo;
}
function writeNotebookToFile(pythonNotebook: INotebook): vscode.Uri {
let notebookContentString = JSON.stringify(pythonNotebook);
let localFile = tempWrite.sync(notebookContentString, 'notebook.ipynb');
let uri = vscode.Uri.file(localFile);
return uri;
}
async function ensureJupyterInstalled(): Promise<void> {
let jupterControllerExports = vscode.extensions.getExtension('Microsoft.sql-vnext').exports;
let jupyterController = jupterControllerExports.getJupterController() as JupyterController;
await jupyterController.jupyterInstallation.installReady;
}
}