From 2a2ac74032ae2bb0fea403a9f12a6020dfdd30de Mon Sep 17 00:00:00 2001 From: Sakshi Sharma <57200045+SakshiS-harma@users.noreply.github.com> Date: Fri, 21 Oct 2022 13:00:03 -0700 Subject: [PATCH] Cleanup generated test files and folders for Sql DB projects (#20862) * Cleanup generated test files and folders * Add await to fix tests --- .../src/test/autorestHelper.test.ts | 4 +++ .../src/test/datasource.test.ts | 4 +++ .../src/test/deploy/deployService.test.ts | 4 +++ .../addDatabaseReferenceDialog.test.ts | 4 +++ .../dialogs/publishDatabaseDialog.test.ts | 9 ++++--- .../test/dialogs/publishOptionsDialog.test.ts | 4 +++ .../updateProjectFromDatabaseDialog.test.ts | 4 +++ .../src/test/netCoreTool.test.ts | 6 ++++- .../src/test/newProjectTool.test.ts | 6 ++++- .../src/test/project.test.ts | 25 +++++++++++++++++++ .../src/test/projectController.test.ts | 10 +++++--- .../src/test/publishProfile.test.ts | 4 +++ .../src/test/testUtils.ts | 19 +++++++++++++- .../src/test/utils.test.ts | 4 ++- 14 files changed, 97 insertions(+), 10 deletions(-) diff --git a/extensions/sql-database-projects/src/test/autorestHelper.test.ts b/extensions/sql-database-projects/src/test/autorestHelper.test.ts index 1d090591fe..ee0da6c8c4 100644 --- a/extensions/sql-database-projects/src/test/autorestHelper.test.ts +++ b/extensions/sql-database-projects/src/test/autorestHelper.test.ts @@ -25,6 +25,10 @@ describe('Autorest tests', function (): void { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should detect autorest', async function (): Promise { sinon.stub(window, 'showInformationMessage').returns(Promise.resolve(runViaNpx)); // stub a selection in case test runner doesn't have autorest installed diff --git a/extensions/sql-database-projects/src/test/datasource.test.ts b/extensions/sql-database-projects/src/test/datasource.test.ts index d6ca7f30ad..c0ec91258a 100644 --- a/extensions/sql-database-projects/src/test/datasource.test.ts +++ b/extensions/sql-database-projects/src/test/datasource.test.ts @@ -14,6 +14,10 @@ describe('Data Sources: DataSource operations', function (): void { await baselines.loadBaselines(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it.skip('Should read DataSources from datasource.json', async function (): Promise { const dataSourcePath = await testUtils.createTestDataSources(baselines.openDataSourcesBaseline); const dataSourceList = await dataSources.load(dataSourcePath); diff --git a/extensions/sql-database-projects/src/test/deploy/deployService.test.ts b/extensions/sql-database-projects/src/test/deploy/deployService.test.ts index 6115d70cb3..7b18b7378d 100644 --- a/extensions/sql-database-projects/src/test/deploy/deployService.test.ts +++ b/extensions/sql-database-projects/src/test/deploy/deployService.test.ts @@ -70,6 +70,10 @@ describe('deploy service', function (): void { sandbox = sinon.createSandbox(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should deploy a database to docker container successfully', async function (): Promise { const testContext = createContext(); const deployProfile: IPublishToDockerSettings = { diff --git a/extensions/sql-database-projects/src/test/dialogs/addDatabaseReferenceDialog.test.ts b/extensions/sql-database-projects/src/test/dialogs/addDatabaseReferenceDialog.test.ts index f6fdc6c7e9..78b96ac710 100644 --- a/extensions/sql-database-projects/src/test/dialogs/addDatabaseReferenceDialog.test.ts +++ b/extensions/sql-database-projects/src/test/dialogs/addDatabaseReferenceDialog.test.ts @@ -31,6 +31,10 @@ describe('Add Database Reference Dialog', () => { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should open dialog successfully', async function (): Promise { const project = await testUtils.createTestProject(baselines.newProjectFileBaseline); const dialog = new AddDatabaseReferenceDialog(project); diff --git a/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts b/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts index de937e35f7..65377845ba 100644 --- a/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts +++ b/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts @@ -5,7 +5,6 @@ import * as should from 'should'; import * as path from 'path'; -import * as os from 'os'; import * as vscode from 'vscode'; import * as baselines from '../baselines/baselines'; import * as templates from '../../templates/templates'; @@ -27,9 +26,13 @@ describe('Publish Database Dialog', () => { testContext = createContext(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should open dialog successfully ', async function (): Promise { const projController = new ProjectsController(testContext.outputChannel); - const projFileDir = path.join(os.tmpdir(), `TestProject_${new Date().getTime()}`); + const projFileDir = path.join(testUtils.generateBaseFolderName(), `TestProject_${new Date().getTime()}`); const projFilePath = await projController.createNewProject({ newProjName: 'TestProjectName', @@ -48,7 +51,7 @@ describe('Publish Database Dialog', () => { it('Should create default database name correctly ', async function (): Promise { const projController = new ProjectsController(testContext.outputChannel); const projFolder = `TestProject_${new Date().getTime()}`; - const projFileDir = path.join(os.tmpdir(), projFolder); + const projFileDir = path.join(testUtils.generateBaseFolderName(), projFolder); const projFilePath = await projController.createNewProject({ newProjName: 'TestProjectName', diff --git a/extensions/sql-database-projects/src/test/dialogs/publishOptionsDialog.test.ts b/extensions/sql-database-projects/src/test/dialogs/publishOptionsDialog.test.ts index 9dd8603407..c267e10a38 100644 --- a/extensions/sql-database-projects/src/test/dialogs/publishOptionsDialog.test.ts +++ b/extensions/sql-database-projects/src/test/dialogs/publishOptionsDialog.test.ts @@ -19,6 +19,10 @@ describe('Publish Database Options Dialog', () => { await baselines.loadBaselines(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should open dialog successfully ', async function (): Promise { const proj = new Project(''); sinon.stub(proj, 'getProjectTargetVersion').returns('150'); diff --git a/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts b/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts index 9ad12f4b1a..f3d892a471 100644 --- a/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts +++ b/extensions/sql-database-projects/src/test/dialogs/updateProjectFromDatabaseDialog.test.ts @@ -21,6 +21,10 @@ describe('Update Project From Database Dialog', () => { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should populate endpoints correctly when no context passed', async function (): Promise { const dialog = new UpdateProjectFromDatabaseDialog(undefined, undefined); await dialog.openDialog(); diff --git a/extensions/sql-database-projects/src/test/netCoreTool.test.ts b/extensions/sql-database-projects/src/test/netCoreTool.test.ts index 5bb3bc1210..780a22351a 100644 --- a/extensions/sql-database-projects/src/test/netCoreTool.test.ts +++ b/extensions/sql-database-projects/src/test/netCoreTool.test.ts @@ -11,7 +11,7 @@ import * as vscode from 'vscode'; import * as sinon from 'sinon'; import { NetCoreTool, DBProjectConfigurationKey, DotnetInstallLocationKey } from '../tools/netcoreTool'; import { getQuotedPath } from '../common/utils'; -import { generateTestFolderPath } from './testUtils'; +import { deleteGeneratedTestFolder, generateTestFolderPath } from './testUtils'; import { createContext, TestContext } from './testContext'; let testContext: TestContext; @@ -25,6 +25,10 @@ describe('NetCoreTool: Net core tests', function (): void { testContext = createContext(); }); + after(async function(): Promise { + await deleteGeneratedTestFolder(); + }); + it('Should override dotnet default value with settings', async function (): Promise { try { // update settings and validate diff --git a/extensions/sql-database-projects/src/test/newProjectTool.test.ts b/extensions/sql-database-projects/src/test/newProjectTool.test.ts index 77b8a2b2f1..3e9ac4c26d 100644 --- a/extensions/sql-database-projects/src/test/newProjectTool.test.ts +++ b/extensions/sql-database-projects/src/test/newProjectTool.test.ts @@ -9,7 +9,7 @@ import * as TypeMoq from 'typemoq'; import * as sinon from 'sinon'; import * as dataworkspace from 'dataworkspace'; import * as newProjectTool from '../tools/newProjectTool'; -import { generateTestFolderPath, createTestFile } from './testUtils'; +import { generateTestFolderPath, createTestFile, deleteGeneratedTestFolder } from './testUtils'; let previousSetting : string; let testFolderPath : string; @@ -29,6 +29,10 @@ describe('NewProjectTool: New project tool tests', function (): void { sinon.stub(vscode.extensions, 'getExtension').returns({ exports: dataWorkspaceMock.object}); }); + after(async function(): Promise { + await deleteGeneratedTestFolder(); + }); + afterEach(async function () { // reset the default project folder path to the previous setting await vscode.workspace.getConfiguration(projectConfigurationKey).update(projectSaveLocationKey, previousSetting, true); diff --git a/extensions/sql-database-projects/src/test/project.test.ts b/extensions/sql-database-projects/src/test/project.test.ts index fadbcafc6a..2bb5cf805f 100644 --- a/extensions/sql-database-projects/src/test/project.test.ts +++ b/extensions/sql-database-projects/src/test/project.test.ts @@ -30,6 +30,10 @@ describe('Project: sqlproj content operations', function (): void { projFilePath = await testUtils.createTestSqlProjFile(baselines.openProjectFileBaseline); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should read Project from sqlproj', async function (): Promise { const project: Project = await Project.openProject(projFilePath); @@ -914,6 +918,10 @@ describe('Project: sdk style project content operations', function (): void { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should read project from sqlproj and files and folders by globbing', async function (): Promise { projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectBaseline); await testUtils.createDummyFileStructureWithPrePostDeployScripts(false, undefined, path.dirname(projFilePath)); @@ -1551,6 +1559,7 @@ describe('Project: sdk style project content operations', function (): void { should(project.files.find(f => f.type === EntryType.File && f.relativePath === externalFileRelativePath)).not.equal(undefined); projFileText = (await fs.readFile(projFilePath)).toString(); should(projFileText.includes(``)).equal(true, projFileText); + await fs.rm(externalSqlFile); }); }); @@ -1559,6 +1568,10 @@ describe('Project: add SQLCMD Variables', function (): void { await baselines.loadBaselines(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should update .sqlproj with new sqlcmd variables', async function (): Promise { projFilePath = await testUtils.createTestSqlProjFile(baselines.openProjectFileBaseline); const project = await Project.openProject(projFilePath); @@ -1584,6 +1597,10 @@ describe('Project: properties', function (): void { await baselines.loadBaselines(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should read target database version', async function (): Promise { projFilePath = await testUtils.createTestSqlProjFile(baselines.openProjectFileBaseline); const project = await Project.openProject(projFilePath); @@ -1749,6 +1766,10 @@ describe('Project: round trip updates', function (): void { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should update SSDT project to work in ADS', async function (): Promise { await testUpdateInRoundTrip(baselines.SSDTProjectFileBaseline, baselines.SSDTProjectAfterUpdateBaseline); }); @@ -1836,6 +1857,10 @@ describe('Project: legacy to SDK-style updates', function (): void { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should update legacy style project to SDK-style', async function (): Promise { const projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline); const list: Uri[] = []; diff --git a/extensions/sql-database-projects/src/test/projectController.test.ts b/extensions/sql-database-projects/src/test/projectController.test.ts index de61083e75..2da42eefcc 100644 --- a/extensions/sql-database-projects/src/test/projectController.test.ts +++ b/extensions/sql-database-projects/src/test/projectController.test.ts @@ -5,7 +5,6 @@ import * as should from 'should'; import * as path from 'path'; -import * as os from 'os'; import * as vscode from 'vscode'; import * as TypeMoq from 'typemoq'; import * as sinon from 'sinon'; @@ -49,11 +48,15 @@ describe('ProjectsController', function (): void { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + describe('project controller operations', function (): void { describe('Project file operations and prompting', function (): void { it('Should create new sqlproj file with correct values', async function (): Promise { const projController = new ProjectsController(testContext.outputChannel); - const projFileDir = path.join(os.tmpdir(), `TestProject_${new Date().getTime()}`); + const projFileDir = path.join(testUtils.generateBaseFolderName(), `TestProject_${new Date().getTime()}`); const projFilePath = await projController.createNewProject({ newProjName: 'TestProjectName', @@ -70,7 +73,7 @@ describe('ProjectsController', function (): void { it('Should create new sqlproj file with correct specified target platform', async function (): Promise { const projController = new ProjectsController(testContext.outputChannel); - const projFileDir = path.join(os.tmpdir(), `TestProject_${new Date().getTime()}`); + const projFileDir = path.join(testUtils.generateBaseFolderName(), `TestProject_${new Date().getTime()}`); const projTargetPlatform = SqlTargetPlatform.sqlAzure; // default is SQL Server 2019 const projFilePath = await projController.createNewProject({ @@ -447,6 +450,7 @@ describe('ProjectsController', function (): void { should(publishedDacpacPath).not.equal('', 'published dacpac path should be set'); should(builtDacpacPath).not.equal(publishedDacpacPath, 'built and published dacpac paths should be different'); should(postCopyContents).equal(fakeDacpacContents, 'contents of built and published dacpacs should match'); + await fs.rm(publishedDacpacPath); }); }); }); diff --git a/extensions/sql-database-projects/src/test/publishProfile.test.ts b/extensions/sql-database-projects/src/test/publishProfile.test.ts index c04e51e77b..f31b5bcce4 100644 --- a/extensions/sql-database-projects/src/test/publishProfile.test.ts +++ b/extensions/sql-database-projects/src/test/publishProfile.test.ts @@ -29,6 +29,10 @@ describe('Publish profile tests', function (): void { sinon.restore(); }); + after(async function(): Promise { + await testUtils.deleteGeneratedTestFolder(); + }); + it('Should read database name, integrated security connection string, and SQLCMD variables from publish profile', async function (): Promise { await baselines.loadBaselines(); const profilePath = await testUtils.createTestFile(baselines.publishProfileIntegratedSecurityBaseline, 'publishProfile.publish.xml'); diff --git a/extensions/sql-database-projects/src/test/testUtils.ts b/extensions/sql-database-projects/src/test/testUtils.ts index 34af034b43..b064db67ff 100644 --- a/extensions/sql-database-projects/src/test/testUtils.ts +++ b/extensions/sql-database-projects/src/test/testUtils.ts @@ -13,6 +13,7 @@ import should = require('should'); import { AssertionError } from 'assert'; import { Project } from '../models/project'; import { Uri } from 'vscode'; +import { exists } from '../common/utils'; export async function shouldThrowSpecificError(block: Function, expectedMessage: string, details?: string) { let succeeded = false; @@ -47,12 +48,17 @@ export async function createTestDataSources(contents: string, folderPath?: strin } export async function generateTestFolderPath(): Promise { - const folderPath = path.join(os.tmpdir(), 'ADS_Tests', `TestRun_${new Date().getTime()}`); + const folderPath = path.join(generateBaseFolderName(), `TestRun_${new Date().getTime()}`); await fs.mkdir(folderPath, { recursive: true }); return folderPath; } +export function generateBaseFolderName(): string { + const folderPath = path.join(os.tmpdir(), 'ADS_Tests'); + return folderPath; +} + export async function createTestFile(contents: string, fileName: string, folderPath?: string): Promise { folderPath = folderPath ?? await generateTestFolderPath(); const filePath = path.join(folderPath, fileName); @@ -249,3 +255,14 @@ export async function createOtherDummyFiles(testFolderPath: string): Promise { + const testFolderPath: string = generateBaseFolderName(); + if (await exists(testFolderPath)) { + // cleanup folder + await fs.rm(testFolderPath, { recursive: true }); + } +} \ No newline at end of file diff --git a/extensions/sql-database-projects/src/test/utils.test.ts b/extensions/sql-database-projects/src/test/utils.test.ts index e45b4ea5ac..1856429122 100644 --- a/extensions/sql-database-projects/src/test/utils.test.ts +++ b/extensions/sql-database-projects/src/test/utils.test.ts @@ -6,7 +6,7 @@ import * as should from 'should'; import * as path from 'path'; import * as os from 'os'; -import { createDummyFileStructure } from './testUtils'; +import { createDummyFileStructure, deleteGeneratedTestFolder } from './testUtils'; import { exists, trimUri, removeSqlCmdVariableFormatting, formatSqlCmdVariable, isValidSqlCmdVariableName, timeConversion, validateSqlServerPortNumber, isEmptyString, detectCommandInstallation, isValidSQLPassword, findSqlVersionInImageName, findSqlVersionInTargetPlatform } from '../common/utils'; import { Uri } from 'vscode'; @@ -20,6 +20,8 @@ describe('Tests to verify utils functions', function (): void { should(await exists(path.join(testFolderPath, 'folder4'))).equal(false); should(await exists(path.join(testFolderPath, 'folder2', 'file4.sql'))).equal(true); should(await exists(path.join(testFolderPath, 'folder4', 'file2.sql'))).equal(false); + + await deleteGeneratedTestFolder(); }); it('Should get correct relative paths of files/folders', async () => {