First version of Stress (#5499)

* First version of Stress - moving over from feat/Stress1 branch

* a working version - still issues with stresssified notebook tests

* update notebooks to use new message event (#5395)

* Latest changes for notebook tests

* Stressify objectExplorer tests

* formatting changes

* removing the tracing added previously and ability to set tsc verbose option in tsconfig.json

* addressing review feedback

* addressing review feedback

* implementing runtime parameter for Stress

* addresing review feedback and moved out stress modules to its own project outside of azuredata source tree

* referencing adstest from the github location

* incorporating review feedback

* Review feedbak

* removing uncommong entries added to .gitignore

* removing unrelated change

* replacing debug/trace statements with console.info or cosole.warn statments in integration-tests\main.tx
This commit is contained in:
Arvind Ranasaria
2019-05-29 11:18:20 -07:00
committed by GitHub
parent 9a55ca3021
commit 9cae7a0a49
11 changed files with 686 additions and 683 deletions

2
.gitignore vendored
View File

@@ -18,7 +18,7 @@ out-vscode-min/
out-vscode-reh/ out-vscode-reh/
out-vscode-reh-min/ out-vscode-reh-min/
out-vscode-reh-pkg/ out-vscode-reh-pkg/
build/node_modules **/node_modules
coverage/ coverage/
test_data/ test_data/
test-results/ test-results/

View File

@@ -49,12 +49,13 @@
"postinstall": "node ./node_modules/vscode/bin/install" "postinstall": "node ./node_modules/vscode/bin/install"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "7.0.43",
"@types/chai": "3.4.34", "@types/chai": "3.4.34",
"@types/node": "7.0.43",
"adstest": "github:ranasaria/adstest.git#0.0.2",
"chai": "3.5.0",
"mocha-junit-reporter": "^1.17.0", "mocha-junit-reporter": "^1.17.0",
"mocha-multi-reporters": "^1.1.7", "mocha-multi-reporters": "^1.1.7",
"vscode": "1.1.5", "vscode": "1.1.5"
"chai": "3.5.0"
}, },
"dependencies": { "dependencies": {
"azure-keyvault": "^3.0.4", "azure-keyvault": "^3.0.4",

View File

@@ -151,13 +151,13 @@ msrestAzure.interactiveLogin().then((credentials) => {
console.log('Done reading values from Azure KeyVault!'); console.log('Done reading values from Azure KeyVault!');
console.log(`Launching new window: ${LAUNCH_OPTION}...`); console.log(`Launching new window: ${LAUNCH_OPTION}...`);
if (LAUNCH_OPTION === LAUNCH_VSCODE) { if (LAUNCH_OPTION === LAUNCH_VSCODE) {
console.warn('Trying to lauch vscode, make sure you have it set properly in the PATH environment variable'); console.warn('Trying to launch vscode, make sure you have it set properly in the PATH environment variable');
} }
child_process.execSync(LAUNCH_OPTION); child_process.execSync(LAUNCH_OPTION);
console.log('New window for running test has been opened.'); console.log('New window for running test has been opened.');
} }
); );
}, (err) => { }, (err) => {
console.error('An error occured while loggin in to Azure portal'); console.error('An error occured while logging in to Azure portal');
console.error(err); console.error(err);
}); });

View File

@@ -4,24 +4,30 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { context } from './testContext'; import { context } from './testContext';
import { getSuiteType, SuiteType } from 'adstest';
const path = require('path'); const path = require('path');
const testRunner = require('vscode/lib/testrunner'); const testRunner = require('vscode/lib/testrunner');
const suite = 'Integration Tests'; const suite = getSuiteType();
const options: any = { const options: any = {
ui: 'tdd', ui: 'tdd',
useColors: true, useColors: true,
timeout: 600000 timeout: 600000 // 600 seconds
}; };
if (suite === SuiteType.Stress) {
options.timeout = 7200000; // 2 hours
}
if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) { if (process.env.BUILD_ARTIFACTSTAGINGDIRECTORY) {
console.log(`environment variable BUILD_ARTIFACTSTAGINGDIRECTORY is set to ${process.env.BUILD_ARTIFACTSTAGINGDIRECTORY} so configuring multiple reporters for test results.\n For this to work the ${process.env.BUILD_ARTIFACTSTAGINGDIRECTORY} must be fully qualified directory and must exist`);
options.reporter = 'mocha-multi-reporters'; options.reporter = 'mocha-multi-reporters';
options.reporterOptions = { options.reporterOptions = {
reporterEnabled: 'spec, mocha-junit-reporter', reporterEnabled: 'spec, mocha-junit-reporter',
mochaJunitReporterReporterOptions: { mochaJunitReporterReporterOptions: {
testsuitesTitle: `${suite} ${process.platform}`, testsuitesTitle: `${suite} Tests ${process.platform}`,
mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`) mochaFile: path.join(process.env.BUILD_ARTIFACTSTAGINGDIRECTORY, `test-results/${process.platform}-${suite.toLowerCase().replace(/[^\w]/g, '-')}-results.xml`)
} }
}; };

View File

@@ -18,10 +18,12 @@ export function activate(context: vscode.ExtensionContext) {
let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); let statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
vscode.commands.registerCommand('test.setupIntegrationTest', async () => { vscode.commands.registerCommand('test.setupIntegrationTest', async () => {
let extensionInstallersFolder = normalize(join(__dirname, '../extensionInstallers')); let extensionInstallersFolder = normalize(join(__dirname, '../extensionInstallers'));
console.info(`extensionInstallersFolder=${extensionInstallersFolder}`);
let installers = fs.readdirSync(extensionInstallersFolder); let installers = fs.readdirSync(extensionInstallersFolder);
for (let i = 0; i < installers.length; i++) { for (let i = 0; i < installers.length; i++) {
if (installers[i].endsWith('.vsix')) { if (installers[i].endsWith('.vsix')) {
let installerFullPath = join(extensionInstallersFolder, installers[i]); let installerFullPath = join(extensionInstallersFolder, installers[i]);
console.info(`installing extension at ${installerFullPath}`);
await azdata.extensions.install(installerFullPath); await azdata.extensions.install(installerFullPath);
} }
} }
@@ -35,20 +37,24 @@ export function activate(context: vscode.ExtensionContext) {
let expectedExtensions = ['Microsoft.agent', 'Microsoft.import', 'Microsoft.mssql', 'Microsoft.profiler']; let expectedExtensions = ['Microsoft.agent', 'Microsoft.import', 'Microsoft.mssql', 'Microsoft.profiler'];
do { do {
let extensions = vscode.extensions.all.filter(ext => { return expectedExtensions.indexOf(ext.id) !== -1; }); let extensions = vscode.extensions.all.filter(ext => { return expectedExtensions.indexOf(ext.id) !== -1; });
console.info(`extensions to load ${JSON.stringify(extensions, undefined, '\t')}`);
let isReady = true; let isReady = true;
for (let i = 0; i < extensions.length; i++) { for (let i = 0; i < extensions.length; i++) {
let extension = extensions[i]; let extension = extensions[i];
console.info(`checking extension:${JSON.stringify(extension, undefined, '\t')} to be ready}`);
isReady = isReady && extension.isActive; isReady = isReady && extension.isActive;
if (!isReady) { if (!isReady) {
console.warn(`extension:${JSON.stringify(extension, undefined, '\t')} is not yet ready}`);
break; break;
} }
} }
if (isReady) { if (isReady) {
console.info('All extensions are ready');
showStatusBarItem(statusBarItem, ALL_EXTENSION_LOADED_TEXT); showStatusBarItem(statusBarItem, ALL_EXTENSION_LOADED_TEXT);
break; break;
} else { } else {
console.warn(`At least one extension is not ready, waiting one second before recheck.}`);
await new Promise(resolve => { setTimeout(resolve, 1000); }); await new Promise(resolve => { setTimeout(resolve, 1000); });
} }
} }

View File

@@ -14,48 +14,90 @@ import { sqlNotebookContent, writeNotebookToFile, sqlKernelMetadata, getFileName
import { getBdcServer, getConfigValue, EnvironmentVariable_PYTHON_PATH } from './testConfig'; import { getBdcServer, getConfigValue, EnvironmentVariable_PYTHON_PATH } from './testConfig';
import { connectToServer } from './utils'; import { connectToServer } from './utils';
import * as fs from 'fs'; import * as fs from 'fs';
import { stressify } from 'adstest';
if (context.RunTest) { if (context.RunTest) {
suite('Notebook integration test suite', function () { suite('Notebook integration test suite', function () {
setup(function () { setup(async function () {
console.log(`Start "${this.currentTest.title}"`); console.log(`Start "${this.currentTest.title}"`);
let server = await getBdcServer();
assert(server && server.serverName, 'No server could be found');
await connectToServer(server, 6000);
}); });
teardown(async function () { teardown(async function () {
let testName = this.currentTest.title; await (new NotebookTester()).cleanup(this.currentTest.title);
try {
let fileName = getFileName(testName);
if (fs.existsSync(fileName)) {
fs.unlinkSync(fileName);
console.log(`"${fileName}" is deleted.`);
}
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
}
catch (err) {
console.log(err);
}
finally {
console.log(`"${testName}" is done`);
}
}); });
test('Sql NB test', async function () { test('Sql NB test', async function () {
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title); await (new NotebookTester()).sqlNbTest(this.test.title);
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('Sql NB multiple cells test', async function () { test('Sql NB multiple cells test', async function () {
let notebook = await openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, this.test.title, true); await (new NotebookTester()).sqlNbMultipleCellsTest(this.test.title);
});
test('Clear all outputs - SQL notebook ', async function () {
await (new NotebookTester()).sqlNbClearAllOutputs(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);
});
}
if (process.env['RUN_PYSPARK_TEST'] === '1') {
test('PySpark3 notebook test', async function () {
await (new NotebookTester()).pySpark3NbTest(this.test.title);
});
}
});
}
class NotebookTester {
private static ParallelCount = 1;
invocationCount: number = 0;
@stressify({ dop: NotebookTester.ParallelCount })
async pySpark3NbTest(title: string): Promise<void> {
let notebook = await this.openNotebook(pySparkNotebookContent, pySpark3KernelMetadata, title + this.invocationCount++);
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.verifyClearAllOutputs(notebook);
}
@stressify({ dop: NotebookTester.ParallelCount })
async python3NbTest(title: string): Promise<void> {
let notebook = await this.openNotebook(pySparkNotebookContent, pythonKernelMetadata, title + this.invocationCount++);
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}`);
}
@stressify({ dop: NotebookTester.ParallelCount })
async sqlNbClearAllOutputs(title: string): Promise<void> {
let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title + this.invocationCount++);
await this.verifyClearAllOutputs(notebook);
}
@stressify({ dop: NotebookTester.ParallelCount })
async sqlNbMultipleCellsTest(title: string): Promise<void> {
let notebook = await this.openNotebook(sqlNotebookMultipleCellsContent, sqlKernelMetadata, title + this.invocationCount++, true);
const expectedOutput0 = '(1 row affected)'; const expectedOutput0 = '(1 row affected)';
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
let cellOutputs = notebook.document.cells[i].contents.outputs; let cellOutputs = notebook.document.cells[i].contents.outputs;
@@ -71,48 +113,50 @@ if (context.RunTest) {
assert(actualOutput2[0] === i.toString(), `Expected result: ${i.toString()}, Actual: '${actualOutput2[0]}'`); assert(actualOutput2[0] === i.toString(), `Expected result: ${i.toString()}, Actual: '${actualOutput2[0]}'`);
console.log('Sql multiple cells NB done'); console.log('Sql multiple cells NB done');
} }
}); }
test('Clear all outputs - SQL notebook ', async function () { @stressify({ dop: NotebookTester.ParallelCount })
let notebook = await openNotebook(sqlNotebookContent, sqlKernelMetadata, this.test.title); async sqlNbTest(title: string): Promise<void> {
await verifyClearAllOutputs(notebook); let notebook = await this.openNotebook(sqlNotebookContent, sqlKernelMetadata, title + this.invocationCount++, false, true);
}); const expectedOutput0 = '(1 row affected)';
if (process.env['RUN_PYTHON3_TEST'] === '1') {
test('Python3 notebook test', async function () {
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title);
let cellOutputs = notebook.document.cells[0].contents.outputs; let cellOutputs = notebook.document.cells[0].contents.outputs;
console.log('Got cell outputs ---'); console.log('Got cell outputs ---');
if (cellOutputs) { if (cellOutputs) {
cellOutputs.forEach(o => console.log(o)); cellOutputs.forEach(o => console.log(o));
} }
let result = (<azdata.nb.IExecuteResult>cellOutputs[0]).data['text/plain']; assert(cellOutputs.length === 3, `Expected length: 3, Actual: ${cellOutputs.length}`);
assert(result === '2', `Expected python result: 2, Actual: ${result}`); let actualOutput0 = (<azdata.nb.IDisplayData>cellOutputs[0]).data['text/html'];
}); console.log('Got first output');
assert(actualOutput0 === expectedOutput0, `Expected row count: ${expectedOutput0}, Actual: ${actualOutput0}`);
test('Clear all outputs - Python3 notebook ', async function () { let actualOutput2 = (<azdata.nb.IExecuteResult>cellOutputs[2]).data['application/vnd.dataresource+json'].data[0];
let notebook = await openNotebook(pySparkNotebookContent, pythonKernelMetadata, this.test.title); assert(actualOutput2[0] === '1', `Expected result: 1, Actual: '${actualOutput2[0]}'`);
await verifyClearAllOutputs(notebook);
});
} }
if (process.env['RUN_PYSPARK_TEST'] === '1') { async cleanup(testName: string): Promise<void> {
test('PySpark3 notebook test', async function () { try {
let notebook = await openNotebook(pySparkNotebookContent, pySpark3KernelMetadata, this.test.title); let fileName = getFileName(testName + this.invocationCount++);
let cellOutputs = notebook.document.cells[0].contents.outputs; if (fs.existsSync(fileName)) {
let sparkResult = (<azdata.nb.IStreamResult>cellOutputs[3]).text; fs.unlinkSync(fileName);
assert(sparkResult === '2', `Expected spark result: 2, Actual: ${sparkResult}`); console.log(`"${fileName}" is deleted.`);
}); }
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
}
catch (err) {
console.log(err);
}
finally {
console.log(`"${testName}" is done`);
}
} }
});
}
async function openNotebook(content: azdata.nb.INotebookContents, kernelMetadata: any, testName: string, runAllCells?: boolean): Promise<azdata.nb.NotebookEditor> { async openNotebook(content: azdata.nb.INotebookContents, kernelMetadata: any, testName: string, runAllCells?: boolean, connectToDifferentServer?: boolean): Promise<azdata.nb.NotebookEditor> {
let notebookConfig = vscode.workspace.getConfiguration('notebook'); let notebookConfig = vscode.workspace.getConfiguration('notebook');
notebookConfig.update('pythonPath', getConfigValue(EnvironmentVariable_PYTHON_PATH), 1); notebookConfig.update('pythonPath', getConfigValue(EnvironmentVariable_PYTHON_PATH), 1);
if (!connectToDifferentServer) {
let server = await getBdcServer(); let server = await getBdcServer();
assert(server && server.serverName, 'No server could be found in openNotebook'); assert(server && server.serverName, 'No server could be found in openNotebook');
await connectToServer(server, 6000); await connectToServer(server, 6000);
}
let notebookJson = Object.assign({}, content, { metadata: kernelMetadata }); let notebookJson = Object.assign({}, content, { metadata: kernelMetadata });
let uri = writeNotebookToFile(notebookJson, testName); let uri = writeNotebookToFile(notebookJson, testName);
console.log(uri); console.log(uri);
@@ -133,8 +177,8 @@ async function openNotebook(content: azdata.nb.INotebookContents, kernelMetadata
} }
return notebook; return notebook;
} }
async function verifyClearAllOutputs(notebook: azdata.nb.NotebookEditor) { 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); 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'); assert(cellWithOutputs !== undefined, 'Could not find notebook cells with outputs');
console.log('Before clearing cell outputs'); console.log('Before clearing cell outputs');
@@ -145,5 +189,6 @@ async function verifyClearAllOutputs(notebook: azdata.nb.NotebookEditor) {
}); });
assert(clearedOutputs, 'Outputs of all the code cells from Python notebook should be cleared'); assert(clearedOutputs, 'Outputs of all the code cells from Python notebook should be cleared');
console.log('After clearing cell outputs'); console.log('After clearing cell outputs');
}
} }

View File

@@ -11,66 +11,76 @@ import { context } from './testContext';
import { getBdcServer, TestServerProfile, getAzureServer, getStandaloneServer } from './testConfig'; import { getBdcServer, TestServerProfile, getAzureServer, getStandaloneServer } from './testConfig';
import { connectToServer, createDB, deleteDB } from './utils'; import { connectToServer, createDB, deleteDB } from './utils';
import assert = require('assert'); import assert = require('assert');
import { stressify } from 'adstest';
if (context.RunTest) { if (context.RunTest) {
suite('Object Explorer integration suite', () => { suite('Object Explorer integration suite', () => {
test('BDC instance node label test', async function () { test('BDC instance node label test', async function () {
const expectedNodeLabel = ['Databases', 'Security', 'Server Objects', 'Data Services']; await (new ObjectExplorerTester()).bdcNodeLabelTest();
let server = await getBdcServer();
await VerifyOeNode(server, 6000, expectedNodeLabel);
}); });
test('Standard alone instance node label test', async function () { test('Standard alone instance node label test', async function () {
await (new ObjectExplorerTester()).standaloneNodeLabelTest();
});
test('Azure SQL DB instance node label test', async function () {
await (new ObjectExplorerTester()).sqlDbNodeLabelTest();
});
test('Standard SQL DB context menu test', async function () {
await (new ObjectExplorerTester()).sqlDbContextMenuTest();
});
test('BDC instance context menu test', async function () {
await (new ObjectExplorerTester()).bdcContextMenuTest();
});
test('Azure SQL DB context menu test', async function () {
await (new ObjectExplorerTester()).sqlDbContextMenuTest();
});
test('Stand alone database context menu test', async function () {
await (new ObjectExplorerTester()).standAloneContextMenuTest();
});
});
}
class ObjectExplorerTester {
private static ParallelCount = 1;
@stressify({ dop: ObjectExplorerTester.ParallelCount })
async bdcNodeLabelTest(): Promise<void> {
const expectedNodeLabel = ['Databases', 'Security', 'Server Objects', 'Data Services'];
let server = await getBdcServer();
await this.verifyOeNode(server, 6000, expectedNodeLabel);
}
@stressify({ dop: ObjectExplorerTester.ParallelCount })
async standaloneNodeLabelTest(): Promise<void> {
if (process.platform === 'win32') { if (process.platform === 'win32') {
const expectedNodeLabel = ['Databases', 'Security', 'Server Objects']; const expectedNodeLabel = ['Databases', 'Security', 'Server Objects'];
let server = await getStandaloneServer(); let server = await getStandaloneServer();
await VerifyOeNode(server, 3000, expectedNodeLabel); await this.verifyOeNode(server, 3000, expectedNodeLabel);
} }
}); }
test('Azure SQL DB instance node label test', async function () {
@stressify({ dop: ObjectExplorerTester.ParallelCount })
async sqlDbNodeLabelTest(): Promise<void> {
const expectedNodeLabel = ['Databases', 'Security']; const expectedNodeLabel = ['Databases', 'Security'];
let server = await getAzureServer(); let server = await getAzureServer();
await VerifyOeNode(server, 3000, expectedNodeLabel); await this.verifyOeNode(server, 3000, expectedNodeLabel);
}); }
test('Standard SQL DB context menu test', async function () { @stressify({ dop: ObjectExplorerTester.ParallelCount })
async sqlDbContextMenuTest(): Promise<void> {
let server = await getStandaloneServer(); let server = await getStandaloneServer();
let expectedActions: string[]; 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 // 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
if (process.platform === 'win32') { if (process.platform === 'win32') {
expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler', 'Properties']; expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler', 'Properties'];
} else { }
else {
expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler']; expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler'];
} }
await this.verifyContextMenu(server, expectedActions);
await verifyContextMenu(server, expectedActions);
});
test('BDC instance context menu test', async function () {
let 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
if (process.platform === 'win32') {
expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler', 'Properties'];
} else {
expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler'];
} }
await verifyContextMenu(server, expectedActions); @stressify({ dop: ObjectExplorerTester.ParallelCount })
}); async standAloneContextMenuTest(): Promise<void> {
test('Azure SQL DB context menu test', async function () {
const server = await getAzureServer();
// Azure DB doesn't have Properties node on server level
const expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler'];
await verifyContextMenu(server, expectedActions);
});
test('Stand alone database context menu test', async function () {
let server = await getStandaloneServer(); let server = await getStandaloneServer();
let expectedActions: string[] = []; let expectedActions: string[] = [];
if (process.platform === 'win32') { if (process.platform === 'win32') {
@@ -79,12 +89,24 @@ if (context.RunTest) {
else { else {
expectedActions = ['Manage', 'New Query', 'Backup', 'Restore', 'Refresh', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard']; expectedActions = ['Manage', 'New Query', 'Backup', 'Restore', 'Refresh', 'Data-tier Application wizard', 'Schema Compare', 'Import wizard'];
} }
await VerifyDBContextMenu(server, 3000, expectedActions); await this.verifyDBContextMenu(server, 3000, expectedActions);
}); }
});
}
async function verifyContextMenu(server: TestServerProfile, expectedActions: string[]): Promise<void> { @stressify({ dop: ObjectExplorerTester.ParallelCount })
async bdcContextMenuTest(): Promise<void> {
let 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
if (process.platform === 'win32') {
expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler', 'Properties'];
}
else {
expectedActions = ['Manage', 'New Query', 'Disconnect', 'Delete Connection', 'Refresh', 'New Notebook', 'Data-tier Application wizard', 'Launch Profiler'];
}
await this.verifyContextMenu(server, expectedActions);
}
async verifyContextMenu(server: TestServerProfile, expectedActions: string[]): Promise<void> {
await connectToServer(server, 3000); await connectToServer(server, 3000);
let nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes(); let nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`); assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
@@ -98,9 +120,9 @@ async function verifyContextMenu(server: TestServerProfile, expectedActions: str
let expectedString = expectedActions.join(','); let expectedString = expectedActions.join(',');
const actualString = actions.join(','); const actualString = actions.join(',');
assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`); assert(expectedActions.length === actions.length && expectedString === actualString, `Expected actions: "${expectedString}", Actual actions: "${actualString}"`);
} }
async function VerifyOeNode(server: TestServerProfile, timeout: number, expectedNodeLabel: string[]): Promise<void> { async verifyOeNode(server: TestServerProfile, timeout: number, expectedNodeLabel: string[]): Promise<void> {
await connectToServer(server, timeout); await connectToServer(server, timeout);
let nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes(); let nodes = <azdata.objectexplorer.ObjectExplorerNode[]>await azdata.objectexplorer.getActiveConnectionNodes();
assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`); assert(nodes.length > 0, `Expecting at least one active connection, actual: ${nodes.length}`);
@@ -113,9 +135,9 @@ async function VerifyOeNode(server: TestServerProfile, timeout: number, expected
children.forEach(c => actualNodeLabel.push(c.label)); children.forEach(c => actualNodeLabel.push(c.label));
assert(expectedNodeLabel.toLocaleString() === actualNodeLabel.toLocaleString(), `Expected node label: "${expectedNodeLabel}", Actual: "${actualNodeLabel}"`); assert(expectedNodeLabel.toLocaleString() === actualNodeLabel.toLocaleString(), `Expected node label: "${expectedNodeLabel}", Actual: "${actualNodeLabel}"`);
} }
async function VerifyDBContextMenu(server: TestServerProfile, timeoutinMS: number, expectedActions: string[]) { async verifyDBContextMenu(server: TestServerProfile, timeoutinMS: number, expectedActions: string[]): Promise<void> {
await connectToServer(server, timeoutinMS); await connectToServer(server, timeoutinMS);
@@ -148,4 +170,5 @@ async function VerifyDBContextMenu(server: TestServerProfile, timeoutinMS: numbe
finally { finally {
await deleteDB(dbName, ownerUri); await deleteDB(dbName, ownerUri);
} }
}
} }

View File

@@ -1,5 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs", "module": "commonjs",
"target": "ES5", "target": "ES5",
"outDir": "out", "outDir": "out",

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@ pushd %~dp0\..
set VSCODEUSERDATADIR=%TMP%\adsuser-%RANDOM%-%TIME:~6,5% set VSCODEUSERDATADIR=%TMP%\adsuser-%RANDOM%-%TIME:~6,5%
set VSCODEEXTENSIONSDIR=%TMP%\adsext-%RANDOM%-%TIME:~6,5% set VSCODEEXTENSIONSDIR=%TMP%\adsext-%RANDOM%-%TIME:~6,5%
echo %VSCODEUSERDATADIR% echo VSCODEUSERDATADIR=%VSCODEUSERDATADIR%
echo %VSCODEEXTENSIONSDIR% echo VSCODEEXTENSIONSDIR=%VSCODEEXTENSIONSDIR%
@echo OFF @echo OFF
if "%SKIP_PYTHON_INSTALL_TEST%" == "1" ( if "%SKIP_PYTHON_INSTALL_TEST%" == "1" (

View File

@@ -13,8 +13,8 @@ else
fi fi
cd $ROOT cd $ROOT
echo $VSCODEUSERDATADIR echo VSCODEUSERDATADIR=$VSCODEUSERDATADIR
echo $VSCODEEXTDIR echo VSCODEEXTDIR=$VSCODEEXTDIR
if [[ "$SKIP_PYTHON_INSTALL_TEST" == "1" ]]; then if [[ "$SKIP_PYTHON_INSTALL_TEST" == "1" ]]; then
echo Skipping Python installation tests. echo Skipping Python installation tests.