Skip to content
This repository has been archived by the owner on Mar 31, 2024. It is now read-only.

Commit

Permalink
Merge branch '4.2' into implement/xsrfProtectionFor4.2
Browse files Browse the repository at this point in the history
  • Loading branch information
spalger committed Nov 11, 2015
2 parents 3b171e0 + 8acbe5a commit 92d3080
Show file tree
Hide file tree
Showing 25 changed files with 1,424 additions and 94 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ target
.idea
*.iml
*.log
/test/output
/esvm
.htpasswd
installedPlugins
Expand Down
35 changes: 35 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,41 @@ The standard `npm run test` task runs several sub tasks and can take several min
</dd>
</dl>

### Functional UI Testing

#### Handy references

- https://theintern.github.io/
- https://theintern.github.io/leadfoot/Element.html

#### Running tests using npm task:

*The Selenium server that is started currently only runs the tests in Firefox*

To runt the functional UI tests, execute the following command:

`npm run test:ui`

The task above takes a little time to start the servers. You can also start the servers and leave them running, and then run the tests separately:

`npm run test:ui:server` will start the server required to run the selenium tests, leave this open

`npm run test:ui:runner` will run the frontend tests and close when complete

#### Running tests locally with your existing (and already running) ElasticSearch, Kibana, and Selenium Server:

Set your es and kibana ports in `test/intern.js` to 9220 and 5620, respecitively. You can configure your Selenium server to run the tests on Chrome,IE, or other browsers here.

Once you've got the services running, execute the following:

`npm run test:ui:runner`

#### General notes:

- Using Page Objects pattern (https://theintern.github.io/intern/#writing-functional-test)
- At least the initial tests for the Settings, Discover, and Visualize tabs all depend on a very specific set of logstash-type data (generated with makelogs). Since that is a static set of data, all the Discover and Visualize tests use a specific Absolute time range. This gaurantees the same results each run.
- These tests have been developed and tested with Chrome and Firefox browser. In theory, they should work on all browsers (that's the benefit of Intern using Leadfoot).
- These tests should also work with an external testing service like https://saucelabs.com/ or https://www.browserstack.com/ but that has not been tested.

### Submit a pull request

Expand Down
5 changes: 4 additions & 1 deletion src/optimize/babelOptions.build.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
var cloneDeep = require('lodash').cloneDeep;
var fromRoot = require('path').resolve.bind(null, __dirname, '../../');
process.env.BABEL_CACHE_PATH = fromRoot('optimize/.babelcache.json');

if (!process.env.BABEL_CACHE_PATH) {
process.env.BABEL_CACHE_PATH = fromRoot('optimize/.babelcache.json');
}

exports.webpack = {
stage: 1,
Expand Down
5 changes: 4 additions & 1 deletion src/optimize/babelOptions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
var cloneDeep = require('lodash').cloneDeep;
var fromRoot = require('path').resolve.bind(null, __dirname, '../../');
process.env.BABEL_CACHE_PATH = fromRoot('optimize/.babelcache.json');

if (!process.env.BABEL_CACHE_PATH) {
process.env.BABEL_CACHE_PATH = fromRoot('optimize/.babelcache.json');
}

exports.webpack = {
stage: 1,
Expand Down
2 changes: 1 addition & 1 deletion tasks/config/esvm.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module.exports = function (grunt) {
purge: true,
config: {
http: {
port: uiConfig.elasticsearch.port
port: uiConfig.servers.elasticsearch.port
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions tasks/config/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ module.exports = function (grunt) {
},
cmd: /^win/.test(platform) ? '.\\bin\\kibana.bat' : './bin/kibana',
args: [
'--server.port=' + uiConfig.kibana.port,
'--elasticsearch.url=' + format(uiConfig.elasticsearch),
'--server.port=' + uiConfig.servers.kibana.port,
'--elasticsearch.url=' + format(uiConfig.servers.elasticsearch),
'--logging.json=false'
]
},
Expand Down Expand Up @@ -89,7 +89,7 @@ module.exports = function (grunt) {
'-jar',
'selenium/selenium-server-standalone-2.47.1.jar',
'-port',
uiConfig.webdriver.port
uiConfig.servers.webdriver.port
]
},

Expand All @@ -105,7 +105,7 @@ module.exports = function (grunt) {
'-jar',
'selenium/selenium-server-standalone-2.47.1.jar',
'-port',
uiConfig.webdriver.port
uiConfig.servers.webdriver.port
]
},

Expand Down
92 changes: 83 additions & 9 deletions test/fixtures/__tests__/scenarioManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ describe('scenario manager', function () {

it('should be able to load scenarios', function () {
return manager.load('makelogs')
.then(function () {
expect(create.getCall(0).args[0].index).to.be('logstash-2015.09.17');
expect(create.getCall(1).args[0].index).to.be('logstash-2015.09.18');
expect(bulk.called).to.be(true);
});
.then(function () {
expect(create.getCall(0).args[0].index).to.be('logstash-2015.09.17');
expect(create.getCall(1).args[0].index).to.be('logstash-2015.09.18');
expect(bulk.called).to.be(true);
});
});

it('should be able to delete all indices', function () {
Expand Down Expand Up @@ -55,19 +55,93 @@ describe('scenario manager', function () {
});
});

it('should load if the index does not exist', function () {
var load = sinon.stub(manager, 'load', Promise.resolve);
var throwError = sinon.stub(manager.client, 'count', Promise.reject);
var id = 'makelogs';
return manager.loadIfEmpty(id).then(function () {
expect(load.calledWith(id)).to.be(true);

load.restore();
throwError.restore();
});
});

it('should load if the index is empty', function () {
var load = sinon.stub(manager, 'load', Promise.resolve);
var returnZero = sinon.stub(manager.client, 'count', function () {
return Promise.resolve({
'count': 0
});
});
var id = 'makelogs';
return manager.loadIfEmpty(id).then(function () {
expect(load.calledWith(id)).to.be(true);

load.restore();
returnZero.restore();
});
});


it('should not load if the index is not empty', function () {
var load = sinon.stub(manager, 'load', Promise.resolve);
var returnOne = sinon.stub(manager.client, 'count', function () {
return Promise.resolve({
'count': 1
});
});
var id = 'makelogs';
return manager.loadIfEmpty(id).then(function () {
expect(load.called).to.be(false);

load.restore();
returnOne.restore();
});
});


afterEach(function () {
bulk.restore();
create.restore();
indicesDelete.restore();
});
});

it('should throw an error if the scenario is not defined', function () {
expect(manager.load).withArgs('makelogs').to.throwError();
describe('load', function () {
it('should reject if the scenario is not specified', function () {
return manager.load()
.then(function () {
throw new Error('Promise should reject')
})
.catch(function () { return; });
});

it('should reject if the scenario is not defined', function () {
return manager.load('idonotexist')
.then(function () {
throw new Error('Promise should reject')
})
.catch(function () { return; });
});
});

it('should throw an error if an index is not defined when clearing', function () {
expect(manager.unload).to.throwError();
describe('unload', function () {
it('should reject if the scenario is not specified', function () {
return manager.unload()
.then(function () {
throw new Error('Promise should reject')
})
.catch(function () { return; });
});

it('should reject if the scenario is not defined', function () {
return manager.unload('idonotexist')
.then(function () {
throw new Error('Promise should reject')
})
.catch(function () { return; });
});
});

it('should throw an error if an es server is not specified', function () {
Expand Down
40 changes: 22 additions & 18 deletions test/fixtures/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,27 @@ var path = require('path');
var rootDir = path.join(__dirname, 'scenarios');

module.exports = {
makelogs: {
baseDir: path.join(rootDir, 'makelogs'),
bulk: [{
indexDefinition: 'makelogsIndexDefinition.js',
indexName: 'logstash-2015.09.17',
source: 'logstash-2015.09.17.js'
}, {
indexDefinition: 'makelogsIndexDefinition.js',
indexName: 'logstash-2015.09.18',
source: 'logstash-2015.09.18.js'
}]
},
emptyKibana: {
baseDir: path.join(rootDir, 'emptyKibana'),
bulk: [{
indexName: '.kibana',
source: 'kibana.js'
}]
scenarios: {
makelogs: {
baseDir: path.join(rootDir, 'makelogs'),
bulk: [{
indexName: 'logstash-2015.09.17',
indexDefinition: 'makelogsIndexDefinition.js',
source: 'logstash-2015.09.17.js'
}, {
indexName: 'logstash-2015.09.18',
indexDefinition: 'makelogsIndexDefinition.js',
source: 'logstash-2015.09.18.js'
}]
},
emptyKibana: {
baseDir: path.join(rootDir, 'emptyKibana'),
bulk: [{
indexName: '.kibana',
indexDefinition: 'kibanaDefinition.js',
source: 'kibana.js',
haltOnFailure: false
}]
}
}
};
59 changes: 47 additions & 12 deletions test/fixtures/scenarioManager.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var path = require('path');
var config = require('./config');
var elasticsearch = require('elasticsearch');
var Promise = require('bluebird');
var config = require('./config').scenarios;

function ScenarioManager(server) {
if (!server) throw new Error('No server defined');
Expand All @@ -16,28 +17,33 @@ function ScenarioManager(server) {
* @return {Promise} A promise that is resolved when elasticsearch has a response
*/
ScenarioManager.prototype.load = function (id) {
var self = this;
var scenario = config[id];
if (!scenario) throw new Error('No scenario found for ' + id);
if (!scenario) return Promise.reject('No scenario found for ' + id);

var self = this;
return Promise.all(scenario.bulk.map(function mapBulk(bulk) {
var loadIndexDefinition;

if (bulk.indexDefinition) {
var body = require(path.join(scenario.baseDir, bulk.indexDefinition));
loadIndexDefinition = self.client.indices.create({
index: bulk.indexName,
body: require(path.join(scenario.baseDir, bulk.indexDefinition))
body: body
});
} else {
loadIndexDefinition = Promise.resolve();
}

return loadIndexDefinition.then(function bulkRequest() {
self.client.bulk({
body: require(path.join(scenario.baseDir, bulk.source)),
return loadIndexDefinition
.then(function bulkRequest() {
var body = require(path.join(scenario.baseDir, bulk.source));
return self.client.bulk({
body: body
});
})
.catch(function (err) {
if (bulk.haltOnFailure === false) return;
throw err;
});

}));
};

Expand All @@ -48,7 +54,7 @@ ScenarioManager.prototype.load = function (id) {
*/
ScenarioManager.prototype.unload = function (id) {
var scenario = config[id];
if (!scenario) throw new Error('Expected index');
if (!scenario) return Promise.reject('No scenario found for ' + id);

var indices = scenario.bulk.map(function mapBulk(bulk) {
return bulk.indexName;
Expand All @@ -67,7 +73,8 @@ ScenarioManager.prototype.unload = function (id) {
ScenarioManager.prototype.reload = function (id) {
var self = this;

return this.unload(id).then(function load() {
return self.unload(id)
.then(function load() {
return self.load(id);
});
};
Expand All @@ -82,4 +89,32 @@ ScenarioManager.prototype.deleteAll = function () {
});
};

module.exports = ScenarioManager;
/**
* Load a testing scenario if not already loaded
* @param {string} id The scenario id to load
* @return {Promise} A promise that is resolved when elasticsearch has a response
*/
ScenarioManager.prototype.loadIfEmpty = function (id) {
var self = this;
var scenario = config[id];
if (!scenario) throw new Error('No scenario found for ' + id);

var self = this;
return Promise.all(scenario.bulk.map(function mapBulk(bulk) {
var loadIndexDefinition;

return self.client.count({
index: bulk.indexName
})
.then(function handleCountResponse(response) {
if (response.count === 0) {
return self.load(id);
}
})
}))
.catch(function (reason) {
return self.load(id);
});
};

module.exports = ScenarioManager;
16 changes: 16 additions & 0 deletions test/fixtures/scenarios/emptyKibana/kibanaDefinition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
settings: {
number_of_shards: 1,
number_of_replicas: 1
},
mappings: {
config: {
properties: {
buildNum: {
type: 'string',
index: 'not_analyzed'
}
}
}
}
}
Loading

0 comments on commit 92d3080

Please sign in to comment.