Merge master.

This commit is contained in:
LeeDr 2015-11-30 15:15:22 -06:00
commit 32cf7762f2
20 changed files with 297 additions and 92 deletions

View file

@ -1,4 +1,4 @@
# Kibana 4.4.0-snapshot
# Kibana 5.0.0-snapshot
[![Build Status](https://travis-ci.org/elastic/kibana.svg?branch=master)](https://travis-ci.org/elastic/kibana?branch=master)
@ -37,7 +37,7 @@ For the daring, snapshot builds are available. These builds are created after ea
| platform | | |
| --- | --- | --- |
| OSX | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-darwin-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-darwin-x64.zip) |
| Linux x64 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-linux-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-linux-x64.zip) |
| Linux x86 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-linux-x86.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-linux-x86.zip) |
| Windows | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-windows.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-4.4.0-snapshot-windows.zip) |
| OSX | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-darwin-x64.zip) |
| Linux x64 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x64.zip) |
| Linux x86 | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-linux-x86.zip) |
| Windows | [tar](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.tar.gz) | [zip](http://download.elastic.co/kibana/kibana-snapshot/kibana-5.0.0-snapshot-windows.zip) |

View file

@ -11,7 +11,7 @@
"dashboarding"
],
"private": false,
"version": "4.4.0-snapshot",
"version": "5.0.0-snapshot",
"build": {
"number": 8467,
"sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9"

View file

@ -191,6 +191,9 @@ define(function (require) {
});
$scope.$watch('vis.aggs', function () {
// no timefield, no vis, nothing to update
if (!$scope.opts.timefield) return;
var buckets = $scope.vis.aggs.bySchemaGroup.buckets;
if (buckets && buckets.length === 1) {

View file

@ -0,0 +1,92 @@
import ngMock from 'ngMock';
import expect from 'expect.js';
import sinon from 'auto-release-sinon';
import RequestQueueProv from '../_request_queue';
import SearchStrategyProv from '../fetch/strategy/search';
import DocStrategyProv from '../fetch/strategy/doc';
describe('Courier Request Queue', function () {
let docStrategy;
let requestQueue;
let searchStrategy;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
docStrategy = Private(DocStrategyProv);
requestQueue = Private(RequestQueueProv);
searchStrategy = Private(SearchStrategyProv);
}));
class MockReq {
constructor(strategy, startable = true) {
this.strategy = strategy;
this.source = {};
this.canStart = sinon.stub().returns(startable);
}
}
describe('#getStartable(strategy)', function () {
it('only returns requests that match one of the passed strategies', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.getStartable(docStrategy)).to.have.length(1);
expect(requestQueue.getStartable(searchStrategy)).to.have.length(3);
});
it('returns all requests when no strategy passed', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.getStartable()).to.have.length(2);
});
it('returns only startable requests', function () {
requestQueue.push(
new MockReq(docStrategy, true),
new MockReq(searchStrategy, false)
);
expect(requestQueue.getStartable()).to.have.length(1);
});
});
describe('#get(strategy)', function () {
it('only returns requests that match one of the passed strategies', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.get(docStrategy)).to.have.length(1);
expect(requestQueue.get(searchStrategy)).to.have.length(3);
});
it('returns all requests when no strategy passed', function () {
requestQueue.push(
new MockReq(docStrategy),
new MockReq(searchStrategy)
);
expect(requestQueue.get()).to.have.length(2);
});
it('returns startable and not-startable requests', function () {
requestQueue.push(
new MockReq(docStrategy, true),
new MockReq(searchStrategy, false)
);
expect(requestQueue.get()).to.have.length(2);
});
});
});

View file

@ -16,8 +16,11 @@ define(function (require) {
});
};
queue.get = function (/* strategies.. */) {
var strategies = _.toArray(arguments);
queue.getStartable = function (...strategies) {
return queue.get(...strategies).filter(req => req.canStart());
};
queue.get = function (...strategies) {
return queue.filter(function (req) {
var strategyMatch = !strategies.length;
if (!strategyMatch) {
@ -26,7 +29,7 @@ define(function (require) {
});
}
return strategyMatch && req.canStart();
return strategyMatch;
});
};

View file

@ -0,0 +1,59 @@
import ngMock from 'ngMock';
import expect from 'expect.js';
import sinon from 'auto-release-sinon';
import RequestQueueProv from '../../_request_queue';
import DocSourceProv from '../doc_source';
describe('DocSource', function () {
require('testUtils/noDigestPromises').activateForSuite();
let requestQueue;
let DocSource;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
requestQueue = Private(RequestQueueProv);
DocSource = Private(DocSourceProv);
}));
describe('#onUpdate()', function () {
it('adds a request to the requestQueue', function () {
const source = new DocSource();
expect(requestQueue).to.have.length(0);
source.onUpdate();
expect(requestQueue).to.have.length(1);
});
it('returns a promise that is resolved with the results', function () {
const source = new DocSource();
const fakeResults = {};
const promise = source.onUpdate().then((results) => {
expect(results).to.be(fakeResults);
});
requestQueue[0].defer.resolve(fakeResults);
return promise;
});
});
describe('#destroy()', function () {
it('aborts all startable requests', function () {
const source = new DocSource();
source.onUpdate();
sinon.stub(requestQueue[0], 'canStart').returns(true);
source.destroy();
expect(requestQueue).to.have.length(0);
});
it('aborts all non-startable requests', function () {
const source = new DocSource();
source.onUpdate();
sinon.stub(requestQueue[0], 'canStart').returns(false);
source.destroy();
expect(requestQueue).to.have.length(0);
});
});
});

View file

@ -0,0 +1,59 @@
import ngMock from 'ngMock';
import expect from 'expect.js';
import sinon from 'auto-release-sinon';
import RequestQueueProv from '../../_request_queue';
import SearchSourceProv from '../search_source';
describe('SearchSource', function () {
require('testUtils/noDigestPromises').activateForSuite();
let requestQueue;
let SearchSource;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
requestQueue = Private(RequestQueueProv);
SearchSource = Private(SearchSourceProv);
}));
describe('#onResults()', function () {
it('adds a request to the requestQueue', function () {
const source = new SearchSource();
expect(requestQueue).to.have.length(0);
source.onResults();
expect(requestQueue).to.have.length(1);
});
it('returns a promise that is resolved with the results', function () {
const source = new SearchSource();
const fakeResults = {};
const promise = source.onResults().then((results) => {
expect(results).to.be(fakeResults);
});
requestQueue[0].defer.resolve(fakeResults);
return promise;
});
});
describe('#destroy()', function () {
it('aborts all startable requests', function () {
const source = new SearchSource();
source.onResults();
sinon.stub(requestQueue[0], 'canStart').returns(true);
source.destroy();
expect(requestQueue).to.have.length(0);
});
it('aborts all non-startable requests', function () {
const source = new SearchSource();
source.onResults();
sinon.stub(requestQueue[0], 'canStart').returns(false);
source.destroy();
expect(requestQueue).to.have.length(0);
});
});
});

View file

@ -167,7 +167,7 @@ define(function (require) {
*/
SourceAbstract.prototype.fetch = function () {
var self = this;
var req = _.first(self._myQueued());
var req = _.first(self._myStartableQueued());
if (!req) {
req = self._createRequest();
@ -183,7 +183,7 @@ define(function (require) {
* @async
*/
SourceAbstract.prototype.fetchQueued = function () {
return courierFetch.these(this._myQueued());
return courierFetch.these(this._myStartableQueued());
};
/**
@ -191,7 +191,10 @@ define(function (require) {
* @return {undefined}
*/
SourceAbstract.prototype.cancelQueued = function () {
_.invoke(this._myQueued(), 'abort');
requestQueue
.get(this._fetchStrategy)
.filter(req => req.source === this)
.forEach(req => req.abort());
};
/**
@ -206,9 +209,10 @@ define(function (require) {
* PRIVATE API
*****/
SourceAbstract.prototype._myQueued = function () {
var reqs = requestQueue.get(this._fetchStrategy);
return _.where(reqs, { source: this });
SourceAbstract.prototype._myStartableQueued = function () {
return requestQueue
.getStartable(this._fetchStrategy)
.filter(req => req.source === this);
};
SourceAbstract.prototype._createRequest = function () {

View file

@ -9,7 +9,7 @@ define(function (require) {
var INCOMPLETE = Private(require('ui/courier/fetch/_req_status')).INCOMPLETE;
function fetchQueued(strategy) {
var requests = requestQueue.get(strategy);
var requests = requestQueue.getStartable(strategy);
if (!requests.length) return Promise.resolve();
else return fetchThese(requests);
}

View file

@ -2,7 +2,6 @@ define(function (require) {
return function CourierSegmentedReqProvider(es, Private, Promise, Notifier, timefilter, config) {
var _ = require('lodash');
var SearchReq = Private(require('ui/courier/fetch/request/search'));
var requestQueue = Private(require('ui/courier/_request_queue'));
var SegmentedHandle = Private(require('ui/courier/fetch/request/_segmented_handle'));
var notify = new Notifier({

View file

@ -60,6 +60,7 @@ ScenarioManager.prototype.unload = function (id) {
return bulk.indexName;
});
console.log('DELETING INDEX: ' + indices);
return this.client.indices.delete({
index: indices
})

View file

@ -85,12 +85,10 @@ define(function (require) {
bdd.it('load query should show query name', function () {
return discoverPage.loadSavedSearch(queryName1)
.then(function () {
return common.tryForTime(15000, function () {
return discoverPage.getCurrentQueryName()
.then(function (actualQueryNameString) {
expect(actualQueryNameString).to.be(queryName1);
});
});
return discoverPage.getCurrentQueryName();
})
.then(function (actualQueryNameString) {
expect(actualQueryNameString).to.be(queryName1);
})
.catch(common.handleError(this));
});

View file

@ -1,4 +1,5 @@
define(function (require) {
var config = require('intern').config;
var Common = require('../../../support/pages/Common');
var SettingsPage = require('../../../support/pages/SettingsPage');
var expect = require('intern/dojo/node!expect.js');
@ -9,7 +10,7 @@ define(function (require) {
var common;
var settingsPage;
var remote;
var longTimeout = 60000;
var defaultTimeout = config.timeouts.default;
bdd.before(function () {
common = new Common(this.remote);
@ -94,7 +95,7 @@ define(function (require) {
});
bdd.it('makelogs data should have expected number of fields', function () {
return common.tryForTime(longTimeout, function () {
return common.tryForTime(defaultTimeout, function () {
return settingsPage.getFieldsTabCount()
.then(function (tabCount) {
expect(tabCount).to.be('' + expectedFieldCount);

View file

@ -177,30 +177,8 @@ define(function (require) {
'2015-09-22 00:00', '2015-09-23 00:00'
];
var yAxisLabels = ['0','200','400','600','800','1,000','1,200','1,400','1,600'];
var expectedAreaChartData = [37,
202,
740,
1437,
1371,
751,
188,
31,
42,
202,
683,
1361,
1415,
707,
177,
27,
32,
175,
707,
1408,
1355,
726,
201,
29
var expectedAreaChartData = [37, 202, 740, 1437, 1371, 751, 188, 31, 42, 202,
683, 1361, 1415, 707, 177, 27, 32, 175, 707, 1408, 1355, 726, 201, 29
];
return visualizePage.getXAxisLabels()

View file

@ -36,14 +36,10 @@ define(function (require) {
});
bdd.before(function () {
common.debug('running bdd.beforeEach');
common.debug('running bdd.before');
this.timeout = 120000;
return remote.setWindowSize(1200,800)
.then(function () {
// start each test with an empty kibana index
return scenarioManager.reload('emptyKibana');
})
// and load a minimal set of makelogs data
// load a minimal set of makelogs data
.then(function loadIfEmptyMakelogs() {
return scenarioManager.loadIfEmpty('logstashFunctional');
});

View file

@ -24,6 +24,9 @@ define(function (require) {
'bluebird': './node_modules/bluebird/js/browser/bluebird.js',
'moment': './node_modules/moment/moment.js'
}
}
},
timeouts: {
default: 90000
},
}, serverConfig);
});

View file

@ -11,7 +11,7 @@ define(function (require) {
this.remote = remote;
}
var defaultTimeout = 60000;
var defaultTimeout = config.timeouts.default;
Common.prototype = {
constructor: Common,
@ -19,6 +19,7 @@ define(function (require) {
navigateToApp: function (appName, testStatusPage) {
var self = this;
var appUrl = getUrl(config.servers.kibana, config.apps[appName]);
self.debug('navigating to ' + appName + ' url: ' + appUrl);
var doNavigation = function (url) {
return self.tryForTime(defaultTimeout, function () {
@ -51,14 +52,13 @@ define(function (require) {
self.debug(msg);
throw new Error(msg);
}
return currentUrl;
});
});
};
return doNavigation(appUrl)
.then(function () {
return self.remote.getCurrentUrl();
})
.then(function (currentUrl) {
var lastUrl = currentUrl;
return self.tryForTime(defaultTimeout, function () {
@ -149,13 +149,9 @@ define(function (require) {
return Promise
.try(block)
.then(function tryForTimeSuccess() {
self.debug('tryForTime success in about ' + (lastTry - start) + ' milliseconds');
return (lastTry - start);
})
.catch(function tryForTimeCatch(err) {
self.debug('failed with "' + err.message + '"');
self.debug('trying again in 1/2 second');
self.debug('tryForTime failure: ' + err.message);
tempMessage = err.message;
return Promise.delay(retryDelay).then(attempt);
});
}

View file

@ -1,11 +1,9 @@
// in test/support/pages/DiscoverPage.js
define(function (require) {
// the page object is created as a constructor
// so we can provide the remote Command object
// at runtime
var config = require('intern').config;
var Common = require('./Common');
var defaultTimeout = 20000;
var defaultTimeout = config.timeouts.default;
var common;
var thisTime;
@ -76,10 +74,11 @@ define(function (require) {
},
getCurrentQueryName: function getCurrentQueryName() {
return thisTime
.findByCssSelector('span.discover-info-title')
// .findByCssSelector('span[bo-bind="opts.savedSearch.title"]')
.getVisibleText();
return common.tryForTime(defaultTimeout, function () {
return thisTime
.findByCssSelector('span.discover-info-title')
.getVisibleText();
});
},
getBarChartData: function getBarChartData() {

View file

@ -1,6 +1,6 @@
// in test/support/pages/HeaderPage.js
define(function (require) {
var config = require('intern').config;
var Common = require('./Common');
var common;
@ -13,14 +13,14 @@ define(function (require) {
common = new Common(this.remote);
}
var defaultTimeout = 5000;
var defaultTimeout = config.timeouts.default;
HeaderPage.prototype = {
constructor: HeaderPage,
clickSelector: function (selector) {
var self = this.remote;
return common.tryForTime(5000, function () {
return common.tryForTime(defaultTimeout, function () {
return self.setFindTimeout(defaultTimeout)
.findByCssSelector(selector)
.then(function (tab) {
@ -118,16 +118,21 @@ define(function (require) {
waitForToastMessageGone: function waitForToastMessageGone() {
var self = this;
return common.tryForTime(defaultTimeout * 5, function tryingForTime() {
return self.remote.setFindTimeout(1000)
.findAllByCssSelector('kbn-truncated.toast-message.ng-isolate-scope')
return common.tryForTime(defaultTimeout, function () {
return self.remote.setFindTimeout(500)
.findAllByCssSelector('kbn-truncated.toast-message')
.then(function toastMessage(messages) {
if (messages.length > 0) {
common.debug('toast message found, waiting...');
throw new Error('waiting for toast message to clear');
} else {
common.debug('now messages = 0 "' + messages + '"');
common.debug('toast message clear');
return messages;
}
})
.catch(function () {
common.debug('toast message not found');
return;
});
});
},

View file

@ -1,13 +1,10 @@
// in test/support/pages/SettingsPage.js
define(function (require) {
// the page object is created as a constructor
// so we can provide the remote Command object
// at runtime
var config = require('intern').config;
var Promise = require('bluebird');
var Common = require('./Common');
var defaultTimeout = 6000;
var defaultTimeout = config.timeouts.default;
var common;
function SettingsPage(remote) {
@ -88,12 +85,22 @@ define(function (require) {
selectTimeFieldOption: function (selection) {
var self = this;
// open dropdown
return self.getTimeFieldNameField().click()
.then(function () {
// close dropdown, keep focus
return self.getTimeFieldNameField().click();
})
.then(function () {
return self.getTimeFieldOption(selection);
return common.tryForTime(defaultTimeout, function () {
return self.getTimeFieldOption(selection).click()
.then(function () {
return self.getTimeFieldOption(selection).isSelected();
})
.then(function (selected) {
if (!selected) throw new Error('option not selected: ' + selected);
});
});
});
},
@ -167,11 +174,13 @@ define(function (require) {
var self = this;
var selector = 'li.kbn-settings-tab.active a small';
return self.remote.setFindTimeout(defaultTimeout)
.findByCssSelector(selector).getVisibleText()
.then(function (theText) {
// the value has () around it, remove them
return theText.replace(/\((.*)\)/, '$1');
return common.tryForTime(defaultTimeout, function () {
return self.remote.setFindTimeout(defaultTimeout / 10)
.findByCssSelector(selector).getVisibleText()
.then(function (theText) {
// the value has () around it, remove them
return theText.replace(/\((.*)\)/, '$1');
});
});
},