aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--requirements.txt1
-rw-r--r--run_basicvm_nomulticloud.py1
-rw-r--r--src/onaptests/configuration/settings.py1
-rw-r--r--src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py3
-rw-r--r--src/onaptests/configuration/ubuntu16_nomulticloud_settings.py2
-rw-r--r--src/onaptests/scenario/basic_vm.py4
-rw-r--r--src/onaptests/steps/reports_collection.py35
-rw-r--r--src/onaptests/templates/reporting/base.html.j2231
-rw-r--r--src/onaptests/templates/reporting/reporting.html.j243
9 files changed, 316 insertions, 5 deletions
diff --git a/requirements.txt b/requirements.txt
index 7ed56d2..a2e82b3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
xtesting
openstacksdk
onapsdk>=7.0.0
+jinja2
diff --git a/run_basicvm_nomulticloud.py b/run_basicvm_nomulticloud.py
index e6be410..9ebefb8 100644
--- a/run_basicvm_nomulticloud.py
+++ b/run_basicvm_nomulticloud.py
@@ -20,3 +20,4 @@ if __name__ == "__main__":
basic_vm_instantiate.cleanup()
except ValueError as error:
logger.info("service instance deleted as expected {0}".format(error))
+ basic_vm_instantiate.reports_collection.generate_report()
diff --git a/src/onaptests/configuration/settings.py b/src/onaptests/configuration/settings.py
index 7385fa0..3339082 100644
--- a/src/onaptests/configuration/settings.py
+++ b/src/onaptests/configuration/settings.py
@@ -38,4 +38,5 @@ LOG_CONFIG = {
}
}
+REPORTING_FILE_PATH = "/tmp/reporting.html"
# SOCK_HTTP = "socks5h://127.0.0.1:8080"
diff --git a/src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py b/src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py
index 341dc16..d45b142 100644
--- a/src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py
+++ b/src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py
@@ -2,6 +2,9 @@ import sys
from .settings import * # pylint: disable=W0614
""" Specific ubuntu16 with multicloud and yaml config scenario."""
+SERVICE_DETAILS = ("Onboarding, distribution and instantiation of a VM" +
+ "using à la carte and Multicloud module")
+SERVICE_COMPONENTS="SDC, DMAAP, AAI, SO, SDNC, Multicloud"
USE_MULTICLOUD = True
# Set ONLY_INSTANTIATE to true to run an instantiation without repeating
diff --git a/src/onaptests/configuration/ubuntu16_nomulticloud_settings.py b/src/onaptests/configuration/ubuntu16_nomulticloud_settings.py
index c6c9e66..310fafc 100644
--- a/src/onaptests/configuration/ubuntu16_nomulticloud_settings.py
+++ b/src/onaptests/configuration/ubuntu16_nomulticloud_settings.py
@@ -9,6 +9,8 @@ from .settings import * # pylint: disable=W0614
# pylint: disable=bad-whitespace
# The ONAP part
+SERVICE_DETAILS="Onboarding, distribution and instanitation of an Ubuntu VM using à la carte"
+SERVICE_COMPONENTS="SDC, DMAAP, AAI, SO, SDNC"
USE_MULTICLOUD = False
# Set ONLY_INSTANTIATE to true to run an instantiation without repeating
# onboarding and related AAI configuration (Cloud config)
diff --git a/src/onaptests/scenario/basic_vm.py b/src/onaptests/scenario/basic_vm.py
index 15a6f5d..48fd169 100644
--- a/src/onaptests/scenario/basic_vm.py
+++ b/src/onaptests/scenario/basic_vm.py
@@ -42,7 +42,7 @@ class BasicVm(testcase.TestCase):
self.__logger.info("No cleanup requested. Test completed.")
self.result = 100
-
def clean(self):
"""Clean Additional resources if needed."""
- pass
+ self.__logger.info("Generate Test report")
+ self.test.reports_collection.generate_report()
diff --git a/src/onaptests/steps/reports_collection.py b/src/onaptests/steps/reports_collection.py
index b61b571..62c0447 100644
--- a/src/onaptests/steps/reports_collection.py
+++ b/src/onaptests/steps/reports_collection.py
@@ -1,5 +1,7 @@
+import sys
from typing import Dict
-
+from jinja2 import Environment, FileSystemLoader, select_autoescape
+from onapsdk.configuration import settings
class ReportsCollection:
"""Collection to store steps execution statuses."""
@@ -29,7 +31,34 @@ class ReportsCollection:
"""
report: Dict[str, str] = {}
for element in self._collection[::-1]:
- print(element)
- print(type(element))
report.update(element)
return report
+
+ def generate_report(self) -> None:
+ step_list = self.report
+ failing_steps = []
+ for step,status in step_list.items():
+ if 'FAIL' in status:
+ failing_steps[step] = status
+ usecase = settings.SERVICE_NAME
+ try:
+ details = settings.SERVICE_DETAILS
+ except:
+ details = ""
+ try:
+ components = settings.SERVICE_COMPONENTS
+ except:
+ components = ""
+ log_path = settings.LOG_CONFIG['handlers']['file']['filename']
+ jinja_env = Environment(
+ autoescape=select_autoescape(['html']),
+ loader=FileSystemLoader(sys.path[-1] + '/onaptests/templates/reporting'))
+
+ jinja_env.get_template('reporting.html.j2').stream(
+ failing_steps=failing_steps,
+ steps=step_list,
+ usecase=usecase,
+ details=details,
+ components=components,
+ log_path=log_path).dump(
+ settings.REPORTING_FILE_PATH)
diff --git a/src/onaptests/templates/reporting/base.html.j2 b/src/onaptests/templates/reporting/base.html.j2
new file mode 100644
index 0000000..cbb4e44
--- /dev/null
+++ b/src/onaptests/templates/reporting/base.html.j2
@@ -0,0 +1,231 @@
+{% macro color(failing, total) %}
+{% if failing == 0 %}
+is-success
+{% else %}
+{% if (failing / total) <= 0.1 %}
+is-warning
+{% else %}
+is-danger
+{% endif %}
+{% endif %}
+{% endmacro %}
+
+{% macro percentage(failing, total) %}
+{{ ((total - failing) / total) | round }}
+{% endmacro %}
+
+{% macro statistic(resource_name, failing, total) %}
+{% set success = total - failing %}
+<div class="level-item has-text-centered">
+ <div>
+ <p class="heading">{{ resource_name | capitalize }}</p>
+ <p class="title">{{ success }}/{{ total }}</p>
+ <progress class="progress {{ color(failing, total) }}" value="{{ success }}" max="{{ total }}">{{ percentage(failing, total) }}</progress>
+ </div>
+ </div>
+{% endmacro %}
+
+{% macro pods_table(pods) %}
+<div id="pods" class="table-container">
+ <table class="table is-fullwidth is-striped is-hoverable">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Ready</th>
+ <th>Status</th>
+ <th>Reason</th>
+ <th>Restarts</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for pod in pods %}
+ <tr>
+ <td><a href="./pod-{{ pod.name }}.html" title="{{ pod.name }}">{{ pod.k8s.metadata.name }}</a></td>
+ {% if pod.init_done %}
+ <td>{{ pod.running_containers }}/{{ (pod.containers | length) }}</td>
+ {% else %}
+ <td>Init:{{ pod.runned_init_containers }}/{{ (pod.init_containers | length) }}</td>
+ {% endif %}
+ <td>{{ pod.k8s.status.phase }}</td>
+ <td>{{ pod.k8s.status.reason }}</td>
+ {% if pod.init_done %}
+ <td>{{ pod.restart_count }}</td>
+ {% else %}
+ <td>{{ pod.init_restart_count }}</td>
+ {% endif %}
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
+{% endmacro %}
+
+{% macro key_value_description_list(title, dict) %}
+<dt><strong>{{ title | capitalize }}:</strong></dt>
+<dd>
+ {% if dict %}
+ {% for key, value in dict.items() %}
+ {% if loop.first %}
+ <dl>
+ {% endif %}
+ <dt>{{ key }}:</dt>
+ <dd>{{ value }}</dd>
+ {% if loop.last %}
+ </dl>
+ {% endif %}
+ {% endfor %}
+ {% endif %}
+</dd>
+{% endmacro %}
+
+{% macro description(k8s) %}
+<div class="container">
+ <h1 class="title is-1">Description</h1>
+ <div class="content">
+ <dl>
+ {% if k8s.spec.type %}
+ <dt><strong>Type:</strong></dt>
+ <dd>{{ k8s.spec.type }}</dd>
+ {% if (k8s.spec.type | lower) == "clusterip" %}
+ <dt><strong>Headless:</strong></dt>
+ <dd>{% if (k8s.spec.cluster_ip | lower) == "none" %}Yes{% else %}No{% endif %}</dd>
+ {% endif %}
+ {% endif %}
+ {{ key_value_description_list('Labels', k8s.metadata.labels) | indent(width=6) }}
+ {{ key_value_description_list('Annotations', k8s.metadata.annotations) | indent(width=6) }}
+ {% if k8s.spec.selector %}
+ {% if k8s.spec.selector.match_labels %}
+ {{ key_value_description_list('Selector', k8s.spec.selector.match_labels) | indent(width=6) }}
+ {% else %}
+ {{ key_value_description_list('Selector', k8s.spec.selector) | indent(width=6) }}
+ {% endif %}
+ {% endif %}
+ {% if k8s.phase %}
+ <dt><strong>Status:</strong></dt>
+ <dd>{{ k8s.phase }}</dd>
+ {% endif %}
+ {% if k8s.metadata.owner_references %}
+ <dt><strong>Controlled By:</strong></dt>
+ <dd>{{ k8s.metadata.owner_references[0].kind }}/{{ k8s.metadata.owner_references[0].name }}</dd>
+ {% endif %}
+ </dl>
+ </div>
+</div>
+{% endmacro %}
+
+{% macro pods_container(pods, parent, has_title=True) %}
+<div class="container">
+ {% if has_title %}
+ <h1 class="title is-1">Pods</h1>
+ {% endif %}
+ {% if (pods | length) > 0 %}
+ {{ pods_table(pods) | indent(width=2) }}
+ {% else %}
+ <div class="notification is-warning">{{ parent }} has no pods!</div>
+ {% endif %}
+</div>
+{% endmacro %}
+
+{% macro two_level_breadcrumb(title, name) %}
+<section class="section">
+ <div class="container">
+ <nav class="breadcrumb" aria-label="breadcrumbs">
+ <ul>
+ <li><a href="./index.html">Summary</a></li>
+ <li class="is-active"><a href="#" aria-current="page">{{ title | capitalize }} {{ name }}</a></li>
+ </ul>
+ </nav>
+ </div>
+</section>
+{% endmacro %}
+
+{% macro pod_parent_summary(title, name, failed_pods, pods) %}
+{{ summary(title, name, [{'title': 'Pod', 'failing': failed_pods, 'total': (pods | length)}]) }}
+{% endmacro %}
+
+{% macro number_ok(number, none_value, total=None) %}
+{% if number %}
+{% if total and number < total %}
+<span class="tag is-warning">{{ number }}</span>
+{% else %}
+{{ number }}
+{% endif %}
+{% else %}
+<span class="tag is-warning">{{ none_value }}</span>
+{% endif %}
+{% endmacro %}
+
+{% macro summary(title, name, statistics) %}
+<section class="hero is-light">
+ <div class="hero-body">
+ <div class="container">
+ <h1 class="title is-1">
+ {{ title | capitalize }} {{ name }} Summary
+ </h1>
+ <nav class="level">
+ {% for stat in statistics %}
+ {% if stat.total > 0 %}
+ {{ statistic(stat.title, stat.failing, stat.total) | indent(width=8) }}
+ {% endif %}
+ {% endfor %}
+ </nav>
+ </div>
+ </div>
+</section>
+{% endmacro %}
+
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Tests results - {% block title %}{% endblock %}</title>
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.0/css/bulma.min.css">
+ <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
+ {% block more_head %}{% endblock %}
+ </head>
+ <body>
+ <nav class="navbar" role="navigation" aria-label="main navigation">
+ <div class="navbar-brand">
+ <a class="navbar-item" href="https://www.onap.org">
+ <img src="https://www.onap.org/wp-content/uploads/sites/20/2017/02/logo_onap_2017.png" width="234" height="50">
+ </a>
+
+ <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
+ <span aria-hidden="true"></span>
+ <span aria-hidden="true"></span>
+ <span aria-hidden="true"></span>
+ </a>
+ </div>
+
+ <div id="navbarBasicExample" class="navbar-menu">
+ <div class="navbar-start">
+ <a class="navbar-item">
+ Summary
+ </a>
+ </div>
+ </div>
+ </nav>
+
+ {% block content %}{% endblock %}
+
+ <footer class="footer">
+ <div class="container">
+ <div class="columns">
+ <div class="column">
+ <p class="has-text-grey-light">
+ <a href="https://bulma.io/made-with-bulma/">
+ <img src="https://bulma.io/images/made-with-bulma.png" alt="Made with Bulma" width="128" height="24">
+ </a>
+ </div>
+ <div class="column">
+ <a class="has-text-grey" href="https://gitlab.com/Orange-OpenSource/lfn/tools/kubernetes-status" style="border-bottom: 1px solid currentColor;">
+ Improve this page on Gitlab
+ </a>
+ </p>
+ </div>
+ </div>
+ </div>
+ </footer>
+ </body>
+</html>
diff --git a/src/onaptests/templates/reporting/reporting.html.j2 b/src/onaptests/templates/reporting/reporting.html.j2
new file mode 100644
index 0000000..5dafe3f
--- /dev/null
+++ b/src/onaptests/templates/reporting/reporting.html.j2
@@ -0,0 +1,43 @@
+{% extends "base.html.j2" %}
+{% block title %}Summary{% endblock %}
+{% block content %}
+ {{ summary('Results', "", [
+ { 'title': 'Pythonsdk Tests', 'failing': (failing_steps | length), 'total': (steps | length)},
+ ])
+ }}
+
+ <section class="section">
+ <div class="container">
+ <h1 class="title is-1">
+ {{ usecase }}
+ </h1>
+ Description: {{ details }}
+ <br>
+ Components: {{ components }}
+ <br>
+ <a href="{{ log_path }}"> Logs</a>
+ <!-- Pythonsdk steps table -->
+ <div id="helms" class="table-container">
+ <table class="table is-fullwidth is-striped is-hoverable">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for step,value in steps.items() %}
+ <tr {% if value == 'FAIL' %} class="has-background-danger" {% else %} class="has-background-success-light" {% endif %}>
+ <td>
+ {{ step }}
+ </td>
+ <td>
+ {{ value }}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+{% endblock %}