mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Merge branch 'master' of github.com:elasticsearch/kibana into feature/config-migration
Conflicts: src/server/config/index.js src/server/index.js
This commit is contained in:
commit
3fa0dfdf3a
22 changed files with 204 additions and 176 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@ target
|
|||
*.iml
|
||||
*.log
|
||||
esvm
|
||||
.htpasswd
|
||||
|
|
|
@ -17,31 +17,16 @@ Please make sure you have signed the [Contributor License Agreement](http://www.
|
|||
nvm install 0.10
|
||||
```
|
||||
|
||||
- Install ruby *1.9.3* (we recommend using [rbenv](https://github.com/sstephenson/rbenv))
|
||||
- See [rbenv docs](https://github.com/sstephenson/rbenv#installation) for installation assistance
|
||||
|
||||
```sh
|
||||
## install ruby and ruby-build using your local package manager (apt, brew, etc)
|
||||
brew install rbenv ruby-build
|
||||
```
|
||||
|
||||
- Run `rbenv init` and add `eval "$(rbenv init -)"` to your shell (ex. .bashrc/.bash_profile)
|
||||
- Run `rbenv install` to install the required version
|
||||
- Run `ruby -v` and make sure you are using 1.9.3
|
||||
- Check the installation docs if you have issues getting the correct version
|
||||
- Install bundler by running `gem install bundler`
|
||||
- Install local gems by running `bundle`
|
||||
|
||||
- Install grunt and bower globally
|
||||
- Install grunt and bower globally (as root if not using nvm)
|
||||
|
||||
```sh
|
||||
npm install -g grunt-cli bower
|
||||
```
|
||||
|
||||
- Install node, bower, and ruby dependencies
|
||||
- Install node and bower dependencies
|
||||
|
||||
```sh
|
||||
npm install && bower install && bundle
|
||||
npm install && bower install
|
||||
```
|
||||
|
||||
- Start the development server.
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"elasticsearch": "^3.1.1",
|
||||
"express": "~4.10.6",
|
||||
"glob": "^4.3.2",
|
||||
"http-auth": "^2.2.5",
|
||||
"jade": "~1.8.2",
|
||||
"js-yaml": "^3.2.5",
|
||||
"less-middleware": "1.0.x",
|
||||
|
|
|
@ -38,7 +38,10 @@ define(function (require) {
|
|||
params: [
|
||||
{
|
||||
name: 'field',
|
||||
filterFieldTypes: 'date'
|
||||
filterFieldTypes: 'date',
|
||||
default: function (aggConfig) {
|
||||
return aggConfig.vis.indexPattern.timeFieldName;
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<span ng-click="sort(indexPattern.timeFieldName)" tooltip="Sort by time">Time <i ng-class="headerClass(indexPattern.timeFieldName)"></i></span>
|
||||
</th>
|
||||
<th ng-repeat="name in columns">
|
||||
<span ng-click="sort(name)" class="table-header-name" tooltip="Sort by {{name | shortDots}}">
|
||||
<span ng-click="sort(name)" class="table-header-name" tooltip="{{tooltip(name)}}">
|
||||
{{name | shortDots}} <i ng-class="headerClass(name)"></i>
|
||||
</span>
|
||||
<span class="table-header-move">
|
||||
|
|
|
@ -4,7 +4,7 @@ define(function (require) {
|
|||
|
||||
require('filters/short_dots');
|
||||
|
||||
module.directive('kbnTableHeader', function () {
|
||||
module.directive('kbnTableHeader', function (shortDotsFilter) {
|
||||
var headerHtml = require('text!components/doc_table/components/table_header.html');
|
||||
return {
|
||||
restrict: 'A',
|
||||
|
@ -21,6 +21,10 @@ define(function (require) {
|
|||
return $scope.indexPattern.fields.byName[field].sortable;
|
||||
};
|
||||
|
||||
$scope.tooltip = function (column) {
|
||||
if (!sortableField(column)) return ''; else return 'Sort by ' + shortDotsFilter(column);
|
||||
};
|
||||
|
||||
$scope.headerClass = function (column) {
|
||||
if (!sortableField(column)) return;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
</table>
|
||||
<kbn-infinite-scroll ng-if="infiniteScroll" more="addRows"></kbn-infinite-scroll>
|
||||
</div>
|
||||
<div ng-if="!hits.length" class="table-vis-error">
|
||||
<h2><i class="fa fa-meh-o"></i></h2>
|
||||
<h4>No results found</h4>
|
||||
</div>
|
||||
<div ng-if="hits != null && !hits.length" class="table-vis-error">
|
||||
<h2><i class="fa fa-meh-o"></i></h2>
|
||||
<h4>No results found</h4>
|
||||
</div>
|
|
@ -76,7 +76,13 @@ define(function (require) {
|
|||
|
||||
if (val == null) {
|
||||
if (aggParam.default == null) return;
|
||||
else val = aggParam.default;
|
||||
|
||||
if (!_.isFunction(aggParam.default)) {
|
||||
val = aggParam.default;
|
||||
} else {
|
||||
val = aggParam.default(self);
|
||||
if (val == null) return;
|
||||
}
|
||||
}
|
||||
|
||||
if (aggParam.deserialize) {
|
||||
|
@ -104,8 +110,8 @@ define(function (require) {
|
|||
* @return {object} the new params object
|
||||
*/
|
||||
AggConfig.prototype.resetParams = function () {
|
||||
// We need to ensure that row doesn't get overriden.
|
||||
return this.fillDefaults(_.pick(this.params, 'row'));
|
||||
// We need to ensure that row and field don't get overriden.
|
||||
return this.fillDefaults(_.pick(this.params, 'row', 'field'));
|
||||
};
|
||||
|
||||
AggConfig.prototype.write = function () {
|
||||
|
|
|
@ -8,9 +8,9 @@ define(function (require) {
|
|||
var sequencer = require('utils/sequencer');
|
||||
|
||||
var SCHEDULE = ResizeChecker.SCHEDULE = sequencer.createEaseIn(
|
||||
5, // shortest delay
|
||||
100, // shortest delay
|
||||
10000, // longest delay
|
||||
125 // tick count
|
||||
50 // tick count
|
||||
);
|
||||
|
||||
// maximum ms that we can delay emitting 'resize'. This is only used
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<div ng-controller="KbnMetricVisController" class="metric-vis">
|
||||
<div class="metric-value" ng-style="{'font-size': vis.params.fontSize+'pt'}">{{metric.value}}</div>
|
||||
<div>{{metric.label}}</div>
|
||||
<div class="metric-container" ng-repeat="metric in metrics">
|
||||
<div class="metric-value" ng-style="{'font-size': vis.params.fontSize+'pt'}">{{metric.value}}</div>
|
||||
<div>{{metric.label}}</div>
|
||||
</div>
|
||||
</div>
|
|
@ -2,12 +2,22 @@
|
|||
@import (reference) "lesshat.less";
|
||||
|
||||
.metric-vis {
|
||||
text-align: center;
|
||||
.flex-parent();
|
||||
.justify-content(center);
|
||||
width: 100%;
|
||||
.display(flex);
|
||||
.flex-direction(row);
|
||||
.flex-wrap(wrap);
|
||||
.justify-content(space-around);
|
||||
.align-items(center);
|
||||
.align-content(space-around);
|
||||
|
||||
.metric-value {
|
||||
font-weight: bold;
|
||||
.ellipsis();
|
||||
}
|
||||
|
||||
.metric-container {
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
.flex();
|
||||
}
|
||||
}
|
|
@ -3,20 +3,27 @@ define(function (require) {
|
|||
// didn't already
|
||||
var module = require('modules').get('kibana/metric_vis', ['kibana']);
|
||||
|
||||
module.controller('KbnMetricVisController', function ($scope) {
|
||||
var metric = $scope.metric = {
|
||||
label: null,
|
||||
value: null
|
||||
module.controller('KbnMetricVisController', function ($scope, Private) {
|
||||
var tabifyAggResponse = Private(require('components/agg_response/tabify/tabify'));
|
||||
|
||||
var metrics = $scope.metrics = [];
|
||||
|
||||
$scope.processTableGroups = function (tableGroups) {
|
||||
tableGroups.tables.forEach(function (table) {
|
||||
table.columns.forEach(function (column, i) {
|
||||
var fieldFormatter = table.aggConfig(column).fieldFormatter();
|
||||
metrics.push({
|
||||
label: column.title,
|
||||
value: fieldFormatter(table.rows[0][i])
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$watch('esResponse', function (resp) {
|
||||
if (!resp) {
|
||||
metric.label = metric.value = null;
|
||||
} else {
|
||||
var agg = $scope.vis.aggs[0];
|
||||
metric.label = agg.makeLabel();
|
||||
if (agg.type.name === 'count') metric.value = resp.hits.total;
|
||||
else metric.value = agg.fieldFormatter()(resp.aggregations[agg.id].value);
|
||||
if (resp) {
|
||||
metrics.length = 0;
|
||||
$scope.processTableGroups(tabifyAggResponse($scope.vis, resp));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,8 +4,6 @@ define(function (require) {
|
|||
require('modules')
|
||||
.get('app/visualize')
|
||||
.directive('visAggParamEditor', function (config, $parse, Private) {
|
||||
var FieldAggParam = Private(require('components/agg_types/param_types/field'));
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: true,
|
||||
|
@ -26,13 +24,6 @@ define(function (require) {
|
|||
|
||||
return true;
|
||||
};
|
||||
|
||||
// set default value on field agg params
|
||||
if ($scope.aggParam instanceof FieldAggParam) {
|
||||
if (!$scope.agg.params[$scope.aggParam.name]) {
|
||||
$scope.agg.params[$scope.aggParam.name] = $scope.indexedFields[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,26 +17,27 @@
|
|||
</vis-editor-vis-options>
|
||||
|
||||
<!-- apply/discard -->
|
||||
<li class="vis-editor-sidebar-buttons sidebar-item">
|
||||
<p
|
||||
ng-if="visualizeEditor.$invalid"
|
||||
class="text-center text-danger sidebar-item-text">
|
||||
<i class="fa fa-warning"></i> {{visualizeEditor.describeErrors()}}
|
||||
</p>
|
||||
<button
|
||||
ng-disabled="!vis.dirty || visualizeEditor.$invalid"
|
||||
type="submit"
|
||||
class="sidebar-item-button success">
|
||||
Apply
|
||||
</button>
|
||||
<button
|
||||
ng-disabled="!vis.dirty"
|
||||
type="button"
|
||||
ng-click="resetEditableVis()"
|
||||
class="sidebar-item-button default">
|
||||
Discard
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="vis-editor-sidebar-buttons">
|
||||
<p
|
||||
ng-if="visualizeEditor.$invalid"
|
||||
class="text-center text-danger sidebar-item-text">
|
||||
<i class="fa fa-warning"></i> {{visualizeEditor.describeErrors()}}
|
||||
</p>
|
||||
<button
|
||||
ng-disabled="!vis.dirty || visualizeEditor.$invalid"
|
||||
type="submit"
|
||||
class="sidebar-item-button success">
|
||||
Apply
|
||||
</button>
|
||||
<button
|
||||
ng-disabled="!vis.dirty"
|
||||
type="button"
|
||||
ng-click="resetEditableVis()"
|
||||
class="sidebar-item-button default">
|
||||
Discard
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -50,33 +50,38 @@
|
|||
&-sidebar {
|
||||
.flex-parent(0, 0, auto);
|
||||
|
||||
overflow: auto;
|
||||
// overflow: auto;
|
||||
|
||||
// overrided for tablet and desktop
|
||||
@media (min-width: @screen-md-min) {
|
||||
.flex-basis(@vis-editor-sidebar-basis);
|
||||
min-width: @vis-editor-sidebar-min-width;
|
||||
max-width: @vis-editor-sidebar-min-width;
|
||||
margin-bottom: (@input-height-base * 2) - 3;
|
||||
// margin-bottom: (@input-height-base * 2) - 3;
|
||||
}
|
||||
|
||||
&-buttons {
|
||||
// overrides for tablet and desktop
|
||||
@media (min-width: @screen-md-min) {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
min-width: @vis-editor-sidebar-min-width;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item {
|
||||
border-top: 0 !important;
|
||||
}
|
||||
|
||||
.sidebar-container {
|
||||
.flex(1, 0, auto);
|
||||
.flex-parent(1, 1, auto);
|
||||
background-color: @body-bg;
|
||||
border-right-color: @sidebar-bg;
|
||||
|
||||
form {
|
||||
.flex-parent(1, 1, auto);
|
||||
|
||||
> ul {
|
||||
.flex(1, 1, auto);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
> .vis-edit-sidebar-buttons {
|
||||
.flex(0, 0, auto)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item-title {
|
||||
|
|
|
@ -2,6 +2,7 @@ var express = require('express');
|
|||
var path = require('path');
|
||||
var favicon = require('serve-favicon');
|
||||
var requestLogger = require('./lib/requestLogger');
|
||||
var auth = require('./lib/auth');
|
||||
var appHeaders = require('./lib/appHeaders');
|
||||
var cookieParser = require('cookie-parser');
|
||||
var bodyParser = require('body-parser');
|
||||
|
@ -18,9 +19,10 @@ app.set('views', path.join(__dirname, 'views'));
|
|||
app.set('view engine', 'jade');
|
||||
app.set('x-powered-by', false);
|
||||
|
||||
app.use(favicon(path.join(config.public_folder, 'styles', 'theme', 'elk.ico')));
|
||||
app.use(requestLogger());
|
||||
app.use(auth());
|
||||
app.use(appHeaders());
|
||||
app.use(favicon(path.join(config.public_folder, 'styles', 'theme', 'elk.ico')));
|
||||
|
||||
if (app.get('env') === 'development') {
|
||||
require('./dev')(app);
|
||||
|
|
|
@ -7,14 +7,24 @@ var configPath = process.env.CONFIG_PATH || path.join(__dirname, 'kibana.yml');
|
|||
var kibana = yaml.safeLoad(fs.readFileSync(configPath, 'utf8'));
|
||||
var env = process.env.NODE_ENV || 'development';
|
||||
|
||||
function checkPath(path) {
|
||||
try {
|
||||
fs.statSync(path);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the local public folder is present. This means we are running in
|
||||
// the NPM module. If it's not there then we are running in the git root.
|
||||
var public_folder = path.resolve(__dirname, '..', 'public');
|
||||
try {
|
||||
fs.statSync(public_folder);
|
||||
} catch (err) {
|
||||
public_folder = path.resolve(__dirname, '..', '..', 'kibana');
|
||||
}
|
||||
if (!checkPath(public_folder)) public_folder = path.resolve(__dirname, '..', '..', 'kibana');
|
||||
|
||||
// Check to see if htpasswd file exists in the root directory otherwise set it to false
|
||||
var htpasswdPath = path.resolve(__dirname, '..', '.htpasswd');
|
||||
if (!checkPath(htpasswdPath)) htpasswdPath = path.resolve(__dirname, '..', '..', '..', '.htpasswd');
|
||||
if (!checkPath(htpasswdPath)) htpasswdPath = false;
|
||||
|
||||
var packagePath = path.resolve(__dirname, '..', 'package.json');
|
||||
try {
|
||||
|
@ -33,7 +43,8 @@ var config = module.exports = {
|
|||
external_plugins_folder : process.env.PLUGINS_FOLDER || null,
|
||||
bundled_plugins_folder : path.resolve(public_folder, 'plugins'),
|
||||
kibana : kibana,
|
||||
package : require(packagePath)
|
||||
package : require(packagePath),
|
||||
htpasswd : htpasswdPath
|
||||
};
|
||||
|
||||
config.plugins = listPlugins(config);
|
||||
|
|
|
@ -38,3 +38,7 @@ verify_ssl: true
|
|||
# the path of the pem file here.
|
||||
# ca: /path/to/your/CA.pem
|
||||
|
||||
# SSL for outgoing requests from the Kibana Server (PEM formatted)
|
||||
# ssl_key_file: /path/to/your/server.key
|
||||
# ssl_cert_file: /path/to/your/server.crt
|
||||
|
||||
|
|
|
@ -3,18 +3,35 @@
|
|||
*/
|
||||
|
||||
var app = require('./app');
|
||||
var http = require('http');
|
||||
var fs = require('fs');
|
||||
var config = require('./config');
|
||||
var logger = require('./lib/logger');
|
||||
var Promise = require('bluebird');
|
||||
var initialization = require('./lib/serverInitialization');
|
||||
var key, cert;
|
||||
try {
|
||||
key = fs.readFileSync(config.kibana.ssl_key_file, 'utf8');
|
||||
cert = fs.readFileSync(config.kibana.ssl_cert_file, 'utf8');
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
logger.fatal('Failed to read %s', err.path);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create HTTP server.
|
||||
* Create HTTPS/HTTP server.
|
||||
*/
|
||||
|
||||
var server = http.createServer(app);
|
||||
var server;
|
||||
if (key && cert) {
|
||||
server = require('https').createServer({
|
||||
key: key,
|
||||
cert: cert
|
||||
}, app);
|
||||
} else {
|
||||
server = require('http').createServer(app);
|
||||
}
|
||||
server.on('error', onError);
|
||||
server.on('listening', onListening);
|
||||
|
||||
|
|
10
src/server/lib/auth.js
Normal file
10
src/server/lib/auth.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
var config = require('../config');
|
||||
var httpAuth = require('http-auth');
|
||||
module.exports = function () {
|
||||
var basic;
|
||||
if (config.htpasswd) {
|
||||
basic = httpAuth.basic({ file: config.htpasswd });
|
||||
return httpAuth.connect(basic);
|
||||
}
|
||||
return function (req, res, next) { return next(); };
|
||||
};
|
|
@ -97,6 +97,7 @@ define(function (require) {
|
|||
var vis;
|
||||
beforeEach(function () {
|
||||
vis = {
|
||||
indexPattern: indexPattern,
|
||||
type: {
|
||||
schemas: new Schemas([
|
||||
{
|
||||
|
@ -140,7 +141,7 @@ define(function (require) {
|
|||
it('should NOT set the defaults defined in the schema when some exist', function () {
|
||||
var ac = new AggConfigs(vis, [{ schema: 'segment', type: 'date_histogram' }]);
|
||||
expect(ac).to.have.length(3);
|
||||
expect(ac.bySchemaName['segment'][0].type.name).to.equal('date_histogram');
|
||||
expect(ac.bySchemaName.segment[0].type.name).to.equal('date_histogram');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,49 +1,11 @@
|
|||
define(function (require) {
|
||||
var metricVis = {
|
||||
aggs: [{
|
||||
type: {name: 'count'},
|
||||
schema: 'metric',
|
||||
makeLabel: function () {
|
||||
return 'Count of documents';
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
var averageVis = {
|
||||
aggs: [{
|
||||
id: 'agg',
|
||||
type: {name: 'average'},
|
||||
schema: 'metric',
|
||||
makeLabel: function () {
|
||||
return 'Average bytes';
|
||||
},
|
||||
fieldFormatter: function () {
|
||||
return function (val) {
|
||||
return val;
|
||||
};
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
var fieldFormatterVis = {
|
||||
aggs: [{
|
||||
id: 'agg',
|
||||
type: {name: 'average'},
|
||||
schema: 'metric',
|
||||
makeLabel: function () {
|
||||
return 'Average bytes';
|
||||
},
|
||||
fieldFormatter: function () {
|
||||
return function (val) {
|
||||
return val.toFixed(3);
|
||||
};
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
describe('metric vis', function () {
|
||||
var $scope;
|
||||
|
||||
var formatter = function (value) {
|
||||
return value.toFixed(3);
|
||||
};
|
||||
|
||||
beforeEach(module('kibana/metric_vis'));
|
||||
beforeEach(inject(function ($rootScope, $controller) {
|
||||
$scope = $rootScope.$new();
|
||||
|
@ -51,44 +13,49 @@ define(function (require) {
|
|||
$scope.$digest();
|
||||
}));
|
||||
|
||||
it('should set the metric', function () {
|
||||
expect($scope).to.have.property('metric');
|
||||
it('should set the metric label and value', function () {
|
||||
$scope.processTableGroups({
|
||||
tables: [{
|
||||
columns: [{title: 'Count'}],
|
||||
rows: [[4301021]],
|
||||
aggConfig: function () {
|
||||
return {
|
||||
fieldFormatter: function () {
|
||||
return formatter;
|
||||
}
|
||||
};
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
expect($scope.metrics.length).to.be(1);
|
||||
expect($scope.metrics[0].label).to.be('Count');
|
||||
expect($scope.metrics[0].value).to.be('4301021.000');
|
||||
});
|
||||
|
||||
it('should set the metric label and value for count', function () {
|
||||
expect($scope.metric.label).to.not.be.ok();
|
||||
expect($scope.metric.value).to.not.be.ok();
|
||||
it('should support multi-value metrics', function () {
|
||||
$scope.processTableGroups({
|
||||
tables: [{
|
||||
columns: [
|
||||
{title: '1st percentile of bytes'},
|
||||
{title: '99th percentile of bytes'}
|
||||
],
|
||||
rows: [[182, 445842.4634666484]],
|
||||
aggConfig: function () {
|
||||
return {
|
||||
fieldFormatter: function () {
|
||||
return formatter;
|
||||
}
|
||||
};
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
$scope.vis = metricVis;
|
||||
$scope.esResponse = {hits: {total: 4826}};
|
||||
$scope.$digest();
|
||||
|
||||
expect($scope.metric.label).to.be('Count of documents');
|
||||
expect($scope.metric.value).to.be($scope.esResponse.hits.total);
|
||||
});
|
||||
|
||||
it('should set the metric value for average', function () {
|
||||
expect($scope.metric.label).to.not.be.ok();
|
||||
expect($scope.metric.value).to.not.be.ok();
|
||||
|
||||
$scope.vis = averageVis;
|
||||
$scope.esResponse = {hits: {total: 4826}, aggregations: {agg: {value: 1234}}};
|
||||
$scope.$digest();
|
||||
|
||||
expect($scope.metric.label).to.be('Average bytes');
|
||||
expect($scope.metric.value).to.be($scope.esResponse.aggregations.agg.value);
|
||||
});
|
||||
|
||||
it('should use the field formatter', function () {
|
||||
expect($scope.metric.label).to.not.be.ok();
|
||||
expect($scope.metric.value).to.not.be.ok();
|
||||
|
||||
$scope.vis = fieldFormatterVis;
|
||||
$scope.esResponse = {hits: {total: 4826}, aggregations: {agg: {value: 1234.12345}}};
|
||||
$scope.$digest();
|
||||
|
||||
expect($scope.metric.label).to.be('Average bytes');
|
||||
expect($scope.metric.value).to.be($scope.esResponse.aggregations.agg.value.toFixed(3));
|
||||
expect($scope.metrics.length).to.be(2);
|
||||
expect($scope.metrics[0].label).to.be('1st percentile of bytes');
|
||||
expect($scope.metrics[0].value).to.be('182.000');
|
||||
expect($scope.metrics[1].label).to.be('99th percentile of bytes');
|
||||
expect($scope.metrics[1].value).to.be('445842.463');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue