mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Add encoded path name tests for SQL kernel (#15197)
* Add encoded path name tests for SQL kernel * Remove invocation count
This commit is contained in:
@@ -7,11 +7,12 @@ import 'mocha';
|
|||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { sqlNotebookContent, writeNotebookToFile, sqlKernelMetadata, getFileName, pySparkNotebookContent, pySparkKernelMetadata, pythonKernelMetadata, sqlNotebookMultipleCellsContent, notebookContentForCellLanguageTest, sqlKernelSpec, pythonKernelSpec, pySparkKernelSpec, CellTypes } from './notebook.util';
|
import * as path from 'path';
|
||||||
|
import { sqlNotebookContent, writeNotebookToFile, sqlKernelMetadata, getTempFilePath, pySparkNotebookContent, pySparkKernelMetadata, pythonKernelMetadata, sqlNotebookMultipleCellsContent, notebookContentForCellLanguageTest, sqlKernelSpec, pythonKernelSpec, pySparkKernelSpec, CellTypes } from './notebook.util';
|
||||||
import { getConfigValue, EnvironmentVariable_PYTHON_PATH, TestServerProfile, getStandaloneServer } from './testConfig';
|
import { getConfigValue, EnvironmentVariable_PYTHON_PATH, TestServerProfile, getStandaloneServer } from './testConfig';
|
||||||
import { connectToServer, sleep, testServerProfileToIConnectionProfile } from './utils';
|
import { connectToServer, sleep, testServerProfileToIConnectionProfile } from './utils';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { isNullOrUndefined, promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
|
||||||
suite('Notebook integration test suite', function () {
|
suite('Notebook integration test suite', function () {
|
||||||
setup(async function () {
|
setup(async function () {
|
||||||
@@ -23,7 +24,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
|
|
||||||
teardown(async function () {
|
teardown(async function () {
|
||||||
try {
|
try {
|
||||||
let fileName = getFileName(this.test.title + this.invocationCount++);
|
let fileName = getTempFilePath(this.test.title);
|
||||||
if (await promisify(fs.exists)(fileName)) {
|
if (await promisify(fs.exists)(fileName)) {
|
||||||
await fs.promises.unlink(fileName);
|
await fs.promises.unlink(fileName);
|
||||||
console.log(`"${fileName}" is deleted.`);
|
console.log(`"${fileName}" is deleted.`);
|
||||||
@@ -39,7 +40,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Sql NB test @UNSTABLE@', async function () {
|
test('Sql NB test @UNSTABLE@', async function () {
|
||||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title);
|
||||||
await runCell(notebook);
|
await runCell(notebook);
|
||||||
const expectedOutput0 = '(1 row affected)';
|
const expectedOutput0 = '(1 row affected)';
|
||||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||||
@@ -56,36 +57,19 @@ suite('Notebook integration test suite', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Sql NB multiple cells test', async function () {
|
test('Sql NB multiple cells test', async function () {
|
||||||
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
await multipleCellsTest(this.test.title);
|
||||||
await runCells(notebook);
|
});
|
||||||
const expectedOutput0 = '(1 row affected)';
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
let cellOutputs = notebook.document.cells[i].contents.outputs;
|
|
||||||
console.log(`Got cell outputs --- ${i}`);
|
|
||||||
|
|
||||||
if (cellOutputs) {
|
test('Sql NB multiple cells test - Path with spaces', async function () {
|
||||||
cellOutputs.forEach(console.log);
|
await multipleCellsTest(path.join('folder with spaces', this.test.title));
|
||||||
}
|
});
|
||||||
|
|
||||||
assert(cellOutputs.length === 3, `Expected length: 3, Actual: '${cellOutputs.length}'`);
|
test('Sql NB multiple cells test - Path with encoded spaces', async function () {
|
||||||
let actualOutput0 = (<azdata.nb.IDisplayData>cellOutputs[0]).data['text/html'];
|
await multipleCellsTest(path.join('folder%20with%20encoded%20spaces', this.test.title));
|
||||||
console.log('Got first output');
|
|
||||||
assert(actualOutput0 === expectedOutput0, `Expected row count: '${expectedOutput0}', Actual: '${actualOutput0}'`);
|
|
||||||
|
|
||||||
const executeResult = cellOutputs[2] as azdata.nb.IExecuteResult;
|
|
||||||
assert(Object.keys(executeResult).includes('data'), `Execute result did not include data key. It included ${Object.keys(executeResult)}`);
|
|
||||||
const applicationDataResource = executeResult.data['application/vnd.dataresource+json'];
|
|
||||||
|
|
||||||
assert(Object.keys(applicationDataResource).includes('data'), `Execute result did not include data key. It included ${Object.keys(applicationDataResource)}`);
|
|
||||||
const actualOutput2 = applicationDataResource.data[0];
|
|
||||||
|
|
||||||
assert(actualOutput2[0] === i.toString(), `Expected result: ${i.toString()}, Actual: '${actualOutput2[0]}'`);
|
|
||||||
console.log('Sql multiple cells NB done');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Sql NB run cells above and below test', async function () {
|
test('Sql NB run cells above and below test', async function () {
|
||||||
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title);
|
||||||
// When running all cells above a cell, ensure that only cells preceding current cell have output
|
// When running all cells above a cell, ensure that only cells preceding current cell have output
|
||||||
await runCells(notebook, true, undefined, notebook.document.cells[1]);
|
await runCells(notebook, true, undefined, notebook.document.cells[1]);
|
||||||
assert(notebook.document.cells[0].contents.outputs.length === 3, `Expected length: '3', Actual: '${notebook.document.cells[0].contents.outputs.length}'`);
|
assert(notebook.document.cells[0].contents.outputs.length === 3, `Expected length: '3', Actual: '${notebook.document.cells[0].contents.outputs.length}'`);
|
||||||
@@ -102,20 +86,20 @@ suite('Notebook integration test suite', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Clear cell output - SQL notebook', async function () {
|
test('Clear cell output - SQL notebook', async function () {
|
||||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title);
|
||||||
await runCell(notebook);
|
await runCell(notebook);
|
||||||
await verifyClearOutputs(notebook);
|
await verifyClearOutputs(notebook);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Clear all outputs - SQL notebook', async function () {
|
test('Clear all outputs - SQL notebook', async function () {
|
||||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title);
|
||||||
await runCell(notebook);
|
await runCell(notebook);
|
||||||
await verifyClearAllOutputs(notebook);
|
await verifyClearAllOutputs(notebook);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sql language test', async function () {
|
test('sql language test', async function () {
|
||||||
let language = 'sql';
|
let language = 'sql';
|
||||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title, language, {
|
||||||
'kernelspec': {
|
'kernelspec': {
|
||||||
'name': language,
|
'name': language,
|
||||||
'display_name': language.toUpperCase()
|
'display_name': language.toUpperCase()
|
||||||
@@ -165,7 +149,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
|
|
||||||
if (process.env['RUN_PYTHON3_TEST'] === '1') {
|
if (process.env['RUN_PYTHON3_TEST'] === '1') {
|
||||||
test('Python3 notebook test', async function () {
|
test('Python3 notebook test', async function () {
|
||||||
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title);
|
||||||
await runCell(notebook);
|
await runCell(notebook);
|
||||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||||
console.log('Got cell outputs ---');
|
console.log('Got cell outputs ---');
|
||||||
@@ -177,14 +161,14 @@ suite('Notebook integration test suite', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Clear all outputs - Python3 notebook ', async function () {
|
test('Clear all outputs - Python3 notebook ', async function () {
|
||||||
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title);
|
||||||
await runCell(notebook);
|
await runCell(notebook);
|
||||||
await verifyClearAllOutputs(notebook);
|
await verifyClearAllOutputs(notebook);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('python language test', async function () {
|
test('python language test', async function () {
|
||||||
let language = 'python';
|
let language = 'python';
|
||||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title, language, {
|
||||||
'kernelspec': {
|
'kernelspec': {
|
||||||
'name': 'python3',
|
'name': 'python3',
|
||||||
'display_name': 'Python 3'
|
'display_name': 'Python 3'
|
||||||
@@ -245,7 +229,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
|
|
||||||
if (process.env['RUN_PYSPARK_TEST'] === '1') {
|
if (process.env['RUN_PYSPARK_TEST'] === '1') {
|
||||||
test('PySpark notebook test', async function () {
|
test('PySpark notebook test', async function () {
|
||||||
let notebook = await openNotebook(pySparkNotebookContent, pySparkKernelMetadata, this.test.title + this.invocationCount++);
|
let notebook = await openNotebook(pySparkNotebookContent, pySparkKernelMetadata, this.test.title);
|
||||||
await runCell(notebook);
|
await runCell(notebook);
|
||||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||||
let sparkResult = (<azdata.nb.IStreamResult>cellOutputs[3]).text;
|
let sparkResult = (<azdata.nb.IStreamResult>cellOutputs[3]).text;
|
||||||
@@ -256,7 +240,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
/* After https://github.com/microsoft/azuredatastudio/issues/5598 is fixed, enable these tests.
|
/* After https://github.com/microsoft/azuredatastudio/issues/5598 is fixed, enable these tests.
|
||||||
test('scala language test', async function () {
|
test('scala language test', async function () {
|
||||||
let language = 'scala';
|
let language = 'scala';
|
||||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title, language, {
|
||||||
'kernelspec': {
|
'kernelspec': {
|
||||||
'name': '',
|
'name': '',
|
||||||
'display_name': ''
|
'display_name': ''
|
||||||
@@ -271,7 +255,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
|
|
||||||
test('empty language test', async function () {
|
test('empty language test', async function () {
|
||||||
let language = '';
|
let language = '';
|
||||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title, language, {
|
||||||
'kernelspec': {
|
'kernelspec': {
|
||||||
'name': language,
|
'name': language,
|
||||||
'display_name': ''
|
'display_name': ''
|
||||||
@@ -286,7 +270,7 @@ suite('Notebook integration test suite', function () {
|
|||||||
|
|
||||||
test('cplusplus language test', async function () {
|
test('cplusplus language test', async function () {
|
||||||
let language = 'cplusplus';
|
let language = 'cplusplus';
|
||||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title, language, {
|
||||||
'kernelspec': {
|
'kernelspec': {
|
||||||
'name': '',
|
'name': '',
|
||||||
'display_name': ''
|
'display_name': ''
|
||||||
@@ -301,7 +285,36 @@ suite('Notebook integration test suite', function () {
|
|||||||
*/
|
*/
|
||||||
});
|
});
|
||||||
|
|
||||||
async function openNotebook(content: azdata.nb.INotebookContents, kernelMetadata: any, testName: string, connectToDifferentServer?: boolean): Promise<azdata.nb.NotebookEditor> {
|
async function multipleCellsTest(relativeFilePath: string): Promise<void> {
|
||||||
|
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, relativeFilePath);
|
||||||
|
await runCells(notebook);
|
||||||
|
const expectedOutput0 = '(1 row affected)';
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
let cellOutputs = notebook.document.cells[i].contents.outputs;
|
||||||
|
console.log(`Got cell outputs --- ${i}`);
|
||||||
|
|
||||||
|
if (cellOutputs) {
|
||||||
|
cellOutputs.forEach(console.log);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(cellOutputs.length === 3, `Expected length: 3, Actual: '${cellOutputs.length}'`);
|
||||||
|
let actualOutput0 = (<azdata.nb.IDisplayData>cellOutputs[0]).data['text/html'];
|
||||||
|
console.log('Got first output');
|
||||||
|
assert(actualOutput0 === expectedOutput0, `Expected row count: '${expectedOutput0}', Actual: '${actualOutput0}'`);
|
||||||
|
|
||||||
|
const executeResult = cellOutputs[2] as azdata.nb.IExecuteResult;
|
||||||
|
assert(Object.keys(executeResult).includes('data'), `Execute result did not include data key. It included ${Object.keys(executeResult)}`);
|
||||||
|
const applicationDataResource = executeResult.data['application/vnd.dataresource+json'];
|
||||||
|
|
||||||
|
assert(Object.keys(applicationDataResource).includes('data'), `Execute result did not include data key. It included ${Object.keys(applicationDataResource)}`);
|
||||||
|
const actualOutput2 = applicationDataResource.data[0];
|
||||||
|
|
||||||
|
assert(actualOutput2[0] === i.toString(), `Expected result: ${i.toString()}, Actual: '${actualOutput2[0]}'`);
|
||||||
|
console.log('Sql multiple cells NB done');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openNotebook(content: azdata.nb.INotebookContents, kernelMetadata: azdata.nb.INotebookMetadata, relativeFilePath: string, connectToDifferentServer?: boolean): Promise<azdata.nb.NotebookEditor> {
|
||||||
let notebookConfig = vscode.workspace.getConfiguration('notebook');
|
let notebookConfig = vscode.workspace.getConfiguration('notebook');
|
||||||
notebookConfig.update('pythonPath', getConfigValue(EnvironmentVariable_PYTHON_PATH), 1);
|
notebookConfig.update('pythonPath', getConfigValue(EnvironmentVariable_PYTHON_PATH), 1);
|
||||||
let server: TestServerProfile;
|
let server: TestServerProfile;
|
||||||
@@ -311,7 +324,7 @@ async function openNotebook(content: azdata.nb.INotebookContents, kernelMetadata
|
|||||||
await connectToServer(server, 6000);
|
await connectToServer(server, 6000);
|
||||||
}
|
}
|
||||||
let notebookJson = Object.assign({}, content, { metadata: kernelMetadata });
|
let notebookJson = Object.assign({}, content, { metadata: kernelMetadata });
|
||||||
let uri = writeNotebookToFile(notebookJson, testName);
|
let uri = writeNotebookToFile(notebookJson, relativeFilePath);
|
||||||
console.log('Notebook uri ' + uri);
|
console.log('Notebook uri ' + uri);
|
||||||
let nbShowOptions: azdata.nb.NotebookShowOptions;
|
let nbShowOptions: azdata.nb.NotebookShowOptions;
|
||||||
if (server) {
|
if (server) {
|
||||||
@@ -335,7 +348,7 @@ async function runCells(notebook: azdata.nb.NotebookEditor, runCellsAbove?: bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function runCell(notebook: azdata.nb.NotebookEditor, cell?: azdata.nb.NotebookCell) {
|
async function runCell(notebook: azdata.nb.NotebookEditor, cell?: azdata.nb.NotebookCell) {
|
||||||
if (isNullOrUndefined(cell)) {
|
if (!cell) {
|
||||||
cell = notebook.document.cells[0];
|
cell = notebook.document.cells[0];
|
||||||
}
|
}
|
||||||
let ran = await notebook.runCell(cell);
|
let ran = await notebook.runCell(cell);
|
||||||
@@ -364,9 +377,9 @@ async function verifyClearOutputs(notebook: azdata.nb.NotebookEditor): Promise<v
|
|||||||
assert(clearedOutputs, 'Outputs of requested code cell should be cleared');
|
assert(clearedOutputs, 'Outputs of requested code cell should be cleared');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cellLanguageTest(content: azdata.nb.INotebookContents, testName: string, languageConfigured: string, metadataInfo: any) {
|
async function cellLanguageTest(content: azdata.nb.INotebookContents, relativeFilePath: string, languageConfigured: string, metadataInfo: azdata.nb.INotebookMetadata) {
|
||||||
let notebookJson = Object.assign({}, content, { metadata: metadataInfo });
|
let notebookJson = Object.assign({}, content, { metadata: metadataInfo });
|
||||||
let uri = writeNotebookToFile(notebookJson, testName);
|
let uri = writeNotebookToFile(notebookJson, relativeFilePath);
|
||||||
let notebook = await azdata.nb.showNotebookDocument(uri);
|
let notebook = await azdata.nb.showNotebookDocument(uri);
|
||||||
await notebook.document.save();
|
await notebook.document.save();
|
||||||
let languageInNotebook = notebook.document.cells[0].contents.metadata.language;
|
let languageInNotebook = notebook.document.cells[0].contents.metadata.language;
|
||||||
|
|||||||
@@ -162,19 +162,23 @@ export const pythonKernelSpec: azdata.nb.IKernelSpec = {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
};
|
};
|
||||||
|
|
||||||
export function writeNotebookToFile(pythonNotebook: azdata.nb.INotebookContents, testName: string): vscode.Uri {
|
export function writeNotebookToFile(pythonNotebook: azdata.nb.INotebookContents, relativeFilePath: string): vscode.Uri {
|
||||||
let fileName = getFileName(testName);
|
let fileName = getTempFilePath(relativeFilePath);
|
||||||
let notebookContentString = JSON.stringify(pythonNotebook);
|
let notebookContentString = JSON.stringify(pythonNotebook);
|
||||||
// eslint-disable-next-line no-sync
|
// eslint-disable-next-line no-sync
|
||||||
|
fs.mkdirSync(path.dirname(fileName), { recursive: true });
|
||||||
|
// eslint-disable-next-line no-sync
|
||||||
fs.writeFileSync(fileName, notebookContentString);
|
fs.writeFileSync(fileName, notebookContentString);
|
||||||
console.log(`Local file is created: '${fileName}'`);
|
console.log(`Local file is created: '${fileName}'`);
|
||||||
let uri = vscode.Uri.file(fileName);
|
let uri = vscode.Uri.file(fileName);
|
||||||
return uri;
|
return uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFileName(testName: string): string {
|
/**
|
||||||
if (testName) {
|
* Creates the path of a file in the temp directory
|
||||||
return path.join(os.tmpdir(), testName + '.ipynb');
|
* @param relativeFilePath The relative path of the file in the temp directory
|
||||||
}
|
* @returns The full path of the file
|
||||||
return undefined;
|
*/
|
||||||
|
export function getTempFilePath(relativeFilePath: string): string {
|
||||||
|
return path.join(os.tmpdir(), relativeFilePath + '.ipynb');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user