From 3648a4e9280ef696de3b2e7ce5e6caf10513fd55 Mon Sep 17 00:00:00 2001 From: Adam Kolodziejczyk Date: Fri, 22 Nov 2024 14:45:23 +0100 Subject: [PATCH] execute automated external browser tests --- .../parameters_aws_auth_tests.json.gpg | 3 + .gitignore | 2 +- Jenkinsfile | 72 +++++++---- ci/container/test_authentication.sh | 9 ++ ci/test_authentication.sh | 14 +++ package.json | 1 + test/authentication/connectionParameters.js | 30 +++++ test/authentication/testExternalBrowser.js | 116 ++++++++++++++++++ test/integration/testManualConnection.js | 65 ---------- 9 files changed, 219 insertions(+), 93 deletions(-) create mode 100644 .github/workflows/parameters_aws_auth_tests.json.gpg create mode 100755 ci/container/test_authentication.sh create mode 100755 ci/test_authentication.sh create mode 100644 test/authentication/connectionParameters.js create mode 100644 test/authentication/testExternalBrowser.js diff --git a/.github/workflows/parameters_aws_auth_tests.json.gpg b/.github/workflows/parameters_aws_auth_tests.json.gpg new file mode 100644 index 000000000..6143d3b24 --- /dev/null +++ b/.github/workflows/parameters_aws_auth_tests.json.gpg @@ -0,0 +1,3 @@ +  Ptn4"Kx{3qr*V}h IV_F-я[qx/,0Njp:k~0;0fpttQF)qv5s٨>P~TyG;Jbo/S uNanlNtGz-T { + before(async () => { + await cleanBrowserProcesses(); + }); + + afterEach(async () => { + await cleanBrowserProcesses(); + }); + + it('Successful connection', async () => { + const connectionOption = { ...connParameters.externalBrowser, clientStoreTemporaryCredential: false }; + const connection = await snowflake.createConnection(connectionOption); + const connectAsyncPromise = connection.connectAsync(function (err, connection) { + connectionHandler(err, connection); + }); + const provideCredentialsPromise = execWithTimeout('node', [provideBrowserCredentialsPath, 'success', login, password], 15000); + await Promise.all([connectAsyncPromise, provideCredentialsPromise]); + }); + + it('Wrong credentials', async () => { + const login = 'itsnotanaccount.com'; + const password = 'fakepassword'; + const connectionOption = { ...connParameters.externalBrowser, clientStoreTemporaryCredential: false }; + const connection = await snowflake.createConnection(connectionOption); + + connection.connectAsync(function (err, connection) { + connectionHandler(err, connection); + }); + const provideCredentialsPromise = execWithTimeout('node', [provideBrowserCredentialsPath, 'fail', login, password]); + await Promise.all([provideCredentialsPromise]); + + }); + + it('External browser timeout', async () => { + const connectionOption = { ...connParameters.externalBrowser, browserActionTimeout: 100, clientStoreTemporaryCredential: false }; + const connection = await snowflake.createConnection(connectionOption); + + const connectAsyncPromise = connection.connectAsync(function (err, connection) { + timeoutConnectionHandler(err, connection); + }); + + const connectToBrowserPromise = execWithTimeout('node', [provideBrowserCredentialsPath, 'timeout']); + await Promise.all([connectAsyncPromise, connectToBrowserPromise]); + }); + }); +}); + +async function timeoutConnectionHandler(err, timeout) { + try { + assert.ok(err, `Browser action timed out after ${timeout} ms.`); + } catch (err){ + await assert.fail(err); + } +} + +async function cleanBrowserProcesses() { + exec('pkill -f chromium'); + exec('pkill -f xdg-open'); +} + +function connectionHandler(err, connection) { + assert.ok(connection.isUp(), 'Connection is not active'); + testUtil.destroyConnection(connection, function () { + try { + assert.ok(!connection.isUp(), 'Connection is not closed'); + } catch (err) { + assert.fail(err); + } + }); +} + +function execWithTimeout(command, args, timeout = 5000) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { shell: true }); + + let stdout = ''; + let stderr = ''; + + child.stdout.on('data', (data) => { + stdout += data; + }); + + child.stderr.on('data', (data) => { + stderr += data; + }); + + child.on('error', (err) => { + reject(err); + }); + + child.on('close', (code) => { + if (code !== 0) { + reject(new Error(`Provide browser credentials process exited with code: ${code}, error: ${stderr}`)); + } else { + resolve({ stdout, stderr }); + } + }); + + setTimeout(() => { + child.kill(); + reject(new Error('Provide browser credentials process timed out')); + }, timeout); + }); +} diff --git a/test/integration/testManualConnection.js b/test/integration/testManualConnection.js index ff375850f..a262ef738 100644 --- a/test/integration/testManualConnection.js +++ b/test/integration/testManualConnection.js @@ -13,71 +13,6 @@ const JsonCredentialManager = require('../../lib/authentication/secure_storage/j if (process.env.RUN_MANUAL_TESTS_ONLY === 'true') { describe('Run manual tests', function () { - describe('Connection test - external browser', function () { - it('Simple Connect', function (done) { - const connection = snowflake.createConnection( - connOption.externalBrowser - ); - - connection.connectAsync(function (err, connection) { - try { - assert.ok(connection.isUp(), 'not active'); - testUtil.destroyConnection(connection, function () { - try { - assert.ok(!connection.isUp(), 'not active'); - done(); - } catch (err) { - done(err); - } - }); - } catch (err) { - done(err); - } - }); - }); - - it('Connect - external browser timeout', function (done) { - const connection = snowflake.createConnection( - connOption.externalBrowserWithShortTimeout - ); - - connection.connectAsync(function (err) { - try { - const browserActionTimeout = - connOption.externalBrowserWithShortTimeout.browserActionTimeout; - assert.ok( - err, - `Browser action timed out after ${browserActionTimeout} ms.` - ); - done(); - } catch (err) { - done(err); - } - }); - }); - - it('Mismatched Username', function (done) { - const connection = snowflake.createConnection( - connOption.externalBrowserMismatchUser - ); - connection.connectAsync(function (err) { - try { - assert.ok( - err, - 'Logged in with different user than one on connection string' - ); - assert.equal( - 'The user you were trying to authenticate as differs from the user currently logged in at the IDP.', - err['message'] - ); - done(); - } catch (err) { - done(err); - } - }); - }); - }); - describe('Connection - ID Token authenticator', function () { const connectionOption = { ...connOption.externalBrowser, clientStoreTemporaryCredential: true }; const key = Util.buildCredentialCacheKey(connectionOption.host, connectionOption.username, 'ID_TOKEN');