mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Add test for schema compare include exclude (#8765)
* add test for schema compare include exclude * combine a few checks * small fixes * add testData folder to whtiespace check exclusion list * addressing comments * fix testData path in gulpfile.hygiene.js * move change up a couple lines
This commit is contained in:
@@ -103,6 +103,7 @@ const indentationFilter = [
|
|||||||
'!extensions/admin-tool-ext-win/ssmsmin/**',
|
'!extensions/admin-tool-ext-win/ssmsmin/**',
|
||||||
'!extensions/resource-deployment/notebooks/**',
|
'!extensions/resource-deployment/notebooks/**',
|
||||||
'!extensions/mssql/notebooks/**',
|
'!extensions/mssql/notebooks/**',
|
||||||
|
'!extensions/integration-tests/testData/**',
|
||||||
'!extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts',
|
'!extensions/big-data-cluster/src/bigDataCluster/controller/apiGenerated.ts',
|
||||||
'!extensions/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts'
|
'!extensions/big-data-cluster/src/bigDataCluster/controller/clusterApiGenerated2.ts'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -69,9 +69,6 @@ if (isTestSetupCompleted()) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Disabling due to intermittent failure with error Editor is not connected
|
|
||||||
// Tracking bug https://github.com/microsoft/azuredatastudio/issues/7323
|
|
||||||
|
|
||||||
const bacpac1: string = path.join(__dirname, '..', 'testData', 'Database1.bacpac');
|
const bacpac1: string = path.join(__dirname, '..', 'testData', 'Database1.bacpac');
|
||||||
test('Import and export bacpac', async function () {
|
test('Import and export bacpac', async function () {
|
||||||
const server = await getStandaloneServer();
|
const server = await getStandaloneServer();
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ import { stressify } from 'adstest';
|
|||||||
let schemaCompareService: mssql.ISchemaCompareService;
|
let schemaCompareService: mssql.ISchemaCompareService;
|
||||||
let dacfxService: mssql.IDacFxService;
|
let dacfxService: mssql.IDacFxService;
|
||||||
let schemaCompareTester: SchemaCompareTester;
|
let schemaCompareTester: SchemaCompareTester;
|
||||||
const dacpac1: string = path.join(__dirname, '../testData/Database1.dacpac');
|
const dacpac1: string = path.join(__dirname, '..','testData', 'Database1.dacpac');
|
||||||
const dacpac2: string = path.join(__dirname, '../testData/Database2.dacpac');
|
const dacpac2: string = path.join(__dirname, '..', 'testData', 'Database2.dacpac');
|
||||||
|
const includeExcludeSourceDacpac: string = path.join(__dirname, '..', 'testData', 'SchemaCompareIncludeExcludeSource.dacpac');
|
||||||
|
const includeExcludeTargetDacpac: string = path.join(__dirname, '..', 'testData', 'SchemaCompareIncludeExcludeTarget.dacpac');
|
||||||
const SERVER_CONNECTION_TIMEOUT: number = 3000;
|
const SERVER_CONNECTION_TIMEOUT: number = 3000;
|
||||||
const retryCount = 24; // 2 minutes
|
const retryCount = 24; // 2 minutes
|
||||||
const folderPath = path.join(os.tmpdir(), 'SchemaCompareTest');
|
const folderPath = path.join(os.tmpdir(), 'SchemaCompareTest');
|
||||||
@@ -47,10 +49,12 @@ if (isTestSetupCompleted()) {
|
|||||||
test('Schema compare database to database comparison, script generation, and scmp', async function () {
|
test('Schema compare database to database comparison, script generation, and scmp', async function () {
|
||||||
await schemaCompareTester.SchemaCompareDatabaseToDatabase();
|
await schemaCompareTester.SchemaCompareDatabaseToDatabase();
|
||||||
});
|
});
|
||||||
// TODO: figure out why this is failing with Error: This editor is not connected to a database Parameter name: OwnerUri
|
test('Schema compare dacpac to database comparison, script generation, and scmp', async function () {
|
||||||
// test('Schema compare dacpac to database comparison, script generation, and scmp', async function () {
|
await schemaCompareTester.SchemaCompareDacpacToDatabase();
|
||||||
// await schemaCompareTester.SchemaCompareDacpacToDatabase();
|
});
|
||||||
// });
|
test('Schema compare dacpac to dacpac comparison with include exclude', async function () {
|
||||||
|
await schemaCompareTester.SchemaCompareIncludeExcludeDacpacToDacpac();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +87,7 @@ class SchemaCompareTester {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
||||||
this.assertSchemaCompareResult(schemaCompareResult, operationId);
|
this.assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||||
|
|
||||||
// save to scmp
|
// save to scmp
|
||||||
const filepath = path.join(folderPath, `ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
const filepath = path.join(folderPath, `ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
||||||
@@ -126,8 +130,8 @@ class SchemaCompareTester {
|
|||||||
|
|
||||||
assert(result1.success === true, 'Deploy source database should succeed');
|
assert(result1.success === true, 'Deploy source database should succeed');
|
||||||
assert(result2.success === true, 'Deploy target database should succeed');
|
assert(result2.success === true, 'Deploy target database should succeed');
|
||||||
utils.assertDatabaseCreationResult(sourceDB, ownerUri, retryCount);
|
await utils.assertDatabaseCreationResult(sourceDB, ownerUri, retryCount);
|
||||||
utils.assertDatabaseCreationResult(targetDB, ownerUri, retryCount);
|
await utils.assertDatabaseCreationResult(targetDB, ownerUri, retryCount);
|
||||||
|
|
||||||
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
||||||
|
|
||||||
@@ -151,7 +155,7 @@ class SchemaCompareTester {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
||||||
this.assertSchemaCompareResult(schemaCompareResult, operationId);
|
this.assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||||
|
|
||||||
let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.script);
|
let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.script);
|
||||||
|
|
||||||
@@ -160,7 +164,7 @@ class SchemaCompareTester {
|
|||||||
await this.assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
await this.assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
||||||
|
|
||||||
// save to scmp
|
// save to scmp
|
||||||
const filepath = path.join(folderPath,`ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
const filepath = path.join(folderPath, `ads_schemaCompare_${now.getTime().toString()}.scmp`);
|
||||||
if (!fs.existsSync(folderPath)) {
|
if (!fs.existsSync(folderPath)) {
|
||||||
fs.mkdirSync(folderPath);
|
fs.mkdirSync(folderPath);
|
||||||
}
|
}
|
||||||
@@ -226,7 +230,7 @@ class SchemaCompareTester {
|
|||||||
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
||||||
|
|
||||||
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
let schemaCompareResult = await schemaCompareService.schemaCompare(operationId, source, target, azdata.TaskExecutionMode.execute, null);
|
||||||
this.assertSchemaCompareResult(schemaCompareResult, operationId);
|
this.assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||||
|
|
||||||
let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.script);
|
let status = await schemaCompareService.schemaCompareGenerateScript(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.script);
|
||||||
await this.assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
await this.assertScriptGenerationResult(status, target.serverName, target.databaseName);
|
||||||
@@ -251,18 +255,89 @@ class SchemaCompareTester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private assertSchemaCompareResult(schemaCompareResult: mssql.SchemaCompareResult, operationId: string): void {
|
@stressify({ dop: SchemaCompareTester.ParallelCount })
|
||||||
|
async SchemaCompareIncludeExcludeDacpacToDacpac(): Promise<void> {
|
||||||
|
assert(schemaCompareService, 'Schema Compare Service Provider is not available');
|
||||||
|
const operationId = 'testOperationId_' + new Date().getTime().toString();
|
||||||
|
|
||||||
|
let source: mssql.SchemaCompareEndpointInfo = {
|
||||||
|
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
|
||||||
|
packageFilePath: includeExcludeSourceDacpac,
|
||||||
|
serverDisplayName: '',
|
||||||
|
serverName: '',
|
||||||
|
databaseName: '',
|
||||||
|
ownerUri: '',
|
||||||
|
connectionDetails: undefined
|
||||||
|
};
|
||||||
|
let target: mssql.SchemaCompareEndpointInfo = {
|
||||||
|
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
|
||||||
|
packageFilePath: includeExcludeTargetDacpac,
|
||||||
|
serverDisplayName: '',
|
||||||
|
serverName: '',
|
||||||
|
databaseName: '',
|
||||||
|
ownerUri: '',
|
||||||
|
connectionDetails: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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');
|
||||||
|
|
||||||
|
// excluding views from the comparison should make it so t2 can be excluded
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.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.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.success === true, `Expected: success in schema compare, Actual: Failure`);
|
||||||
assert(schemaCompareResult.differences.length === 4, `Expected: 4 differences. Actual differences: "${schemaCompareResult.differences.length}"`);
|
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}`);
|
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<void> {
|
private async assertScriptGenerationResult(resultstatus: azdata.ResultStatus, server: string, database: string): Promise<void> {
|
||||||
// TODO add more validation
|
// TODO add more validation
|
||||||
assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`);
|
assert(resultstatus.success === true, `Expected: success true Actual: "${resultstatus.success}" Error Message: "${resultstatus.errorMessage}`);
|
||||||
const taskService = await azdata.dataprotocol.getProvider<azdata.TaskServicesProvider>('MSSQL', azdata.DataProviderType.TaskServicesProvider);
|
const taskService = azdata.dataprotocol.getProvider<azdata.TaskServicesProvider>('MSSQL', azdata.DataProviderType.TaskServicesProvider);
|
||||||
const tasks = await taskService.getAllTasks({ listActiveTasksOnly: true });
|
const tasks = await taskService.getAllTasks({ listActiveTasksOnly: true });
|
||||||
let foundTask: azdata.TaskInfo;
|
let foundTask: azdata.TaskInfo;
|
||||||
tasks.tasks.forEach(t => {
|
tasks.tasks.forEach(t => {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user