mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Dacpac - Showing error message to user if operation fails (#13830)
* Showing error message to user if operation fails. * Added more tests
This commit is contained in:
@@ -67,3 +67,5 @@ export const reservedValueErrorMessage = localize('dacfx.reservedValueErrorMessa
|
|||||||
export const trailingWhitespaceErrorMessage = localize('dacfx.trailingWhitespaceErrorMessage', "File name cannot end with a whitespace");
|
export const trailingWhitespaceErrorMessage = localize('dacfx.trailingWhitespaceErrorMessage', "File name cannot end with a whitespace");
|
||||||
export const tooLongFilenameErrorMessage = localize('dacfx.tooLongFilenameErrorMessage', "File name is over 255 characters");
|
export const tooLongFilenameErrorMessage = localize('dacfx.tooLongFilenameErrorMessage', "File name is over 255 characters");
|
||||||
export function deployPlanErrorMessage(errorMessage: string): string { return localize('dacfx.deployPlanErrorMessage', "Generating deploy plan failed '{0}'", errorMessage ? errorMessage : 'Unknown'); }
|
export function deployPlanErrorMessage(errorMessage: string): string { return localize('dacfx.deployPlanErrorMessage', "Generating deploy plan failed '{0}'", errorMessage ? errorMessage : 'Unknown'); }
|
||||||
|
export function generateDeployErrorMessage(errorMessage: string): string { return localize('dacfx.generateDeployErrorMessage', "Generating deploy script failed '{0}'", errorMessage ? errorMessage : 'Unknown'); }
|
||||||
|
export function operationErrorMessage(operation: string, errorMessage: string): string { return localize('dacfx.operationErrorMessage', "{0} operation failed '{1}'", operation, errorMessage ? errorMessage : 'Unknown'); }
|
||||||
|
|||||||
@@ -5,8 +5,11 @@
|
|||||||
|
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
|
import * as vscode from 'vscode';
|
||||||
import * as should from 'should';
|
import * as should from 'should';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
|
import * as TypeMoq from 'typemoq';
|
||||||
|
import * as loc from '../localizedConstants';
|
||||||
import { DataTierApplicationWizard, Operation } from '../wizard/dataTierApplicationWizard';
|
import { DataTierApplicationWizard, Operation } from '../wizard/dataTierApplicationWizard';
|
||||||
import { DacFxDataModel } from '../wizard/api/models';
|
import { DacFxDataModel } from '../wizard/api/models';
|
||||||
import { DacFxTestService, deployOperationId, extractOperationId, importOperationId, exportOperationId, generateDeployPlan } from './testDacFxService';
|
import { DacFxTestService, deployOperationId, extractOperationId, importOperationId, exportOperationId, generateDeployPlan } from './testDacFxService';
|
||||||
@@ -60,6 +63,95 @@ describe('Dacfx wizard with connection', function (): void {
|
|||||||
await validateServiceCalls(wizard, Operation.export, exportOperationId);
|
await validateServiceCalls(wizard, Operation.export, exportOperationId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('executeOperation should show error message if deploy fails', async () => {
|
||||||
|
let service = TypeMoq.Mock.ofInstance(new DacFxTestService());
|
||||||
|
service.setup(x => x.deployDacpac(TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny())).returns(x => Promise.resolve({
|
||||||
|
errorMessage: 'error1',
|
||||||
|
success: false,
|
||||||
|
operationId: ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
let wizard = new DataTierApplicationWizard(service.object);
|
||||||
|
wizard.model = <DacFxDataModel>{};
|
||||||
|
wizard.model.server = connectionProfileMock;
|
||||||
|
let showErrorMessageStub = sinon.stub(vscode.window, 'showErrorMessage').resolves();
|
||||||
|
wizard.selectedOperation = Operation.deploy;
|
||||||
|
await wizard.executeOperation();
|
||||||
|
should(showErrorMessageStub.calledOnce).be.true();
|
||||||
|
should.equal(showErrorMessageStub.getCall(0).args[0], loc.operationErrorMessage(loc.deploy, 'error1'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('executeOperation should show error message if export fails', async () => {
|
||||||
|
let service = TypeMoq.Mock.ofInstance(new DacFxTestService());
|
||||||
|
service.setup(x => x.exportBacpac(TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny())).returns(x => Promise.resolve({
|
||||||
|
errorMessage: 'error1',
|
||||||
|
success: false,
|
||||||
|
operationId: ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
let wizard = new DataTierApplicationWizard(service.object);
|
||||||
|
wizard.model = <DacFxDataModel>{};
|
||||||
|
wizard.model.server = connectionProfileMock;
|
||||||
|
let showErrorMessageStub = sinon.stub(vscode.window, 'showErrorMessage').resolves();
|
||||||
|
wizard.selectedOperation = Operation.export;
|
||||||
|
await wizard.executeOperation();
|
||||||
|
should(showErrorMessageStub.calledOnce).be.true();
|
||||||
|
should.equal(showErrorMessageStub.getCall(0).args[0], loc.operationErrorMessage(loc.exportText, 'error1'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('executeOperation should show error message if extract fails', async () => {
|
||||||
|
let service = TypeMoq.Mock.ofInstance(new DacFxTestService());
|
||||||
|
service.setup(x => x.extractDacpac(TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny())).returns(x => Promise.resolve({
|
||||||
|
errorMessage: 'error1',
|
||||||
|
success: false,
|
||||||
|
operationId: ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
let wizard = new DataTierApplicationWizard(service.object);
|
||||||
|
wizard.model = <DacFxDataModel>{};
|
||||||
|
wizard.model.server = connectionProfileMock;
|
||||||
|
let showErrorMessageStub = sinon.stub(vscode.window, 'showErrorMessage').resolves();
|
||||||
|
wizard.selectedOperation = Operation.extract;
|
||||||
|
await wizard.executeOperation();
|
||||||
|
should(showErrorMessageStub.calledOnce).be.true();
|
||||||
|
should.equal(showErrorMessageStub.getCall(0).args[0], loc.operationErrorMessage(loc.extract, 'error1'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should show error message if generateDeployScript fails', async () => {
|
||||||
|
let service = TypeMoq.Mock.ofInstance(new DacFxTestService());
|
||||||
|
service.setup(x => x.generateDeployScript(TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny())).returns(x => Promise.resolve({
|
||||||
|
errorMessage: 'error1',
|
||||||
|
success: false,
|
||||||
|
operationId: ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
let wizard = new DataTierApplicationWizard(service.object);
|
||||||
|
wizard.model = <DacFxDataModel>{};
|
||||||
|
wizard.model.server = connectionProfileMock;
|
||||||
|
let showErrorMessageStub = sinon.stub(vscode.window, 'showErrorMessage').resolves();
|
||||||
|
await wizard.generateDeployScript();
|
||||||
|
should(showErrorMessageStub.calledOnce).be.true();
|
||||||
|
should.equal(showErrorMessageStub.getCall(0).args[0], loc.generateDeployErrorMessage('error1'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('executeOperation should show error message if import fails', async () => {
|
||||||
|
let service = TypeMoq.Mock.ofInstance(new DacFxTestService());
|
||||||
|
service.setup(x => x.importBacpac(TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny(),TypeMoq.It.isAny())).returns(x => Promise.resolve({
|
||||||
|
errorMessage: 'error1',
|
||||||
|
success: false,
|
||||||
|
operationId: ''
|
||||||
|
}));
|
||||||
|
|
||||||
|
let wizard = new DataTierApplicationWizard(service.object);
|
||||||
|
wizard.model = <DacFxDataModel>{};
|
||||||
|
wizard.model.server = connectionProfileMock;
|
||||||
|
let showErrorMessageStub = sinon.stub(vscode.window, 'showErrorMessage').resolves();
|
||||||
|
wizard.selectedOperation = Operation.import;
|
||||||
|
await wizard.executeOperation();
|
||||||
|
should(showErrorMessageStub.calledOnce).be.true();
|
||||||
|
should.equal(showErrorMessageStub.getCall(0).args[0], loc.operationErrorMessage(loc.importText, 'error1'));
|
||||||
|
});
|
||||||
|
|
||||||
it('Should call deploy plan generator correctly', async () => {
|
it('Should call deploy plan generator correctly', async () => {
|
||||||
wizard.model.server = connectionProfileMock;
|
wizard.model.server = connectionProfileMock;
|
||||||
|
|
||||||
|
|||||||
@@ -242,18 +242,47 @@ export class DataTierApplicationWizard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async executeOperation(): Promise<mssql.DacFxResult> {
|
public async executeOperation(): Promise<mssql.DacFxResult> {
|
||||||
|
let result: mssql.DacFxResult;
|
||||||
|
|
||||||
switch (this.selectedOperation) {
|
switch (this.selectedOperation) {
|
||||||
case Operation.deploy: {
|
case Operation.deploy: {
|
||||||
return await this.deploy();
|
result = await this.deploy();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case Operation.extract: {
|
case Operation.extract: {
|
||||||
return await this.extract();
|
result = await this.extract();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case Operation.import: {
|
case Operation.import: {
|
||||||
return await this.import();
|
result = await this.import();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case Operation.export: {
|
case Operation.export: {
|
||||||
return await this.export();
|
result = await this.export();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result || !result.success) {
|
||||||
|
vscode.window.showErrorMessage(this.getOperationErrorMessage(this.selectedOperation, result?.errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getOperationErrorMessage(operation: Operation, error: any): string {
|
||||||
|
switch (this.selectedOperation) {
|
||||||
|
case Operation.deploy: {
|
||||||
|
return loc.operationErrorMessage(loc.deploy, error);
|
||||||
|
}
|
||||||
|
case Operation.extract: {
|
||||||
|
return loc.operationErrorMessage(loc.extract, error);
|
||||||
|
}
|
||||||
|
case Operation.import: {
|
||||||
|
return loc.operationErrorMessage(loc.importText, error);
|
||||||
|
}
|
||||||
|
case Operation.export: {
|
||||||
|
return loc.operationErrorMessage(loc.exportText, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -286,7 +315,7 @@ export class DataTierApplicationWizard {
|
|||||||
return await service.importBacpac(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
return await service.importBacpac(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async generateDeployScript(): Promise<mssql.DacFxResult> {
|
public async generateDeployScript(): Promise<mssql.DacFxResult> {
|
||||||
const service = await this.getService(msSqlProvider);
|
const service = await this.getService(msSqlProvider);
|
||||||
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
const ownerUri = await azdata.connection.getUriForConnection(this.model.server.connectionId);
|
||||||
this.wizard.message = {
|
this.wizard.message = {
|
||||||
@@ -295,7 +324,12 @@ export class DataTierApplicationWizard {
|
|||||||
description: ''
|
description: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
return await service.generateDeployScript(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.script);
|
let result = await service.generateDeployScript(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.script);
|
||||||
|
|
||||||
|
if (!result || !result.success) {
|
||||||
|
vscode.window.showErrorMessage(loc.generateDeployErrorMessage(result?.errorMessage));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPage(idx: number): Page {
|
public getPage(idx: number): Page {
|
||||||
@@ -344,7 +378,7 @@ export class DataTierApplicationWizard {
|
|||||||
const result = await service.generateDeployPlan(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
const result = await service.generateDeployPlan(this.model.filePath, this.model.database, ownerUri, azdata.TaskExecutionMode.execute);
|
||||||
|
|
||||||
if (!result || !result.success) {
|
if (!result || !result.success) {
|
||||||
vscode.window.showErrorMessage(loc.deployPlanErrorMessage(result.errorMessage));
|
vscode.window.showErrorMessage(loc.deployPlanErrorMessage(result?.errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.report;
|
return result.report;
|
||||||
|
|||||||
Reference in New Issue
Block a user