From 869b50fca9012163fe7e142812ea360313830f07 Mon Sep 17 00:00:00 2001 From: delvedor Date: Thu, 8 Nov 2018 19:36:05 +0100 Subject: [PATCH] Updated test --- test/integration/index.js | 101 ++++++++------- test/unit/connection-pool.test.js | 198 +++++++++++++++++++++++------- test/unit/connection.test.js | 45 +++++++ test/unit/transport.test.js | 77 +++++++----- 4 files changed, 301 insertions(+), 120 deletions(-) diff --git a/test/integration/index.js b/test/integration/index.js index 6492e18a1..0b498000c 100644 --- a/test/integration/index.js +++ b/test/integration/index.js @@ -1,8 +1,8 @@ 'use strict' const assert = require('assert') -const { readFileSync, accessSync, mkdirSync, readdirSync } = require('fs') -const { join } = require('path') +const { readFileSync, accessSync, mkdirSync, readdirSync, statSync } = require('fs') +const { join, sep } = require('path') const yaml = require('js-yaml') const Git = require('simple-git') const ora = require('ora') @@ -14,6 +14,7 @@ const TestRunner = require('./test-runner') const esRepo = 'https://github.com/elastic/elasticsearch.git' const esFolder = join(__dirname, '..', '..', 'elasticsearch') const yamlFolder = join(esFolder, 'rest-api-spec', 'src', 'main', 'resources', 'rest-api-spec', 'test') +// const xPackYamlFolder = join(esFolder, 'x-pack', 'plugin', 'src', 'test', 'resources', 'rest-api-spec', 'test') function Runner (opts) { if (!(this instanceof Runner)) { @@ -33,7 +34,6 @@ function Runner (opts) { * Runs the test suite */ Runner.prototype.start = function () { - const getTest = this.getTest.bind(this) const parse = this.parse.bind(this) const client = this.client @@ -51,57 +51,58 @@ Runner.prototype.start = function () { return } const { number: version, build_hash: sha } = body.version + // Set the repository to the given sha and run the test suite this.withSHA(sha, () => { this.log.succeed('Done!') runTest.call(this, version) }) + + // client.xpack.license.postStartTrial({ acknowledge: true }, (err, { body }) => { + // if (err) { + // this.log.fail(err.message) + // return + // } + // }) }) function runTest (version) { - const testFolders = getTest() - testFolders.forEach(runTestFolder.bind(this)) - function runTestFolder (testFolder) { - // if (testFolder !== 'tasks.get') return + const files = [] + .concat(getAllFiles(yamlFolder)) + // .concat(getAllFiles(xPackYamlFolder)) + .filter(t => !/(README|TODO)/g.test(t)) + + files.forEach(runTestFile.bind(this)) + function runTestFile (file) { // create a subtest for the specific folder - tap.test(testFolder, { jobs: 1 }, tap1 => { - const files = getTest(testFolder) - files.forEach(file => { - // if (file !== '20_typed_keys.yml') return - // create a subtest for the specific folder + test file - tap1.test(file.slice(0, -4), { jobs: 1 }, tap2 => { - const path = join(yamlFolder, testFolder, file) - // read the yaml file - const data = readFileSync(path, 'utf8') - // get the test yaml (as object), some file has multiple yaml documents inside, - // every document is separated by '---', so we split on the separator - // and then we remove the empty strings, finally we parse them - const tests = data - .split('---') - .map(s => s.trim()) - .filter(Boolean) - .map(parse) + tap.test(file.slice(file.indexOf(`${sep}elasticsearch${sep}`)), { jobs: 1 }, tap1 => { + // read the yaml file + const data = readFileSync(file, 'utf8') + // get the test yaml (as object), some file has multiple yaml documents inside, + // every document is separated by '---', so we split on the separator + // and then we remove the empty strings, finally we parse them + const tests = data + .split('---') + .map(s => s.trim()) + .filter(Boolean) + .map(parse) - // get setup and teardown if present - var setupTest = null - var teardownTest = null - tests.forEach(test => { - if (test.setup) setupTest = test.setup - if (test.teardown) teardownTest = test.teardown - }) + // get setup and teardown if present + var setupTest = null + var teardownTest = null + tests.forEach(test => { + if (test.setup) setupTest = test.setup + if (test.teardown) teardownTest = test.teardown + }) - // run the tests - tests.forEach(test => { - const name = Object.keys(test)[0] - if (name === 'setup' || name === 'teardown') return - // create a subtest for the specific folder + test file + test name - tap2.test(name, { jobs: 1, bail: this.bailout }, tap3 => { - const testRunner = TestRunner({ client, version, tap: tap3 }) - testRunner.run(setupTest, test[name], teardownTest, () => tap3.end()) - }) - }) - - tap2.end() + // run the tests + tests.forEach(test => { + const name = Object.keys(test)[0] + if (name === 'setup' || name === 'teardown') return + // create a subtest for the specific folder + test file + test name + tap1.test(name, { jobs: 1, bail: this.bailout }, tap2 => { + const testRunner = TestRunner({ client, version, tap: tap2 }) + testRunner.run(setupTest, test[name], teardownTest, () => tap2.end()) }) }) @@ -127,14 +128,12 @@ Runner.prototype.parse = function (data) { } /** - * Returns the content of the `yamlFolder`. - * If a folder name is given as parameter, it will return - * the content of join(yamlFolder, folder) + * Returns the filtered content of a given folder * @param {string} folder * @returns {Array} The content of the given folder */ Runner.prototype.getTest = function (folder) { - const tests = readdirSync(join(yamlFolder, folder || '')) + const tests = readdirSync(folder) return tests.filter(t => !/(README|TODO)/g.test(t)) } @@ -238,6 +237,7 @@ if (require.main === module) { string: ['host', 'version'], boolean: ['bailout'], default: { + // host: 'http://elastic:passw0rd@localhost:9200', host: 'http://localhost:9200', version: '6.4', bailout: false @@ -248,4 +248,11 @@ if (require.main === module) { runner.start() } +const getAllFiles = dir => + readdirSync(dir).reduce((files, file) => { + const name = join(dir, file) + const isDirectory = statSync(name).isDirectory() + return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name] + }, []) + module.exports = Runner diff --git a/test/unit/connection-pool.test.js b/test/unit/connection-pool.test.js index f435fffd2..b0c1ce65b 100644 --- a/test/unit/connection-pool.test.js +++ b/test/unit/connection-pool.test.js @@ -12,7 +12,7 @@ test('API', t => { const href = 'http://localhost:9200/' pool.addConnection(href) t.ok(pool.connections.get(href) instanceof Connection) - t.deepEqual(pool.alive, [href]) + t.strictEqual(pool.connections.get(href).status, Connection.statuses.ALIVE) t.deepEqual(pool.dead, []) t.end() }) @@ -38,7 +38,6 @@ test('API', t => { connection = pool.connections.get(href) t.strictEqual(connection.deadCount, 1) t.true(connection.resurrectTimeout > 0) - t.deepEqual(pool.alive, []) t.deepEqual(pool.dead, [href]) t.end() }) @@ -66,7 +65,7 @@ test('API', t => { connection = pool.connections.get(href) t.strictEqual(connection.deadCount, 0) t.strictEqual(connection.resurrectTimeout, 0) - t.deepEqual(pool.alive, [href]) + t.strictEqual(connection.status, Connection.statuses.ALIVE) t.deepEqual(pool.dead, []) t.end() }) @@ -91,7 +90,7 @@ test('API', t => { connection = pool.connections.get(connection.id) t.strictEqual(connection.deadCount, 0) t.strictEqual(connection.resurrectTimeout, 0) - t.deepEqual(pool.alive, [href]) + t.strictEqual(connection.status, Connection.statuses.ALIVE) t.deepEqual(pool.dead, []) t.end() }) @@ -113,7 +112,7 @@ test('API', t => { connection = pool.connections.get(connection.id) t.strictEqual(connection.deadCount, 2) t.true(connection.resurrectTimeout > 0) - t.deepEqual(pool.alive, []) + t.strictEqual(connection.status, Connection.statuses.DEAD) t.deepEqual(pool.dead, [href]) t.end() }) @@ -135,7 +134,7 @@ test('API', t => { connection = pool.connections.get(connection.id) t.strictEqual(connection.deadCount, 1) t.true(connection.resurrectTimeout > 0) - t.deepEqual(pool.alive, [href]) + t.strictEqual(connection.status, Connection.statuses.ALIVE) t.deepEqual(pool.dead, []) t.end() }) @@ -154,7 +153,7 @@ test('API', t => { connection = pool.connections.get(href) t.strictEqual(connection.deadCount, 1) t.true(connection.resurrectTimeout > 0) - t.deepEqual(pool.alive, []) + t.strictEqual(connection.status, Connection.statuses.DEAD) t.deepEqual(pool.dead, [href]) t.end() }) @@ -183,31 +182,8 @@ test('API', t => { t.end() }) - t.test('weighter option', t => { - const pool = new ConnectionPool() - const href1 = 'http://localhost:9200/' - const href2 = 'http://localhost:9200/other' - pool.addConnection([href1, href2]) - - const weighter = node => node.id === href1 - t.strictEqual(pool.getConnection({ weighter }).id, href2) - t.end() - }) - - t.test('filter should be run before the weighter', t => { - const pool = new ConnectionPool() - const href1 = 'http://localhost:9200/' - const href2 = 'http://localhost:9200/other' - pool.addConnection([href1, href2]) - - const filter = node => node.id === href1 - const weighter = node => node.id !== href2 - t.strictEqual(pool.getConnection({ weighter, filter }).id, href1) - t.end() - }) - t.test('filter and weighter should get Connection objects', t => { - t.plan(3) + t.plan(2) const pool = new ConnectionPool() const href1 = 'http://localhost:9200/' const href2 = 'http://localhost:9200/other' @@ -217,12 +193,11 @@ test('API', t => { t.ok(node instanceof Connection) return true } - const weighter = node => t.ok(node instanceof Connection) - pool.getConnection({ weighter, filter }) + pool.getConnection({ filter }) }) - t.test('filter and weighter should get alive connections', t => { - t.plan(3) + t.test('filter should get alive connections', t => { + t.plan(2) const pool = new ConnectionPool() const href1 = 'http://localhost:9200/' const href2 = 'http://localhost:9200/other' @@ -234,11 +209,10 @@ test('API', t => { t.strictEqual(node.status, Connection.statuses.ALIVE) return true } - const weighter = node => t.strictEqual(node.status, Connection.statuses.ALIVE) - pool.getConnection({ weighter, filter }) + pool.getConnection({ filter }) }) - t.test('filter and weighter as ConnectionPool option', t => { + t.test('filter as ConnectionPool option', t => { t.plan(3) const href1 = 'http://localhost:9200/' @@ -246,11 +220,7 @@ test('API', t => { const pool = new ConnectionPool({ nodeFilter: node => { t.ok('called') - return node.id === href1 - }, - nodeWeighter: node => { - t.ok('called') - return node.id !== href2 + return true } }) pool.addConnection([href1, href2]) @@ -276,7 +246,6 @@ test('API', t => { pool.addConnection('http://localhost:9201/') pool.empty() t.strictEqual(pool.connections.size, 0) - t.deepEqual(pool.alive, []) t.deepEqual(pool.dead, []) t.end() }) @@ -328,5 +297,146 @@ test('API', t => { t.end() }) + t.test('update', t => { + t.test('Should not update existing connections', t => { + t.plan(2) + class CustomConnectionPool extends ConnectionPool { + markAlive () { + t.fail('Should not be called') + } + } + const pool = new CustomConnectionPool() + pool.addConnection([{ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: { + master: true, + data: true, + ingest: true + } + }, { + host: new URL('http://127.0.0.1:9201'), + id: 'a2', + roles: { + master: true, + data: true, + ingest: true + } + }]) + + pool.update([{ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: null + }, { + host: new URL('http://127.0.0.1:9201'), + id: 'a2', + roles: null + }]) + + t.ok(pool.connections.get('a1').roles !== null) + t.ok(pool.connections.get('a2').roles !== null) + }) + + t.test('Should not update existing connections (mark alive)', t => { + t.plan(4) + class CustomConnectionPool extends ConnectionPool { + markAlive (connection) { + t.ok('called') + super.markAlive(connection) + } + } + const pool = new CustomConnectionPool() + const conn1 = pool.addConnection({ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: { + master: true, + data: true, + ingest: true + } + }) + + const conn2 = pool.addConnection({ + host: new URL('http://127.0.0.1:9201'), + id: 'a2', + roles: { + master: true, + data: true, + ingest: true + } + }) + + pool.markDead(conn1) + pool.markDead(conn2) + + pool.update([{ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: null + }, { + host: new URL('http://127.0.0.1:9201'), + id: 'a2', + roles: null + }]) + + t.ok(pool.connections.get('a1').roles !== null) + t.ok(pool.connections.get('a2').roles !== null) + }) + + t.test('Add a new connection', t => { + t.plan(2) + const pool = new ConnectionPool() + pool.addConnection({ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: { + master: true, + data: true, + ingest: true + } + }) + + pool.update([{ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: null + }, { + host: new URL('http://127.0.0.1:9201'), + id: 'a2', + roles: null + }]) + + t.ok(pool.connections.get('a1').roles !== null) + t.true(pool.connections.has('a2')) + }) + + t.test('Remove old connections', t => { + t.plan(3) + const pool = new ConnectionPool() + pool.addConnection({ + host: new URL('http://127.0.0.1:9200'), + id: 'a1', + roles: null + }) + + pool.update([{ + host: new URL('http://127.0.0.1:9200'), + id: 'a2', + roles: null + }, { + host: new URL('http://127.0.0.1:9201'), + id: 'a3', + roles: null + }]) + + t.false(pool.connections.has('a1')) + t.true(pool.connections.has('a2')) + t.true(pool.connections.has('a3')) + }) + + t.end() + }) + t.end() }) diff --git a/test/unit/connection.test.js b/test/unit/connection.test.js index 67c752576..3ee6b8234 100644 --- a/test/unit/connection.test.js +++ b/test/unit/connection.test.js @@ -374,3 +374,48 @@ test('Should not close a connection if there are open requests', t => { }) }) }) + +test('Url with auth', t => { + t.plan(2) + + function handler (req, res) { + t.match(req.headers, { + authorization: 'Basic Zm9vOmJhcg==' + }) + res.end('ok') + } + + buildServer(handler, ({ port }, server) => { + const connection = new Connection({ + host: new URL(`http://foo:bar@localhost:${port}`) + }) + connection.request({ + path: '/hello', + method: 'GET' + }, (err, res) => { + t.error(err) + }) + }) +}) + +test('Url with querystring', t => { + t.plan(2) + + function handler (req, res) { + t.strictEqual(req.url, '/hello?foo=bar&baz=faz') + res.end('ok') + } + + buildServer(handler, ({ port }, server) => { + const connection = new Connection({ + host: new URL(`http://localhost:${port}?foo=bar`) + }) + connection.request({ + path: '/hello', + method: 'GET', + querystring: 'baz=faz' + }, (err, res) => { + t.error(err) + }) + }) +}) diff --git a/test/unit/transport.test.js b/test/unit/transport.test.js index e0464456c..c7bc712a6 100644 --- a/test/unit/transport.test.js +++ b/test/unit/transport.test.js @@ -575,22 +575,14 @@ test('Override requestTimeout', t => { test('sniff', t => { t.test('sniffOnStart', t => { - t.plan(4) + t.plan(3) class CustomConnectionPool extends ConnectionPool { - empty () { + update () { t.ok('called') return this } - addConnection (hosts) { - // the first `addConnection` call should work - if (typeof hosts === 'string') { - return super.addConnection(hosts) - } - t.true(Array.isArray(hosts)) - } - nodesToHost (nodes) { t.ok('called') return [] @@ -622,23 +614,14 @@ test('sniff', t => { }) t.test('sniffOnConnectionFault', t => { - t.plan(4) + t.plan(3) class CustomConnectionPool extends ConnectionPool { - empty () { + update () { t.ok('called') return this } - addConnection (hosts) { - // the first `addConnection` call should work - if (typeof hosts === 'string') { - return super.addConnection(hosts) - } - - t.true(Array.isArray(hosts)) - } - nodesToHost (nodes) { t.ok('called') return [] @@ -683,17 +666,10 @@ test('sniff', t => { t.plan(9) class CustomConnectionPool extends ConnectionPool { - empty () { + update () { return this } - addConnection (hosts) { - // the first `addConnection` call should work - if (typeof hosts === 'string') { - return super.addConnection(hosts) - } - } - nodesToHost (nodes) { return [] } @@ -1360,3 +1336,46 @@ test('Warning header', t => { t.end() }) + +test('asHttpResponse enabled', t => { + t.plan(3) + function handler (req, res) { + res.setHeader('Content-Type', 'application/json;utf=8') + res.end(JSON.stringify({ hello: 'world' })) + } + + buildServer(handler, ({ port }, server) => { + const pool = new ConnectionPool() + pool.addConnection(`http://localhost:${port}`) + + const transport = new Transport({ + emit: () => {}, + connectionPool: pool, + serializer: new Serializer(), + maxRetries: 3, + requestTimeout: 30000, + sniffInterval: false, + sniffOnStart: false + }) + + transport.request({ + method: 'GET', + path: '/hello', + asHttpResponse: true + }, (err, response) => { + t.error(err) + t.match(response.headers, { + connection: 'keep-alive', + 'content-type': 'application/json;utf=8' + }) + + var payload = '' + response.setEncoding('utf8') + response.on('data', chunk => { payload += chunk }) + response.on('error', err => t.fail(err)) + response.on('end', () => { + t.deepEqual(JSON.parse(payload), { hello: 'world' }) + }) + }) + }) +})