Merging spenceralger:travis_and_coveralls. Summary of changes:

- removed several unneeded devDeps
- removed old get_spec.js script
- the client's ping method will now send back true as the body when the ping
  succceeds, and false when it does not. When the ping fails, the error will
  still be sent back and the connection's status will still be set to "dead".
- All of the client's methods now have a spec property, which will provide the
  JSON spec used to run that method.
- The yaml test runner will only camelCase param names that are documented, uses
  the client's method's new spec property
- Trace log events will now have their proper original query string parameters
- The "tracer" logger will now write to elasticsearch-tracer.log by default, and
  will truncate the file if it already exists.
- When running the integration tests, the client will now use a tracer logger which
  writes to stderr. The default level is "warning", but with the VERBOSE environment
  var it becomes "trace" and the logger will write to it's default file
- Added .idea to the .gitignore, it was being published to NPM
- Cleanup of the grunt tasks. Consilidated several tiny files into seperate moderately sized ones.
This commit is contained in:
Spencer Alger
2013-12-18 13:21:40 -07:00
parent 4c3bd0080d
commit 96b44ebf8b
25 changed files with 199 additions and 229 deletions

3
.gitignore vendored
View File

@ -5,6 +5,7 @@ node_modules
scripts/scratch*
test/integration/yaml_suite/log
.aws-config.json
.idea
## generated files
scripts/last_rest_spec_update.sha
@ -12,5 +13,5 @@ test/integration/browser_yaml_suite/yaml_tests.js
test/integration/yaml_suite/yaml_tests.json
junit-*.xml
test.log
elasticsearch.log
elasticsearch*.log
coverage.html

View File

@ -5,4 +5,6 @@ node_js:
services:
- elasticsearch
before_script:
- npm install -g grunt-cli
- npm install -g grunt-cli
script:
- grunt travis

View File

@ -1,6 +1,8 @@
# elasticsearch.js
The official low-level Elasticsearch client for Node.js and the browser. [![Build Status](https://build.elasticsearch.org/job/es-js_nightly/badge/icon)](https://build.elasticsearch.org/job/es-js_nightly/)
The official low-level Elasticsearch client for Node.js and the browser.
[![Build Status](https://travis-ci.org/elasticsearch/elasticsearch-js.png?branch=master)](https://travis-ci.org/elasticsearch/elasticsearch-js) [![Coverage Status](https://coveralls.io/repos/elasticsearch/elasticsearch-js/badge.png)](https://coveralls.io/r/elasticsearch/elasticsearch-js) [![Build Status](https://build.elasticsearch.org/job/es-js_nightly/badge/icon)](https://build.elasticsearch.org/job/es-js_nightly/)
## Features

69
grunt/browser_clients.js Normal file
View File

@ -0,0 +1,69 @@
module.exports = function (grunt) {
grunt.registerTask('browser_clients:test', [
'build',
'run:browser_unit_tests',
'run:browser_integration_tests'
]);
grunt.registerTask('browser_clients:build', [
'clean:dist',
'browserify',
'uglify:dist',
'concat:dist_banners'
]);
grunt.registerTask('browser_clients:publish', [
'browser_clients_build',
'compress:dist_zip',
'compress:dist_tarball',
's3:latest'
]);
grunt.registerTask('browser_clients:release', [
'prompt:confirm_release',
'__check_for_confirmation',
'browser_clients_build',
'compress:dist_zip',
'compress:dist_tarball',
's3:release'
]);
grunt.registerTask('__check_for_confirmation', function () {
if (grunt.config.get('confirm.release')) {
grunt.log.verbose.writeln('release confirmed');
} else {
throw new Error('Aborting release');
}
});
// grunt.registerTask('browser_clients:export_all', function () {
// grunt.task.run([
// 'build',
// 'export_client:angular:../bower-elasticsearch-angular',
// 'export_client::../bower-elasticsearch-browser',
// 'export_client:jquery:../bower-elasticsearch-jquery'
// ]);
// });
// grunt.registerTask('browser_clients:export_client', function (build, outDir) {
// var path = require('path');
// grunt.config.set('copy.export_client', {
// expand: true,
// cwd: './dist/',
// src: 'elasticsearch' + (build ? '.' + build : '') + '{.min,}.js',
// dest: outDir,
// rename: function (dest, src) {
// return path.join(dest, 'elasticsearch' + (~src.indexOf('.min') ? '.min' : '') + '.js');
// }
// });
// this.requires('build');
// grunt.task.run([
// 'copy:export_client'
// ]);
// });
};

View File

@ -1,8 +0,0 @@
module.exports = function (grunt) {
grunt.registerTask('browser_clients_build', [
'clean:dist',
'browserify',
'uglify:dist',
'concat:dist_banners'
]);
};

View File

@ -1,30 +0,0 @@
module.exports = function (grunt) {
grunt.registerTask('export_client', function (build, outDir) {
var path = require('path');
grunt.config.set('copy.export_client', {
expand: true,
cwd: './dist/',
src: 'elasticsearch' + (build ? '.' + build : '') + '{.min,}.js',
dest: outDir,
rename: function (dest, src) {
return path.join(dest, 'elasticsearch' + (~src.indexOf('.min') ? '.min' : '') + '.js');
}
});
this.requires('build');
grunt.task.run([
'copy:export_client'
]);
});
grunt.registerTask('export_all_clients', function () {
grunt.task.run([
'build',
'export_client:angular:../bower-elasticsearch-angular',
'export_client::../bower-elasticsearch-browser',
'export_client:jquery:../bower-elasticsearch-jquery'
]);
});
};

View File

@ -1,10 +0,0 @@
module.exports = function (grunt) {
grunt.registerTask('browser_clients_publish', [
'browser_clients_build',
'compress:dist_zip',
'compress:dist_tarball',
's3:latest'
]);
};

View File

@ -1,20 +0,0 @@
module.exports = function (grunt) {
grunt.registerTask('browser_clients_release', [
'prompt:confirm_release',
'check_for_confirmation',
'browser_clients_build',
'compress:dist_zip',
'compress:dist_tarball',
's3:release'
]);
grunt.registerTask('check_for_confirmation', function () {
if (grunt.config.get('confirm.release')) {
grunt.log.verbose.writeln('release confirmed');
} else {
throw new Error('Aborting release');
}
});
};

32
grunt/config/mochacov.js Normal file
View File

@ -0,0 +1,32 @@
var unitTests = ['test/unit/test_*.js'];
var integrationTests = ['test/integration/yaml_suite/index.js'];
module.exports = {
options: {
require: ['should']
},
coverage: {
src: unitTests,
options: {
reporter: 'mocha-lcov-reporter',
coveralls: {
serviceName: 'travis-ci',
repoToken: process.env.ESJS_COVERALS_REPO_TOKEN
}
}
},
unit: {
src: unitTests
},
integration: {
src: integrationTests
},
make_html_unit_cov: {
src: unitTests,
options: {
reporter: 'html-cov',
output: 'coverage.html'
}
},
};

View File

@ -2,24 +2,6 @@ module.exports = {
generate: {
exec: 'node scripts/generate'
},
unit_tests: {
exec: 'node scripts/run_tests --unit --no-browsers',
options: {
passArgs: [
'port',
'host'
]
}
},
integration_tests: {
exec: 'node scripts/run_tests --integration --no-browsers',
options: {
passArgs: [
'port',
'host'
]
}
},
browser_unit_tests: {
exec: 'node scripts/run_tests --unit --no-server',
options: {

View File

@ -7,7 +7,7 @@ module.exports = {
'Gruntfile.js'
],
tasks: [
// 'jshint',
'jshint',
'run:unit_tests'
],
options: {

View File

@ -1,9 +0,0 @@
module.exports = function (grunt) {
// Default task runs the build process.
grunt.registerTask('default', [
'run:generate',
'test'
]);
};

View File

@ -1,5 +0,0 @@
module.exports = function (grunt) {
grunt.registerTask('generate', [
'run:generate'
]);
};

29
grunt/tasks.js Normal file
View File

@ -0,0 +1,29 @@
module.exports = function (grunt) {
// Default task runs the build process.
grunt.registerTask('default', [
'generate',
'test'
]);
grunt.registerTask('generate', [
'run:generate'
]);
grunt.registerTask('test', [
'jshint',
'mochacov:unit',
'run:generate',
'mochacov:integration',
]);
grunt.registerTask('coverage', [
'mochacov:make_html_unit_cov',
'open:html_unit_cov'
]);
grunt.registerTask('travis', [
'test',
'mochacov:coverage'
]);
};

View File

@ -1,16 +0,0 @@
module.exports = function (grunt) {
grunt.registerTask('test', [
'jshint',
'run:unit_tests',
'run:generate',
'run:integration_tests'
]);
grunt.registerTask('browser_clients_test', [
'build',
'run:browser_unit_tests',
'run:browser_integration_tests'
]);
};

View File

@ -14,27 +14,21 @@
"./test/mocks/server.js": "./test/mocks/browser_server.js"
},
"devDependencies": {
"tar": "~0.1.18",
"mocha": "~1.14.0",
"async": "~0.2.9",
"mkdirp": "~0.3.5",
"moment": "~2.4.0",
"should": "~2.1.0",
"js-yaml": "~2.1.3",
"optimist": "~0.6.0",
"expect.js": "~0.2.0",
"minimatch": "~0.2.12",
"browserify": "~2.35.1",
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.7.1",
"grunt-mocha-test": "~0.7.0",
"grunt-browserify": "~1.2.11",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-uglify": "~0.2.7",
"grunt-contrib-concat": "~0.3.0",
"xmlbuilder": "~0.4.3",
"grunt-contrib-watch": "~0.5.3",
"coveralls": "~2.6.0",
"mocha-lcov-reporter": "0.0.1",
"blanket": "~1.1.5",
"sinon": "~1.7.3",
@ -48,9 +42,8 @@
"relative-fs": "0.0.1",
"grunt-contrib-compress": "~0.5.3",
"grunt-contrib-copy": "~0.4.1",
"grunt-mocha": "~0.4.7",
"grunt-prompt": "~0.1.2",
"readable-stream": "~1.1.9"
"grunt-mocha-cov": "~0.1.1"
},
"license": "Apache 2.0",
"dependencies": {

View File

@ -1,68 +0,0 @@
var EventEmitter = require('events').EventEmitter;
var Minimatch = require('minimatch').Minimatch;
var https = require('https');
var tar = require('tar');
var zlib = require('zlib');
var path = require('path');
var _ = require('lodash');
var url = require('url');
var tarUrl = 'https://github.com/elasticsearch/elasticsearch-rest-api-spec/tarball/master';
var topDir = null; // remove the lowest directory, which changes with each commit.
exports.get = function (pattern) {
var stream = new EventEmitter();
var matcher = new Minimatch(pattern);
var req = https.get(tarUrl, function receiveTarBall(incoming) {
if (incoming.statusCode !== 200) {
req.abort();
if (incoming.headers.location) {
req = https.get(_.extend(
url.parse(tarUrl),
url.parse(incoming.headers.location)
),
receiveTarBall
);
} else {
console.error('request failed', incoming.statusCode, incoming.headers);
}
} else {
incoming
.pipe(zlib.createGunzip())
.pipe(tar.Parse())
.on('entry', function (entry) {
if (!topDir) {
topDir = entry.path.split('/').shift();
}
entry.path = path.relative(topDir, entry.path);
if (matcher.match(entry.path)) {
collectData(entry);
} else {
entry.resume();
}
})
.on('end', function () {
stream.emit('end');
});
}
});
function collectData(entry) {
entry.data = '';
entry.on('data', onData);
entry.on('end', onEnd);
function onData(chunk) {
entry.data += chunk;
}
function onEnd() {
entry.removeListener('data', onData);
entry.removeListener('end', onEnd);
stream.emit('entry', entry);
}
}
return stream;
};

View File

@ -66,6 +66,7 @@ Client.prototype.ping = ca({
url: {
fmt: '/'
},
castExists: true,
requestTimeout: 100
});

View File

@ -16,7 +16,7 @@ function ClientAction(spec) {
spec.method = 'GET';
}
return function (params, cb) {
function action(params, cb) {
if (typeof params === 'function') {
cb = params;
params = {};
@ -34,7 +34,11 @@ function ClientAction(spec) {
return when.reject(e);
}
}
};
}
action.spec = spec;
return action;
}
var castType = {

View File

@ -271,12 +271,15 @@ Log.prototype.trace = function (method, requestUrl, body, responseBody, response
if (this.listenerCount('trace')) {
if (typeof requestUrl === 'string') {
requestUrl = url.parse(requestUrl, true, true);
} else if (requestUrl.path) {
requestUrl.query = url.parse(requestUrl.path, true, false).query;
}
requestUrl = _.defaults({
host: 'localhost:9200',
query: _.defaults({
query: _.defaults(requestUrl.query || {}, {
pretty: true
}, requestUrl.query)
})
}, requestUrl);
delete requestUrl.auth;

View File

@ -12,13 +12,20 @@
module.exports = Tracer;
var FileLogger = require('./file');
var StreamLogger = require('./stream');
var fs = require('fs');
var _ = require('../utils');
function Tracer(log, config) {
FileLogger.call(this, log, config);
if (config.path === false) {
config.stream = process.stderr;
} else {
config.stream = fs.createWriteStream(config.path || 'elasticsearch-tracer.log');
}
StreamLogger.call(this, log, config);
}
_.inherits(Tracer, FileLogger);
_.inherits(Tracer, StreamLogger);
Tracer.prototype.onTrace = _.handler(function (message, curlCall) {
this.write('TRACE', message, curlCall);

View File

@ -6,8 +6,7 @@ var defaults = {
clusterName: 'yaml-test-runner',
dataPath: '/tmp/yaml-test-runner',
host: 'localhost',
port: '9200',
match: '**'
port: '9200'
};
if (process.browser) {

View File

@ -1,4 +1,7 @@
if (process.browser) {
var BROWSER = process.env.browser;
var VERBOSE = process.env.VERBOSE;
if (BROWSER) {
/* jshint browser: true */
var es = window.elasticsearch;
} else {
@ -69,8 +72,15 @@ module.exports = {
}
],
log: {
type: process.browser ? 'console' : 'stdio',
level: process.env.VERBOSE ? 'trace' : 'warning'
type: BROWSER
? 'console'
: VERBOSE
? 'tracer'
: 'stdio',
level: VERBOSE
? 'trace'
: 'warning',
path: VERBOSE ? undefined : false
}
});

View File

@ -1,15 +1,12 @@
var path = require('path');
var async = require('async');
var jsYaml = require('js-yaml');
var expect = require('expect.js');
var YamlFile = require('./yaml_file');
var _ = require('../../../src/lib/utils');
var es = require('../../../src/elasticsearch');
var clientManager = require('./client_manager');
var Minimatch = require('minimatch').Minimatch;
var argv = require('./argv');
var testDir = path.resolve(__dirname, './tests');
var doPattern = new Minimatch(argv.match);
describe('integration', function () {
this.timeout(30000);
@ -30,9 +27,7 @@ describe('integration', function () {
});
var files = _.map(require('./yaml_tests.json'), function (docs, filename) {
if (doPattern.match(filename)) {
return new YamlFile(filename, docs);
}
return new YamlFile(filename, docs);
});
});

View File

@ -8,8 +8,8 @@
module.exports = YamlDoc;
var _ = require('../../../src/lib/utils');
var should = require('should');
var clientManager = require('./client_manager');
var expect = require('expect.js');
/**
* The version that ES is running, in comparable string form XXX-XXX-XXX, fetched when needed
@ -42,7 +42,7 @@ function getVersionFromES(done) {
if (err) {
throw new Error('unable to get info about ES');
}
expect(resp.version.number).to.match(versionRE);
should(resp.version.number).match(versionRE);
ES_VERSION = versionToComparableString(versionRE.exec(resp.version.number)[1]);
done();
});
@ -77,7 +77,7 @@ function versionToComparableString(version) {
*/
function rangeMatchesCurrentVersion(rangeString, done) {
function doWork() {
expect(rangeString).to.match(versionRangeRE);
should(rangeString).match(versionRangeRE);
var range = versionRangeRE.exec(rangeString);
range = _.map(_.last(range, 2), versionToComparableString);
@ -114,7 +114,7 @@ function YamlDoc(doc, file) {
var method = self['do_' + action.name];
// check that it's a function
expect(method).to.be.a('function');
should(method).have.type('function');
if (_.isPlainObject(action.args)) {
action.name += ' ' + _.keys(action.args).join(', ');
@ -306,11 +306,18 @@ YamlDoc.prototype = {
var action = Object.keys(args).pop();
var clientActionName = _.map(action.split('.'), _.camelCase).join('.');
var clientAction = this.get(clientActionName, client);
var params = _.transform(args[action], function (note, val, name) {
note[_.camelCase(name)] = (typeof val === 'string' && val[0] === '$') ? this.get(val) : val;
var params = _.transform(args[action], function (params, val, name) {
var camelName = _.camelCase(name);
// undocumented params should be passed through as-is
var paramName = name;
if (clientAction && clientAction.spec && clientAction.spec.params && clientAction.spec.params[camelName]) {
paramName = camelName;
}
params[paramName] = (typeof val === 'string' && val[0] === '$') ? this.get(val) : val;
}, {}, this);
expect(clientAction || clientActionName).to.be.a('function');
should(clientAction || clientActionName).have.type('function');
if (typeof clientAction === 'function') {
if (_.isNumeric(catcher)) {
@ -325,11 +332,11 @@ YamlDoc.prototype = {
if (catcher) {
if (catcher instanceof RegExp) {
// error message should match the regexp
expect(error.message).to.match(catcher);
should(error.message).match(catcher);
error = null;
} else if (typeof catcher === 'function') {
// error should be an instance of
expect(error).to.be.a(catcher);
should(error).be.an.instanceOf(catcher);
error = null;
} else {
return done(new Error('Invalid catcher ' + catcher));
@ -373,7 +380,7 @@ YamlDoc.prototype = {
* @return {undefined}
*/
do_is_true: function (path) {
expect(this.get(path)).to.be.ok;
should(Boolean(this.get(path))).equal(true, 'path: ' + path);
},
/**
@ -384,7 +391,7 @@ YamlDoc.prototype = {
* @return {undefined}
*/
do_is_false: function (path) {
expect(this.get(path)).to.not.be.ok;
should(Boolean(this.get(path))).equal(false, 'path: ' + path);
},
/**
@ -398,7 +405,7 @@ YamlDoc.prototype = {
if (val[0] === '$') {
val = this.get(val);
}
expect(this.get(path)).to.eql(val);
should(this.get(path)).eql(val, 'path: ' + path);
}, this);
},
@ -410,7 +417,7 @@ YamlDoc.prototype = {
*/
do_lt: function (args) {
_.forOwn(args, function (num, path) {
expect(this.get(path)).to.be.below(num);
should(this.get(path)).be.below(num, 'path: ' + path);
}, this);
},
@ -422,7 +429,7 @@ YamlDoc.prototype = {
*/
do_gt: function (args) {
_.forOwn(args, function (num, path) {
expect(this.get(path)).to.be.above(num);
should(this.get(path)).be.above(num, 'path: ' + path);
}, this);
},
@ -435,7 +442,7 @@ YamlDoc.prototype = {
*/
do_length: function (args) {
_.forOwn(args, function (len, path) {
expect(_.size(this.get(path))).to.be(len);
should(_.size(this.get(path))).eql(len, 'path: ' + path);
}, this);
}
};