Add reporting page creation in pythonsdk-tests 80/113680/2
authormrichomme <morgan.richomme@orange.com>
Thu, 8 Oct 2020 11:46:50 +0000 (13:46 +0200)
committermrichomme <morgan.richomme@orange.com>
Thu, 8 Oct 2020 13:46:29 +0000 (15:46 +0200)
Issue-ID: TEST-269

Signed-off-by: mrichomme <morgan.richomme@orange.com>
Change-Id: I4ab0a2f7a1a1e98ae5d05166c6aa06212d24eeae
Signed-off-by: mrichomme <morgan.richomme@orange.com>
requirements.txt
run_basicvm_nomulticloud.py
src/onaptests/configuration/settings.py
src/onaptests/configuration/ubuntu16_multicloud_yaml_settings.py
src/onaptests/configuration/ubuntu16_nomulticloud_settings.py
src/onaptests/scenario/basic_vm.py
src/onaptests/steps/reports_collection.py
src/onaptests/templates/reporting/base.html.j2 [new file with mode: 0644]
src/onaptests/templates/reporting/reporting.html.j2 [new file with mode: 0644]

index 7ed56d2..a2e82b3 100644 (file)
@@ -1,3 +1,4 @@
 xtesting
 openstacksdk
 onapsdk>=7.0.0
+jinja2
index e6be410..9ebefb8 100644 (file)
@@ -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()
index 7385fa0..3339082 100644 (file)
@@ -38,4 +38,5 @@ LOG_CONFIG = {
     }
 }
 
+REPORTING_FILE_PATH = "/tmp/reporting.html"
 # SOCK_HTTP = "socks5h://127.0.0.1:8080"
index 341dc16..d45b142 100644 (file)
@@ -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
index c6c9e66..310fafc 100644 (file)
@@ -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)
index 15a6f5d..48fd169 100644 (file)
@@ -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()
index b61b571..62c0447 100644 (file)
@@ -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 (file)
index 0000000..cbb4e44
--- /dev/null
@@ -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 (file)
index 0000000..5dafe3f
--- /dev/null
@@ -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 %}