From 5de1c10dd14bf801adcd43163cda1d6e70cd3e88 Mon Sep 17 00:00:00 2001 From: Charles Gagnon Date: Tue, 29 Sep 2020 14:23:27 -0700 Subject: [PATCH] Fix disabled azdata tests (#12659) * Fix successful install * fix more tests * Fix stubs * Don't throw * fix check --- extensions/azdata/src/common/httpClient.ts | 12 +-- extensions/azdata/src/test/azdata.test.ts | 98 ++++++++----------- .../azdata/src/test/common/httpClient.test.ts | 4 +- 3 files changed, 50 insertions(+), 64 deletions(-) diff --git a/extensions/azdata/src/common/httpClient.ts b/extensions/azdata/src/common/httpClient.ts index 4ff550ced9..a452190859 100644 --- a/extensions/azdata/src/common/httpClient.ts +++ b/extensions/azdata/src/common/httpClient.ts @@ -73,6 +73,11 @@ export namespace HttpClient { reject(downloadError); downloadRequest.abort(); }); + } else { + response.on('end', () => { + Logger.log(loc.downloadFinished); + resolve(strings.join('')); + }); } let contentLength = response.headers['content-length']; let totalBytes = parseInt(contentLength || '0'); @@ -92,13 +97,6 @@ export namespace HttpClient { printThreshold += 0.1; } } - }) - .on('close', async () => { - if (targetFolder === undefined) { - - Logger.log(loc.downloadFinished); - resolve(strings.join('')); - } }); }); } diff --git a/extensions/azdata/src/test/azdata.test.ts b/extensions/azdata/src/test/azdata.test.ts index 3dea97a345..915a4241fd 100644 --- a/extensions/azdata/src/test/azdata.test.ts +++ b/extensions/azdata/src/test/azdata.test.ts @@ -25,7 +25,7 @@ const releaseJson = { 'version': '9999.999.999' } }; - +let executeSudoCommandStub: sinon.SinonStub; describe('azdata', function () { afterEach(function (): void { @@ -53,13 +53,14 @@ describe('azdata', function () { }); describe('installAzdata', function (): void { + beforeEach(function (): void { sinon.stub(vscode.window, 'showErrorMessage').returns(Promise.resolve(loc.yes)); sinon.stub(utils, 'searchForCmd').returns(Promise.resolve('/path/to/azdata')); - sinon.stub(childProcess, 'executeSudoCommand').returns(Promise.resolve({ stdout: '', stderr: '' })); + executeSudoCommandStub = sinon.stub(childProcess, 'executeSudoCommand').returns(Promise.resolve({ stdout: '', stderr: '' })); }); - it.skip('successful install', async function (): Promise { + it('successful install', async function (): Promise { switch (process.platform) { case 'win32': await testWin32SuccessfulInstall(); @@ -74,14 +75,18 @@ describe('azdata', function () { }); if (process.platform === 'win32') { - it.skip('unsuccessful download - win32', async function (): Promise { + it('unsuccessful download - win32', async function (): Promise { sinon.stub(HttpClient, 'downloadFile').rejects(); - const downloadPromise = azdata.checkAndInstallAzdata(); - await should(downloadPromise).be.rejected(); + sinon.stub(childProcess, 'executeCommand') + .onFirstCall() + .rejects(new Error('not Found')) // First call mock the tool not being found + .resolves({ stdout: '1.0.0', stderr: '' }); + const azdataTool = await azdata.checkAndInstallAzdata(); + should(azdataTool).be.undefined(); }); } - it.skip('unsuccessful install', async function (): Promise { + it('unsuccessful install', async function (): Promise { switch (process.platform) { case 'win32': await testWin32UnsuccessfulInstall(); @@ -99,10 +104,10 @@ describe('azdata', function () { describe('updateAzdata', function (): void { beforeEach(function (): void { sinon.stub(vscode.window, 'showInformationMessage').returns(Promise.resolve(loc.yes)); - sinon.stub(childProcess, 'executeSudoCommand').returns(Promise.resolve({ stdout: '', stderr: '' })); + executeSudoCommandStub = sinon.stub(childProcess, 'executeSudoCommand').returns(Promise.resolve({ stdout: '', stderr: '' })); }); - it.skip('successful update', async function (): Promise { + it('successful update', async function (): Promise { switch (process.platform) { case 'win32': await testWin32SuccessfulUpdate(); @@ -117,7 +122,7 @@ describe('azdata', function () { }); - it.skip('unsuccessful update', async function (): Promise { + it('unsuccessful update', async function (): Promise { switch (process.platform) { case 'win32': await testWin32UnsuccessfulUpdate(); @@ -141,7 +146,7 @@ describe('azdata', function () { }); async function testLinuxUnsuccessfulUpdate() { - const executeSudoCommandStub = sinon.stub(childProcess, 'executeSudoCommand').rejects(); + executeSudoCommandStub.rejects(); const updateDone = await azdata.checkAndUpdateAzdata(oldAzdataMock); should(updateDone).be.false(); should(executeSudoCommandStub.calledOnce).be.true(); @@ -171,7 +176,7 @@ async function testDarwinUnsuccessfulUpdate() { return Promise.reject(new Error('not Found')); }) .callsFake(async (_command: string, _args: string[]) => { // by default return success - return Promise.resolve({stderr: '', stdout: 'success'}); + return Promise.resolve({ stderr: '', stdout: 'success' }); }); const updateDone = await azdata.checkAndUpdateAzdata(oldAzdataMock); should(updateDone).be.false(); @@ -180,16 +185,16 @@ async function testDarwinUnsuccessfulUpdate() { async function testWin32UnsuccessfulUpdate() { sinon.stub(HttpClient, 'downloadFile').returns(Promise.resolve(__filename)); - const executeCommandStub = sinon.stub(childProcess, 'executeCommand').rejects(); + executeSudoCommandStub.rejects(); const updateDone = await azdata.checkAndUpdateAzdata(oldAzdataMock); - should(updateDone).be.false(); - should(executeCommandStub.calledOnce).be.true(); + should(updateDone).be.false('Update should not have been successful'); + should(executeSudoCommandStub.calledOnce).be.true(); } async function testLinuxSuccessfulUpdate() { sinon.stub(HttpClient, 'getTextContent').returns(Promise.resolve(JSON.stringify(releaseJson))); const executeCommandStub = sinon.stub(childProcess, 'executeCommand').returns(Promise.resolve({ stdout: '0.0.0', stderr: '' })); - const executeSudoCommandStub = sinon.stub(childProcess, 'executeSudoCommand').returns(Promise.resolve({ stdout: '0.0.0', stderr: '' })); + executeSudoCommandStub.resolves({ stdout: '0.0.0', stderr: '' }); await azdata.checkAndUpdateAzdata(oldAzdataMock); should(executeSudoCommandStub.callCount).be.equal(6); should(executeCommandStub.calledOnce).be.true(); @@ -208,50 +213,39 @@ async function testDarwinSuccessfulUpdate() { }]; const executeCommandStub = sinon.stub(childProcess, 'executeCommand') .onThirdCall() //third call is brew info azdata-cli --json which needs to return json of new available azdata versions. - .callsFake(async (command: string, args: string[]) => { - should(command).be.equal('brew'); - should(args).deepEqual(['info', 'azdata-cli', '--json']); - return Promise.resolve({ - stderr: '', - stdout: JSON.stringify(brewInfoOutput) - }); + .resolves({ + stderr: '', + stdout: JSON.stringify(brewInfoOutput) }) - .callsFake(async (_command: string, _args: string[]) => { // return success on all other command executions - return Promise.resolve({ stdout: '0.0.0', stderr: '' }); - }); + .resolves({ stdout: '0.0.0', stderr: '' }); await azdata.checkAndUpdateAzdata(oldAzdataMock); should(executeCommandStub.callCount).be.equal(6); + should(executeCommandStub.getCall(2).args[0]).be.equal('brew', '3rd call should have been to brew'); + should(executeCommandStub.getCall(2).args[1]).deepEqual(['info', 'azdata-cli', '--json'], '3rd call did not have expected arguments'); } async function testWin32SuccessfulUpdate() { sinon.stub(HttpClient, 'getTextContent').returns(Promise.resolve(JSON.stringify(releaseJson))); sinon.stub(HttpClient, 'downloadFile').returns(Promise.resolve(__filename)); - const executeCommandStub = sinon.stub(childProcess, 'executeCommand').callsFake(async (command: string, args: string[]) => { - should(command).be.equal('msiexec'); - should(args[0]).be.equal('/qn'); - should(args[1]).be.equal('/i'); - return { stdout: '0.0.0', stderr: '' }; - }); await azdata.checkAndUpdateAzdata(oldAzdataMock); - should(executeCommandStub.calledOnce).be.true(); + should(executeSudoCommandStub.calledOnce).be.true('executeSudoCommand should have been called once'); + should(executeSudoCommandStub.getCall(0).args[0]).startWith('msiexec /qn /i'); } async function testWin32SuccessfulInstall() { + sinon.stub(HttpClient, 'getTextContent').returns(Promise.resolve(JSON.stringify(releaseJson))); sinon.stub(HttpClient, 'downloadFile').returns(Promise.resolve(__filename)); const executeCommandStub = sinon.stub(childProcess, 'executeCommand') .onFirstCall() - .callsFake(async (_command: string, _args: string[]) => { - return Promise.reject(new Error('not Found')); - }) - .callsFake(async (command: string, args: string[]) => { - should(command).be.equal('msiexec'); - should(args[0]).be.equal('/qn'); - should(args[1]).be.equal('/i'); - return { stdout: '0.0.0', stderr: '' }; - }); + .rejects(new Error('not Found')) // First call mock the tool not being found + .resolves({ stdout: '1.0.0', stderr: '' }); + executeSudoCommandStub + .returns({ stdout: '', stderr: '' }); await azdata.checkAndInstallAzdata(); should(executeCommandStub.calledTwice).be.true(`executeCommand should have been called twice. Actual ${executeCommandStub.getCalls().length}`); + should(executeSudoCommandStub.calledOnce).be.true(`executeSudoCommand should have been called once. Actual ${executeSudoCommandStub.getCalls().length}`); + should(executeSudoCommandStub.getCall(0).args[0]).startWith('msiexec /qn /i'); } async function testDarwinSuccessfulInstall() { @@ -270,23 +264,17 @@ async function testDarwinSuccessfulInstall() { async function testLinuxSuccessfulInstall() { const executeCommandStub = sinon.stub(childProcess, 'executeCommand') .onFirstCall() - .callsFake(async (_command: string, _args: string[]) => { - return Promise.reject(new Error('not Found')); - }) - .callsFake(async (_command: string, _args: string[]) => { - return Promise.resolve({ stdout: '0.0.0', stderr: '' }); - }); - const executeSudoCommandStub = sinon.stub(childProcess, 'executeSudoCommand') - .callsFake(async (_command: string ) => { - return Promise.resolve({ stdout: 'success', stderr: '' }); - }); + .rejects(new Error('not Found')) + .resolves({ stdout: '0.0.0', stderr: '' }); + executeSudoCommandStub + .resolves({ stdout: 'success', stderr: '' }); await azdata.checkAndInstallAzdata(); should(executeSudoCommandStub.callCount).be.equal(6); should(executeCommandStub.calledThrice).be.true(); } async function testLinuxUnsuccessfulInstall() { - const executeSudoCommandStub = sinon.stub(childProcess, 'executeSudoCommand').rejects(); + executeSudoCommandStub.rejects(); const downloadPromise = azdata.installAzdata(); await should(downloadPromise).be.rejected(); should(executeSudoCommandStub.calledOnce).be.true(); @@ -300,9 +288,9 @@ async function testDarwinUnsuccessfulInstall() { } async function testWin32UnsuccessfulInstall() { - const executeCommandStub = sinon.stub(childProcess, 'executeCommand').rejects(); + executeSudoCommandStub.rejects(); sinon.stub(HttpClient, 'downloadFile').returns(Promise.resolve(__filename)); const downloadPromise = azdata.installAzdata(); await should(downloadPromise).be.rejected(); - should(executeCommandStub.calledOnce).be.true(); + should(executeSudoCommandStub.calledOnce).be.true(); } diff --git a/extensions/azdata/src/test/common/httpClient.test.ts b/extensions/azdata/src/test/common/httpClient.test.ts index 3d79597201..3ddb2c45bd 100644 --- a/extensions/azdata/src/test/common/httpClient.test.ts +++ b/extensions/azdata/src/test/common/httpClient.test.ts @@ -73,12 +73,12 @@ describe('HttpClient', function (): void { }); describe('getTextContent', function (): void { - it.skip('Gets file contents correctly', async function (): Promise { + it('Gets file contents correctly', async function (): Promise { nock('https://127.0.0.1') .get('/arbitraryFile') .replyWithFile(200, __filename); const receivedContents = await HttpClient.getTextContent(`https://127.0.0.1/arbitraryFile`); - should(receivedContents).equal(await fs.promises.readFile(__filename)); + should(receivedContents).equal((await fs.promises.readFile(__filename)).toString()); }); it('rejects on response error', async function (): Promise {