mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-01 17:23:35 -05:00
Arc updates for March release (#14970)
* Updated Postgres Spec for where to find engine version, removed calling calling -ev in edit commands (#14735) * Added spec.engine.version, took out calling engine version with edit calls * Added text wrong place * missed updates * PR fix * Update Arc Postgres troubleshooting notebook Co-authored-by: Brian Bergeron <brberger@microsoft.com> * Remove AzdataSession from azdata commands (#14856) * remove session * Add in controller-context support * Revert "Add in controller-context support" This reverts commit 3b39b968efbf6054041cb01cb2d8443532643a82. * Add azdataContext to login * Undo book change * Undo change correctly * Add controller context support (#14862) * remove session * Add in controller-context support * Add params to fake * Fix tests * Add info and placeholder for controller URL/name (#14887) * Add info and placeholder for controller URL * add period + update name * update memento and allow editing of namespace/URL * vBump * vBump * Fix tests Co-authored-by: nasc17 <69922333+nasc17@users.noreply.github.com> Co-authored-by: Brian Bergeron <brian.e.bergeron@gmail.com> Co-authored-by: Brian Bergeron <brberger@microsoft.com>
This commit is contained in:
@@ -22,6 +22,20 @@ interface ExtensionGlobalMemento extends vscode.Memento {
|
||||
setKeysForSync(keys: string[]): void;
|
||||
}
|
||||
|
||||
function getDefaultControllerInfo(): ControllerInfo {
|
||||
return {
|
||||
id: uuid(),
|
||||
endpoint: '127.0.0.1',
|
||||
kubeConfigFilePath: '/path/to/.kube/config',
|
||||
kubeClusterContext: 'currentCluster',
|
||||
username: 'admin',
|
||||
name: 'arc',
|
||||
namespace: 'arc-ns',
|
||||
rememberPassword: true,
|
||||
resources: []
|
||||
};
|
||||
}
|
||||
|
||||
describe('ControllerModel', function (): void {
|
||||
afterEach(function (): void {
|
||||
sinon.restore();
|
||||
@@ -39,15 +53,15 @@ describe('ControllerModel', function (): void {
|
||||
|
||||
beforeEach(function (): void {
|
||||
sinon.stub(ConnectToControllerDialog.prototype, 'showDialog');
|
||||
sinon.stub(kubeUtils, 'getKubeConfigClusterContexts').resolves([{ name: 'currentCluster', isCurrentContext: true }]);
|
||||
sinon.stub(kubeUtils, 'getKubeConfigClusterContexts').returns([{ name: 'currentCluster', isCurrentContext: true }]);
|
||||
sinon.stub(vscode.window, 'showErrorMessage').resolves(<any>loc.yes);
|
||||
});
|
||||
|
||||
it('Rejected with expected error when user cancels', async function (): Promise<void> {
|
||||
// Returning an undefined model here indicates that the dialog closed without clicking "Ok" - usually through the user clicking "Cancel"
|
||||
sinon.stub(ConnectToControllerDialog.prototype, 'waitForClose').returns(Promise.resolve(undefined));
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] });
|
||||
await should(model.acquireAzdataSession()).be.rejectedWith(new UserCancelledError(loc.userCancelledError));
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo());
|
||||
await should(model.login()).be.rejectedWith(new UserCancelledError(loc.userCancelledError));
|
||||
});
|
||||
|
||||
it('Reads password from cred store', async function (): Promise<void> {
|
||||
@@ -62,13 +76,13 @@ describe('ControllerModel', function (): void {
|
||||
|
||||
const azdataExtApiMock = TypeMoq.Mock.ofType<azdataExt.IExtension>();
|
||||
const azdataMock = TypeMoq.Mock.ofType<azdataExt.IAzdataApi>();
|
||||
azdataMock.setup(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataMock.setup(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataExtApiMock.setup(x => x.azdata).returns(() => azdataMock.object);
|
||||
sinon.stub(vscode.extensions, 'getExtension').returns(<any>{ exports: azdataExtApiMock.object });
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] });
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo());
|
||||
|
||||
await model.acquireAzdataSession();
|
||||
azdataMock.verify(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
await model.login();
|
||||
azdataMock.verify(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
|
||||
it('Prompt for password when not in cred store', async function (): Promise<void> {
|
||||
@@ -83,18 +97,18 @@ describe('ControllerModel', function (): void {
|
||||
|
||||
const azdataExtApiMock = TypeMoq.Mock.ofType<azdataExt.IExtension>();
|
||||
const azdataMock = TypeMoq.Mock.ofType<azdataExt.IAzdataApi>();
|
||||
azdataMock.setup(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataMock.setup(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataExtApiMock.setup(x => x.azdata).returns(() => azdataMock.object);
|
||||
sinon.stub(vscode.extensions, 'getExtension').returns(<any>{ exports: azdataExtApiMock.object });
|
||||
|
||||
// Set up dialog to return new model with our password
|
||||
const newModel = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] }, password);
|
||||
const newModel = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo(), password);
|
||||
sinon.stub(ConnectToControllerDialog.prototype, 'waitForClose').returns(Promise.resolve({ controllerModel: newModel, password: password }));
|
||||
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] });
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo());
|
||||
|
||||
await model.acquireAzdataSession();
|
||||
azdataMock.verify(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
await model.login();
|
||||
azdataMock.verify(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
|
||||
it('Prompt for password when rememberPassword is true but prompt reconnect is true', async function (): Promise<void> {
|
||||
@@ -108,19 +122,19 @@ describe('ControllerModel', function (): void {
|
||||
|
||||
const azdataExtApiMock = TypeMoq.Mock.ofType<azdataExt.IExtension>();
|
||||
const azdataMock = TypeMoq.Mock.ofType<azdataExt.IAzdataApi>();
|
||||
azdataMock.setup(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataMock.setup(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataExtApiMock.setup(x => x.azdata).returns(() => azdataMock.object);
|
||||
sinon.stub(vscode.extensions, 'getExtension').returns(<any>{ exports: azdataExtApiMock.object });
|
||||
|
||||
// Set up dialog to return new model with our new password from the reprompt
|
||||
const newModel = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] }, password);
|
||||
const newModel = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo(), password);
|
||||
const waitForCloseStub = sinon.stub(ConnectToControllerDialog.prototype, 'waitForClose').returns(Promise.resolve({ controllerModel: newModel, password: password }));
|
||||
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] });
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo());
|
||||
|
||||
await model.acquireAzdataSession(true);
|
||||
await model.login(true);
|
||||
should(waitForCloseStub.called).be.true('waitForClose should have been called');
|
||||
azdataMock.verify(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
azdataMock.verify(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
|
||||
it('Prompt for password when we already have a password but prompt reconnect is true', async function (): Promise<void> {
|
||||
@@ -134,20 +148,20 @@ describe('ControllerModel', function (): void {
|
||||
|
||||
const azdataExtApiMock = TypeMoq.Mock.ofType<azdataExt.IExtension>();
|
||||
const azdataMock = TypeMoq.Mock.ofType<azdataExt.IAzdataApi>();
|
||||
azdataMock.setup(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataMock.setup(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataExtApiMock.setup(x => x.azdata).returns(() => azdataMock.object);
|
||||
sinon.stub(vscode.extensions, 'getExtension').returns(<any>{ exports: azdataExtApiMock.object });
|
||||
|
||||
// Set up dialog to return new model with our new password from the reprompt
|
||||
const newModel = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] }, password);
|
||||
const newModel = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo(), password);
|
||||
const waitForCloseStub = sinon.stub(ConnectToControllerDialog.prototype, 'waitForClose').returns(Promise.resolve({ controllerModel: newModel, password: password }));
|
||||
|
||||
// Set up original model with a password
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), { id: uuid(), url: '127.0.0.1', kubeConfigFilePath: '/path/to/.kube/config', kubeClusterContext: 'currentCluster', username: 'admin', name: 'arc', rememberPassword: true, resources: [] }, 'originalPassword');
|
||||
const model = new ControllerModel(new AzureArcTreeDataProvider(mockExtensionContext.object), getDefaultControllerInfo(), 'originalPassword');
|
||||
|
||||
await model.acquireAzdataSession(true);
|
||||
await model.login(true);
|
||||
should(waitForCloseStub.called).be.true('waitForClose should have been called');
|
||||
azdataMock.verify(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
azdataMock.verify(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), password, TypeMoq.It.isAny()), TypeMoq.Times.once());
|
||||
});
|
||||
|
||||
it('Model values are updated correctly when modified during reconnect', async function (): Promise<void> {
|
||||
@@ -162,7 +176,7 @@ describe('ControllerModel', function (): void {
|
||||
|
||||
const azdataExtApiMock = TypeMoq.Mock.ofType<azdataExt.IExtension>();
|
||||
const azdataMock = TypeMoq.Mock.ofType<azdataExt.IAzdataApi>();
|
||||
azdataMock.setup(x => x.acquireSession(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataMock.setup(x => x.login(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => <any>Promise.resolve(undefined));
|
||||
azdataExtApiMock.setup(x => x.azdata).returns(() => azdataMock.object);
|
||||
sinon.stub(vscode.extensions, 'getExtension').returns(<any>{ exports: azdataExtApiMock.object });
|
||||
|
||||
@@ -170,27 +184,19 @@ describe('ControllerModel', function (): void {
|
||||
const originalPassword = 'originalPassword';
|
||||
const model = new ControllerModel(
|
||||
treeDataProvider,
|
||||
{
|
||||
id: uuid(),
|
||||
url: '127.0.0.1',
|
||||
kubeConfigFilePath: '/path/to/.kube/config',
|
||||
kubeClusterContext: 'currentCluster',
|
||||
username: 'admin',
|
||||
name: 'arc',
|
||||
rememberPassword: false,
|
||||
resources: []
|
||||
},
|
||||
getDefaultControllerInfo(),
|
||||
originalPassword
|
||||
);
|
||||
await treeDataProvider.addOrUpdateController(model, originalPassword);
|
||||
|
||||
const newInfo: ControllerInfo = {
|
||||
id: model.info.id, // The ID stays the same since we're just re-entering information for the same model
|
||||
url: 'newUrl',
|
||||
endpoint: 'newUrl',
|
||||
kubeConfigFilePath: '/path/to/.kube/config',
|
||||
kubeClusterContext: 'currentCluster',
|
||||
username: 'newUser',
|
||||
name: 'newName',
|
||||
namespace: 'newNamespace',
|
||||
rememberPassword: true,
|
||||
resources: []
|
||||
};
|
||||
@@ -203,7 +209,7 @@ describe('ControllerModel', function (): void {
|
||||
const waitForCloseStub = sinon.stub(ConnectToControllerDialog.prototype, 'waitForClose').returns(Promise.resolve(
|
||||
{ controllerModel: newModel, password: newPassword }));
|
||||
|
||||
await model.acquireAzdataSession(true);
|
||||
await model.login(true);
|
||||
should(waitForCloseStub.called).be.true('waitForClose should have been called');
|
||||
should((await treeDataProvider.getChildren()).length).equal(1, 'Tree Data provider should still only have 1 node');
|
||||
should(model.info).deepEqual(newInfo, 'Model info should have been updated');
|
||||
|
||||
@@ -40,7 +40,8 @@ export const FakePostgresServerShowOutput: azdataExt.AzdataOutput<azdataExt.Post
|
||||
extensions: [{ name: '' }],
|
||||
settings: {
|
||||
default: { ['']: '' }
|
||||
}
|
||||
},
|
||||
version: ''
|
||||
},
|
||||
scale: {
|
||||
shards: 0,
|
||||
@@ -114,7 +115,7 @@ describe('PostgresModel', function (): void {
|
||||
controllerModel = new FakeControllerModel();
|
||||
|
||||
//Stub calling azdata login and acquiring session
|
||||
sinon.stub(controllerModel, 'acquireAzdataSession').returns(Promise.resolve(vscode.Disposable.from()));
|
||||
sinon.stub(controllerModel, 'login').returns(Promise.resolve());
|
||||
|
||||
// Stub the azdata CLI API
|
||||
azdataApi = new FakeAzdataApi();
|
||||
|
||||
Reference in New Issue
Block a user