summaryrefslogtreecommitdiffstats
path: root/cvp/3rd_party/static/testapi-ui/components/results-report
diff options
context:
space:
mode:
authorgrakiss <grakiss.wanglei@huawei.com>2017-09-28 03:47:54 -0400
committergrakiss <grakiss.wanglei@huawei.com>2017-09-28 05:15:01 -0400
commit0cf6b232ac9cf128ee9183a27c08f4f74ab2e2e6 (patch)
tree7be233b8f8f65fa968c7b93f1d1e75b691952ed9 /cvp/3rd_party/static/testapi-ui/components/results-report
parent63c2e2aa4b8d86349a767f611123ceafc19fa6d6 (diff)
add api&web services for cvp
JIRA: DOVETAIL-512 add api&web services for cvp Change-Id: I9ef9525e980fe61dc3108035ef9a3ff8783b2697 Signed-off-by: grakiss <grakiss.wanglei@huawei.com>
Diffstat (limited to 'cvp/3rd_party/static/testapi-ui/components/results-report')
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/results-report/partials/editTestModal.html65
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/results-report/partials/fullTestListModal.html13
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/results-report/partials/reportDetails.html65
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/results-report/resultsReport.html46
-rw-r--r--cvp/3rd_party/static/testapi-ui/components/results-report/resultsReportController.js182
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()">&times;</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();
+ }
+
+})();