/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var App = require('app');
describe('App.WidgetMixin', function () {
var mixinClass = Em.Object.extend(App.WidgetMixin, {metrics: [], content: {}});
describe('#loadMetrics()', function () {
var mixinObject = mixinClass.create();
beforeEach(function () {
this.mock = sinon.stub(mixinObject, 'getRequestData');
sinon.stub(App.WidgetLoadAggregator, 'add');
});
afterEach(function () {
this.mock.restore();
App.WidgetLoadAggregator.add.restore();
});
it('has host_component_criteria', function () {
this.mock.returns({'key1': {host_component_criteria: 'criteria'}});
mixinObject.set('isLoaded', false);
mixinObject.loadMetrics();
expect(App.WidgetLoadAggregator.add.calledOnce).to.be.true;
});
it('host_component_criteria is absent', function () {
this.mock.returns({'key1': {}});
mixinObject.set('isLoaded', false);
mixinObject.loadMetrics();
expect(App.WidgetLoadAggregator.add.calledOnce).to.be.true;
});
});
describe("#extractExpressions()", function () {
var mixinObject = mixinClass.create();
var testCases = [
{
data: '',
result: []
},
{
data: 'text',
result: []
},
{
data: 'text${a}',
result: ['a']
},
{
data: 'text${a} - ${a.b}',
result: ['a', 'a.b']
},
{
data: '${o.a-(b+4)/cc*tt}',
result: ['o.a-(b+4)/cc*tt']
}
];
testCases.forEach(function (test) {
it('input: ' + test.data, function () {
var input = {value: test.data};
expect(mixinObject.extractExpressions(input)).to.eql(test.result);
});
});
it('input is null', function () {
var input = null;
expect(mixinObject.extractExpressions(input)).to.be.empty;
});
});
describe("#getRequestData()", function () {
var mixinObject = mixinClass.create();
it("", function () {
var data = [
{
"name": "regionserver.Server.percentFilesLocal",
"metric_path": "metrics/hbase/regionserver/percentFilesLocal",
"service_name": "HBASE",
"component_name": "HBASE_REGIONSERVER"
},
{
"name": "regionserver.Server.percentFilesLocal2",
"metric_path": "w2",
"service_name": "HBASE",
"component_name": "HBASE_REGIONSERVER"
},
{
"name": "regionserver.Server.percentFilesLocal",
"metric_path": "metrics/hbase/regionserver/percentFilesLocal",
"service_name": "HBASE",
"component_name": "HBASE_REGIONSERVER",
"host_component_criteria": 'c1'
},
{
"name": "regionserver.Server.percentFilesLocal",
"metric_path": "metrics/hbase/regionserver/percentFilesLocal",
"service_name": "HDFS",
"component_name": "DATANODE",
"host_component_criteria": 'c1'
}
];
expect(JSON.stringify(mixinObject.getRequestData(data))).to.eql(JSON.stringify({
"HBASE_HBASE_REGIONSERVER": {
"name": "regionserver.Server.percentFilesLocal",
"service_name": "HBASE",
"component_name": "HBASE_REGIONSERVER",
"metric_paths": [
{
"metric_path": "metrics/hbase/regionserver/percentFilesLocal",
"metric_type": "POINT_IN_TIME",
"id": "metrics/hbase/regionserver/percentFilesLocal_POINT_IN_TIME",
"context": {}
},
{
"metric_path": "w2",
"metric_type": "POINT_IN_TIME",
"id": "w2_POINT_IN_TIME",
"context": {}
}
]
},
"HBASE_HBASE_REGIONSERVER_c1": {
"name": "regionserver.Server.percentFilesLocal",
"service_name": "HBASE",
"component_name": "HBASE_REGIONSERVER",
"host_component_criteria": "c1",
"metric_paths": [
{
"metric_path": "metrics/hbase/regionserver/percentFilesLocal",
"metric_type": "POINT_IN_TIME",
"id": "metrics/hbase/regionserver/percentFilesLocal_POINT_IN_TIME",
"context": {}
}
]
},
"HDFS_DATANODE_c1": {
"name": "regionserver.Server.percentFilesLocal",
"service_name": "HDFS",
"component_name": "DATANODE",
"host_component_criteria": "c1",
"metric_paths": [
{
"metric_path": "metrics/hbase/regionserver/percentFilesLocal",
"metric_type": "POINT_IN_TIME",
"id": "metrics/hbase/regionserver/percentFilesLocal_POINT_IN_TIME",
"context": {}
}
]
}
}));
});
});
describe("#getServiceComponentMetrics()", function () {
var mixinObject = mixinClass.create();
before(function () {
sinon.stub(App.ajax, 'send');
});
after(function () {
App.ajax.send.restore();
});
it("", function () {
var request = {
service_name: 'S1',
component_name: 'C1',
metric_paths: [
{
"metric_path": "w1",
"metric_type": "POINT_IN_TIME",
"id": "w1_POINT_IN_TIME",
"context": {}
},
{
"metric_path": "w2",
"metric_type": "POINT_IN_TIME",
"id": "w2_POINT_IN_TIME",
"context": {}
}
]
};
mixinObject.getServiceComponentMetrics(request);
expect(App.ajax.send.getCall(0).args[0]).to.eql({
name: 'widgets.serviceComponent.metrics.get',
sender: mixinObject,
data: {
serviceName: 'S1',
componentName: 'C1',
metricPaths: 'w1,w2'
}
})
});
});
describe("#getMetricsSuccessCallback()", function () {
var mixinObject = mixinClass.create();
it("", function () {
var data = {
metrics: {
"hbase": {
"ipc": {
"IPC": {
"numOpenConnections": 11.5
}
}
}
}
};
mixinObject.set('content.metrics', [
{
metric_path: 'metrics/hbase/ipc/IPC/numOpenConnections'
}
]);
mixinObject.getMetricsSuccessCallback(data);
expect(mixinObject.get('metrics').findProperty('metric_path', 'metrics/hbase/ipc/IPC/numOpenConnections').data).to.equal(11.5);
});
});
describe("#getHostComponentMetrics()", function () {
var mixinObject = mixinClass.create();
before(function () {
sinon.stub(App.ajax, 'send');
sinon.stub(mixinObject, 'computeHostComponentCriteria').returns('criteria')
});
after(function () {
App.ajax.send.restore();
mixinObject.computeHostComponentCriteria.restore();
});
it("", function () {
var request = {
component_name: 'C1',
metric_paths: [
{
"metric_path": "w1",
"metric_type": "POINT_IN_TIME",
"id": "w1_POINT_IN_TIME",
"context": {}
},
{
"metric_path": "w2",
"metric_type": "POINT_IN_TIME",
"id": "w2_POINT_IN_TIME",
"context": {}
}
],
host_component_criteria: 'c1'
};
mixinObject.getHostComponentMetrics(request);
expect(App.ajax.send.getCall(0).args[0]).to.eql({
name: 'widgets.hostComponent.metrics.get',
sender: mixinObject,
data: {
componentName: 'C1',
metricPaths: 'w1,w2',
hostComponentCriteria: 'criteria'
}
})
});
});
describe("#calculateValues()", function () {
var mixinObject = mixinClass.create();
beforeEach(function () {
sinon.stub(mixinObject, 'extractExpressions');
this.mock = sinon.stub(mixinObject, 'computeExpression');
});
afterEach(function () {
mixinObject.extractExpressions.restore();
this.mock.restore();
});
it("value compute correctly", function () {
this.mock.returns({'${a}': 1});
mixinObject.set('content.values', [{
value: '${a}'
}]);
mixinObject.calculateValues();
expect(mixinObject.get('content.values')[0].computedValue).to.equal('1');
});
it("value not available", function () {
this.mock.returns({});
mixinObject.set('content.values', [{
value: '${a}'
}]);
mixinObject.calculateValues();
expect(mixinObject.get('content.values')[0].computedValue).to.equal('n/a');
});
it("value is null", function () {
this.mock.returns({'${a}': null});
mixinObject.set('content.values', [{
value: '${a}'
}]);
mixinObject.calculateValues();
expect(mixinObject.get('content.values')[0].computedValue).to.equal('n/a');
});
});
describe("#computeExpression()", function () {
var mixinObject = mixinClass.create();
it("expression missing metrics", function () {
var expressions = ['e.m1'];
var metrics = [];
expect(mixinObject.computeExpression(expressions, metrics)).to.eql({
"${e.m1}": ""
});
});
it("Value is not correct mathematical expression", function () {
var expressions = ['e.m1'];
var metrics = [{
name: 'e.m1',
data: 'a+1'
}];
expect(mixinObject.computeExpression(expressions, metrics)).to.eql({
"${e.m1}": ""
});
});
it("correct expression", function () {
var expressions = ['e.m1+e.m1'];
var metrics = [{
name: 'e.m1',
data: 1
}];
expect(mixinObject.computeExpression(expressions, metrics)).to.eql({
"${e.m1+e.m1}": "2"
});
});
});
describe("#cloneWidget()", function () {
var mixinObject = mixinClass.create();
before(function () {
sinon.spy(App, 'showConfirmationPopup');
sinon.stub(mixinObject, 'postWidgetDefinition', Em.K);
});
after(function () {
App.showConfirmationPopup.restore();
mixinObject.postWidgetDefinition.restore();
});
it("", function () {
var popup = mixinObject.cloneWidget();
expect(App.showConfirmationPopup.calledOnce).to.be.true;
popup.onPrimary();
expect(mixinObject.postWidgetDefinition.calledOnce).to.be.true;
});
});
describe("#postWidgetDefinition()", function () {
var mixinObject = mixinClass.create();
before(function () {
sinon.spy(App.ajax, 'send');
sinon.stub(mixinObject, 'collectWidgetData').returns({});
});
after(function () {
App.ajax.send.restore();
mixinObject.collectWidgetData.restore();
});
it("", function () {
mixinObject.postWidgetDefinition();
expect(App.ajax.send.getCall(0).args[0]).to.eql({
name: 'widgets.wizard.add',
sender: mixinObject,
data: {
data: {}
},
success: 'postWidgetDefinitionSuccessCallback'
});
});
});
});
describe('App.WidgetLoadAggregator', function () {
var aggregator = App.WidgetLoadAggregator;
describe("#add()", function () {
beforeEach(function () {
sinon.stub(window, 'setTimeout').returns('timeId');
});
afterEach(function () {
window.setTimeout.restore();
});
it("timeout started", function () {
aggregator.set('timeoutId', 'timeId');
aggregator.get('requests').clear();
aggregator.add({});
expect(aggregator.get('requests')).to.not.be.empty;
expect(window.setTimeout.called).to.be.false;
});
it("timeout started", function () {
aggregator.set('timeoutId', null);
aggregator.get('requests').clear();
aggregator.add({});
expect(aggregator.get('requests')).to.not.be.empty;
expect(window.setTimeout.calledOnce).to.be.true;
expect(aggregator.get('timeoutId')).to.equal('timeId');
});
});
describe("#groupRequests()", function () {
it("", function () {
var requests = [
{
startCallName: 'n1',
data: {
component_name: 'C1',
metric_paths: ['m1']
},
context: Em.Object.create({
content: {
widgetType: 'GRAPH'
}
})
},
{
startCallName: 'n1',
data: {
component_name: 'C1',
metric_paths: ['m2']
},
context: Em.Object.create({
content: {
widgetType: 'NUMBER'
}
})
},
{
startCallName: 'n2',
data: {
component_name: 'C1',
metric_paths: ['m3']
},
context: Em.Object.create({
content: {
widgetType: 'TEMPLATE'
}
})
},
{
startCallName: 'n1',
data: {
component_name: 'C2',
metric_paths: ['m4']
},
context: Em.Object.create({
content: {
widgetType: 'GAUGE'
}
})
}
];
var result = aggregator.groupRequests(requests);
expect(result['n1_C1'].subRequests.length).to.equal(1);
expect(result['n1_C1'].data.metric_paths.length).to.equal(1);
expect(result['n1_C1_graph'].subRequests.length).to.equal(1);
expect(result['n1_C1_graph'].data.metric_paths.length).to.equal(1);
expect(result['n2_C1'].subRequests.length).to.equal(1);
expect(result['n2_C1'].data.metric_paths.length).to.equal(1);
expect(result['n1_C2'].subRequests.length).to.equal(1);
expect(result['n1_C2'].data.metric_paths.length).to.equal(1);
});
});
describe("#runRequests()", function () {
var mock = Em.Object.create({
f1: function () {
return {
done: Em.K,
complete: Em.K
}
},
state: 'inDOM'
});
beforeEach(function () {
sinon.stub(aggregator, 'groupRequests', function (requests) {
return requests;
});
sinon.spy(mock, 'f1');
});
afterEach(function () {
aggregator.groupRequests.restore();
mock.f1.restore();
});
it("view in DOM", function () {
var requests = {
'r1': {
data: {
metric_paths: ['m1', 'm1', 'm2']
},
context: mock,
startCallName: 'f1'
}
};
aggregator.runRequests(requests);
expect(mock.f1.calledWith(requests['r1'].data)).to.be.true;
});
it("view destroyed", function () {
var requests = {
'r1': {
data: {
metric_paths: ['m1', 'm1', 'm2']
},
context: mock,
startCallName: 'f1'
}
};
mock.set('state', 'destroyed');
aggregator.runRequests(requests);
expect(mock.f1.called).to.be.false;
});
});
});