mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Merge branch 'master' into implement/betterErrorReading
This commit is contained in:
commit
43ee9e8d22
37 changed files with 439 additions and 593 deletions
|
@ -21,5 +21,4 @@ if [ ! -x "$NODE" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
exec "${NODE}" "${DIR}/src/cli" ${@}
|
||||
|
||||
exec "${NODE}" $NODE_OPTIONS "${DIR}/src/cli" ${@}
|
||||
|
|
|
@ -18,7 +18,7 @@ If Not Exist "%NODE%" (
|
|||
)
|
||||
|
||||
TITLE Kibana Server
|
||||
"%NODE%" "%DIR%\src\cli" %*
|
||||
"%NODE%" %NODE_OPTIONS% "%DIR%\src\cli" %*
|
||||
|
||||
:finally
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ module.exports = function (kibana) {
|
|||
key: Joi.string()
|
||||
}).default(),
|
||||
apiVersion: Joi.string().default('2.0'),
|
||||
minimumVersion: Joi.string().default('2.1.0')
|
||||
engineVersion: Joi.string().valid('^2.1.0').default('^2.1.0')
|
||||
}).default();
|
||||
},
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ describe('plugins/elasticsearch', function () {
|
|||
var plugin;
|
||||
|
||||
beforeEach(function () {
|
||||
var get = sinon.stub().withArgs('elasticserach.minimumVersion').returns('1.4.3');
|
||||
var get = sinon.stub().withArgs('elasticsearch.engineVersion').returns('^1.4.3');
|
||||
var config = function () { return { get: get }; };
|
||||
server = {
|
||||
log: _.noop,
|
||||
|
|
|
@ -55,7 +55,7 @@ describe('plugins/elasticsearch', function () {
|
|||
});
|
||||
|
||||
it('should set the cluster green if everything is ready', function () {
|
||||
get.withArgs('elasticsearch.minimumVersion').returns('1.4.4');
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
client.cluster.health.returns(Promise.resolve({ timed_out: false, status: 'green' }));
|
||||
|
@ -74,7 +74,7 @@ describe('plugins/elasticsearch', function () {
|
|||
it('should set the cluster red if the ping fails, then to green', function () {
|
||||
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.minimumVersion').returns('1.4.4');
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.onCall(0).returns(Promise.reject(new NoConnections()));
|
||||
client.ping.onCall(1).returns(Promise.resolve());
|
||||
|
@ -98,7 +98,7 @@ describe('plugins/elasticsearch', function () {
|
|||
|
||||
it('should set the cluster red if the health check status is red, then to green', function () {
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.minimumVersion').returns('1.4.4');
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
client.cluster.health.onCall(0).returns(Promise.resolve({ timed_out: false, status: 'red' }));
|
||||
|
@ -121,7 +121,7 @@ describe('plugins/elasticsearch', function () {
|
|||
|
||||
it('should set the cluster yellow if the health check timed_out and create index', function () {
|
||||
get.withArgs('elasticsearch.url').returns('http://localhost:9210');
|
||||
get.withArgs('elasticsearch.minimumVersion').returns('1.4.4');
|
||||
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
|
||||
get.withArgs('kibana.index').returns('.my-kibana');
|
||||
client.ping.returns(Promise.resolve());
|
||||
client.cluster.health.onCall(0).returns(Promise.resolve({ timed_out: true, status: 'red' }));
|
||||
|
|
|
@ -1,134 +0,0 @@
|
|||
var _ = require('lodash');
|
||||
var versionMath = require('../version_math');
|
||||
var expect = require('expect.js');
|
||||
var versions = [
|
||||
'1.1.12',
|
||||
'1.1.12',
|
||||
'1.1.12',
|
||||
'1.1.12',
|
||||
'0.90.0',
|
||||
'0.90.1',
|
||||
'1.0.0',
|
||||
'1.0',
|
||||
'1.2.3',
|
||||
'2.0.0',
|
||||
'2.0.1',
|
||||
'2.3.1'
|
||||
];
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('lib/version_math', function () {
|
||||
describe('version math (0.90.0 - 2.3.1)', function () {
|
||||
var methods = 'max,min,eq,is,lt,lte,gt,gte'.split(',');
|
||||
describe('methods', function () {
|
||||
it('should have ' + methods.join(', ') + ' methods', function () {
|
||||
_.each(methods, function (method) {
|
||||
expect(versionMath[method]).to.be.a(Function);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('min & max', function () {
|
||||
it('has a max of 2.3.1', function () {
|
||||
expect(versionMath.max(versions)).to.be('2.3.1');
|
||||
});
|
||||
|
||||
it('has a min of 0.90.0', function () {
|
||||
expect(versionMath.min(versions)).to.be('0.90.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('eq / lowest version', function () {
|
||||
it('should be true for 0.90.0', function () {
|
||||
expect(versionMath.eq('0.90.0', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('should be false for 1.0', function () {
|
||||
expect(versionMath.eq('1.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gt / lowest version', function () {
|
||||
it('is > 0.20.3', function () {
|
||||
expect(versionMath.gt('0.20.3', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not > 0.90.0', function () {
|
||||
expect(versionMath.gt('0.90.0', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is not > 1.0.0', function () {
|
||||
expect(versionMath.gt('1.0.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gte / lowest version', function () {
|
||||
it('is >= 0.20.3', function () {
|
||||
expect(versionMath.gte('0.20.3', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is >= 0.90.0', function () {
|
||||
expect(versionMath.gte('0.90.0', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not >= 1.0.0', function () {
|
||||
expect(versionMath.gte('1.0.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lt / highest version', function () {
|
||||
it('is not < 0.20.3', function () {
|
||||
expect(versionMath.lt('0.20.3', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is not < 2.3.1', function () {
|
||||
expect(versionMath.lt('2.3.1', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is < 2.5', function () {
|
||||
expect(versionMath.lt('2.5', versions)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lte / highest version', function () {
|
||||
it('is not =< 0.20.3', function () {
|
||||
expect(versionMath.lte('0.20.3', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is =< 2.3.1', function () {
|
||||
expect(versionMath.lte('2.3.1', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is =< 2.5', function () {
|
||||
expect(versionMath.lte('2.5', versions)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('is', function () {
|
||||
it('exactly, <, <=, >, >=', function () {
|
||||
expect(versionMath.is('0.90.0', versions)).to.be(true);
|
||||
expect(versionMath.is('0.20.0', versions)).to.be(false);
|
||||
|
||||
expect(versionMath.is('>0.20.0', versions)).to.be(true);
|
||||
expect(versionMath.is('>0.90.0', versions)).to.be(false);
|
||||
expect(versionMath.is('>0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionMath.is('>=0.20.0', versions)).to.be(true);
|
||||
expect(versionMath.is('>=0.90.0', versions)).to.be(true);
|
||||
expect(versionMath.is('>=0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionMath.is('<2.5', versions)).to.be(true);
|
||||
expect(versionMath.is('<2.3.1', versions)).to.be(false);
|
||||
expect(versionMath.is('<0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionMath.is('<=2.5', versions)).to.be(true);
|
||||
expect(versionMath.is('<=2.3.1', versions)).to.be(true);
|
||||
expect(versionMath.is('<=0.90.1', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
45
src/plugins/elasticsearch/lib/__tests__/version_satisfies.js
Normal file
45
src/plugins/elasticsearch/lib/__tests__/version_satisfies.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
var versionSatisfies = require('../version_satisfies');
|
||||
var expect = require('expect.js');
|
||||
|
||||
var versionChecks = [
|
||||
// order is: ['actual version', 'match expression', satisfied (true/false)]
|
||||
['0.90.0', '>=0.90.0', true],
|
||||
['1.2.0', '>=1.2.1 <2.0.0', false],
|
||||
['1.2.1', '>=1.2.1 <2.0.0', true],
|
||||
['1.4.4', '>=1.2.1 <2.0.0', true],
|
||||
['1.7.4', '>=1.3.1 <2.0.0', true],
|
||||
['2.0.0', '>=1.3.1 <2.0.0', false],
|
||||
['1.4.3', '^1.4.3', true],
|
||||
['1.4.3-Beta1', '^1.4.3', true],
|
||||
['1.4.4', '^1.4.3', true],
|
||||
['1.1.12', '^1.0.0', true],
|
||||
['1.1.12', '~1.0.0', false],
|
||||
['1.6.1-SNAPSHOT', '1.6.1', true],
|
||||
['1.6.1-SNAPSHOT', '1.6.2', false],
|
||||
['1.7.1-SNAPSHOT', '^1.3.1', true],
|
||||
['1.3.4', '^1.4.0', false],
|
||||
['2.0.1', '^2.0.0', true],
|
||||
['2.1.1', '^2.1.0', true],
|
||||
['2.2.0', '^2.1.0', true],
|
||||
['3.0.0-snapshot', '^2.1.0', false],
|
||||
['3.0.0', '^2.1.0', false],
|
||||
['2.10.20-snapshot', '^2.10.20', true],
|
||||
['2.10.999', '^2.10.20', true],
|
||||
];
|
||||
|
||||
describe('plugins/elasticsearch', function () {
|
||||
describe('lib/version_satisfies', function () {
|
||||
versionChecks.forEach(function (spec) {
|
||||
var actual = spec[0];
|
||||
var match = spec[1];
|
||||
var satisfied = spec[2];
|
||||
var desc = actual + ' satisfies ' + match;
|
||||
|
||||
describe(desc, function () {
|
||||
it('should be ' + satisfied, function () {
|
||||
expect(versionSatisfies(actual, match)).to.be(satisfied);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,13 +1,13 @@
|
|||
var _ = require('lodash');
|
||||
var esBool = require('./es_bool');
|
||||
var versionMath = require('./version_math');
|
||||
var versionSatisfies = require('./version_satisfies');
|
||||
var SetupError = require('./setup_error');
|
||||
|
||||
module.exports = function (server) {
|
||||
server.log(['plugin', 'debug'], 'Checking Elasticsearch version');
|
||||
|
||||
var client = server.plugins.elasticsearch.client;
|
||||
var minimumElasticsearchVersion = server.config().get('elasticsearch.minimumVersion');
|
||||
var engineVersion = server.config().get('elasticsearch.engineVersion');
|
||||
|
||||
return client.nodes.info()
|
||||
.then(function (info) {
|
||||
|
@ -18,9 +18,8 @@ module.exports = function (server) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// remove nodes that are gte the min version
|
||||
var v = node.version.split('-')[0];
|
||||
return !versionMath.gte(minimumElasticsearchVersion, v);
|
||||
// remove nodes that satify required engine version
|
||||
return !versionSatisfies(node.version, engineVersion);
|
||||
});
|
||||
|
||||
if (!badNodes.length) return true;
|
||||
|
@ -30,7 +29,7 @@ module.exports = function (server) {
|
|||
});
|
||||
|
||||
var message = `This version of Kibana requires Elasticsearch ` +
|
||||
`${minimumElasticsearchVersion} or higher on all nodes. I found ` +
|
||||
`${engineVersion} on all nodes. I found ` +
|
||||
`the following incompatible nodes in your cluster: ${badNodeNames.join(',')}`;
|
||||
|
||||
throw new SetupError(server, message);
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
var _ = require('lodash');
|
||||
|
||||
function VersionMathException(message) {
|
||||
this.message = message;
|
||||
this.name = 'VersionMathException';
|
||||
}
|
||||
|
||||
// Determine if a specific version meets the minimum requirement
|
||||
var compare = function (required, installed) {
|
||||
if (_.isUndefined(installed)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!required || !installed) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var a = installed.split('.');
|
||||
var b = required.split('.');
|
||||
var i;
|
||||
|
||||
// leave suffixes as is ("RC1 or -SNAPSHOT")
|
||||
for (i = 0; i < Math.min(a.length, 3); ++i) {
|
||||
a[i] = Number(a[i]);
|
||||
}
|
||||
for (i = 0; i < Math.min(b.length, 3); ++i) {
|
||||
b[i] = Number(b[i]);
|
||||
}
|
||||
if (a.length === 2) {
|
||||
a[2] = 0;
|
||||
}
|
||||
|
||||
if (a[0] > b[0]) { return true; }
|
||||
if (a[0] < b[0]) { return false; }
|
||||
|
||||
if (a[1] > b[1]) { return true; }
|
||||
if (a[1] < b[1]) { return false; }
|
||||
|
||||
if (a[2] > b[2]) { return true; }
|
||||
if (a[2] < b[2]) { return false; }
|
||||
|
||||
if (a.length > 3) {
|
||||
// rc/beta suffix
|
||||
if (b.length <= 3) {
|
||||
return false;
|
||||
} // no suffix on b -> a<b
|
||||
return a[3] >= b[3];
|
||||
}
|
||||
if (b.length > 3) {
|
||||
// b has a suffix but a not -> a>b
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Sort versions from lowest to highest
|
||||
var sortVersions = function (versions) {
|
||||
if (!_.isArray(versions)) versions = [versions];
|
||||
|
||||
return _.uniq(versions).sort(function (a, b) {
|
||||
return compare(a, b) ? -1 : 1;
|
||||
});
|
||||
};
|
||||
|
||||
// Get the max version in this cluster
|
||||
var max = function (versions) {
|
||||
return sortVersions(versions).pop();
|
||||
};
|
||||
|
||||
// Return the lowest version in the cluster
|
||||
var min = function (versions) {
|
||||
return sortVersions(versions).shift();
|
||||
};
|
||||
|
||||
// Check if the lowest version in the cluster is >= to `version`
|
||||
var gte = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return compare(version, min(_versions));
|
||||
};
|
||||
|
||||
// Check if the highest version in the cluster is <= to `version`
|
||||
var lte = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return compare(max(_versions), version);
|
||||
};
|
||||
|
||||
// check if lowest version in cluster = `version`
|
||||
var eq = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === min(_versions) ? true : false;
|
||||
};
|
||||
|
||||
// version > lowest version in cluster?
|
||||
var gt = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === min(_versions) ? false : gte(version, _versions);
|
||||
};
|
||||
|
||||
// version < highest version in cluster?
|
||||
var lt = function (version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === max(_versions) ? false : lte(version, _versions);
|
||||
};
|
||||
|
||||
/*
|
||||
Takes a version string with one of the following optional comparison prefixes: >,>=,<.<=
|
||||
and evaluates if the cluster meets the requirement. If the prefix is omitted exact match
|
||||
is assumed
|
||||
*/
|
||||
var is = function (equation, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
var _v = equation;
|
||||
var _cf;
|
||||
|
||||
if (_v.charAt(0) === '>') {
|
||||
_cf = _v.charAt(1) === '=' ? gte(_v.slice(2), _versions) : gt(_v.slice(1), _versions);
|
||||
} else if (_v.charAt(0) === '<') {
|
||||
_cf = _v.charAt(1) === '=' ? lte(_v.slice(2), _versions) : lt(_v.slice(1), _versions);
|
||||
} else {
|
||||
_cf = eq(_v, _versions);
|
||||
}
|
||||
|
||||
return _cf;
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
min: min,
|
||||
max: max,
|
||||
is: is,
|
||||
eq: eq,
|
||||
gt: gt,
|
||||
gte: gte,
|
||||
lt: lt,
|
||||
lte: lte
|
||||
};
|
||||
|
16
src/plugins/elasticsearch/lib/version_satisfies.js
Normal file
16
src/plugins/elasticsearch/lib/version_satisfies.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
var semver = require('semver');
|
||||
|
||||
module.exports = function (actual, expected) {
|
||||
try {
|
||||
var ver = cleanVersion(actual);
|
||||
return semver.satisfies(ver, expected);
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function cleanVersion(version) {
|
||||
var match = version.match(/\d+\.\d+\.\d+/);
|
||||
if (!match) return version;
|
||||
return match[0];
|
||||
}
|
||||
};
|
|
@ -1,9 +1,9 @@
|
|||
<div class="app-container">
|
||||
<nav class="navbar navbar-default navbar-static-top subnav">
|
||||
<nav class="navbar navbar-default navbar-static-top subnav" data-test-subj="settingsNav">
|
||||
<div class="container-fluid">
|
||||
<ul class="nav navbar-nav">
|
||||
<li ng-repeat="section in sections" ng-class="section.class">
|
||||
<a class="navbar-link" kbn-href="{{section.url}}">{{section.display}}</a>
|
||||
<a class="navbar-link" kbn-href="{{section.url}}" data-test-subj="{{section.name}}">{{section.display}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<tr ng-class="conf.value === undefined ? 'default' : 'custom'">
|
||||
<tr ng-class="conf.value === undefined ? 'default' : 'custom'" data-test-subj="advancedSetting {{conf.name}}" >
|
||||
<td class="name">
|
||||
<b>{{conf.name}}</b>
|
||||
<span class="smaller" ng-show="!conf.isCustom && conf.value !== undefined">
|
||||
|
@ -59,12 +59,13 @@
|
|||
name="conf.name"
|
||||
ng-model="conf.unsavedValue"
|
||||
ng-options="option as option for option in conf.options"
|
||||
class="form-control">
|
||||
class="form-control"
|
||||
data-test-subj="selectInput">
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<!-- Setting display formats -->
|
||||
<span ng-if="!conf.editting">
|
||||
<span ng-if="!conf.editting" data-test-subj="currentValue">
|
||||
<span ng-show="(conf.normal || conf.json || conf.select)">{{conf.value || conf.defVal}}</span>
|
||||
<span ng-show="conf.array">{{(conf.value || conf.defVal).join(', ')}}</span>
|
||||
<span ng-show="conf.bool">{{conf.value === undefined ? conf.defVal : conf.value}}</span>
|
||||
|
@ -77,7 +78,8 @@
|
|||
ng-click="edit(conf)"
|
||||
class="btn btn-default"
|
||||
ng-disabled="conf.tooComplex"
|
||||
aria-label="Edit">
|
||||
aria-label="Edit"
|
||||
data-test-subj="editButton">
|
||||
<span class="sr-only">Edit</span>
|
||||
<i aria-hidden="true" class="fa fa-pencil"></i>
|
||||
</button>
|
||||
|
@ -87,7 +89,8 @@
|
|||
ng-click="save(conf)"
|
||||
class="btn btn-success"
|
||||
ng-disabled="conf.loading || conf.tooComplex || forms.configEdit.$invalid"
|
||||
aria-label="Save">
|
||||
aria-label="Save"
|
||||
data-test-subj="saveButton">
|
||||
<span class="sr-only">Save</span>
|
||||
<i aria-hidden="true" ng-if="!conf.loading" class="fa fa-save"></i>
|
||||
<i aria-hidden="true" ng-if="conf.loading" class="fa fa-spinner"></i>
|
||||
|
@ -98,7 +101,8 @@
|
|||
ng-click="clear(conf)"
|
||||
ng-hide="conf.value === undefined"
|
||||
class="btn btn-danger"
|
||||
aria-label="Clear">
|
||||
aria-label="Clear"
|
||||
data-test-subj="clearButton">
|
||||
<span class="sr-only">Clear</span>
|
||||
<i aria-hidden="true" class="fa fa-trash-o"></i>
|
||||
</button>
|
||||
|
@ -107,7 +111,8 @@
|
|||
ng-if="conf.editting"
|
||||
ng-click="cancelEdit(conf)"
|
||||
class="btn btn-default"
|
||||
aria-label="Cancel edit">
|
||||
aria-label="Cancel edit"
|
||||
data-test-subj="cancelButton">
|
||||
<span class="sr-only">Cancel Edit</span>
|
||||
<i aria-hidden="true" class="fa fa-times"></i>
|
||||
</button>
|
||||
|
|
|
@ -4,7 +4,9 @@ import KbnServer from '../../KbnServer';
|
|||
describe('cookie validation', function () {
|
||||
let kbnServer;
|
||||
beforeEach(function () {
|
||||
kbnServer = new KbnServer();
|
||||
kbnServer = new KbnServer({
|
||||
server: { autoListen: false }
|
||||
});
|
||||
return kbnServer.ready();
|
||||
});
|
||||
afterEach(function () {
|
||||
|
|
|
@ -93,7 +93,12 @@ define(function (require) {
|
|||
ignore_unavailable: true,
|
||||
preference: sessionId,
|
||||
body: body
|
||||
}));
|
||||
}))
|
||||
.catch(function (err) {
|
||||
return strategy.handleResponseError
|
||||
? strategy.handleResponseError(executable, err)
|
||||
: Promise.reject(err);
|
||||
});
|
||||
})
|
||||
.then(function (clientResp) {
|
||||
return strategy.getResponses(clientResp);
|
||||
|
|
|
@ -31,6 +31,57 @@ describe('ui/courier/fetch/strategy/search', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#handleResponseError()', () => {
|
||||
let error;
|
||||
beforeEach(() => {
|
||||
error = { status: 404, body: { error: { index: '[-*]' } } };
|
||||
});
|
||||
|
||||
it('recovers 404 for index -* with empty response', () => {
|
||||
let resp;
|
||||
search.handleResponseError(reqsFetchParams, error).then(val => resp = val);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(resp.responses).not.to.be(undefined);
|
||||
});
|
||||
|
||||
it('mocks all of the bundled searches', () => {
|
||||
let resp;
|
||||
reqsFetchParams.push({});
|
||||
search.handleResponseError(reqsFetchParams, error).then(val => resp = val);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(Array.isArray(resp.responses)).to.be(true);
|
||||
expect(resp.responses.length).to.be(2);
|
||||
resp.responses.forEach(res => {
|
||||
expect(res.hits.total).to.be(0);
|
||||
expect(res.hits.hits.length).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
context('when not a 404', () => {
|
||||
it('rejects with the original response', () => {
|
||||
error.status = 403;
|
||||
let err;
|
||||
search.handleResponseError(reqsFetchParams, error).catch(val => err = val);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(err).to.be(error);
|
||||
});
|
||||
});
|
||||
|
||||
context('when not for -* index', () => {
|
||||
it('rejects with the original response', () => {
|
||||
error.body.error.index = '[foo-*]';
|
||||
let err;
|
||||
search.handleResponseError(reqsFetchParams, error).catch(val => err = val);
|
||||
$rootScope.$apply();
|
||||
|
||||
expect(err).to.be(error);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#reqsFetchParamsToBody()', () => {
|
||||
it('filters out any body properties that begin with $', () => {
|
||||
let value;
|
||||
|
|
|
@ -4,9 +4,32 @@ define(function (require) {
|
|||
var angular = require('angular');
|
||||
var toJson = require('ui/utils/aggressive_parse').toJson;
|
||||
|
||||
function emptyResponse() {
|
||||
return { hits: { total: 0, hits: [] } };
|
||||
};
|
||||
|
||||
return {
|
||||
clientMethod: 'msearch',
|
||||
|
||||
/**
|
||||
* Recover from a 404 when searching against no indexes
|
||||
*
|
||||
* If we get a 404 while intentionally searching for no indexes, we can
|
||||
* simply mock an empty result since that is ultimately what kibana cares
|
||||
* about.
|
||||
*
|
||||
* @param {object} response - the client response from elasticsearch
|
||||
* @return {Promise} - fulfilled by mock or rejected with original error
|
||||
*/
|
||||
handleResponseError: function (requests, response) {
|
||||
var is404 = _.get(response, 'status') === 404;
|
||||
var isEmptyIndexList = _.get(response, 'body.error.index') === '[-*]';
|
||||
|
||||
return is404 && isEmptyIndexList
|
||||
? Promise.resolve({ responses: requests.map(emptyResponse) })
|
||||
: Promise.reject(response);
|
||||
},
|
||||
|
||||
/**
|
||||
* Flatten a series of requests into as ES request body
|
||||
*
|
||||
|
|
33
src/ui/public/index_patterns/__tests__/index_patterns.js
Normal file
33
src/ui/public/index_patterns/__tests__/index_patterns.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import ngMock from 'ngMock';
|
||||
import expect from 'expect.js';
|
||||
import sinon from 'auto-release-sinon';
|
||||
|
||||
describe('IndexPatterns service', function () {
|
||||
let indexPatterns;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (Private) {
|
||||
const IndexPattern = Private(require('../_index_pattern'));
|
||||
indexPatterns = Private(require('../index_patterns'));
|
||||
|
||||
// prevent IndexPattern initialization from doing anything
|
||||
Private.stub(
|
||||
require('../_index_pattern'),
|
||||
function (...args) {
|
||||
const indexPattern = new IndexPattern(...args);
|
||||
sinon.stub(indexPattern, 'init', function () {
|
||||
return new Promise();
|
||||
});
|
||||
return indexPattern;
|
||||
}
|
||||
);
|
||||
}));
|
||||
|
||||
it('does not cache gets without an id', function () {
|
||||
expect(indexPatterns.get()).to.not.be(indexPatterns.get());
|
||||
});
|
||||
|
||||
it('does cache gets for the same id', function () {
|
||||
expect(indexPatterns.get(1)).to.be(indexPatterns.get(1));
|
||||
});
|
||||
});
|
|
@ -16,6 +16,7 @@ define(function (require) {
|
|||
var flattenHit = Private(require('ui/index_patterns/_flatten_hit'));
|
||||
var formatHit = require('ui/index_patterns/_format_hit');
|
||||
var calculateIndices = Private(require('ui/index_patterns/_calculate_indices'));
|
||||
var patternCache = Private(require('ui/index_patterns/_pattern_cache'));
|
||||
|
||||
var type = 'index-pattern';
|
||||
|
||||
|
@ -236,7 +237,14 @@ define(function (require) {
|
|||
|
||||
return safeConfirm(confirmMessage).then(
|
||||
function () {
|
||||
return docSource.doIndex(body).then(setId);
|
||||
return Promise.try(function () {
|
||||
const cached = patternCache.get(self.id);
|
||||
if (cached) {
|
||||
return cached.then(pattern => pattern.destroy());
|
||||
}
|
||||
})
|
||||
.then(() => docSource.doIndex(body))
|
||||
.then(setId);
|
||||
},
|
||||
_.constant(false) // if the user doesn't overwrite, resolve with false
|
||||
);
|
||||
|
@ -275,6 +283,11 @@ define(function (require) {
|
|||
return '' + self.toJSON();
|
||||
};
|
||||
|
||||
self.destroy = function () {
|
||||
patternCache.clear(self.id);
|
||||
docSource.destroy();
|
||||
};
|
||||
|
||||
self.metaFields = config.get('metaFields');
|
||||
self.getComputedFields = getComputedFields.bind(self);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ define(function (require) {
|
|||
var module = require('ui/modules').get('kibana/index_patterns');
|
||||
require('ui/filters/short_dots');
|
||||
|
||||
module.service('indexPatterns', function (es, Notifier, Private, Promise, kbnIndex) {
|
||||
function IndexPatternsProvider(es, Notifier, Private, Promise, kbnIndex) {
|
||||
var self = this;
|
||||
var _ = require('lodash');
|
||||
var errors = require('ui/errors');
|
||||
|
@ -25,7 +25,8 @@ define(function (require) {
|
|||
|
||||
self.delete = function (pattern) {
|
||||
self.getIds.clearCache();
|
||||
patternCache.delete(pattern.id);
|
||||
pattern.destroy();
|
||||
|
||||
return es.delete({
|
||||
index: kbnIndex,
|
||||
type: 'index-pattern',
|
||||
|
@ -44,5 +45,8 @@ define(function (require) {
|
|||
self.patternToWildcard = Private(require('ui/index_patterns/_pattern_to_wildcard'));
|
||||
self.fieldFormats = Private(require('ui/registry/field_formats'));
|
||||
self.IndexPattern = IndexPattern;
|
||||
});
|
||||
}
|
||||
|
||||
module.service('indexPatterns', Private => Private(IndexPatternsProvider));
|
||||
return IndexPatternsProvider;
|
||||
});
|
||||
|
|
7
src/ui/public/stringify/icons/index.js
Normal file
7
src/ui/public/stringify/icons/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/go.png');
|
||||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/stop.png');
|
||||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/de.png');
|
||||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/ne.png');
|
||||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/us.png');
|
||||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/ni.png');
|
||||
require('!!file?name=[path][name].[ext]!ui/stringify/icons/cv.png');
|
|
@ -3,7 +3,9 @@ define(function (require) {
|
|||
var _ = require('lodash');
|
||||
|
||||
var FieldFormat = Private(require('ui/index_patterns/_field_format/FieldFormat'));
|
||||
|
||||
require('ui/field_format_editor/pattern/pattern');
|
||||
require('ui/stringify/icons');
|
||||
|
||||
_.class(Url).inherits(FieldFormat);
|
||||
function Url(params) {
|
||||
|
@ -28,7 +30,7 @@ define(function (require) {
|
|||
template: require('ui/stringify/editors/url.html'),
|
||||
controllerAs: 'url',
|
||||
controller: function ($scope) {
|
||||
var iconPattern = 'ui/stringify/icons/{{value}}.png';
|
||||
var iconPattern = '/bundles/src/ui/public/stringify/icons/{{value}}.png';
|
||||
|
||||
this.samples = {
|
||||
a: [ 'john', '/some/pathname/asset.png', 1234 ],
|
||||
|
|
52
src/ui/public/timepicker/__tests__/offset_timezone.js
Normal file
52
src/ui/public/timepicker/__tests__/offset_timezone.js
Normal file
|
@ -0,0 +1,52 @@
|
|||
var angular = require('angular');
|
||||
var expect = require('expect.js');
|
||||
var ngMock = require('ngMock');
|
||||
var moment = require('moment-timezone');
|
||||
var sinon = require('sinon');
|
||||
var $ = require('jquery');
|
||||
|
||||
require('ui/timepicker/offset_timezone');
|
||||
|
||||
describe('Offset timezone', function () {
|
||||
let $compile;
|
||||
let $rootScope;
|
||||
let element;
|
||||
let getTimezoneOffset;
|
||||
|
||||
const html = '<div offset-timezone ng-model="value"/>{{value}}</div>';
|
||||
const timezoneOffset = 60;
|
||||
const mockDate = '2015-11-23T15:01:18-01:00';
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(ngMock.inject(function (_$compile_, _$rootScope_) {
|
||||
$compile = _$compile_;
|
||||
$rootScope = _$rootScope_;
|
||||
getTimezoneOffset = sinon.stub(Date.prototype, 'getTimezoneOffset', function () {
|
||||
return timezoneOffset;
|
||||
});
|
||||
}));
|
||||
|
||||
beforeEach(function () {
|
||||
element = $compile(html)($rootScope);
|
||||
});
|
||||
|
||||
it('should offset the timezone so the day is not changed when converting from moment to the Date constructor', function () {
|
||||
var mockDate = $rootScope.value = moment(mockDate).tz('UTC');
|
||||
$rootScope.$digest();
|
||||
var offsetDate = moment(element.controller('ngModel').$modelValue);
|
||||
|
||||
expect(offsetDate.diff(mockDate, 'minutes')).to.be(timezoneOffset);
|
||||
});
|
||||
|
||||
it('should keep the date the same when reading from the DOM', function () {
|
||||
var mockDate = $rootScope.value = moment(mockDate).tz('UTC');
|
||||
$rootScope.$digest();
|
||||
var domDate = moment($(element).text().replace(/"/g, ''));
|
||||
|
||||
expect(domDate.diff(mockDate, 'minutes')).to.be(0);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
getTimezoneOffset.restore();
|
||||
});
|
||||
});
|
55
src/ui/public/timepicker/offset_timezone.js
Normal file
55
src/ui/public/timepicker/offset_timezone.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var angular = require('angular');
|
||||
var moment = require('moment');
|
||||
|
||||
/**
|
||||
* moment objects can have an associated timezone, and when converting to a Date the
|
||||
* timezone is changed to browser time. This can cause issues, such as a day picker
|
||||
* showing the wrong day.
|
||||
* When a moment date is passed in, offset the timezone so that after converting to a Date object
|
||||
* the day does not appear changed. When reading back, convert to moment and remove the offset.
|
||||
*/
|
||||
require('ui/modules')
|
||||
.get('kibana')
|
||||
.directive('offsetTimezone', function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: 'ngModel',
|
||||
link: function (scope, $el, attrs, ngModelCntrl) {
|
||||
ngModelCntrl.$formatters.unshift(toDatePicker);
|
||||
ngModelCntrl.$parsers.unshift(fromDatePicker);
|
||||
|
||||
// State for whether the last change was internal or external
|
||||
// Internal changes(i.e selecting a new day multiple times) should not
|
||||
// continue to offset the date.
|
||||
var offsetDate = false;
|
||||
|
||||
//Going from Date object to moment
|
||||
function fromDatePicker(value) {
|
||||
if (!value) return;
|
||||
var date = moment(value);
|
||||
|
||||
if (offsetDate) {
|
||||
var offset = value.getTimezoneOffset() + date.utcOffset();
|
||||
offsetDate = false;
|
||||
date.minutes(date.minutes() - offset);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
//Going from moment to Date object
|
||||
function toDatePicker(value) {
|
||||
if (!value) return;
|
||||
var date = new Date(value.format('YYYY-MM-DDTHH:mm:ss.SSSZ'));
|
||||
|
||||
var offset = date.getTimezoneOffset() + value.utcOffset();
|
||||
date.setMinutes(date.getMinutes() + offset);
|
||||
offsetDate = true;
|
||||
|
||||
ngModelCntrl.$modelValue = date;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
|
@ -124,7 +124,11 @@
|
|||
<input type="text" required class="form-control" input-datetime="{{format}}" ng-model="absolute.from">
|
||||
</div>
|
||||
<div>
|
||||
<datepicker ng-model="absolute.from" max-date="absolute.to" show-weeks="false"></datepicker>
|
||||
<datepicker
|
||||
offset-timezone
|
||||
ng-model="absolute.from"
|
||||
max-date="absolute.to"
|
||||
show-weeks="false"></datepicker>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -137,7 +141,11 @@
|
|||
<input type="text" required class="form-control" input-datetime="{{format}}" ng-model="absolute.to">
|
||||
</div>
|
||||
<div>
|
||||
<datepicker ng-model="absolute.to" min-date="absolute.from" show-weeks="false"></datepicker>
|
||||
<datepicker
|
||||
offset-timezone
|
||||
ng-model="absolute.to"
|
||||
min-date="absolute.from"
|
||||
show-weeks="false"></datepicker>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ define(function (require) {
|
|||
require('ui/timepicker/quick_ranges');
|
||||
require('ui/timepicker/refresh_intervals');
|
||||
require('ui/timepicker/time_units');
|
||||
require('ui/timepicker/offset_timezone');
|
||||
|
||||
module.directive('kbnTimepicker', function (quickRanges, timeUnits, refreshIntervals) {
|
||||
return {
|
||||
|
@ -60,14 +61,6 @@ define(function (require) {
|
|||
{text: 'Years ago', value: 'y'},
|
||||
];
|
||||
|
||||
$scope.$watch('absolute.from', function (date) {
|
||||
if (_.isDate(date)) $scope.absolute.from = moment(date);
|
||||
});
|
||||
|
||||
$scope.$watch('absolute.to', function (date) {
|
||||
if (_.isDate(date)) $scope.absolute.to = moment(date);
|
||||
});
|
||||
|
||||
$scope.setMode = function (thisMode) {
|
||||
switch (thisMode) {
|
||||
case 'quick':
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
var _ = require('lodash');
|
||||
var versionmath = require('ui/utils/versionmath');
|
||||
var expect = require('expect.js');
|
||||
var versions = [
|
||||
'1.1.12',
|
||||
'1.1.12',
|
||||
'1.1.12',
|
||||
'1.1.12',
|
||||
'0.90.0',
|
||||
'0.90.1',
|
||||
'1.0.0',
|
||||
'1.0',
|
||||
'1.2.3',
|
||||
'2.0.0',
|
||||
'2.0.1',
|
||||
'2.3.1'
|
||||
];
|
||||
|
||||
describe('version math (0.90.0 - 2.3.1)', function () {
|
||||
var methods = 'max,min,eq,is,lt,lte,gt,gte'.split(',');
|
||||
describe('methods', function () {
|
||||
it('should have ' + methods.join(', ') + ' methods', function () {
|
||||
_.each(methods, function (method) {
|
||||
expect(versionmath[method]).to.be.a(Function);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('min & max', function () {
|
||||
it('has a max of 2.3.1', function () {
|
||||
expect(versionmath.max(versions)).to.be('2.3.1');
|
||||
});
|
||||
|
||||
it('has a min of 0.90.0', function () {
|
||||
expect(versionmath.min(versions)).to.be('0.90.0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('eq / lowest version', function () {
|
||||
it('should be true for 0.90.0', function () {
|
||||
expect(versionmath.eq('0.90.0', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('should be false for 1.0', function () {
|
||||
expect(versionmath.eq('1.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gt / lowest version', function () {
|
||||
it('is > 0.20.3', function () {
|
||||
expect(versionmath.gt('0.20.3', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not > 0.90.0', function () {
|
||||
expect(versionmath.gt('0.90.0', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is not > 1.0.0', function () {
|
||||
expect(versionmath.gt('1.0.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('gte / lowest version', function () {
|
||||
it('is >= 0.20.3', function () {
|
||||
expect(versionmath.gte('0.20.3', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is >= 0.90.0', function () {
|
||||
expect(versionmath.gte('0.90.0', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is not >= 1.0.0', function () {
|
||||
expect(versionmath.gte('1.0.0', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lt / highest version', function () {
|
||||
it('is not < 0.20.3', function () {
|
||||
expect(versionmath.lt('0.20.3', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is not < 2.3.1', function () {
|
||||
expect(versionmath.lt('2.3.1', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is < 2.5', function () {
|
||||
expect(versionmath.lt('2.5', versions)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('lte / highest version', function () {
|
||||
it('is not =< 0.20.3', function () {
|
||||
expect(versionmath.lte('0.20.3', versions)).to.be(false);
|
||||
});
|
||||
|
||||
it('is =< 2.3.1', function () {
|
||||
expect(versionmath.lte('2.3.1', versions)).to.be(true);
|
||||
});
|
||||
|
||||
it('is =< 2.5', function () {
|
||||
expect(versionmath.lte('2.5', versions)).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('is', function () {
|
||||
it('exactly, <, <=, >, >=', function () {
|
||||
expect(versionmath.is('0.90.0', versions)).to.be(true);
|
||||
expect(versionmath.is('0.20.0', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('>0.20.0', versions)).to.be(true);
|
||||
expect(versionmath.is('>0.90.0', versions)).to.be(false);
|
||||
expect(versionmath.is('>0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('>=0.20.0', versions)).to.be(true);
|
||||
expect(versionmath.is('>=0.90.0', versions)).to.be(true);
|
||||
expect(versionmath.is('>=0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('<2.5', versions)).to.be(true);
|
||||
expect(versionmath.is('<2.3.1', versions)).to.be(false);
|
||||
expect(versionmath.is('<0.90.1', versions)).to.be(false);
|
||||
|
||||
expect(versionmath.is('<=2.5', versions)).to.be(true);
|
||||
expect(versionmath.is('<=2.3.1', versions)).to.be(true);
|
||||
expect(versionmath.is('<=0.90.1', versions)).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -1,139 +0,0 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
|
||||
function VersionMathException(message) {
|
||||
this.message = message;
|
||||
this.name = 'VersionMathException';
|
||||
}
|
||||
|
||||
// Get the max version in this cluster
|
||||
function max(versions) {
|
||||
return sortVersions(versions).pop();
|
||||
}
|
||||
|
||||
// Return the lowest version in the cluster
|
||||
function min(versions) {
|
||||
return sortVersions(versions).shift();
|
||||
}
|
||||
|
||||
// Sort versions from lowest to highest
|
||||
function sortVersions(versions) {
|
||||
if (!_.isArray(versions)) versions = [versions];
|
||||
|
||||
return _.uniq(versions).sort(function (a, b) {
|
||||
return compare(a, b) ? -1 : 1;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Takes a version string with one of the following optional comparison prefixes: >,>=,<.<=
|
||||
and evaluates if the cluster meets the requirement. If the prefix is omitted exact match
|
||||
is assumed
|
||||
*/
|
||||
function is(equation, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
var _v = equation;
|
||||
var _cf;
|
||||
|
||||
if (_v.charAt(0) === '>') {
|
||||
_cf = _v.charAt(1) === '=' ? gte(_v.slice(2), _versions) : gt(_v.slice(1), _versions);
|
||||
} else if (_v.charAt(0) === '<') {
|
||||
_cf = _v.charAt(1) === '=' ? lte(_v.slice(2), _versions) : lt(_v.slice(1), _versions);
|
||||
} else {
|
||||
_cf = eq(_v, _versions);
|
||||
}
|
||||
|
||||
return _cf;
|
||||
}
|
||||
|
||||
// check if lowest version in cluster = `version`
|
||||
function eq(version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === min(_versions) ? true : false;
|
||||
}
|
||||
|
||||
// version > lowest version in cluster?
|
||||
function gt(version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === min(_versions) ? false : gte(version, _versions);
|
||||
}
|
||||
|
||||
// version < highest version in cluster?
|
||||
function lt(version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return version === max(_versions) ? false : lte(version, _versions);
|
||||
}
|
||||
|
||||
// Check if the lowest version in the cluster is >= to `version`
|
||||
function gte(version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return compare(version, min(_versions));
|
||||
}
|
||||
|
||||
// Check if the highest version in the cluster is <= to `version`
|
||||
function lte(version, versions) {
|
||||
var _versions = sortVersions(versions);
|
||||
return compare(max(_versions), version);
|
||||
}
|
||||
|
||||
// Determine if a specific version meets the minimum requirement
|
||||
function compare(required, installed) {
|
||||
if (_.isUndefined(installed)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!required || !installed) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var a = installed.split('.');
|
||||
var b = required.split('.');
|
||||
var i;
|
||||
|
||||
// leave suffixes as is ("RC1 or -SNAPSHOT")
|
||||
for (i = 0; i < Math.min(a.length, 3); ++i) {
|
||||
a[i] = Number(a[i]);
|
||||
}
|
||||
for (i = 0; i < Math.min(b.length, 3); ++i) {
|
||||
b[i] = Number(b[i]);
|
||||
}
|
||||
if (a.length === 2) {
|
||||
a[2] = 0;
|
||||
}
|
||||
|
||||
if (a[0] > b[0]) { return true; }
|
||||
if (a[0] < b[0]) { return false; }
|
||||
|
||||
if (a[1] > b[1]) { return true; }
|
||||
if (a[1] < b[1]) { return false; }
|
||||
|
||||
if (a[2] > b[2]) { return true; }
|
||||
if (a[2] < b[2]) { return false; }
|
||||
|
||||
if (a.length > 3) {
|
||||
// rc/beta suffix
|
||||
if (b.length <= 3) {
|
||||
return false;
|
||||
} // no suffix on b -> a<b
|
||||
return a[3] >= b[3];
|
||||
}
|
||||
if (b.length > 3) {
|
||||
// b has a suffix but a not -> a>b
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
min: min,
|
||||
max: max,
|
||||
is: is,
|
||||
eq: eq,
|
||||
gt: gt,
|
||||
gte: gte,
|
||||
lt: lt,
|
||||
lte: lte
|
||||
};
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
define(function (require) {
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var HeaderPage = require('../../../support/pages/HeaderPage');
|
||||
var SettingsPage = require('../../../support/pages/SettingsPage');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
var DiscoverPage = require('../../../support/pages/DiscoverPage');
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
|
||||
|
|
45
test/functional/apps/settings/_advanced_settings.js
Normal file
45
test/functional/apps/settings/_advanced_settings.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
define(function (require) {
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
return function (bdd, scenarioManager) {
|
||||
bdd.describe('creating and deleting default index', function describeIndexTests() {
|
||||
var common;
|
||||
var settingsPage;
|
||||
|
||||
bdd.before(function () {
|
||||
common = new Common(this.remote);
|
||||
settingsPage = new SettingsPage(this.remote);
|
||||
|
||||
return scenarioManager.reload('emptyKibana')
|
||||
.then(function () {
|
||||
return settingsPage.navigateTo();
|
||||
});
|
||||
});
|
||||
|
||||
bdd.describe('index pattern creation', function indexPatternCreation() {
|
||||
bdd.before(function () {
|
||||
return settingsPage.createIndexPattern();
|
||||
});
|
||||
|
||||
bdd.it('should allow setting advanced settings', function () {
|
||||
return settingsPage.clickAdvancedTab()
|
||||
.then(function TestCallSetAdvancedSettingsForTimezone() {
|
||||
common.log('calling setAdvancedSetting');
|
||||
return settingsPage.setAdvancedSettings('dateFormat:tz', 'America/Phoenix');
|
||||
})
|
||||
.then(function GetAdvancedSetting() {
|
||||
return settingsPage.getAdvancedSettings('dateFormat:tz');
|
||||
})
|
||||
.then(function (advancedSetting) {
|
||||
expect(advancedSetting).to.be('America/Phoenix');
|
||||
})
|
||||
.catch(common.handleError(this));
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
};
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
define(function (require) {
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var SettingsPage = require('../../../support/pages/SettingsPage');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
|
||||
return function (bdd, scenarioManager) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
define(function (require) {
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var SettingsPage = require('../../../support/pages/SettingsPage');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
define(function (require) {
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var SettingsPage = require('../../../support/pages/SettingsPage');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
//var Promise = require('bluebird');
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
define(function (require) {
|
||||
var config = require('intern').config;
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var SettingsPage = require('../../../support/pages/SettingsPage');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
var Promise = require('bluebird');
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
define(function (require) {
|
||||
var expect = require('intern/dojo/node!expect.js');
|
||||
var Common = require('../../../support/pages/Common');
|
||||
var SettingsPage = require('../../../support/pages/SettingsPage');
|
||||
var SettingsPage = require('../../../support/pages/settings_page');
|
||||
|
||||
return function (bdd, scenarioManager) {
|
||||
bdd.describe('initial state', function () {
|
||||
|
|
|
@ -9,6 +9,7 @@ define(function (require) {
|
|||
var indexPatternCreateDeleteTest = require('./_index_pattern_create_delete');
|
||||
var indexPatternResultsSortTest = require('./_index_pattern_results_sort');
|
||||
var indexPatternPopularityTest = require('./_index_pattern_popularity');
|
||||
var advancedSettingsTest = require('./_advanced_settings');
|
||||
|
||||
bdd.describe('settings app', function () {
|
||||
var scenarioManager = new ScenarioManager(url.format(config.servers.elasticsearch));
|
||||
|
@ -30,6 +31,7 @@ define(function (require) {
|
|||
});
|
||||
});
|
||||
|
||||
advancedSettingsTest(bdd, scenarioManager);
|
||||
initialStateTest(bdd, scenarioManager);
|
||||
creationChangesTest(bdd, scenarioManager);
|
||||
indexPatternCreateDeleteTest(bdd, scenarioManager);
|
||||
|
|
|
@ -202,7 +202,8 @@ define(function (require) {
|
|||
});
|
||||
},
|
||||
|
||||
findTestSubject: function (selector) {
|
||||
findTestSubject: function findTestSubject(selector) {
|
||||
this.debug('in findTestSubject: ' + selector);
|
||||
return this.remote.findByCssSelector(testSubjSelector(selector));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// in test/support/pages/SettingsPage.js
|
||||
// in test/support/pages/settings_page.js
|
||||
define(function (require) {
|
||||
var config = require('intern').config;
|
||||
var Promise = require('bluebird');
|
||||
|
@ -7,13 +7,39 @@ define(function (require) {
|
|||
var defaultTimeout = config.timeouts.default;
|
||||
var common;
|
||||
|
||||
function SettingsPage(remote) {
|
||||
function settingsPage(remote) {
|
||||
this.remote = remote;
|
||||
common = new Common(this.remote);
|
||||
}
|
||||
|
||||
SettingsPage.prototype = {
|
||||
constructor: SettingsPage,
|
||||
settingsPage.prototype = {
|
||||
constructor: settingsPage,
|
||||
|
||||
clickAdvancedTab: function () {
|
||||
common.debug('in clickAdvancedTab');
|
||||
return common.findTestSubject('settingsNav advanced').click();
|
||||
},
|
||||
|
||||
setAdvancedSettings: function setAdvancedSettings(propertyName, propertyValue) {
|
||||
var self = this;
|
||||
return common.findTestSubject('advancedSetting&' + propertyName + ' editButton')
|
||||
.click()
|
||||
.then(function setAdvancedSettingsClickPropertyValue(selectList) {
|
||||
return self.remote.findByCssSelector('option[label="' + propertyValue + '"]')
|
||||
.click();
|
||||
})
|
||||
.then(function setAdvancedSettingsClickSaveButton() {
|
||||
return common.findTestSubject('advancedSetting&' + propertyName + ' saveButton')
|
||||
.click();
|
||||
});
|
||||
},
|
||||
|
||||
getAdvancedSettings: function getAdvancedSettings(propertyName) {
|
||||
common.debug('in setAdvancedSettings');
|
||||
return common.findTestSubject('advancedSetting&' + propertyName + ' currentValue')
|
||||
.getVisibleText();
|
||||
},
|
||||
|
||||
|
||||
navigateTo: function () {
|
||||
return common.navigateToApp('settings');
|
||||
|
@ -295,5 +321,5 @@ define(function (require) {
|
|||
}
|
||||
};
|
||||
|
||||
return SettingsPage;
|
||||
return settingsPage;
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue