diff --git a/app/js/controllers/tests-detail.js b/app/js/controllers/tests-detail.js
new file mode 100644
index 00000000..f7876a5f
--- /dev/null
+++ b/app/js/controllers/tests-detail.js
@@ -0,0 +1,82 @@
+'use strict';
+
+var controllersModule = require('./_index');
+var _ = require('underscore');
+
+/**
+ * @ngInject
+ */
+function TestsDetailController($scope, healthService, testService, key, $location) {
+
+ // ViewModel
+ var vm = this;
+ vm.searchTest = '';
+ vm.key = decodeURIComponent(key);
+
+ vm.processData = function(data) {
+ vm.chartData = {};
+
+ var testsByHierarchy = _.groupBy(data.tests, function(test) {
+ var testId = testService.removeIdNoise(test.test_id);
+ var keyMatcher = /^(\w*)\./g;
+ var matches = keyMatcher.exec(testId);
+
+ if (matches) {
+ return matches[1];
+ }
+
+ return 'Others';
+ });
+
+ var getTestFailureAvg = function(test) {
+ return test.failure / test.run_count;
+ };
+
+ _.each(testsByHierarchy, function(tests, hierarchy, list) {
+ if (!vm.chartData[hierarchy]) {
+ vm.chartData[hierarchy] = [{
+ key: hierarchy,
+ values: [],
+ tests: []
+ }];
+ }
+
+ var orderedTests = _.sortBy(tests, function(test) {
+ return getTestFailureAvg(test) * -1;
+ });
+
+ var topFailures = _.first(orderedTests, 10);
+
+ topFailures.forEach(function(test) {
+ var failureAverage = getTestFailureAvg(test);
+ if (!isNaN(failureAverage) && parseFloat(failureAverage) > 0.01) {
+ var chartData = {
+ label: test.test_id,
+ value: failureAverage
+ };
+ vm.chartData[hierarchy][0].values.push(chartData);
+ }
+ });
+
+ orderedTests.forEach(function(test) {
+ test.failureAverage = getTestFailureAvg(test);
+ vm.chartData[hierarchy][0].tests.push(test);
+ });
+ });
+ };
+
+ vm.loadData = function() {
+ healthService.getTests().then(function(response) {
+ vm.processData(response.data);
+ });
+ };
+
+ vm.searchTest = $location.search().searchTest || '';
+
+ vm.loadData();
+
+ vm.onSearchChange = function() {
+ $location.search('searchTest', $scope.testsDetail.searchTest);
+ };
+}
+controllersModule.controller('TestsDetailController', TestsDetailController);
diff --git a/app/js/controllers/tests.js b/app/js/controllers/tests.js
index 227fac0d..87777557 100644
--- a/app/js/controllers/tests.js
+++ b/app/js/controllers/tests.js
@@ -27,40 +27,15 @@ function TestsController($scope, healthService, testService, $location) {
return 'Others';
});
- var getTestFailureAvg = function(test) {
- return test.failure / test.run_count;
- };
-
- _.each(testsByHierarchy, function(tests, hierarchy, list) {
- if (!vm.chartData[hierarchy]) {
- vm.chartData[hierarchy] = [{
- key: hierarchy,
+ var sortedKeys = _.sortBy(_.keys(testsByHierarchy));
+ _.each(sortedKeys, function(key) {
+ if (!vm.chartData[key]) {
+ vm.chartData[key] = [{
+ key: key,
values: [],
tests: []
}];
}
-
- var orderedTests = _.sortBy(tests, function(test) {
- return getTestFailureAvg(test) * -1;
- });
-
- var topFailures = _.first(orderedTests, 10);
-
- topFailures.forEach(function(test) {
- var failureAverage = getTestFailureAvg(test);
- if (!isNaN(failureAverage) && parseFloat(failureAverage) > 0.01) {
- var chartData = {
- label: test.test_id,
- value: failureAverage
- };
- vm.chartData[hierarchy][0].values.push(chartData);
- }
- });
-
- orderedTests.forEach(function(test) {
- test.failureAverage = getTestFailureAvg(test);
- vm.chartData[hierarchy][0].tests.push(test);
- });
});
};
diff --git a/app/js/on_config.js b/app/js/on_config.js
index 6a3bd252..2f7b8ef9 100644
--- a/app/js/on_config.js
+++ b/app/js/on_config.js
@@ -31,6 +31,17 @@ function OnConfig($stateProvider, $locationProvider, $urlRouterProvider) {
templateUrl: 'tests.html',
title: 'Tests'
})
+ .state('testsDetail', {
+ url: '/tests/:key',
+ controller: 'TestsDetailController as testsDetail',
+ templateUrl: 'tests-detail.html',
+ title: 'Tests Detail',
+ resolve: /*@ngInject*/ {
+ 'key': function($stateParams) {
+ return $stateParams.key;
+ }
+ }
+ })
.state('job', {
url: '/job/:jobName',
controller: 'JobController as job',
diff --git a/app/js/services/health-api.js b/app/js/services/health-api.js
index 4bfa50e9..44139dbe 100644
--- a/app/js/services/health-api.js
+++ b/app/js/services/health-api.js
@@ -100,6 +100,7 @@ function HealthService($http, config) {
service.getTests = function() {
return config.get().then(function(config) {
return $http.jsonp(config.apiRoot + '/tests', {
+ cache: true,
params: { callback: 'JSON_CALLBACK' }
});
});
diff --git a/app/views/tests-detail.html b/app/views/tests-detail.html
new file mode 100644
index 00000000..733106c2
--- /dev/null
+++ b/app/views/tests-detail.html
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Test ID
+ |
+
+ Passed
+ |
+
+ Failed
+ |
+
+ Failure %
+ |
+
+ Avg. Runtime (secs.)
+ |
+
+
+
+
+
+ {{test.test_id | limitTo: 110}}
+ |
+ {{ test.success | number }} |
+ {{ test.failure | number }} |
+ {{ test.failureAverage * 100 | number: 2 }}% |
+ {{ test.run_time | number: 2 }} |
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/tests.html b/app/views/tests.html
index a016e000..4fe4a2af 100644
--- a/app/views/tests.html
+++ b/app/views/tests.html
@@ -13,58 +13,18 @@
-
-
-
-
-
-
-
-
-
- Test ID
- |
-
- Passed
- |
-
- Failed
- |
-
- Failure %
- |
-
- Avg. Runtime (secs.)
- |
-
-
-
-
-
- {{test.test_id | limitTo: 110}}
- |
- {{ test.success | number }} |
- {{ test.failure | number }} |
- {{ test.failureAverage * 100 | number: 2 }}% |
- {{ test.run_time | number: 2 }} |
-
-
-
+
-
diff --git a/test/unit/controllers/tests_detail_spec.js b/test/unit/controllers/tests_detail_spec.js
new file mode 100644
index 00000000..186fb1c5
--- /dev/null
+++ b/test/unit/controllers/tests_detail_spec.js
@@ -0,0 +1,107 @@
+describe('TestsDetailController', function() {
+ beforeEach(function() {
+ module('app');
+ module('app.controllers');
+ });
+
+ var $scope, $httpBackend, $controller, healthService;
+ var API_ROOT = 'http://8.8.4.4:8080';
+ var DEFAULT_START_DATE = new Date();
+
+ beforeEach(inject(function($rootScope, _$httpBackend_, _$controller_, _healthService_) {
+ $httpBackend = _$httpBackend_;
+
+ mockConfigService();
+ mockHealthService();
+
+ $scope = $rootScope.$new();
+ $controller = _$controller_;
+ healthService = _healthService_;
+ }));
+
+ function mockHealthService() {
+ var expectedResponse = {
+ tests: [
+ {
+ failure: 5592,
+ id: '00187173-ab23-4181-9a15-e291a0d8e2d1',
+ run_count: 55920,
+ run_time: 0.608151,
+ success: 55920,
+ test_id: 'tempest.api.identity.admin.v2.test_users.one'
+ },
+ {
+ failure: 0,
+ id: '001c6860-c966-4c0b-9928-ecccd162bed0',
+ run_count: 4939,
+ run_time: 5.97596,
+ success: 4939,
+ test_id: 'tempest.api.volume.admin.test_snapshots_actions.two'
+ },
+ {
+ failure: 1,
+ id: '002a15e0-f6d1-472a-bd66-bb13ac4d77aa',
+ run_count: 32292,
+ run_time: 1.18864,
+ success: 32291,
+ test_id: 'tempest.api.network.test_routers.three'
+ }
+ ]
+ };
+
+ var endpoint = API_ROOT + '/tests?callback=JSON_CALLBACK';
+ $httpBackend.expectJSONP(endpoint)
+ .respond(200, expectedResponse);
+ }
+
+ function mockConfigService() {
+ var expectedResponse = { apiRoot: API_ROOT };
+ var endpoint = 'config.json';
+ $httpBackend.expectGET(endpoint).respond(200, expectedResponse);
+ }
+
+ it('should process chart data correctly', function() {
+ var testsDetailController = $controller('TestsDetailController', {
+ healthService: healthService,
+ $scope: $scope,
+ key: 'tempest'
+ });
+ $httpBackend.flush();
+
+ var expectedChartData = {
+ 'tempest': [{
+ key: 'tempest',
+ values: [{
+ label: 'tempest.api.identity.admin.v2.test_users.one',
+ value: 0.1
+ }],
+ tests: [{
+ failure: 5592,
+ id: '00187173-ab23-4181-9a15-e291a0d8e2d1',
+ run_count: 55920,
+ run_time: 0.608151,
+ success: 55920,
+ test_id: 'tempest.api.identity.admin.v2.test_users.one',
+ failureAverage: 0.1
+ }, {
+ failure: 1,
+ id: '002a15e0-f6d1-472a-bd66-bb13ac4d77aa',
+ run_count: 32292,
+ run_time: 1.18864,
+ success: 32291,
+ test_id: 'tempest.api.network.test_routers.three',
+ failureAverage: 0.0000309674222717701
+ }, {
+ failure: 0,
+ id: '001c6860-c966-4c0b-9928-ecccd162bed0',
+ run_count: 4939,
+ run_time: 5.97596,
+ success: 4939,
+ test_id: 'tempest.api.volume.admin.test_snapshots_actions.two',
+ failureAverage: 0
+ }]
+ }]
+ };
+ expect(testsDetailController.chartData).toEqual(expectedChartData);
+ });
+});
diff --git a/test/unit/controllers/tests_spec.js b/test/unit/controllers/tests_spec.js
index 3988c4c2..ebfdbd23 100644
--- a/test/unit/controllers/tests_spec.js
+++ b/test/unit/controllers/tests_spec.js
@@ -70,35 +70,8 @@ describe('TestsController', function() {
var expectedChartData = {
'tempest': [{
key: 'tempest',
- values: [{
- label: 'tempest.api.identity.admin.v2.test_users.one',
- value: 0.1
- }],
- tests: [{
- failure: 5592,
- id: '00187173-ab23-4181-9a15-e291a0d8e2d1',
- run_count: 55920,
- run_time: 0.608151,
- success: 55920,
- test_id: 'tempest.api.identity.admin.v2.test_users.one',
- failureAverage: 0.1
- }, {
- failure: 1,
- id: '002a15e0-f6d1-472a-bd66-bb13ac4d77aa',
- run_count: 32292,
- run_time: 1.18864,
- success: 32291,
- test_id: 'tempest.api.network.test_routers.three',
- failureAverage: 0.0000309674222717701
- }, {
- failure: 0,
- id: '001c6860-c966-4c0b-9928-ecccd162bed0',
- run_count: 4939,
- run_time: 5.97596,
- success: 4939,
- test_id: 'tempest.api.volume.admin.test_snapshots_actions.two',
- failureAverage: 0
- }]
+ values: [],
+ tests: []
}]
};
expect(testsController.chartData).toEqual(expectedChartData);