diff --git a/extensions/integration-tests/package.json b/extensions/integration-tests/package.json index 5d989f3d78..e386f908fa 100644 --- a/extensions/integration-tests/package.json +++ b/extensions/integration-tests/package.json @@ -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", diff --git a/extensions/integration-tests/src/tests/index.ts b/extensions/integration-tests/src/tests/index.ts index 3295278159..047811dde9 100644 --- a/extensions/integration-tests/src/tests/index.ts +++ b/extensions/integration-tests/src/tests/index.ts @@ -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; diff --git a/extensions/integration-tests/src/tests/notebook.test.ts b/extensions/integration-tests/src/tests/notebook.test.ts index 8a850893dc..c5fd6cad08 100644 --- a/extensions/integration-tests/src/tests/notebook.test.ts +++ b/extensions/integration-tests/src/tests/notebook.test.ts @@ -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 { - let notebook = await this.openNotebook(pySparkNotebookContent, pySparkKernelMetadata, title + this.invocationCount++); - await this.runCell(notebook); - let cellOutputs = notebook.document.cells[0].contents.outputs; - let sparkResult = (cellOutputs[3]).text; - assert(sparkResult === '2', `Expected spark result: 2, Actual: ${sparkResult}`); - } - - @stressify({ dop: NotebookTester.ParallelCount }) - async python3ClearAllOutputs(title: string): Promise { - 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 { - 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 = (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 = (cellOutputs[0]).data['text/html']; + console.log('Got first output'); + assert(actualOutput0 === expectedOutput0, `Expected row count: ${expectedOutput0}, Actual: ${actualOutput0}`); + let actualOutput2 = (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 { - let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title + this.invocationCount++); - await this.runCell(notebook); - await this.verifyClearAllOutputs(notebook); - } - - async sqlNbClearOutputs(title: string): Promise { - 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 { - 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 { - 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 { - 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 = (cellOutputs[0]).data['text/html']; - console.log('Got first output'); - assert(actualOutput0 === expectedOutput0, `Expected row count: ${expectedOutput0}, Actual: ${actualOutput0}`); - let actualOutput2 = (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 { - 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 { + // 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 = (cellOutputs[0]).data['text/plain']; + assert(result === '2', `Expected python result: 2, Actual: ${result}`); + }); - async pythonChangeKernelDifferentProviderTest(title: string): Promise { - 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 { - 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 { + 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 = (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 { - 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 { + 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 { - 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 { - 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 { + 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 { - 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 { - 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 { - 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 { - 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 { + 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 { + 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}`); } diff --git a/extensions/integration-tests/src/tests/objectExplorer.test.ts b/extensions/integration-tests/src/tests/objectExplorer.test.ts index 6d4a549651..89c988daed 100644 --- a/extensions/integration-tests/src/tests/objectExplorer.test.ts +++ b/extensions/integration-tests/src/tests/objectExplorer.test.ts @@ -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 { const expectedNodeLabel = ['Databases', 'Security', 'Server Objects']; const server = await getBdcServer(); - return await this.verifyOeNode(server, DefaultConnectTimeoutInMs, expectedNodeLabel); - } - - @stressify({ dop: ObjectExplorerTester.ParallelCount }) - async standaloneNodeLabelTest(): Promise { + 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 { + }); + 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 { - 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 { - 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 { + 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 { + await connectToServer(server, DefaultConnectTimeoutInMs); + const nodes = 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 { + await connectToServer(server, timeout); + const nodes = 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 { - await connectToServer(server, DefaultConnectTimeoutInMs); - const nodes = 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 { - const node = nodes[index]; - const actions = await azdata.objectexplorer.getNodeActions(node.connectionId, node.nodePath); + await connectToServer(server, timeoutinMS); + + const nodes = 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 { - await connectToServer(server, timeout); - const nodes = 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 { - - await connectToServer(server, timeoutinMS); - - const nodes = 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); } } + diff --git a/extensions/integration-tests/src/tests/schemaCompare.test.ts b/extensions/integration-tests/src/tests/schemaCompare.test.ts index 95d983df57..7ab6290e22 100644 --- a/extensions/integration-tests/src/tests/schemaCompare.test.ts +++ b/extensions/integration-tests/src/tests/schemaCompare.test.ts @@ -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 { 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 { + }); + 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 { + }); + 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 { + }); + 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 { - // TODO add more validation - assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`); - const taskService = azdata.dataprotocol.getProvider('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 { + // TODO add more validation + assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`); + const taskService = azdata.dataprotocol.getProvider('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.'); } } diff --git a/extensions/integration-tests/yarn.lock b/extensions/integration-tests/yarn.lock index 8fa9bba0c7..46d809bf88 100644 --- a/extensions/integration-tests/yarn.lock +++ b/extensions/integration-tests/yarn.lock @@ -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==