mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-29 01:25:37 -05:00
Remove adstest package (#9956)
This commit is contained in:
@@ -28,7 +28,6 @@
|
||||
"devDependencies": {
|
||||
"@types/chai": "3.4.34",
|
||||
"@types/node": "^10.14.8",
|
||||
"adstest": "github:ranasaria/adstest.git#0.0.2",
|
||||
"chai": "3.5.0",
|
||||
"mocha-junit-reporter": "^1.17.0",
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as testRunner from 'vscode/lib/testrunner';
|
||||
import { SuiteType, getSuiteType } from 'adstest';
|
||||
import * as path from 'path';
|
||||
|
||||
const suite = getSuiteType();
|
||||
const suite = 'Extension Integration Tests';
|
||||
|
||||
const options: any = {
|
||||
ui: 'tdd',
|
||||
@@ -15,17 +14,6 @@ const options: any = {
|
||||
timeout: 600000
|
||||
};
|
||||
|
||||
if (suite === SuiteType.Stress) {
|
||||
options.timeout = 7200000; // 2 hours
|
||||
// StressRuntime sets the default run time in stress/perf mode for those suites. By default ensure that there is sufficient timeout available.
|
||||
// if ADS_TEST_TIMEOUT is also defined then that value overrides this calculated timeout value. User needs to ensure that ADS_TEST_GREP > StressRuntime if
|
||||
// both are set.
|
||||
if (process.env.StressRuntime) {
|
||||
options.timeout = (120 + 1.2 * parseInt(process.env.StressRuntime)) * 1000; // allow sufficient timeout based on StressRuntime setting
|
||||
console.log(`setting options.timeout to: ${options.timeout} based on process.env.StressRuntime value of ${process.env.StressRuntime} seconds`);
|
||||
}
|
||||
}
|
||||
|
||||
// set relevant mocha options from the environment
|
||||
if (process.env.ADS_TEST_GREP) {
|
||||
options.grep = process.env.ADS_TEST_GREP;
|
||||
|
||||
@@ -11,7 +11,6 @@ import { sqlNotebookContent, writeNotebookToFile, sqlKernelMetadata, getFileName
|
||||
import { getConfigValue, EnvironmentVariable_PYTHON_PATH, TestServerProfile, getStandaloneServer } from './testConfig';
|
||||
import { connectToServer, sleep, testServerProfileToIConnectionProfile } from './utils';
|
||||
import * as fs from 'fs';
|
||||
import { stressify } from 'adstest';
|
||||
import { isNullOrUndefined, promisify } from 'util';
|
||||
|
||||
suite('Notebook integration test suite', function () {
|
||||
@@ -23,136 +22,42 @@ suite('Notebook integration test suite', function () {
|
||||
});
|
||||
|
||||
teardown(async function () {
|
||||
await (new NotebookTester()).cleanup(this.currentTest.title);
|
||||
try {
|
||||
let fileName = getFileName(this.test.title + this.invocationCount++);
|
||||
if (await promisify(fs.exists)(fileName)) {
|
||||
await fs.promises.unlink(fileName);
|
||||
console.log(`"${fileName}" is deleted.`);
|
||||
}
|
||||
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
finally {
|
||||
console.log(`"${this.test.title}" is done`);
|
||||
}
|
||||
});
|
||||
|
||||
test('Sql NB test @UNSTABLE@', async function () {
|
||||
await (new NotebookTester()).sqlNbTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Sql NB multiple cells test @UNSTABLE@', async function () {
|
||||
await (new NotebookTester()).sqlNbMultipleCellsTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Sql NB run cells above and below test', async function () {
|
||||
await (new NotebookTester()).sqlNbRunCellsAboveBelowTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Clear cell output - SQL notebook', async function () {
|
||||
await (new NotebookTester()).sqlNbClearOutputs(this.test.title);
|
||||
});
|
||||
|
||||
test('Clear all outputs - SQL notebook ', async function () {
|
||||
await (new NotebookTester()).sqlNbClearAllOutputs(this.test.title);
|
||||
});
|
||||
|
||||
test('sql language test', async function () {
|
||||
await (new NotebookTester()).sqlLanguageTest(this.test.title);
|
||||
});
|
||||
|
||||
// TODO: Need to make this test more reliable.
|
||||
test('should not be dirty after saving notebook test @UNSTABLE@', async function () {
|
||||
await (new NotebookTester().shouldNotBeDirtyAfterSavingNotebookTest(this.test.title));
|
||||
});
|
||||
|
||||
if (process.env['RUN_PYTHON3_TEST'] === '1') {
|
||||
test('Python3 notebook test', async function () {
|
||||
await (new NotebookTester()).python3NbTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Clear all outputs - Python3 notebook ', async function () {
|
||||
await (new NotebookTester()).python3ClearAllOutputs(this.test.title);
|
||||
});
|
||||
|
||||
test('python language test', async function () {
|
||||
await (new NotebookTester()).pythonLanguageTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Change kernel different provider SQL to Python to SQL', async function () {
|
||||
await (new NotebookTester()).sqlNbChangeKernelDifferentProviderTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Change kernel different provider Python to SQL to Python', async function () {
|
||||
await (new NotebookTester()).pythonChangeKernelDifferentProviderTest(this.test.title);
|
||||
});
|
||||
|
||||
test('Change kernel same provider Python to PySpark to Python', async function () {
|
||||
await (new NotebookTester()).pythonChangeKernelSameProviderTest(this.test.title);
|
||||
});
|
||||
}
|
||||
|
||||
if (process.env['RUN_PYSPARK_TEST'] === '1') {
|
||||
test('PySpark notebook test', async function () {
|
||||
await (new NotebookTester()).pySparkNbTest(this.test.title);
|
||||
});
|
||||
}
|
||||
|
||||
/* After https://github.com/microsoft/azuredatastudio/issues/5598 is fixed, enable these tests.
|
||||
test('scala language test', async function () {
|
||||
await (new NotebookTester()).scalaLanguageTest(this.test.title);
|
||||
});
|
||||
|
||||
test('empty language test', async function () {
|
||||
await (new NotebookTester()).emptyLanguageTest(this.test.title);
|
||||
});
|
||||
|
||||
test('cplusplus language test', async function () {
|
||||
await (new NotebookTester()).cplusplusLanguageTest(this.test.title);
|
||||
});
|
||||
*/
|
||||
});
|
||||
|
||||
class NotebookTester {
|
||||
private static ParallelCount = 1;
|
||||
|
||||
invocationCount: number = 0;
|
||||
|
||||
@stressify({ dop: NotebookTester.ParallelCount })
|
||||
async pySparkNbTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(pySparkNotebookContent, pySparkKernelMetadata, title + this.invocationCount++);
|
||||
await this.runCell(notebook);
|
||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||
let sparkResult = (<azdata.nb.IStreamResult>cellOutputs[3]).text;
|
||||
assert(sparkResult === '2', `Expected spark result: 2, Actual: ${sparkResult}`);
|
||||
}
|
||||
|
||||
@stressify({ dop: NotebookTester.ParallelCount })
|
||||
async python3ClearAllOutputs(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(pySparkNotebookContent, pythonKernelMetadata, title + this.invocationCount++);
|
||||
await this.runCell(notebook);
|
||||
await this.verifyClearAllOutputs(notebook);
|
||||
}
|
||||
|
||||
@stressify({ dop: NotebookTester.ParallelCount })
|
||||
async python3NbTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(pySparkNotebookContent, pythonKernelMetadata, title + this.invocationCount++);
|
||||
await this.runCell(notebook);
|
||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++, true);
|
||||
await runCell(notebook);
|
||||
const expectedOutput0 = '(1 row affected)';
|
||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||
console.log('Got cell outputs ---');
|
||||
if (cellOutputs) {
|
||||
cellOutputs.forEach(o => console.log(JSON.stringify(o, undefined, '\t')));
|
||||
cellOutputs.forEach(o => console.log(o));
|
||||
}
|
||||
let result = (<azdata.nb.IExecuteResult>cellOutputs[0]).data['text/plain'];
|
||||
assert(result === '2', `Expected python result: 2, Actual: ${result}`);
|
||||
}
|
||||
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}`);
|
||||
let actualOutput2 = (<azdata.nb.IExecuteResult>cellOutputs[2]).data['application/vnd.dataresource+json'].data[0];
|
||||
assert(actualOutput2[0] === '1', `Expected result: 1, Actual: '${actualOutput2[0]}'`);
|
||||
});
|
||||
|
||||
@stressify({ dop: NotebookTester.ParallelCount })
|
||||
async sqlNbClearAllOutputs(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title + this.invocationCount++);
|
||||
await this.runCell(notebook);
|
||||
await this.verifyClearAllOutputs(notebook);
|
||||
}
|
||||
|
||||
async sqlNbClearOutputs(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title + this.invocationCount++);
|
||||
await this.runCell(notebook);
|
||||
await this.verifyClearOutputs(notebook);
|
||||
}
|
||||
|
||||
@stressify({ dop: NotebookTester.ParallelCount })
|
||||
async sqlNbMultipleCellsTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, title + this.invocationCount++);
|
||||
await this.runCells(notebook);
|
||||
test('Sql NB multiple cells test @UNSTABLE@', async function () {
|
||||
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
||||
await runCells(notebook);
|
||||
const expectedOutput0 = '(1 row affected)';
|
||||
for (let i = 0; i < 3; i++) {
|
||||
let cellOutputs = notebook.document.cells[i].contents.outputs;
|
||||
@@ -177,12 +82,12 @@ class NotebookTester {
|
||||
assert(actualOutput2[0] === i.toString(), `Expected result: ${i.toString()}, Actual: '${actualOutput2[0]}'`);
|
||||
console.log('Sql multiple cells NB done');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async sqlNbRunCellsAboveBelowTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, title + this.invocationCount++);
|
||||
test('Sql NB run cells above and below test', async function () {
|
||||
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
||||
// When running all cells above a cell, ensure that only cells preceding current cell have output
|
||||
await this.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[1].contents.outputs.length === 0, `Expected length: '0', Actual: '${notebook.document.cells[1].contents.outputs.length}'`);
|
||||
assert(notebook.document.cells[2].contents.outputs.length === 0, `Expected length: '0', Actual: '${notebook.document.cells[2].contents.outputs.length}'`);
|
||||
@@ -190,49 +95,44 @@ class NotebookTester {
|
||||
await notebook.clearAllOutputs();
|
||||
|
||||
// When running all cells below a cell, ensure that current cell and cells after have output
|
||||
await this.runCells(notebook, undefined, true, notebook.document.cells[1]);
|
||||
await runCells(notebook, undefined, true, notebook.document.cells[1]);
|
||||
assert(notebook.document.cells[0].contents.outputs.length === 0, `Expected length: '0', Actual: '${notebook.document.cells[0].contents.outputs.length}'`);
|
||||
assert(notebook.document.cells[1].contents.outputs.length === 3, `Expected length: '3', Actual: '${notebook.document.cells[1].contents.outputs.length}'`);
|
||||
assert(notebook.document.cells[2].contents.outputs.length === 3, `Expected length: '3', Actual: '${notebook.document.cells[2].contents.outputs.length}'`);
|
||||
}
|
||||
});
|
||||
|
||||
@stressify({ dop: NotebookTester.ParallelCount })
|
||||
async sqlNbTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title + this.invocationCount++, true);
|
||||
await this.runCell(notebook);
|
||||
const expectedOutput0 = '(1 row affected)';
|
||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||
console.log('Got cell outputs ---');
|
||||
if (cellOutputs) {
|
||||
cellOutputs.forEach(o => console.log(o));
|
||||
}
|
||||
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}`);
|
||||
let actualOutput2 = (<azdata.nb.IExecuteResult>cellOutputs[2]).data['application/vnd.dataresource+json'].data[0];
|
||||
assert(actualOutput2[0] === '1', `Expected result: 1, Actual: '${actualOutput2[0]}'`);
|
||||
}
|
||||
test('Clear cell output - SQL notebook', async function () {
|
||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
||||
await runCell(notebook);
|
||||
await verifyClearOutputs(notebook);
|
||||
});
|
||||
|
||||
async sqlNbChangeKernelDifferentProviderTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title);
|
||||
await this.runCell(notebook);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(notebook.document.kernelSpec.name === 'SQL', `Expected first kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
test('Clear all outputs - SQL notebook ', async function () {
|
||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title + this.invocationCount++);
|
||||
await runCell(notebook);
|
||||
await verifyClearAllOutputs(notebook);
|
||||
});
|
||||
|
||||
let kernelChanged = await notebook.changeKernel(pythonKernelSpec);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'python3', `Expected second kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
test('sql language test', async function () {
|
||||
let language = 'sql';
|
||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': language,
|
||||
'display_name': language.toUpperCase()
|
||||
},
|
||||
'language_info': {
|
||||
'name': language,
|
||||
'version': '',
|
||||
'mimetype': ''
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
kernelChanged = await notebook.changeKernel(sqlKernelSpec);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'SQL', `Expected third kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
}
|
||||
|
||||
async shouldNotBeDirtyAfterSavingNotebookTest(title: string): Promise<void> {
|
||||
// TODO: Need to make this test more reliable.
|
||||
test('should not be dirty after saving notebook test @UNSTABLE@', async function () {
|
||||
// Given a notebook that's been edited (in this case, open notebook runs the 1st cell and adds an output)
|
||||
let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title);
|
||||
await this.runCell(notebook);
|
||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title);
|
||||
await runCell(notebook);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(notebook.document.kernelSpec.name === 'SQL', `Expected first kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
assert(notebook.document.isDirty === true, 'Notebook should be dirty after edit');
|
||||
@@ -262,27 +162,75 @@ class NotebookTester {
|
||||
await sleep(100);
|
||||
assert(saved === true, 'Expect save after edit to succeed');
|
||||
assert(notebook.document.isDirty === false, 'Notebook should not be dirty after 2nd save');
|
||||
});
|
||||
|
||||
}
|
||||
if (process.env['RUN_PYTHON3_TEST'] === '1') {
|
||||
test('Python3 notebook test', async function () {
|
||||
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title + this.invocationCount++);
|
||||
await runCell(notebook);
|
||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||
console.log('Got cell outputs ---');
|
||||
if (cellOutputs) {
|
||||
cellOutputs.forEach(o => console.log(JSON.stringify(o, undefined, '\t')));
|
||||
}
|
||||
let result = (<azdata.nb.IExecuteResult>cellOutputs[0]).data['text/plain'];
|
||||
assert(result === '2', `Expected python result: 2, Actual: ${result}`);
|
||||
});
|
||||
|
||||
async pythonChangeKernelDifferentProviderTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(pySparkNotebookContent, pythonKernelMetadata, title);
|
||||
await this.runCell(notebook);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(notebook.document.kernelSpec.name === 'python3', `Expected first kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
test('Clear all outputs - Python3 notebook ', async function () {
|
||||
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title + this.invocationCount++);
|
||||
await runCell(notebook);
|
||||
await verifyClearAllOutputs(notebook);
|
||||
});
|
||||
|
||||
let kernelChanged = await notebook.changeKernel(sqlKernelSpec);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'SQL', `Expected second kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
test('python language test', async function () {
|
||||
let language = 'python';
|
||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': 'python3',
|
||||
'display_name': 'Python 3'
|
||||
},
|
||||
'language_info': {
|
||||
'name': language,
|
||||
'version': '',
|
||||
'mimetype': ''
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
kernelChanged = await notebook.changeKernel(pythonKernelSpec);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'python3', `Expected third kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
}
|
||||
test('Change kernel different provider SQL to Python to SQL', async function () {
|
||||
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title);
|
||||
await runCell(notebook);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(notebook.document.kernelSpec.name === 'SQL', `Expected first kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
|
||||
async pythonChangeKernelSameProviderTest(title: string): Promise<void> {
|
||||
let notebook = await this.openNotebook(pySparkNotebookContent, pythonKernelMetadata, title);
|
||||
await this.runCell(notebook);
|
||||
let kernelChanged = await notebook.changeKernel(pythonKernelSpec);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'python3', `Expected second kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
|
||||
kernelChanged = await notebook.changeKernel(sqlKernelSpec);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'SQL', `Expected third kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
});
|
||||
|
||||
test('Change kernel different provider Python to SQL to Python', async function () {
|
||||
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title);
|
||||
await runCell(notebook);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(notebook.document.kernelSpec.name === 'python3', `Expected first kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
|
||||
let kernelChanged = await notebook.changeKernel(sqlKernelSpec);
|
||||
assert(notebook.document.providerId === 'sql', `Expected providerId to be sql, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'SQL', `Expected second kernel name: SQL, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
|
||||
kernelChanged = await notebook.changeKernel(pythonKernelSpec);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'python3', `Expected third kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
});
|
||||
|
||||
test('Change kernel same provider Python to PySpark to Python', async function () {
|
||||
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title);
|
||||
await runCell(notebook);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(notebook.document.kernelSpec.name === 'python3', `Expected first kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
|
||||
@@ -293,11 +241,23 @@ class NotebookTester {
|
||||
kernelChanged = await notebook.changeKernel(pythonKernelSpec);
|
||||
assert(notebook.document.providerId === 'jupyter', `Expected providerId to be jupyter, Actual: ${notebook.document.providerId}`);
|
||||
assert(kernelChanged && notebook.document.kernelSpec.name === 'python3', `Expected third kernel name: python3, Actual: ${notebook.document.kernelSpec.name}`);
|
||||
});
|
||||
}
|
||||
|
||||
async scalaLanguageTest(title: string): Promise<void> {
|
||||
if (process.env['RUN_PYSPARK_TEST'] === '1') {
|
||||
test('PySpark notebook test', async function () {
|
||||
let notebook = await openNotebook(pySparkNotebookContent, pySparkKernelMetadata, this.test.title + this.invocationCount++);
|
||||
await runCell(notebook);
|
||||
let cellOutputs = notebook.document.cells[0].contents.outputs;
|
||||
let sparkResult = (<azdata.nb.IStreamResult>cellOutputs[3]).text;
|
||||
assert(sparkResult === '2', `Expected spark result: 2, Actual: ${sparkResult}`);
|
||||
});
|
||||
}
|
||||
|
||||
/* After https://github.com/microsoft/azuredatastudio/issues/5598 is fixed, enable these tests.
|
||||
test('scala language test', async function () {
|
||||
let language = 'scala';
|
||||
await this.cellLanguageTest(notebookContentForCellLanguageTest, title + this.invocationCount++, language, {
|
||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': '',
|
||||
'display_name': ''
|
||||
@@ -308,26 +268,11 @@ class NotebookTester {
|
||||
mimetype: ''
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async cplusplusLanguageTest(title: string): Promise<void> {
|
||||
let language = 'cplusplus';
|
||||
await this.cellLanguageTest(notebookContentForCellLanguageTest, title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': '',
|
||||
'display_name': ''
|
||||
},
|
||||
'language_info': {
|
||||
name: language,
|
||||
version: '',
|
||||
mimetype: ''
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async emptyLanguageTest(title: string): Promise<void> {
|
||||
test('empty language test', async function () {
|
||||
let language = '';
|
||||
await this.cellLanguageTest(notebookContentForCellLanguageTest, title + this.invocationCount++, language, {
|
||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': language,
|
||||
'display_name': ''
|
||||
@@ -338,124 +283,93 @@ class NotebookTester {
|
||||
mimetype: 'x-scala'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async sqlLanguageTest(title: string): Promise<void> {
|
||||
let language = 'sql';
|
||||
await this.cellLanguageTest(notebookContentForCellLanguageTest, title + this.invocationCount++, language, {
|
||||
test('cplusplus language test', async function () {
|
||||
let language = 'cplusplus';
|
||||
await cellLanguageTest(notebookContentForCellLanguageTest, this.test.title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': language,
|
||||
'display_name': language.toUpperCase()
|
||||
'name': '',
|
||||
'display_name': ''
|
||||
},
|
||||
'language_info': {
|
||||
'name': language,
|
||||
'version': '',
|
||||
'mimetype': ''
|
||||
name: language,
|
||||
version: '',
|
||||
mimetype: ''
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
*/
|
||||
});
|
||||
|
||||
async pythonLanguageTest(title: string): Promise<void> {
|
||||
let language = 'python';
|
||||
await this.cellLanguageTest(notebookContentForCellLanguageTest, title + this.invocationCount++, language, {
|
||||
'kernelspec': {
|
||||
'name': 'python3',
|
||||
'display_name': 'Python 3'
|
||||
},
|
||||
'language_info': {
|
||||
'name': language,
|
||||
'version': '',
|
||||
'mimetype': ''
|
||||
}
|
||||
});
|
||||
async function openNotebook(content: azdata.nb.INotebookContents, kernelMetadata: any, testName: string, connectToDifferentServer?: boolean): Promise<azdata.nb.NotebookEditor> {
|
||||
let notebookConfig = vscode.workspace.getConfiguration('notebook');
|
||||
notebookConfig.update('pythonPath', getConfigValue(EnvironmentVariable_PYTHON_PATH), 1);
|
||||
let server: TestServerProfile;
|
||||
if (!connectToDifferentServer) {
|
||||
server = await getStandaloneServer();
|
||||
assert(server && server.serverName, 'No server could be found in openNotebook');
|
||||
await connectToServer(server, 6000);
|
||||
}
|
||||
|
||||
async cleanup(testName: string): Promise<void> {
|
||||
try {
|
||||
let fileName = getFileName(testName + this.invocationCount++);
|
||||
if (await promisify(fs.exists)(fileName)) {
|
||||
await fs.promises.unlink(fileName);
|
||||
console.log(`"${fileName}" is deleted.`);
|
||||
}
|
||||
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
finally {
|
||||
console.log(`"${testName}" is done`);
|
||||
}
|
||||
}
|
||||
|
||||
async openNotebook(content: azdata.nb.INotebookContents, kernelMetadata: any, testName: string, connectToDifferentServer?: boolean): Promise<azdata.nb.NotebookEditor> {
|
||||
let notebookConfig = vscode.workspace.getConfiguration('notebook');
|
||||
notebookConfig.update('pythonPath', getConfigValue(EnvironmentVariable_PYTHON_PATH), 1);
|
||||
let server: TestServerProfile;
|
||||
if (!connectToDifferentServer) {
|
||||
server = await getStandaloneServer();
|
||||
assert(server && server.serverName, 'No server could be found in openNotebook');
|
||||
await connectToServer(server, 6000);
|
||||
}
|
||||
let notebookJson = Object.assign({}, content, { metadata: kernelMetadata });
|
||||
let uri = writeNotebookToFile(notebookJson, testName);
|
||||
console.log('Notebook uri ' + uri);
|
||||
let nbShowOptions: azdata.nb.NotebookShowOptions;
|
||||
if (server) {
|
||||
nbShowOptions = { connectionProfile: testServerProfileToIConnectionProfile(server) };
|
||||
}
|
||||
let notebook = await azdata.nb.showNotebookDocument(uri, nbShowOptions);
|
||||
return notebook;
|
||||
}
|
||||
|
||||
async runCells(notebook: azdata.nb.NotebookEditor, runCellsAbove?: boolean, runCellsBelow?: boolean, currentCell?: azdata.nb.NotebookCell) {
|
||||
assert(notebook !== undefined && notebook !== null, 'Expected notebook object is defined');
|
||||
let ran;
|
||||
if (runCellsAbove) {
|
||||
ran = await notebook.runAllCells(undefined, currentCell);
|
||||
} else if (runCellsBelow) {
|
||||
ran = await notebook.runAllCells(currentCell, undefined);
|
||||
} else {
|
||||
ran = await notebook.runAllCells();
|
||||
}
|
||||
assert(ran, 'Notebook runCell should succeed');
|
||||
}
|
||||
|
||||
async runCell(notebook: azdata.nb.NotebookEditor, cell?: azdata.nb.NotebookCell) {
|
||||
if (isNullOrUndefined(cell)) {
|
||||
cell = notebook.document.cells[0];
|
||||
}
|
||||
let ran = await notebook.runCell(cell);
|
||||
assert(ran, 'Notebook runCell should succeed');
|
||||
}
|
||||
|
||||
async verifyClearAllOutputs(notebook: azdata.nb.NotebookEditor): Promise<void> {
|
||||
let cellWithOutputs = notebook.document.cells.find(cell => cell.contents && cell.contents.outputs && cell.contents.outputs.length > 0);
|
||||
assert(cellWithOutputs !== undefined, 'Could not find notebook cells with outputs');
|
||||
console.log('Before clearing cell outputs');
|
||||
let clearedOutputs = await notebook.clearAllOutputs();
|
||||
let cells = notebook.document.cells;
|
||||
cells.forEach(cell => {
|
||||
assert(cell.contents && cell.contents.outputs && cell.contents.outputs.length === 0, `Expected Output: 0, Actual: '${cell.contents.outputs.length}'`);
|
||||
});
|
||||
assert(clearedOutputs, 'Outputs of all the code cells from Python notebook should be cleared');
|
||||
console.log('After clearing cell outputs');
|
||||
}
|
||||
|
||||
async verifyClearOutputs(notebook: azdata.nb.NotebookEditor): Promise<void> {
|
||||
let cellWithOutputs = notebook.document.cells[0].contents && notebook.document.cells[0].contents.outputs && notebook.document.cells[0].contents.outputs.length > 0;
|
||||
assert(cellWithOutputs === true, 'Expected first cell to have outputs');
|
||||
let clearedOutputs = await notebook.clearOutput(notebook.document.cells[0]);
|
||||
let firstCell = notebook.document.cells[0];
|
||||
assert(firstCell.contents && firstCell.contents.outputs && firstCell.contents.outputs.length === 0, `Expected Output: 0, Actual: '${firstCell.contents.outputs.length}'`);
|
||||
assert(clearedOutputs, 'Outputs of requested code cell should be cleared');
|
||||
}
|
||||
|
||||
async cellLanguageTest(content: azdata.nb.INotebookContents, testName: string, languageConfigured: string, metadataInfo: any) {
|
||||
let notebookJson = Object.assign({}, content, { metadata: metadataInfo });
|
||||
let uri = writeNotebookToFile(notebookJson, testName);
|
||||
let notebook = await azdata.nb.showNotebookDocument(uri);
|
||||
await notebook.document.save();
|
||||
let languageInNotebook = notebook.document.cells[0].contents.metadata.language;
|
||||
assert(languageInNotebook === languageConfigured, `Expected cell language is: ${languageConfigured}, Actual: ${languageInNotebook}`);
|
||||
let notebookJson = Object.assign({}, content, { metadata: kernelMetadata });
|
||||
let uri = writeNotebookToFile(notebookJson, testName);
|
||||
console.log('Notebook uri ' + uri);
|
||||
let nbShowOptions: azdata.nb.NotebookShowOptions;
|
||||
if (server) {
|
||||
nbShowOptions = { connectionProfile: testServerProfileToIConnectionProfile(server) };
|
||||
}
|
||||
let notebook = await azdata.nb.showNotebookDocument(uri, nbShowOptions);
|
||||
return notebook;
|
||||
}
|
||||
|
||||
async function runCells(notebook: azdata.nb.NotebookEditor, runCellsAbove?: boolean, runCellsBelow?: boolean, currentCell?: azdata.nb.NotebookCell) {
|
||||
assert(notebook !== undefined && notebook !== null, 'Expected notebook object is defined');
|
||||
let ran;
|
||||
if (runCellsAbove) {
|
||||
ran = await notebook.runAllCells(undefined, currentCell);
|
||||
} else if (runCellsBelow) {
|
||||
ran = await notebook.runAllCells(currentCell, undefined);
|
||||
} else {
|
||||
ran = await notebook.runAllCells();
|
||||
}
|
||||
assert(ran, 'Notebook runCell should succeed');
|
||||
}
|
||||
|
||||
async function runCell(notebook: azdata.nb.NotebookEditor, cell?: azdata.nb.NotebookCell) {
|
||||
if (isNullOrUndefined(cell)) {
|
||||
cell = notebook.document.cells[0];
|
||||
}
|
||||
let ran = await notebook.runCell(cell);
|
||||
assert(ran, 'Notebook runCell should succeed');
|
||||
}
|
||||
|
||||
async function verifyClearAllOutputs(notebook: azdata.nb.NotebookEditor): Promise<void> {
|
||||
let cellWithOutputs = notebook.document.cells.find(cell => cell.contents && cell.contents.outputs && cell.contents.outputs.length > 0);
|
||||
assert(cellWithOutputs !== undefined, 'Could not find notebook cells with outputs');
|
||||
console.log('Before clearing cell outputs');
|
||||
let clearedOutputs = await notebook.clearAllOutputs();
|
||||
let cells = notebook.document.cells;
|
||||
cells.forEach(cell => {
|
||||
assert(cell.contents && cell.contents.outputs && cell.contents.outputs.length === 0, `Expected Output: 0, Actual: '${cell.contents.outputs.length}'`);
|
||||
});
|
||||
assert(clearedOutputs, 'Outputs of all the code cells from Python notebook should be cleared');
|
||||
console.log('After clearing cell outputs');
|
||||
}
|
||||
|
||||
async function verifyClearOutputs(notebook: azdata.nb.NotebookEditor): Promise<void> {
|
||||
let cellWithOutputs = notebook.document.cells[0].contents && notebook.document.cells[0].contents.outputs && notebook.document.cells[0].contents.outputs.length > 0;
|
||||
assert(cellWithOutputs === true, 'Expected first cell to have outputs');
|
||||
let clearedOutputs = await notebook.clearOutput(notebook.document.cells[0]);
|
||||
let firstCell = notebook.document.cells[0];
|
||||
assert(firstCell.contents && firstCell.contents.outputs && firstCell.contents.outputs.length === 0, `Expected Output: 0, Actual: '${firstCell.contents.outputs.length}'`);
|
||||
assert(clearedOutputs, 'Outputs of requested code cell should be cleared');
|
||||
}
|
||||
|
||||
async function cellLanguageTest(content: azdata.nb.INotebookContents, testName: string, languageConfigured: string, metadataInfo: any) {
|
||||
let notebookJson = Object.assign({}, content, { metadata: metadataInfo });
|
||||
let uri = writeNotebookToFile(notebookJson, testName);
|
||||
let notebook = await azdata.nb.showNotebookDocument(uri);
|
||||
await notebook.document.save();
|
||||
let languageInNotebook = notebook.document.cells[0].contents.metadata.language;
|
||||
assert(languageInNotebook === languageConfigured, `Expected cell language is: ${languageConfigured}, Actual: ${languageInNotebook}`);
|
||||
}
|
||||
|
||||
@@ -8,78 +8,26 @@ import * as azdata from 'azdata';
|
||||
import { getBdcServer, TestServerProfile, getAzureServer, getStandaloneServer } from './testConfig';
|
||||
import { connectToServer, createDB, deleteDB, DefaultConnectTimeoutInMs, asyncTimeout } from './utils';
|
||||
import * as assert from 'assert';
|
||||
import { stressify } from 'adstest';
|
||||
|
||||
suite('Object Explorer integration suite', () => {
|
||||
test.skip('BDC instance node label test', async function () {
|
||||
return await (new ObjectExplorerTester()).bdcNodeLabelTest();
|
||||
});
|
||||
test('Standalone instance node label test', async function () {
|
||||
return await (new ObjectExplorerTester()).standaloneNodeLabelTest();
|
||||
});
|
||||
test('Azure SQL DB instance node label test @UNSTABLE@', async function () {
|
||||
return await (new ObjectExplorerTester()).sqlDbNodeLabelTest();
|
||||
});
|
||||
test.skip('BDC instance context menu test', async function () {
|
||||
return await (new ObjectExplorerTester()).bdcContextMenuTest();
|
||||
});
|
||||
test('Azure SQL DB context menu test @UNSTABLE@', async function () {
|
||||
return await (new ObjectExplorerTester()).sqlDbContextMenuTest();
|
||||
});
|
||||
test('Standalone database context menu test', async function () {
|
||||
return await (new ObjectExplorerTester()).standaloneContextMenuTest();
|
||||
});
|
||||
});
|
||||
|
||||
class ObjectExplorerTester {
|
||||
private static ParallelCount = 1;
|
||||
|
||||
@stressify({ dop: ObjectExplorerTester.ParallelCount })
|
||||
async bdcNodeLabelTest(): Promise<void> {
|
||||
const expectedNodeLabel = ['Databases', 'Security', 'Server Objects'];
|
||||
const server = await getBdcServer();
|
||||
return await this.verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel);
|
||||
}
|
||||
|
||||
@stressify({ dop: ObjectExplorerTester.ParallelCount })
|
||||
async standaloneNodeLabelTest(): Promise<void> {
|
||||
await verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel);
|
||||
});
|
||||
test('Standalone instance node label test', async function () {
|
||||
if (process.platform === 'win32') {
|
||||
const expectedNodeLabel = ['Databases', 'Security', 'Server Objects'];
|
||||
const server = await getStandaloneServer();
|
||||
return await this.verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel);
|
||||
await verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@stressify({ dop: ObjectExplorerTester.ParallelCount })
|
||||
async sqlDbNodeLabelTest(): Promise<void> {
|
||||
});
|
||||
test('Azure SQL DB instance node label test @UNSTABLE@', async function () {
|
||||
const expectedNodeLabel = ['Databases', 'Security'];
|
||||
const server = await getAzureServer();
|
||||
return await this.verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel);
|
||||
}
|
||||
|
||||
@stressify({ dop: ObjectExplorerTester.ParallelCount })
|
||||
async sqlDbContextMenuTest(): Promise<void> {
|
||||
const server = await getAzureServer();
|
||||
const expectedActions = ['Manage', 'New Query', 'New Notebook', 'Disconnect', 'Delete Connection', 'Refresh', 'Data-tier Application wizard', 'Launch Profiler'];
|
||||
return await this.verifyContextMenu(server, expectedActions);
|
||||
}
|
||||
|
||||
@stressify({ dop: ObjectExplorerTester.ParallelCount })
|
||||
async standaloneContextMenuTest(): Promise<void> {
|
||||
const server = await getStandaloneServer();
|
||||
let expectedActions: string[] = [];
|
||||
// Generate Scripts and Properties come from the admin-tool-ext-win extension which is for Windows only, so the item won't show up on non-Win32 platforms
|
||||
if (process.platform === 'win32') {
|
||||
expectedActions = ['Manage', 'New Query', 'New Notebook', 'Refresh', 'Backup', 'Restore', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard', 'Generate Scripts...', 'Properties'];
|
||||
}
|
||||
else {
|
||||
expectedActions = ['Manage', 'New Query', 'New Notebook', 'Refresh', 'Backup', 'Restore', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard'];
|
||||
}
|
||||
return await this.verifyDBContextMenu(server, DefaultConnectTimeoutInMs, expectedActions);
|
||||
}
|
||||
|
||||
@stressify({ dop: ObjectExplorerTester.ParallelCount })
|
||||
async bdcContextMenuTest(): Promise<void> {
|
||||
await verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel);
|
||||
});
|
||||
test.skip('BDC instance context menu test', async function () {
|
||||
const server = await getBdcServer();
|
||||
let expectedActions: string[];
|
||||
// Properties comes from the admin-tool-ext-win extension which is for Windows only, so the item won't show up on non-Win32 platforms
|
||||
@@ -89,80 +37,99 @@ class ObjectExplorerTester {
|
||||
else {
|
||||
expectedActions = ['Manage', 'New Query', 'New Notebook', 'Disconnect', 'Delete Connection', 'Refresh', 'Data-tier Application wizard', 'Launch Profiler'];
|
||||
}
|
||||
return await this.verifyContextMenu(server, expectedActions);
|
||||
return await verifyContextMenu(server, expectedActions);
|
||||
});
|
||||
test('Azure SQL DB context menu test @UNSTABLE@', async function () {
|
||||
const server = await getAzureServer();
|
||||
const expectedActions = ['Manage', 'New Query', 'New Notebook', 'Disconnect', 'Delete Connection', 'Refresh', 'Data-tier Application wizard', 'Launch Profiler'];
|
||||
await verifyContextMenu(server, expectedActions);
|
||||
});
|
||||
test('Standalone database context menu test', async function () {
|
||||
const server = await getStandaloneServer();
|
||||
let expectedActions: string[] = [];
|
||||
// Generate Scripts and Properties come from the admin-tool-ext-win extension which is for Windows only, so the item won't show up on non-Win32 platforms
|
||||
if (process.platform === 'win32') {
|
||||
expectedActions = ['Manage', 'New Query', 'New Notebook', 'Refresh', 'Backup', 'Restore', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard', 'Generate Scripts...', 'Properties'];
|
||||
}
|
||||
else {
|
||||
expectedActions = ['Manage', 'New Query', 'New Notebook', 'Refresh', 'Backup', 'Restore', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard'];
|
||||
}
|
||||
await verifyDBContextMenu(server, DefaultConnectTimeoutInMs, expectedActions);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
async function verifyContextMenu(server: TestServerProfile, expectedActions: string[]): Promise<void> {
|
||||
await connectToServer(server, DefaultConnectTimeoutInMs);
|
||||
const nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
|
||||
|
||||
const index = nodes.findIndex(node => node.nodePath.includes(server.serverName));
|
||||
assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`);
|
||||
|
||||
const node = nodes[index];
|
||||
const actions = await azdata.objectexplorer.getNodeActions(node.connectionId, node.nodePath);
|
||||
|
||||
const expectedString = expectedActions.join(',');
|
||||
const actualString = actions.join(',');
|
||||
return assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`);
|
||||
}
|
||||
|
||||
async function verifyOeNode(server: TestServerProfile, timeout: number, expectedNodeLabel: string[]): Promise<void> {
|
||||
await connectToServer(server, timeout);
|
||||
const nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
|
||||
|
||||
const index = nodes.findIndex(node => node.nodePath.includes(server.serverName));
|
||||
assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`);
|
||||
// TODO: #7146 HDFS isn't always filled in by the call to getChildren since it's loaded asynchronously. To avoid this test being flaky just removing
|
||||
// the node for now if it exists until a proper fix can be made.
|
||||
|
||||
let children: azdata.objectexplorer.ObjectExplorerNode[];
|
||||
try {
|
||||
children = await asyncTimeout(nodes[index].getChildren(), timeout);
|
||||
} catch (e) {
|
||||
return assert.fail('getChildren() timed out...', e);
|
||||
}
|
||||
|
||||
async verifyContextMenu(server: TestServerProfile, expectedActions: string[]): Promise<void> {
|
||||
await connectToServer(server, DefaultConnectTimeoutInMs);
|
||||
const nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
|
||||
const nonHDFSChildren = children.filter(c => c.label !== 'HDFS');
|
||||
const actualLabelsString = nonHDFSChildren.map(c => c.label).join(',');
|
||||
const expectedLabelString = expectedNodeLabel.join(',');
|
||||
return assert(expectedNodeLabel.length === nonHDFSChildren.length && expectedLabelString === actualLabelsString, `Expected node label: "${expectedLabelString}", Actual: "${actualLabelsString}"`);
|
||||
}
|
||||
|
||||
const index = nodes.findIndex(node => node.nodePath.includes(server.serverName));
|
||||
assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`);
|
||||
async function verifyDBContextMenu(server: TestServerProfile, timeoutinMS: number, expectedActions: string[]): Promise<void> {
|
||||
|
||||
const node = nodes[index];
|
||||
const actions = await azdata.objectexplorer.getNodeActions(node.connectionId, node.nodePath);
|
||||
await connectToServer(server, timeoutinMS);
|
||||
|
||||
const nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
|
||||
|
||||
const index = nodes.findIndex(node => node.nodePath.includes(server.serverName));
|
||||
assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`);
|
||||
|
||||
const ownerUri = await azdata.connection.getUriForConnection(nodes[index].connectionId);
|
||||
const dbName: string = 'ads_test_VerifyDBContextMenu_' + new Date().getTime().toString();
|
||||
try {
|
||||
await createDB(dbName, ownerUri);
|
||||
|
||||
const serverNode = nodes[index];
|
||||
const children = await serverNode.getChildren();
|
||||
|
||||
assert(children[0].label === 'Databases', `Expected Databases node. Actual ${children[0].label}`);
|
||||
const databasesFolder = children[0];
|
||||
|
||||
const databases = await databasesFolder.getChildren();
|
||||
assert(databases.length > 2, `No database present, can not test further`); // System Databses folder and at least one database
|
||||
|
||||
const actions = await azdata.objectexplorer.getNodeActions(databases[1].connectionId, databases[1].nodePath);
|
||||
|
||||
const expectedString = expectedActions.join(',');
|
||||
const actualString = actions.join(',');
|
||||
return assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`);
|
||||
}
|
||||
|
||||
async verifyOeNode(server: TestServerProfile, timeout: number, expectedNodeLabel: string[]): Promise<void> {
|
||||
await connectToServer(server, timeout);
|
||||
const nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
|
||||
|
||||
const index = nodes.findIndex(node => node.nodePath.includes(server.serverName));
|
||||
assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`);
|
||||
// TODO: #7146 HDFS isn't always filled in by the call to getChildren since it's loaded asynchronously. To avoid this test being flaky just removing
|
||||
// the node for now if it exists until a proper fix can be made.
|
||||
|
||||
let children: azdata.objectexplorer.ObjectExplorerNode[];
|
||||
try {
|
||||
children = await asyncTimeout(nodes[index].getChildren(), timeout);
|
||||
} catch (e) {
|
||||
return assert.fail('getChildren() timed out...', e);
|
||||
}
|
||||
|
||||
const nonHDFSChildren = children.filter(c => c.label !== 'HDFS');
|
||||
const actualLabelsString = nonHDFSChildren.map(c => c.label).join(',');
|
||||
const expectedLabelString = expectedNodeLabel.join(',');
|
||||
return assert(expectedNodeLabel.length === nonHDFSChildren.length && expectedLabelString === actualLabelsString, `Expected node label: "${expectedLabelString}", Actual: "${actualLabelsString}"`);
|
||||
}
|
||||
|
||||
async verifyDBContextMenu(server: TestServerProfile, timeoutinMS: number, expectedActions: string[]): Promise<void> {
|
||||
|
||||
await connectToServer(server, timeoutinMS);
|
||||
|
||||
const nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
|
||||
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
|
||||
|
||||
const index = nodes.findIndex(node => node.nodePath.includes(server.serverName));
|
||||
assert(index !== -1, `Failed to find server: "${server.serverName}" in OE tree`);
|
||||
|
||||
const ownerUri = await azdata.connection.getUriForConnection(nodes[index].connectionId);
|
||||
const dbName: string = 'ads_test_VerifyDBContextMenu_' + new Date().getTime().toString();
|
||||
try {
|
||||
await createDB(dbName, ownerUri);
|
||||
|
||||
const serverNode = nodes[index];
|
||||
const children = await serverNode.getChildren();
|
||||
|
||||
assert(children[0].label === 'Databases', `Expected Databases node. Actual ${children[0].label}`);
|
||||
const databasesFolder = children[0];
|
||||
|
||||
const databases = await databasesFolder.getChildren();
|
||||
assert(databases.length > 2, `No database present, can not test further`); // System Databses folder and at least one database
|
||||
|
||||
const actions = await azdata.objectexplorer.getNodeActions(databases[1].connectionId, databases[1].nodePath);
|
||||
|
||||
const expectedString = expectedActions.join(',');
|
||||
const actualString = actions.join(',');
|
||||
return assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`);
|
||||
}
|
||||
finally {
|
||||
await deleteDB(server, dbName, ownerUri);
|
||||
}
|
||||
finally {
|
||||
await deleteDB(server, dbName, ownerUri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,13 @@ import * as utils from './utils';
|
||||
import * as mssql from '../../../mssql';
|
||||
import * as os from 'os';
|
||||
import * as fs from 'fs';
|
||||
const path = require('path');
|
||||
import * as path from 'path';
|
||||
import * as assert from 'assert';
|
||||
import { getStandaloneServer } from './testConfig';
|
||||
import { stressify } from 'adstest';
|
||||
import { promisify } from 'util';
|
||||
|
||||
let schemaCompareService: mssql.ISchemaCompareService;
|
||||
let dacfxService: mssql.IDacFxService;
|
||||
let schemaCompareTester: SchemaCompareTester;
|
||||
const dacpac1: string = path.join(__dirname, '..', '..', 'testData', 'Database1.dacpac');
|
||||
const dacpac2: string = path.join(__dirname, '..', '..', 'testData', 'Database2.dacpac');
|
||||
const includeExcludeSourceDacpac: string = path.join(__dirname, '..', '..', 'testData', 'SchemaCompareIncludeExcludeSource.dacpac');
|
||||
@@ -39,28 +37,9 @@ suite('Schema compare integration test suite', () => {
|
||||
await utils.sleep(1000); // To ensure the providers are registered.
|
||||
}
|
||||
dacfxService = ((await vscode.extensions.getExtension(mssql.extension.name).activate() as mssql.IExtension)).dacFx;
|
||||
schemaCompareTester = new SchemaCompareTester();
|
||||
console.log(`Start schema compare tests`);
|
||||
});
|
||||
test('Schema compare dacpac to dacpac comparison and scmp', async function () {
|
||||
await schemaCompareTester.SchemaCompareDacpacToDacpac();
|
||||
});
|
||||
test('Schema compare database to database comparison, script generation, and scmp', async function () {
|
||||
await schemaCompareTester.SchemaCompareDatabaseToDatabase();
|
||||
});
|
||||
test('Schema compare dacpac to database comparison, script generation, and scmp', async function () {
|
||||
await schemaCompareTester.SchemaCompareDacpacToDatabase();
|
||||
});
|
||||
test('Schema compare dacpac to dacpac comparison with include exclude', async function () {
|
||||
await schemaCompareTester.SchemaCompareIncludeExcludeDacpacToDacpac();
|
||||
});
|
||||
});
|
||||
|
||||
class SchemaCompareTester {
|
||||
private static ParallelCount = 1;
|
||||
|
||||
@stressify({ dop: SchemaCompareTester.ParallelCount })
|
||||
async SchemaCompareDacpacToDacpac(): Promise<void> {
|
||||
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
||||
const now = new Date();
|
||||
const operationId = 'testOperationId_' + now.getTime().toString();
|
||||
@@ -85,7 +64,7 @@ class SchemaCompareTester {
|
||||
};
|
||||
|
||||
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
||||
this.assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
|
||||
// save to scmp
|
||||
const filepath = path.join(folderPath, `ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
||||
@@ -101,10 +80,8 @@ class SchemaCompareTester {
|
||||
assert(openScmpResult.success && !openScmpResult.errorMessage, `Open scmp should succeed. Expected: there should be no error. Actual Error message: "${openScmpResult.errorMessage}`);
|
||||
assert(openScmpResult.sourceEndpointInfo.packageFilePath === source.packageFilePath, `Expected: source packageFilePath to be ${source.packageFilePath}, Actual: ${openScmpResult.sourceEndpointInfo.packageFilePath}`);
|
||||
assert(openScmpResult.targetEndpointInfo.packageFilePath === target.packageFilePath, `Expected: target packageFilePath to be ${target.packageFilePath}, Actual: ${openScmpResult.targetEndpointInfo.packageFilePath}`);
|
||||
}
|
||||
|
||||
@stressify({ dop: SchemaCompareTester.ParallelCount })
|
||||
async SchemaCompareDatabaseToDatabase(): Promise<void> {
|
||||
});
|
||||
test('Schema compare database to database comparison, script generation, and scmp', async function () {
|
||||
let server = await getStandaloneServer();
|
||||
await utils.connectToServer(server, SERVER_CONNECTION_TIMEOUT);
|
||||
|
||||
@@ -153,13 +130,13 @@ class SchemaCompareTester {
|
||||
};
|
||||
|
||||
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
||||
this.assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
|
||||
let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.script);
|
||||
|
||||
// TODO : add wait for tasks to complete
|
||||
// script generation might take too long and the 'success' status does not mean that script is created.
|
||||
await this.assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
||||
await assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
||||
|
||||
// save to scmp
|
||||
const filepath = path.join(folderPath, `ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
||||
@@ -182,10 +159,8 @@ class SchemaCompareTester {
|
||||
await utils.deleteDB(server, sourceDB, ownerUri);
|
||||
await utils.deleteDB(server, targetDB, ownerUri);
|
||||
}
|
||||
}
|
||||
|
||||
@stressify({ dop: SchemaCompareTester.ParallelCount })
|
||||
async SchemaCompareDacpacToDatabase(): Promise<void> {
|
||||
});
|
||||
test('Schema compare dacpac to database comparison, script generation, and scmp', async function () {
|
||||
let server = await getStandaloneServer();
|
||||
await utils.connectToServer(server, SERVER_CONNECTION_TIMEOUT);
|
||||
|
||||
@@ -228,10 +203,10 @@ class SchemaCompareTester {
|
||||
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
||||
|
||||
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
||||
this.assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
|
||||
let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.script);
|
||||
await this.assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
||||
await assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
||||
|
||||
// save to scmp
|
||||
const filepath = path.join(folderPath, `ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
||||
@@ -251,10 +226,8 @@ class SchemaCompareTester {
|
||||
finally {
|
||||
await utils.deleteDB(server, targetDB, ownerUri);
|
||||
}
|
||||
}
|
||||
|
||||
@stressify({ dop: SchemaCompareTester.ParallelCount })
|
||||
async SchemaCompareIncludeExcludeDacpacToDacpac(): Promise<void> {
|
||||
});
|
||||
test('Schema compare dacpac to dacpac comparison with include exclude', async function () {
|
||||
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
||||
const operationId = 'testOperationId_' + new Date().getTime().toString();
|
||||
|
||||
@@ -280,26 +253,26 @@ class SchemaCompareTester {
|
||||
const deploymentOptionsResult = await schemaCompareService.schemaCompareGetDefaultOptions();
|
||||
let deploymentOptions = deploymentOptionsResult.defaultDeploymentOptions;
|
||||
const schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, deploymentOptions);
|
||||
this.assertSchemaCompareResult(schemaCompareResult, operationId, 5);
|
||||
assertSchemaCompareResult(schemaCompareResult, operationId, 5);
|
||||
|
||||
// try to exclude table t2 and it should fail because a dependency is still included
|
||||
const t2Difference = schemaCompareResult.differences.find(e => e.sourceValue && e.sourceValue[1] === 't2' && e.name === 'SqlTable');
|
||||
assert(t2Difference !== undefined, 'The difference Table t2 should be found. Should not be undefined');
|
||||
const excludeResult = await schemaCompareService.schemaCompareIncludeExcludeNode(operationId, t2Difference, false, azdata.TaskExecutionMode.execute);
|
||||
this.assertIncludeExcludeResult(excludeResult, false, 1, 0);
|
||||
assertIncludeExcludeResult(excludeResult, false, 1, 0);
|
||||
assert(excludeResult.blockingDependencies[0].sourceValue[1] === 'v1', `Blocking dependency should be view v1. Actual: ${excludeResult.blockingDependencies[0].sourceValue[1]}`);
|
||||
|
||||
// Exclude the view v1 that t2 was a dependency for and it should succeed and t2 should also be excluded
|
||||
const v1Difference = schemaCompareResult.differences.find(e => e.sourceValue && e.sourceValue[1] === 'v1' && e.name === 'SqlView');
|
||||
assert(v1Difference !== undefined, 'The difference View v1 should be found. Should not be undefined');
|
||||
const excludeResult2 = await schemaCompareService.schemaCompareIncludeExcludeNode(operationId, v1Difference, false, azdata.TaskExecutionMode.execute);
|
||||
this.assertIncludeExcludeResult(excludeResult2, true, 0, 1);
|
||||
assertIncludeExcludeResult(excludeResult2, true, 0, 1);
|
||||
assert(excludeResult2.affectedDependencies[0].sourceValue[1] === 't2', `Table t2 should be the affected dependency. Actual: ${excludeResult2.affectedDependencies[0].sourceValue[1]}`);
|
||||
assert(excludeResult2.affectedDependencies[0].included === false, 'Table t2 should be excluded as a result of excluding v1. Actual: true');
|
||||
|
||||
// including the view v1 should also include the table t2
|
||||
const includeResult = await schemaCompareService.schemaCompareIncludeExcludeNode(operationId, v1Difference, true, azdata.TaskExecutionMode.execute);
|
||||
this.assertIncludeExcludeResult(includeResult, true, 0, 1);
|
||||
assertIncludeExcludeResult(includeResult, true, 0, 1);
|
||||
assert(includeResult.affectedDependencies[0].sourceValue[1] === 't2', `Table t2 should be the affected dependency. Actual: ${includeResult.affectedDependencies[0].sourceValue[1]}`);
|
||||
assert(includeResult.affectedDependencies[0].included === true, 'Table t2 should be included as a result of including v1. Actual: false');
|
||||
|
||||
@@ -307,62 +280,62 @@ class SchemaCompareTester {
|
||||
deploymentOptions.excludeObjectTypes.push(mssql.SchemaObjectType.Views);
|
||||
await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, deploymentOptions);
|
||||
const excludeResult3 = await schemaCompareService.schemaCompareIncludeExcludeNode(operationId, t2Difference, false, azdata.TaskExecutionMode.execute);
|
||||
this.assertIncludeExcludeResult(excludeResult3, true, 0, 0);
|
||||
assertIncludeExcludeResult(excludeResult3, true, 0, 0);
|
||||
});
|
||||
});
|
||||
|
||||
function assertIncludeExcludeResult(result: mssql.SchemaCompareIncludeExcludeResult, expectedSuccess: boolean, expectedBlockingDependenciesLength: number, expectedAffectedDependenciesLength: number): void {
|
||||
assert(result.success === expectedSuccess, `Operation success should have been ${expectedSuccess}. Actual: ${result.success}`);
|
||||
if (result.blockingDependencies) {
|
||||
assert(result.blockingDependencies.length === expectedBlockingDependenciesLength, `Expected ${expectedBlockingDependenciesLength} blocking dependencies. Actual: ${result.blockingDependencies}`);
|
||||
} else if (expectedBlockingDependenciesLength !== 0) {
|
||||
throw new Error(`ExpectedBlockingDependencies length was ${expectedBlockingDependenciesLength} but blockingDependencies was undefined`);
|
||||
}
|
||||
|
||||
private assertIncludeExcludeResult(result: mssql.SchemaCompareIncludeExcludeResult, expectedSuccess: boolean, expectedBlockingDependenciesLength: number, expectedAffectedDependenciesLength: number): void {
|
||||
assert(result.success === expectedSuccess, `Operation success should have been ${expectedSuccess}. Actual: ${result.success}`);
|
||||
if (result.blockingDependencies) {
|
||||
assert(result.blockingDependencies.length === expectedBlockingDependenciesLength, `Expected ${expectedBlockingDependenciesLength} blocking dependencies. Actual: ${result.blockingDependencies}`);
|
||||
} else if (expectedBlockingDependenciesLength !== 0) {
|
||||
throw new Error(`ExpectedBlockingDependencies length was ${expectedBlockingDependenciesLength} but blockingDependencies was undefined`);
|
||||
}
|
||||
if (result.affectedDependencies) {
|
||||
assert(result.affectedDependencies.length === expectedAffectedDependenciesLength, `Expected ${expectedAffectedDependenciesLength} affected dependencies. Actual: ${result.affectedDependencies}`);
|
||||
} else if (expectedAffectedDependenciesLength !== 0) {
|
||||
throw new Error(`ExpectedAffectedDependencies length was ${expectedAffectedDependenciesLength} but affectedDependencies was undefined`);
|
||||
}
|
||||
}
|
||||
|
||||
private assertSchemaCompareResult(schemaCompareResult: mssql.SchemaCompareResult, operationId: string, expectedDifferenceCount: number): void {
|
||||
assert(schemaCompareResult.areEqual === false, `Expected: the schemas are not to be equal Actual: Equal`);
|
||||
assert(schemaCompareResult.errorMessage === null, `Expected: there should be no error. Actual Error message: "${schemaCompareResult.errorMessage}"`);
|
||||
assert(schemaCompareResult.success === true, `Expected: success in schema compare, Actual: Failure`);
|
||||
assert(schemaCompareResult.differences.length === expectedDifferenceCount, `Expected: ${expectedDifferenceCount} differences. Actual differences: "${schemaCompareResult.differences.length}"`);
|
||||
assert(schemaCompareResult.operationId === operationId, `Operation Id Expected to be same as passed. Expected : ${operationId}, Actual ${schemaCompareResult.operationId}`);
|
||||
}
|
||||
|
||||
private async assertScriptGenerationResult(resultstatus: azdata.ResultStatus, server: string, database: string): Promise<void> {
|
||||
// TODO add more validation
|
||||
assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`);
|
||||
const taskService = azdata.dataprotocol.getProvider<azdata.TaskServicesProvider>('MSSQL', azdata.DataProviderType.TaskServicesProvider);
|
||||
const tasks = await taskService.getAllTasks({ listActiveTasksOnly: true });
|
||||
let foundTask: azdata.TaskInfo;
|
||||
tasks.tasks.forEach(t => {
|
||||
if (t.serverName === server && t.databaseName === database && t.taskExecutionMode === azdata.TaskExecutionMode.script) {
|
||||
foundTask = t;
|
||||
}
|
||||
});
|
||||
assert(foundTask, 'Could not find Script task');
|
||||
assert(foundTask.isCancelable, 'The task should be cancellable');
|
||||
|
||||
if (foundTask.status !== azdata.TaskStatus.Succeeded) {
|
||||
// wait for all tasks completion before exiting test and cleaning up db otherwise tasks fail
|
||||
let retry = 10;
|
||||
let allCompleted = false;
|
||||
while (retry > 0 && !allCompleted) {
|
||||
retry--;
|
||||
await utils.sleep(1000);
|
||||
allCompleted = true;
|
||||
let tasks = await taskService.getAllTasks({ listActiveTasksOnly: true });
|
||||
tasks.tasks.forEach(t => {
|
||||
if (t.status !== azdata.TaskStatus.Succeeded) {
|
||||
allCompleted = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// TODO: add proper validation for task completion to ensure all tasks successfully complete before exiting test
|
||||
assert(tasks !== null && tasks.tasks.length > 0, 'Tasks should still show in list. This is to ensure that the tasks actually complete.');
|
||||
}
|
||||
if (result.affectedDependencies) {
|
||||
assert(result.affectedDependencies.length === expectedAffectedDependenciesLength, `Expected ${expectedAffectedDependenciesLength} affected dependencies. Actual: ${result.affectedDependencies}`);
|
||||
} else if (expectedAffectedDependenciesLength !== 0) {
|
||||
throw new Error(`ExpectedAffectedDependencies length was ${expectedAffectedDependenciesLength} but affectedDependencies was undefined`);
|
||||
}
|
||||
}
|
||||
|
||||
function assertSchemaCompareResult(schemaCompareResult: mssql.SchemaCompareResult, operationId: string, expectedDifferenceCount: number): void {
|
||||
assert(schemaCompareResult.areEqual === false, `Expected: the schemas are not to be equal Actual: Equal`);
|
||||
assert(schemaCompareResult.errorMessage === null, `Expected: there should be no error. Actual Error message: "${schemaCompareResult.errorMessage}"`);
|
||||
assert(schemaCompareResult.success === true, `Expected: success in schema compare, Actual: Failure`);
|
||||
assert(schemaCompareResult.differences.length === expectedDifferenceCount, `Expected: ${expectedDifferenceCount} differences. Actual differences: "${schemaCompareResult.differences.length}"`);
|
||||
assert(schemaCompareResult.operationId === operationId, `Operation Id Expected to be same as passed. Expected : ${operationId}, Actual ${schemaCompareResult.operationId}`);
|
||||
}
|
||||
|
||||
async function assertScriptGenerationResult(resultstatus: azdata.ResultStatus, server: string, database: string): Promise<void> {
|
||||
// TODO add more validation
|
||||
assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`);
|
||||
const taskService = azdata.dataprotocol.getProvider<azdata.TaskServicesProvider>('MSSQL', azdata.DataProviderType.TaskServicesProvider);
|
||||
const tasks = await taskService.getAllTasks({ listActiveTasksOnly: true });
|
||||
let foundTask: azdata.TaskInfo;
|
||||
tasks.tasks.forEach(t => {
|
||||
if (t.serverName === server && t.databaseName === database && t.taskExecutionMode === azdata.TaskExecutionMode.script) {
|
||||
foundTask = t;
|
||||
}
|
||||
});
|
||||
assert(foundTask, 'Could not find Script task');
|
||||
assert(foundTask.isCancelable, 'The task should be cancellable');
|
||||
|
||||
if (foundTask.status !== azdata.TaskStatus.Succeeded) {
|
||||
// wait for all tasks completion before exiting test and cleaning up db otherwise tasks fail
|
||||
let retry = 10;
|
||||
let allCompleted = false;
|
||||
while (retry > 0 && !allCompleted) {
|
||||
retry--;
|
||||
await utils.sleep(1000);
|
||||
allCompleted = true;
|
||||
let tasks = await taskService.getAllTasks({ listActiveTasksOnly: true });
|
||||
tasks.tasks.forEach(t => {
|
||||
if (t.status !== azdata.TaskStatus.Succeeded) {
|
||||
allCompleted = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// TODO: add proper validation for task completion to ensure all tasks successfully complete before exiting test
|
||||
assert(tasks !== null && tasks.tasks.length > 0, 'Tasks should still show in list. This is to ensure that the tasks actually complete.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,16 +32,6 @@ adal-node@^0.1.28:
|
||||
xmldom ">= 0.1.x"
|
||||
xpath.js "~1.1.0"
|
||||
|
||||
"adstest@github:ranasaria/adstest.git#0.0.2":
|
||||
version "0.0.2"
|
||||
resolved "https://codeload.github.com/ranasaria/adstest/tar.gz/6e85375ac776bd0bbc06b938a2b528cc1ad123ee"
|
||||
dependencies:
|
||||
class-validator "^0.9.1"
|
||||
debug "^4.1.1"
|
||||
supports-color "^6.1.0"
|
||||
ts-node "^8.1.0"
|
||||
typescript "^3.4.5"
|
||||
|
||||
ajv@^6.5.5:
|
||||
version "6.10.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
|
||||
@@ -93,11 +83,6 @@ ansi-wrap@0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf"
|
||||
integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768=
|
||||
|
||||
arg@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0"
|
||||
integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==
|
||||
|
||||
arr-diff@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a"
|
||||
@@ -263,11 +248,6 @@ buffer-equal-constant-time@1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
|
||||
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
@@ -298,14 +278,6 @@ charenc@~0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
||||
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
|
||||
|
||||
class-validator@^0.9.1:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.9.1.tgz#d60e58c5d14abca0a41bce38cf792ad4c46d1531"
|
||||
integrity sha512-3wApflrd3ywVZyx4jaasGoFt8pmo4aGLPPAEKCKCsTRWVGPilahD88q3jQjRQwja50rl9a7rsP5LAxJYwGK8/Q==
|
||||
dependencies:
|
||||
google-libphonenumber "^3.1.6"
|
||||
validator "10.4.0"
|
||||
|
||||
clone-buffer@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58"
|
||||
@@ -419,13 +391,6 @@ debug@^3.1.0:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
deep-assign@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/deep-assign/-/deep-assign-1.0.0.tgz#b092743be8427dc621ea0067cdec7e70dd19f37b"
|
||||
@@ -450,11 +415,6 @@ diff@3.2.0:
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
|
||||
integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k=
|
||||
|
||||
diff@^3.1.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
||||
|
||||
duplexer2@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db"
|
||||
@@ -759,11 +719,6 @@ glogg@^1.0.0:
|
||||
dependencies:
|
||||
sparkles "^1.0.0"
|
||||
|
||||
google-libphonenumber@^3.1.6:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-3.2.2.tgz#3d9d7ba727e99a50812f21b0ed313723b76c5c54"
|
||||
integrity sha512-ubjGeosYPeusjYbUHy76lCniGTTI0k1rIFc+uKBX+jHQLDmWOSUtlFUxaeoLJ+Y+PAMM6dWp+C1HjHx5BI8kEw==
|
||||
|
||||
graceful-fs@^4.0.0, graceful-fs@^4.1.2:
|
||||
version "4.1.15"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||
@@ -917,11 +872,6 @@ has-flag@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
|
||||
integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
has-gulplog@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce"
|
||||
@@ -1295,11 +1245,6 @@ lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.11:
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
||||
make-error@^1.1.1:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8"
|
||||
integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==
|
||||
|
||||
map-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8"
|
||||
@@ -1471,11 +1416,6 @@ ms@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
||||
|
||||
multimatch@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b"
|
||||
@@ -1775,24 +1715,11 @@ source-map-support@^0.4.11:
|
||||
dependencies:
|
||||
source-map "^0.5.6"
|
||||
|
||||
source-map-support@^0.5.6:
|
||||
version "0.5.12"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599"
|
||||
integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.5.6:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
sparkles@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c"
|
||||
@@ -1917,13 +1844,6 @@ supports-color@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
|
||||
|
||||
supports-color@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
|
||||
integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
tar@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
|
||||
@@ -1990,17 +1910,6 @@ tough-cookie@~2.4.3:
|
||||
psl "^1.1.24"
|
||||
punycode "^1.4.1"
|
||||
|
||||
ts-node@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.1.0.tgz#8c4b37036abd448577db22a061fd7a67d47e658e"
|
||||
integrity sha512-34jpuOrxDuf+O6iW1JpgTRDFynUZ1iEqtYruBqh35gICNjN8x+LpVcPAcwzLPi9VU6mdA3ym+x233nZmZp445A==
|
||||
dependencies:
|
||||
arg "^4.1.0"
|
||||
diff "^3.1.0"
|
||||
make-error "^1.1.1"
|
||||
source-map-support "^0.5.6"
|
||||
yn "^3.0.0"
|
||||
|
||||
tunnel-agent@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
||||
@@ -2028,11 +1937,6 @@ type-detect@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
|
||||
integrity sha1-diIXzAbbJY7EiQihKY6LlRIejqI=
|
||||
|
||||
typescript@^3.4.5:
|
||||
version "3.4.5"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.5.tgz#2d2618d10bb566572b8d7aad5180d84257d70a99"
|
||||
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
|
||||
|
||||
"underscore@>= 1.3.1":
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
|
||||
@@ -2081,11 +1985,6 @@ vali-date@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6"
|
||||
integrity sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=
|
||||
|
||||
validator@10.4.0:
|
||||
version "10.4.0"
|
||||
resolved "https://registry.yarnpkg.com/validator/-/validator-10.4.0.tgz#ee99a44afb3bb5ed350a159f056ca72a204cfc3c"
|
||||
integrity sha512-Q/wBy3LB1uOyssgNlXSRmaf22NxjvDNZM2MtIQ4jaEOAB61xsh1TQxsq1CgzUMBV1lDrVMogIh8GjG1DYW0zLg==
|
||||
|
||||
verror@1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
||||
@@ -2224,8 +2123,3 @@ yazl@^2.2.1:
|
||||
integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==
|
||||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
|
||||
yn@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.0.tgz#fcbe2db63610361afcc5eb9e0ac91e976d046114"
|
||||
integrity sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==
|
||||
|
||||
Reference in New Issue
Block a user