diff options
Diffstat (limited to 'cvp/3rd_party/static/testapi-ui/components/results-report')
5 files changed, 371 insertions, 0 deletions
diff --git a/cvp/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html b/cvp/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html new file mode 100644 index 00000000..583c9b92 --- /dev/null +++ b/cvp/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html @@ -0,0 +1,65 @@ +<div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" aria-hidden="true" ng-click="modal.close()">×</button> + <h4>Edit Test Run Metadata</h4> + <p>Make changes to your test metadata.</p> + </div> + <div class="modal-body"> + <div class="form-group"> + <strong>Publicly Shared:</strong> + <select ng-model="modal.metaCopy.shared" + class="form-control"> + <option value="true">Yes</option> + <option value="">No</option> + </select> + <br /> + <strong>Associated Guideline:</strong> + <select ng-model="modal.metaCopy.guideline" + ng-options="o as o.slice(0, -5) for o in modal.versionList" + class="form-control"> + <option value="">None</option> + </select> + <br /> + <strong>Associated Target Program:</strong> + <select ng-model="modal.metaCopy.target" + class="form-control"> + <option value="">None</option> + <option value="platform">OpenStack Powered Platform</option> + <option value="compute">OpenStack Powered Compute</option> + <option value="object">OpenStack Powered Object Storage</option> + </select> + <hr> + <strong>Associated Product:</strong> + <select ng-options="product as product.name for product in modal.products | arrayConverter | orderBy: 'name' track by product.id" + ng-model="modal.selectedProduct" + ng-change="modal.getProductVersions()" + class="form-control"> + <option value="">-- No Product --</option> + </select> + + <span ng-if="modal.productVersions.length"> + <strong>Product Version:</strong> + <select ng-options="version as version.version for version in modal.productVersions | orderBy: 'version' track by version.id" + ng-model="modal.selectedVersion" + class="form-control"> + </select> + + </span> + + </div> + <div ng-show="modal.showError" class="alert alert-danger" role="alert"> + <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> + <span class="sr-only">Error:</span> + {{modal.error}} + </div> + <div ng-show="modal.showSuccess" class="alert alert-success" role="success"> + <span class="glyphicon glyphicon-ok" aria-hidden="true"></span> + <span class="sr-only">Success:</span> + Changes saved successfully. + </div> + </div> + <div class="modal-footer"> + <button class="btn btn-primary" type="button" ng-click="modal.saveChanges()">Save Changes</button> + <button class="btn btn-primary" type="button" ng-click="modal.close()">Close</button> + </div> +</div> diff --git a/cvp/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html b/cvp/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html new file mode 100644 index 00000000..6db198b0 --- /dev/null +++ b/cvp/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html @@ -0,0 +1,13 @@ +<div class="modal-content"> + <div class="modal-header"> + <h4>All Passed Tests ({{modal.tests.length}})</h4> + </div> + <div class="modal-body tests-modal-content"> + <div class="form-group"> + <textarea class="form-control" rows="20" id="tests" wrap="off">{{modal.getTestListString()}}</textarea> + </div> + </div> + <div class="modal-footer"> + <button class="btn btn-primary" type="button" ng-click="modal.close()">Close</button> + </div> +</div> diff --git a/cvp/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html b/cvp/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html new file mode 100644 index 00000000..9f8ed140 --- /dev/null +++ b/cvp/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html @@ -0,0 +1,65 @@ +<!-- +HTML for each accordion group that separates the status types on the results +report page. +--> + +Test Filters:<br /> +<div class="btn-toolbar" role="toolbar"> + <div class="btn-group button-margin" data-toggle="buttons"> + <label class="btn btn-default" ng-class="{'active': ctrl.testStatus === 'total'}"> + <input type="radio" ng-model="ctrl.testStatus" value="total"> + <span class="text-primary">All</span> + </label> + <label class="btn btn-default" ng-class="{'active': ctrl.testStatus === 'passed'}"> + <input type="radio" ng-model="ctrl.testStatus" value="passed"> + <span class="text-success">Passed</span> + </label> + <label class="btn btn-default" ng-class="{'active': ctrl.testStatus === 'not passed'}"> + <input type="radio" ng-model="ctrl.testStatus" value="not passed"> + <span class="text-danger">Not Passed</span> + </label> + </div> + <div class="btn-group button-margin" style="float:right"> + <button type="button" class="btn btn-default" ng-click="ctrl.openAll()">Expand</button> + <button type="button" class="btn btn-default" ng-click="ctrl.folderAll()">Collapse</button> + </div> +</div> + +<uib-accordion-group is-open="isOpen" is-disabled="ctrl.cases == 0"> +<uib-accordion-heading> + {{ ctrl.testId }} + <small> + (<strong>Total:</strong> {{ ctrl.cases.length }} tests) + </small> + <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': isOpen, 'glyphicon-chevron-right': !isOpen}"></i> + </uib-accordion-heading> + <ol class="capabilities"> + <li ng-repeat="testcase in ctrl.cases" ng-show="(ctrl.testStatus == 'passed' && testcase.pass != 0) || (ctrl.testStatus == 'not passed' && testcase.fail != 0) || ctrl.testStatus == 'total'"> + + <a ng-click="testcase.folder = !testcase.folder"> + {{ testcase.build_tag.split('-').pop() }} + <span ng-if="ctrl.testStatus == 'total'" ng-class="{'text-success': testcase.total == testcase.pass, 'text-warning': (testcase.pass < testcase.total && testcase.pass > 0), 'text-danger': testcase.pass == 0}">[{{ testcase.pass }}/{{ testcase.total }}]</span> + <span ng-if="ctrl.testStatus == 'passed'" class="text-success">[{{ testcase.pass }}]</span> + <span ng-if="ctrl.testStatus == 'not passed'" class="text-danger">[{{ testcase.fail }}]</span> + </a> + + <ul class="list-unstyled" uib-collapse="testcase.folder"> + <li ng-if="!testcase.details.success"> + <span ng-class="{'glyphicon glyphicon-ok text-success':testcase.criteria == 'PASS'}" aria-hidden="true"></span> + <span ng-class="{'glyphicon glyphicon-remove text-warning':testcase.criteria != 'PASS'}"></span> + {{ testcase.case_name }} + </li> + + <li ng-repeat="sub in testcase.details.success" ng-if="testcase.details.success && ctrl.testStatus != 'not passed'"> + <span class="glyphicon glyphicon-ok text-success" aria-hidden="true"></span> + <a ng-click="ctrl.gotoDoc(sub)">{{ sub }}</a> + </li> + + <li ng-repeat="sub in testcase.details.errors" ng-if="testcase.details.errors && ctrl.testStatus != 'passed'"> + <span class="glyphicon glyphicon-remove text-warning"></span> + <a ng-click="ctrl.gotoDoc(sub)">{{ sub }}</a> + </li> + </ul> + </li> + </ol> +</uib-accordion-group> diff --git a/cvp/3rd_party/static/testapi-ui/components/results-report/resultsReport.html b/cvp/3rd_party/static/testapi-ui/components/results-report/resultsReport.html new file mode 100644 index 00000000..537a3460 --- /dev/null +++ b/cvp/3rd_party/static/testapi-ui/components/results-report/resultsReport.html @@ -0,0 +1,46 @@ +<h3>Test Run Results</h3> + +<div ng-show="ctrl.testId" class="container-fluid"> + <div class="row"> + <div class="pull-left"> + <div class="test-report"> + <strong>Test ID:</strong> {{ctrl.testId}}<br /> + </div> + </div> + </div> +</div> + +<strong>Total: {{ctrl.total}}, Pass: {{ ctrl.mandatory_pass + ctrl.optional_pass }}, Rate: {{ (ctrl.mandatory_pass + ctrl.optional_pass) / ctrl.total * 100 | number:2 }}%</strong></br> +<strong>Mandatory Total: {{ctrl.mandatory_total}}, Pass: {{ ctrl.mandatory_pass }}, Rate: {{ ctrl.mandatory_pass / ctrl.mandatory_total * 100 | number:2 }}%</strong></br> +<strong>Optional Total: {{ctrl.optional_total}}, Pass: {{ ctrl.optional_pass }}, Rate: {{ ctrl.optional_pass / ctrl.optional_total * 100 | number:2 }}%</strong></br> + +<div ng-show="ctrl.cases"> + <hr > + + <div ng-show="ctrl.cases"> + + <hr> + <h4>Test Result Overview</h4> + + <uib-accordion close-others=false> + <!-- The ng-repeat is used to pass in a local variable to the template. --> + <ng-include + src="ctrl.detailsTemplate" + onload="isOpen = true"> + </ng-include> + <br /> + </uib-accordion> + </div> +</div> + +<!-- +<div class="loading"> + <div cg-busy="{promise:resultsRequest,message:'Loading results'}"></div> +</div> + +<div ng-show="ctrl.showError" class="alert alert-danger" role="alert"> + <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> + <span class="sr-only">Error:</span> + {{ctrl.error}} +</div> +--> diff --git a/cvp/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js b/cvp/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js new file mode 100644 index 00000000..5f8cac8e --- /dev/null +++ b/cvp/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js @@ -0,0 +1,182 @@ +/* + * Licensed 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. + */ + +(function () { + 'use strict'; + + angular + .module('testapiApp') + .controller('ResultsReportController', ResultsReportController); + + ResultsReportController.$inject = [ + '$http', '$stateParams', '$window', + '$uibModal', 'testapiApiUrl', 'raiseAlert' + ]; + + /** + * TestAPI Results Report Controller + * This controller is for the '/results/<test run ID>' page where a user can + * view details for a specific test run. + */ + function ResultsReportController($http, $stateParams, $window, + $uibModal, testapiApiUrl, raiseAlert) { + + var ctrl = this; + + ctrl.getResults = getResults; + ctrl.gotoDoc = gotoDoc; + ctrl.openAll = openAll; + ctrl.folderAll = folderAll; + + /** The testID extracted from the URL route. */ + ctrl.testId = $stateParams.testID; + ctrl.innerId = $stateParams.innerID; + + /** The HTML template that all accordian groups will use. */ + ctrl.detailsTemplate = 'testapi-ui/components/results-report/partials/' + + 'reportDetails.html'; + + ctrl.total = 0; + ctrl.mandatory_total = 0; + ctrl.mandatory_pass = 0; + ctrl.mandatory_fail = 0; + ctrl.optional_total = 0; + ctrl.optional_pass = 0; + ctrl.optional_fail = 0; + + ctrl.testStatus = 'total'; + + + /** + * Retrieve results from the TestAPI API server based on the test + * run id in the URL. This function is the first function that will + * be called from the controller. Upon successful retrieval of results, + * the function that gets the version list will be called. + */ + function getResults() { + ctrl.cases = {}; + $http.get(testapiApiUrl + '/tests/' + ctrl.innerId).success(function(test_data){ + var results = test_data.results; + angular.forEach(results, function(ele){ + var content_url = testapiApiUrl + '/results/' + ele; + ctrl.resultsRequest = + $http.get(content_url).success(function(data) { + var result_case = data; + if(result_case.project_name == 'yardstick'){ + yardstickHandler(result_case); + }else{ + functestHandler(result_case); + } + result_case.folder = true; + ctrl.cases[result_case._id] = result_case; + count(result_case); + }).error(function (error) { + ctrl.showError = true; + ctrl.resultsData = null; + ctrl.error = 'Error retrieving results from server: ' + + angular.toJson(error); + }); + }); + }); + } + + function functestHandler(result_case){ + result_case.total = 0; + result_case.pass = 0; + result_case.fail = 0; + if(result_case.details.success && result_case.details.success.length != 0){ + var sub_cases = result_case.details.success; + if(result_case.case_name != 'refstack_defcore'){ + angular.forEach(sub_cases, function(ele, index){ + sub_cases[index] = ele.split(' ')[ele.split(' ').length - 1]; + }); + } + result_case.details.success = sub_cases; + result_case.total += sub_cases.length; + result_case.pass += sub_cases.length; + } + if(result_case.details.errors && result_case.details.errors.length != 0){ + var sub_cases = result_case.details.errors; + if(result_case.case_name != 'refstack_defcore'){ + angular.forEach(sub_cases, function(ele, index){ + sub_cases[index] = ele.split(' ')[ele.split(' ').length - 1]; + }); + } + result_case.details.errors = sub_cases; + result_case.total += sub_cases.length; + result_case.fail += sub_cases.length; + } + if(result_case.total == 0){ + result_case.total = 1; + if(result_case.criteria == 'PASS'){ + result_case.pass = 1; + }else{ + result_case.fail = 1; + } + } + } + + function yardstickHandler(result_case){ + result_case.total = 0; + result_case.pass = 0; + result_case.fail = 0; + angular.forEach(result_case.details.results, function(ele){ + if(ele.benchmark){ + result_case.total = 1; + if(ele.benchmark.data.sla_pass == 1){ + result_case.criteria = 'PASS'; + result_case.pass = 1; + }else{ + result_case.criteria = 'FAILED'; + result_case.fail = 1; + } + return false; + } + }); + } + + function count(result_case){ + var build_tag = result_case.build_tag; + var tag = build_tag.split('-').pop().split('.')[1]; + ctrl.total += result_case.total; + if(tag == 'ha' || tag == 'defcore' || tag == 'vping'){ + ctrl.mandatory_total += result_case.total; + ctrl.mandatory_pass += result_case.pass; + ctrl.mandatory_fail += result_case.fail; + }else{ + ctrl.optional_total += result_case.total; + ctrl.optional_pass += result_case.pass; + ctrl.optional_fail += result_case.fail; + } + } + + function gotoDoc(sub_case){ + } + + function openAll(){ + angular.forEach(ctrl.cases, function(id, ele){ + ele.folder = false; + }); + } + + function folderAll(){ + angular.forEach(ctrl.cases, function(id, ele){ + ele.folder = true; + }); + } + + getResults(); + } + +})(); |