mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-08 01:28:26 -05:00
Add acquireLoginSession API for Azdata (#13985)
* wip * fix tests * add tests * PR comments
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as azdataExt from 'azdata-ext';
|
||||
import * as should from 'should';
|
||||
import * as sinon from 'sinon';
|
||||
import * as vscode from 'vscode';
|
||||
@@ -16,6 +17,7 @@ import * as fs from 'fs';
|
||||
import { AzdataReleaseInfo } from '../azdataReleaseInfo';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
import { eulaAccepted } from '../constants';
|
||||
import { sleep } from './testUtils';
|
||||
|
||||
const oldAzdataMock = new azdata.AzdataTool('/path/to/azdata', '0.0.0');
|
||||
const currentAzdataMock = new azdata.AzdataTool('/path/to/azdata', '9999.999.999');
|
||||
@@ -170,18 +172,6 @@ describe('azdata', function () {
|
||||
});
|
||||
});
|
||||
});
|
||||
it('login', async function (): Promise<void> {
|
||||
const endpoint = 'myEndpoint';
|
||||
const username = 'myUsername';
|
||||
const password = 'myPassword';
|
||||
await azdataTool.login(endpoint, username, password);
|
||||
verifyExecuteCommandCalledWithArgs(['login', endpoint, username]);
|
||||
});
|
||||
it('version', async function (): Promise<void> {
|
||||
executeCommandStub.resolves({ stdout: '1.0.0', stderr: '' });
|
||||
await azdataTool.version();
|
||||
verifyExecuteCommandCalledWithArgs(['--version']);
|
||||
});
|
||||
it('general error throws', async function (): Promise<void> {
|
||||
const err = new Error();
|
||||
executeCommandStub.throws(err);
|
||||
@@ -228,12 +218,136 @@ describe('azdata', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('login', async function (): Promise<void> {
|
||||
const endpoint = 'myEndpoint';
|
||||
const username = 'myUsername';
|
||||
const password = 'myPassword';
|
||||
await azdataTool.login(endpoint, username, password);
|
||||
verifyExecuteCommandCalledWithArgs(['login', endpoint, username]);
|
||||
});
|
||||
|
||||
describe('acquireSession', function (): void {
|
||||
it('calls login', async function (): Promise<void> {
|
||||
const endpoint = 'myEndpoint';
|
||||
const username = 'myUsername';
|
||||
const password = 'myPassword';
|
||||
const session = await azdataTool.acquireSession(endpoint, username, password);
|
||||
session.dispose();
|
||||
verifyExecuteCommandCalledWithArgs(['login', endpoint, username]);
|
||||
});
|
||||
|
||||
it('command executed under current session completes', async function (): Promise<void> {
|
||||
const session = await azdataTool.acquireSession('', '', '');
|
||||
try {
|
||||
await azdataTool.arc.dc.config.show(undefined, session);
|
||||
} finally {
|
||||
session.dispose();
|
||||
}
|
||||
verifyExecuteCommandCalledWithArgs(['login'], 0);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'dc', 'config', 'show'], 1);
|
||||
});
|
||||
it('multiple commands executed under current session completes', async function (): Promise<void> {
|
||||
const session = await azdataTool.acquireSession('', '', '');
|
||||
try {
|
||||
// Kick off multiple commands at the same time and then ensure that they both complete
|
||||
await Promise.all([
|
||||
azdataTool.arc.dc.config.show(undefined, session),
|
||||
azdataTool.arc.sql.mi.list(undefined, session)
|
||||
]);
|
||||
} finally {
|
||||
session.dispose();
|
||||
}
|
||||
verifyExecuteCommandCalledWithArgs(['login'], 0);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'dc', 'config', 'show'], 1);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'sql', 'mi', 'list'], 2);
|
||||
});
|
||||
it('command executed without session context is queued up until session is closed', async function (): Promise<void> {
|
||||
const session = await azdataTool.acquireSession('', '', '');
|
||||
let nonSessionCommand: Promise<any> | undefined = undefined;
|
||||
try {
|
||||
// Start one command in the current session
|
||||
await azdataTool.arc.dc.config.show(undefined, session);
|
||||
// Verify that the command isn't executed until after the session is disposed
|
||||
let isFulfilled = false;
|
||||
nonSessionCommand = azdataTool.arc.sql.mi.list().then(() => isFulfilled = true);
|
||||
await sleep(2000);
|
||||
should(isFulfilled).equal(false, 'The command should not be completed yet');
|
||||
} finally {
|
||||
session.dispose();
|
||||
}
|
||||
await nonSessionCommand;
|
||||
verifyExecuteCommandCalledWithArgs(['login'], 0);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'dc', 'config', 'show'], 1);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'sql', 'mi', 'list'], 2);
|
||||
});
|
||||
it('multiple commands executed without session context are queued up until session is closed', async function (): Promise<void> {
|
||||
const session = await azdataTool.acquireSession('', '', '');
|
||||
let nonSessionCommand1: Promise<any> | undefined = undefined;
|
||||
let nonSessionCommand2: Promise<any> | undefined = undefined;
|
||||
try {
|
||||
// Start one command in the current session
|
||||
await azdataTool.arc.dc.config.show(undefined, session);
|
||||
// Verify that neither command is completed until the session is closed
|
||||
let isFulfilled = false;
|
||||
nonSessionCommand1 = azdataTool.arc.sql.mi.list().then(() => isFulfilled = true);
|
||||
nonSessionCommand2 = azdataTool.arc.postgres.server.list().then(() => isFulfilled = true);
|
||||
await sleep(2000);
|
||||
should(isFulfilled).equal(false, 'The commands should not be completed yet');
|
||||
} finally {
|
||||
session.dispose();
|
||||
}
|
||||
await Promise.all([nonSessionCommand1, nonSessionCommand2]);
|
||||
verifyExecuteCommandCalledWithArgs(['login'], 0);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'dc', 'config', 'show'], 1);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'sql', 'mi', 'list'], 2);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'postgres', 'server', 'list'], 3);
|
||||
});
|
||||
it('attempting to acquire a second session while a first is still active queues the second session', async function (): Promise<void> {
|
||||
const firstSession = await azdataTool.acquireSession('', '', '');
|
||||
let sessionPromise: Promise<azdataExt.AzdataSession> | undefined = undefined;
|
||||
let secondSessionCommand: Promise<any> | undefined = undefined;
|
||||
try {
|
||||
try {
|
||||
// Start one command in the current session
|
||||
await azdataTool.arc.dc.config.show(undefined, firstSession);
|
||||
// Verify that none of the commands for the second session are completed before the first is disposed
|
||||
let isFulfilled = false;
|
||||
sessionPromise = azdataTool.acquireSession('', '', '');
|
||||
sessionPromise.then(session => {
|
||||
isFulfilled = true;
|
||||
secondSessionCommand = azdataTool.arc.sql.mi.list(undefined, session).then(() => isFulfilled = true);
|
||||
});
|
||||
await sleep(2000);
|
||||
should(isFulfilled).equal(false, 'The commands should not be completed yet');
|
||||
} finally {
|
||||
firstSession.dispose();
|
||||
}
|
||||
} finally {
|
||||
(await sessionPromise)?.dispose();
|
||||
}
|
||||
should(secondSessionCommand).not.equal(undefined, 'The second command should have been queued already');
|
||||
await secondSessionCommand!;
|
||||
|
||||
|
||||
verifyExecuteCommandCalledWithArgs(['login'], 0);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'dc', 'config', 'show'], 1);
|
||||
verifyExecuteCommandCalledWithArgs(['login'], 2);
|
||||
verifyExecuteCommandCalledWithArgs(['arc', 'sql', 'mi', 'list'], 3);
|
||||
});
|
||||
});
|
||||
|
||||
it('version', async function (): Promise<void> {
|
||||
executeCommandStub.resolves({ stdout: '1.0.0', stderr: '' });
|
||||
await azdataTool.version();
|
||||
verifyExecuteCommandCalledWithArgs(['--version']);
|
||||
});
|
||||
|
||||
/**
|
||||
* Verifies that the specified args were included in the call to executeCommand
|
||||
* @param args The args to check were included in the execute command call
|
||||
*/
|
||||
function verifyExecuteCommandCalledWithArgs(args: string[]): void {
|
||||
const commandArgs = executeCommandStub.args[0][1] as string[];
|
||||
function verifyExecuteCommandCalledWithArgs(args: string[], callIndex = 0): void {
|
||||
const commandArgs = executeCommandStub.args[callIndex][1] as string[];
|
||||
args.forEach(arg => should(commandArgs).containEql(arg));
|
||||
}
|
||||
|
||||
@@ -469,8 +583,8 @@ describe('azdata', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('promptForEula', function(): void {
|
||||
it('skipped because of config', async function(): Promise<void> {
|
||||
describe('promptForEula', function (): void {
|
||||
it('skipped because of config', async function (): Promise<void> {
|
||||
const configMock = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
|
||||
configMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => azdata.AzdataDeployOption.dontPrompt);
|
||||
sinon.stub(vscode.workspace, 'getConfiguration').returns(configMock.object);
|
||||
@@ -479,7 +593,7 @@ describe('azdata', function () {
|
||||
should(result).be.false();
|
||||
});
|
||||
|
||||
it('always prompt if user requested', async function(): Promise<void> {
|
||||
it('always prompt if user requested', async function (): Promise<void> {
|
||||
const configMock = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
|
||||
configMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => azdata.AzdataDeployOption.dontPrompt);
|
||||
sinon.stub(vscode.workspace, 'getConfiguration').returns(configMock.object);
|
||||
@@ -490,7 +604,7 @@ describe('azdata', function () {
|
||||
should(showInformationMessage.calledOnce).be.true('showInformationMessage should have been called to prompt user');
|
||||
});
|
||||
|
||||
it('prompt if config set to do so', async function(): Promise<void> {
|
||||
it('prompt if config set to do so', async function (): Promise<void> {
|
||||
const configMock = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
|
||||
configMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => azdata.AzdataDeployOption.prompt);
|
||||
sinon.stub(vscode.workspace, 'getConfiguration').returns(configMock.object);
|
||||
@@ -501,7 +615,7 @@ describe('azdata', function () {
|
||||
should(showInformationMessage.calledOnce).be.true('showInformationMessage should have been called to prompt user');
|
||||
});
|
||||
|
||||
it('update config if user chooses not to prompt', async function(): Promise<void> {
|
||||
it('update config if user chooses not to prompt', async function (): Promise<void> {
|
||||
const configMock = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
|
||||
configMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => azdata.AzdataDeployOption.prompt);
|
||||
sinon.stub(vscode.workspace, 'getConfiguration').returns(configMock.object);
|
||||
@@ -513,7 +627,7 @@ describe('azdata', function () {
|
||||
should(showInformationMessage.calledOnce).be.true('showInformationMessage should have been called to prompt user');
|
||||
});
|
||||
|
||||
it('user accepted EULA', async function(): Promise<void> {
|
||||
it('user accepted EULA', async function (): Promise<void> {
|
||||
const configMock = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
|
||||
configMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => azdata.AzdataDeployOption.prompt);
|
||||
sinon.stub(vscode.workspace, 'getConfiguration').returns(configMock.object);
|
||||
@@ -525,7 +639,7 @@ describe('azdata', function () {
|
||||
should(showInformationMessage.calledOnce).be.true('showInformationMessage should have been called to prompt user');
|
||||
});
|
||||
|
||||
it('user accepted EULA - require user action', async function(): Promise<void> {
|
||||
it('user accepted EULA - require user action', async function (): Promise<void> {
|
||||
const configMock = TypeMoq.Mock.ofType<vscode.WorkspaceConfiguration>();
|
||||
configMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => azdata.AzdataDeployOption.prompt);
|
||||
sinon.stub(vscode.workspace, 'getConfiguration').returns(configMock.object);
|
||||
@@ -538,7 +652,7 @@ describe('azdata', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isEulaAccepted', function(): void {
|
||||
describe('isEulaAccepted', function (): void {
|
||||
const mementoMock = TypeMoq.Mock.ofType<vscode.Memento>();
|
||||
mementoMock.setup(x => x.get(TypeMoq.It.isAny())).returns(() => true);
|
||||
should(azdata.isEulaAccepted(mementoMock.object)).be.true();
|
||||
|
||||
Reference in New Issue
Block a user