From 477f1aff84bd8874e2d0627ff7f49667c47d2428 Mon Sep 17 00:00:00 2001 From: Spencer Alger Date: Mon, 25 Nov 2013 14:14:00 -0700 Subject: [PATCH] Fixed the integration tests, set the default method for indices.putTemplate and indices.putMapping to PUT --- docs/api.md | 1 + scripts/generate/js_api/actions.js | 40 ++++++++++++++----- scripts/run_tests.js | 12 ++++-- src/lib/api.js | 8 +++- src/lib/client_action.js | 3 +- src/lib/connection_pool.js | 9 +++-- src/lib/connectors/http.js | 2 + src/lib/host.js | 4 +- src/lib/transport.js | 5 ++- test/{unit => }/.jshintrc | 1 + test/integration/yaml_suite/client_manager.js | 6 +-- test/integration/yaml_suite/reporter.js | 2 +- test/integration/yaml_suite/yaml_file.js | 6 +-- 13 files changed, 70 insertions(+), 29 deletions(-) rename test/{unit => }/.jshintrc (99%) diff --git a/docs/api.md b/docs/api.md index 9e717ace2..6e00a85d9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -89,6 +89,7 @@ http://elasticsearch.org/guide/reference/api/bulk/ |`refresh` | Boolean | Refresh the index after performing the operation| |`[replication=sync]` | String | Explicitely set the replication type| |`type` | String | Default document type for items which don't provide one| +|`timeout` | Date or Number | Explicit operation timeout| |`index` | String | Default index for items which don't provide one| diff --git a/scripts/generate/js_api/actions.js b/scripts/generate/js_api/actions.js index 0ccab70e1..833eb2c22 100644 --- a/scripts/generate/js_api/actions.js +++ b/scripts/generate/js_api/actions.js @@ -119,8 +119,8 @@ function transformFile(entry) { .replace(/(^|\.)(delete|default)(\.|$)/g, '[\'$2\']'); var action = { + _methods: spec.methods, spec: _.pick(spec, [ - 'methods', 'params', 'url', 'urls', @@ -137,7 +137,7 @@ function transformFile(entry) { function hasMethod(/* ...methods */) { for (var i = 0; i < arguments.length; i++) { - if (~action.spec.methods.indexOf(arguments[i])) { + if (~action._methods.indexOf(arguments[i])) { continue; } else { return false; @@ -146,13 +146,13 @@ function transformFile(entry) { return true; } function methodsAre(/* ...methods */) { - return hasMethod.apply(null, arguments) && arguments.length === action.spec.methods.length; + return hasMethod.apply(null, arguments) && arguments.length === action._methods.length; } var method; - if (action.spec.methods.length === 1) { - method = action.spec.methods[0]; + if (action._methods.length === 1) { + method = action._methods[0]; } else { // we need to define what the default method(s) will be if (hasMethod('DELETE', 'POST')) { @@ -162,7 +162,7 @@ function transformFile(entry) { method = 'DELETE'; } else if (methodsAre('POST', 'PUT')) { - method = 'POST'; + method = action.name.match(/put/i) ? 'PUT' : 'POST'; } else if (methodsAre('GET', 'POST')) { method = 'POST'; @@ -180,7 +180,6 @@ function transformFile(entry) { if (method !== 'GET') { action.spec.method = method; } - delete action.spec.methods; } else { throw new Error('unable to pick a method for ' + JSON.stringify(action, null, ' ')); } @@ -191,9 +190,32 @@ function transformFile(entry) { } if (actions.push(action) === specCount && doneParsing) { - module.exports.emit('ready', action); + module.exports.emit('ready', actions); } }); } -module.exports = new EventEmitter(); +/** + * un-comment to print out the default method for any action that has multiple options + */ +// module.exports = new EventEmitter(); +// module.exports.on('ready', function (actions) { +// var longestName = 0; +// var lines = []; +// actions.forEach(function (action) { +// // console.log(action); +// if (action._methods.length > 1) { +// var name = action.name + ' (' + action._methods.join('/') + ')'; +// longestName = Math.max(name.length, longestName); +// lines.push([name, action.spec.method || 'GET', action.docUrl]); +// } +// }); + +// lines.forEach(function (line) { +// var name = line[0]; +// var def = line[1]; +// var docUrl = line[2]; +// var spacing = (new Array(longestName - name.length + 1)).join(' '); +// console.log(name + spacing + ' [' + def + (def.length === 3 ? ' ' : '') + '] -> ' + docUrl); +// }); +// }); diff --git a/scripts/run_tests.js b/scripts/run_tests.js index 578252a7b..dc6f0ba8a 100644 --- a/scripts/run_tests.js +++ b/scripts/run_tests.js @@ -1,6 +1,7 @@ var async = require('async'); var cp = require('child_process'); var chalk = require('chalk'); +var path = require('path'); var argv = require('optimist') .usage([ 'Runner for the Elasticsearch.js unit and integration tests in both node and the browser.', @@ -13,6 +14,7 @@ var argv = require('optimist') integration: false, host: 'localhost', port: 9200, + 'xml-output': true, 'check-upstream': false }) .describe({ @@ -24,6 +26,7 @@ var argv = require('optimist') i: 'integration', b: 'browser', s: 'server', + x: 'xml-output' }); if (process.argv.indexOf('help') + process.argv.indexOf('--help') + process.argv.indexOf('-h') !== -3) { @@ -65,10 +68,11 @@ if (argv.integration) { 'mocha', 'test/integration/yaml_suite/index.js', '-b', - '--require=should', - '--host=' + argv.host, - '--port=' + argv.port - ]); + '--require', 'should', + argv.x ? '--reporter' : '', argv.x ? path.join(__dirname, '../test/integration/yaml_suite/reporter.js') : '', + '--host', argv.host, + '--port', argv.port + ].filter(Boolean)); } if (argv.browser) { commands.push(['node', 'scripts/run_browser_integration_suite/index.js']); diff --git a/src/lib/api.js b/src/lib/api.js index 20a6e804e..5ba0e113a 100644 --- a/src/lib/api.js +++ b/src/lib/api.js @@ -13,6 +13,7 @@ api._namespaces = ['cluster', 'indices']; * @param {Boolean} params.refresh - Refresh the index after performing the operation * @param {String} [params.replication=sync] - Explicitely set the replication type * @param {String} params.type - Default document type for items which don't provide one + * @param {Date or Number} params.timeout - Explicit operation timeout * @param {String} params.index - Default index for items which don't provide one */ api.bulk = ca({ @@ -38,6 +39,9 @@ api.bulk = ca({ }, type: { type: 'string' + }, + timeout: { + type: 'time' } }, urls: [ @@ -2119,7 +2123,7 @@ api.indices.prototype.putMapping = ca({ }, sortOrder: -2 }, - method: 'POST' + method: 'PUT' }); @@ -2185,7 +2189,7 @@ api.indices.prototype.putTemplate = ca({ }, sortOrder: -1 }, - method: 'POST' + method: 'PUT' }); diff --git a/src/lib/client_action.js b/src/lib/client_action.js index caf179f5c..a13f1524d 100644 --- a/src/lib/client_action.js +++ b/src/lib/client_action.js @@ -65,7 +65,8 @@ var castType = { switch (typeof val) { case 'number': case 'string': - return val; + case 'boolean': + return '' + val; case 'object': if (_.isArray(val)) { return val.join(','); diff --git a/src/lib/connection_pool.js b/src/lib/connection_pool.js index a5add3553..3168bc38b 100644 --- a/src/lib/connection_pool.js +++ b/src/lib/connection_pool.js @@ -20,8 +20,11 @@ function ConnectionPool(config) { this.log = new Log(); } + this._config = config; + // get the selector config var - this.selector = _.funcEnum(config, 'selector', ConnectionPool.selectors, ConnectionPool.defaultSelectors); + this.selector = _.funcEnum(config, 'selector', ConnectionPool.selectors, ConnectionPool.defaultSelector); + // get the connection class this.Connection = _.funcEnum(config, 'connectionClass', ConnectionPool.connectionClasses, ConnectionPool.defaultConnectionClass); @@ -37,7 +40,7 @@ function ConnectionPool(config) { // selector options ConnectionPool.selectors = require('./selectors'); -ConnectionPool.defaultSelectors = 'round_robin'; +ConnectionPool.defaultSelector = 'roundRobin'; // get the connection options ConnectionPool.connectionClasses = require('./connectors'); @@ -154,7 +157,7 @@ ConnectionPool.prototype.setHosts = function (hosts) { if (this.index[id]) { delete toRemove[id]; } else { - connection = new this.Connection(host); + connection = new this.Connection(host, this._config); connection.id = id; this.addConnection(connection); } diff --git a/src/lib/connectors/http.js b/src/lib/connectors/http.js index 75123a05d..83f90e458 100644 --- a/src/lib/connectors/http.js +++ b/src/lib/connectors/http.js @@ -19,6 +19,8 @@ var qs = require('querystring'); var KeepAliveAgent = require('agentkeepalive'); var ConnectionAbstract = require('../connection'); +var log = _.bindKey(process.stdout, 'write'); + /** * Connector used to talk to an elasticsearch node via HTTP * diff --git a/src/lib/host.js b/src/lib/host.js index 956f7be9c..50b147c7a 100644 --- a/src/lib/host.js +++ b/src/lib/host.js @@ -28,6 +28,7 @@ function Host(config) { // defaults this.protocol = 'http'; this.host = 'localhost'; + this.path = ''; this.port = 9200; this.auth = null; this.query = null; @@ -75,8 +76,7 @@ function Host(config) { } // make sure the path starts with a leading slash - // and that empty paths convert to '/' - if (!this.path || this.path.charAt(0) !== '/') { + if (this.path && this.path.charAt(0) !== '/') { this.path = '/' + (this.path || ''); } diff --git a/src/lib/transport.js b/src/lib/transport.js index a72acd0f5..530f4bb71 100644 --- a/src/lib/transport.js +++ b/src/lib/transport.js @@ -28,6 +28,9 @@ function Transport(config) { var Serializer = _.funcEnum(config, 'serializer', Transport.serializers, 'json'); this.serializer = new Serializer(config); + // setup max retries + this.maxRetries = config.hasOwnProperty('maxRetries') ? config.maxRetries : 3; + if (config.hosts) { var hostsConfig = _.createArray(config.hosts, function (val) { if (_.isPlainObject(val) || _.isString(val)) { @@ -130,7 +133,7 @@ Transport.prototype.request = function (params, cb) { self.connectionPool.select(sendReqWithConnection); } else { self.log.info('Request complete'); - respond(err, body, status); + respond(err ? new errors.ConnectionFault() : void 0, body, status); } } diff --git a/test/unit/.jshintrc b/test/.jshintrc similarity index 99% rename from test/unit/.jshintrc rename to test/.jshintrc index a49cab70f..ef050dd78 100644 --- a/test/unit/.jshintrc +++ b/test/.jshintrc @@ -1,3 +1,4 @@ + { "node": true, "white": true, diff --git a/test/integration/yaml_suite/client_manager.js b/test/integration/yaml_suite/client_manager.js index f51d6db49..d87bbde50 100644 --- a/test/integration/yaml_suite/client_manager.js +++ b/test/integration/yaml_suite/client_manager.js @@ -6,8 +6,8 @@ if (process.browser) { } var argv = require('./argv'); var server = require('./server'); -var path = require('path'); -var fs = require('fs'); +// var path = require('path'); +// var fs = require('fs'); var _ = require('../../../src/lib/utils'); // current client @@ -38,7 +38,7 @@ module.exports = { doCreateClient(function () { client.ping(function (err) { if (err instanceof es.errors.ConnectionFault) { - externalExists = !err; + externalExists = false; create(done); } else { done(err); diff --git a/test/integration/yaml_suite/reporter.js b/test/integration/yaml_suite/reporter.js index 35df4358a..b0ec13032 100644 --- a/test/integration/yaml_suite/reporter.js +++ b/test/integration/yaml_suite/reporter.js @@ -112,7 +112,7 @@ function EsjsReporter(runner) { runner.on('end', function () { restoreStdio(); - var outputFilename = path.join(__dirname, '../../test-output-node-yaml.xml'); + var outputFilename = path.join(__dirname, '../../../test-output-node-yaml.xml'); var xml = makeJUnitXml('node ' + process.version + ' yaml tests', { stats: stats, suites: _.map(rootSuite.suites, function removeElements(suite) { diff --git a/test/integration/yaml_suite/yaml_file.js b/test/integration/yaml_suite/yaml_file.js index 258da0c85..23a96e3f0 100644 --- a/test/integration/yaml_suite/yaml_file.js +++ b/test/integration/yaml_suite/yaml_file.js @@ -20,19 +20,19 @@ function YamlFile(filename, docs) { doc = new YamlDoc(doc, file); if (doc.description === 'setup') { beforeEach(/* doc */function (done) { - // console.log('setting up:', filename); + console.log('setting up:', filename); async.series(_.pluck(doc._actions, 'testable'), done); }); } else { it(doc.description, function (done) { - // console.log('test doc'); + console.log('test doc'); async.series(_.pluck(doc._actions, 'testable'), done); }); } }); afterEach(/* doc */function (done) { - // console.log('clearing indices'); + console.log('clearing indices'); clientManager.get().indices.delete({ index: '*', ignore: 404